乐愚社区Beta

 编程语言  >  pygame入门05.02 —— 经典贪吃蛇游戏01

pygame入门05.02 —— 经典贪吃蛇游戏01

原来是稀琳  L6  • 12小时前 • 回复 1 • 只看楼主举报    

我是一个python入门的小白,做这个系列即是为了巩固pygame的相关知识,也是为了考验自己坚持做一件事。另外如果以下内容有错误或不规范的请各位大佬积极指出,谢谢大家 。

要想完成贪吃蛇游戏就必须了解贪吃蛇游戏的一些规则:

1、蛇头会不断的运动

2、食物会随机的生成,且食物不会生成在蛇的身体上

3、蛇头每吃一个食物就会增加一节身体

4、蛇吃到自己的身体或蛇头碰到墙壁(窗口边界)都宣判死亡。

——————————————————————————————————————————————————————

好的接下来一一讲解:

1、蛇头不断的运动 

蛇头本质上是一个正方形的运动,这个可以看上一节的教程(pygame入门05.01),它讲的就是这个问题,我个人觉得还是比较详细的,如果不懂,可以在评论区留言,我有时间会进行回复的。

2、食物会随机的生成,且食物不会生成在蛇的身体上

食物也是一个正方形,实际上讲的就是随机生成一个正方形的意思,那么应该如何做呢?随机数的生成肯定是数字的随机生成,很明显要找变量,下面会有一个代码:

  import pygame
import sys
import random
'''
主题内容省略,
如窗口大小,名称

为了更好的讲解窗口长 = 640,宽 = 480
'''
# 画食物的变量
food_x = random.randint(0,32) * 20
food_y = random.randint(0,23) * 20
food_height = 20
food_width = 20

'''  循环中 '''
    #吃食物   第二步
    if head_x == food_x and head_y == food_y:
        food_x = random.randint(0,31) * 20
        food_y = random.randint(0,23) * 20
        food_height = 20
        food_width = 20
            #显示食物
        pygame.draw.rect(screen,(225,0,0),(food_x,food_y,
                                       food_width,food_height))
    else:
        snake_parts.pop(0)
    
    while (food_x,food_y) in snake_parts:
            food_x = random.randint(0,32) * 20
            food_y = random.randint(0,23) * 20

    #显示食物  第一步
    pygame.draw.rect(screen,(225,0,0),(food_x,food_y,
                                       food_width,food_height))
'''  循环中 '''
#关闭游戏窗口
pygame.quit()     
sys.exit()
  

     随机数的在食物的X,Y坐标中生成,这样就可以解决食物随机生成的问题了。

另外在上面的代码中,你会看到 food_x = random.randint(0,32) * 20 这样的代码,那么这是为什么呢,首先你在完成贪吃蛇游戏的时候一定要有网格的思想,你要明确蛇头和身体是正方形,食物也是正方形,它们应该处在网格中运动,否则整个游戏会出现一个非常大的问题(自己写过就明白了)

食物不会生成在蛇的身体上怎么解决呢?其实还挺简单的,只要确保食物的xy坐标不在蛇身体的xy坐标上就行,上面的代码:while (food_x,food_y) in snake_parts: 就是解决方法,在上面的代码没有给出snake_parts变量是什么,后面在整个代码出现会给出。

3、蛇头每吃一个食物就会增加一节身体

吃食物的办法是身体的X,Y坐标和食物X,Y坐标一旦相等就让食物消失再随机生成,蛇也算是吃了食物。

吃食物后蛇身体增加其实还是挺复杂的,看图在进行讲解:

 

看到图后,我们就可以明白,其实就是在原来的基础上,在原先的头前增加一个头,之前的那个头颜色改变,这样既不会有延迟,也可以避免在头转弯吃食物时的代码不多想和多余。

4、蛇吃到自己的身体或蛇头碰到墙壁(窗口边界)都宣判死亡。

这个其实非常的简单,基础的逻辑语句就可以完成,我本人用的时函数的知识和其它的一些逻辑运用,自己写的话会有不同的体会的。

完整代码展示:

import pygame
import sys
import random

from pygame import*
pygame.init()

#节省内存
game_clock = pygame.time.Clock()
game_speed =  60

#建立游戏窗口
screen = pygame.display.set_mode((640,480))
pygame.display.set_caption("经典贪吃蛇游戏")


# 画食物的变量
food_x = random.randint(0,32) * 20
food_y = random.randint(0,23) * 20
food_height = 20
food_width = 20

#画蛇头的变量
head_x = 0
head_y = 0
head_height = 20
head_width = 20

#蛇头运动变量
snake_direction = 'RIGHT'
snake_speed = 20
clock = pygame.time.Clock()

#增加蛇身体的变量
snake_parts = [(head_x,head_y)]

#游戏结束函数
def GameOver():
    font = pygame.font.SysFont(None,50)
    text_content = font.render("GAME OVER",True,(184,184,184),(0,0,0))
    text_rect = text_content.get_rect()
    text_rect.center = (640 // 2,480 // 2)
    screen.blit(text_content,text_rect)
    pygame.display.update()   
    pygame.quit()  
    sys.exit()

#主循环
runing = True
while runing:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            runing = False

    #蛇头运动
        elif event.type == pygame.KEYDOWN:
            if event.key  == pygame.K_UP and snake_direction != 'DOWN': 
                snake_direction = 'UP' 
            elif event.key  == pygame.K_DOWN and snake_direction != 'UP': 
                snake_direction = 'DOWN' 
            elif event.key  == pygame.K_LEFT and snake_direction != 'RIGHT': 
                snake_direction = 'LEFT' 
            elif event.key  == pygame.K_RIGHT and snake_direction != 'LEFT': 
                snake_direction = 'RIGHT' 
 
    # 更新蛇头位置 
    if snake_direction == 'UP': 
        head_y -= snake_speed 
    elif snake_direction == 'DOWN': 
        head_y += snake_speed 
    elif snake_direction == 'LEFT': 
        head_x -= snake_speed 
    elif snake_direction == 'RIGHT': 
        head_x += snake_speed 
    
    #限定蛇的运动范围
    if head_x < 0 or head_y < 0:
        GameOver()
        
        
    elif head_x > 640 or head_y > 480:
        GameOver()
        

    #吃食物
    if head_x == food_x and head_y == food_y:
        food_x = random.randint(0,31) * 20
        food_y = random.randint(0,23) * 20
        food_height = 20
        food_width = 20
            #显示食物
        pygame.draw.rect(screen,(225,0,0),(food_x,food_y,
                                       food_width,food_height))
    else:
        snake_parts.pop(0)
    
    while (food_x,food_y) in snake_parts:
            food_x = random.randint(0,32) * 20
            food_y = random.randint(0,23) * 20
        
        #增加蛇的身体
    snake_parts.append((head_x,head_y))

    # 蛇吃到身体后的结束程序
    head_rect = pygame.Rect(head_x,head_y,head_width,head_height)
    for part in snake_parts[:-1]:
        body_rect = pygame.Rect(part[0], part[1], head_width, head_height)
        if head_rect.colliderect(body_rect):
            GameOver()

    #更新画面
    screen.fill((0,0,0))

    
    #显示身体 
    
    for part in snake_parts:
        pygame.draw.rect(screen,(12,140,240),(part[0] ,part[1] ,
                                        head_height,head_width))
        
    #显示蛇头
    pygame.draw.rect(screen,(0,225,100),(head_x,head_y,
                                        head_height,head_width))
    #显示食物
    pygame.draw.rect(screen,(225,0,0),(food_x,food_y,
                                       food_width,food_height))
    

    #刷新屏幕
    pygame.display.update()
    clock.tick(8)

#关闭游戏窗口
pygame.quit()     
sys.exit()

 

总而言之,贪吃蛇游戏代码完成的方式不止一种,后面我会分享另外一种方法,这是我一起浅学面向对象的时候网上看到的,逻辑即清晰又不好理解,可以学习一下。能一路走到这里真的很不容易,继续努力吧。

与君共勉,下期再见。

 


1条回帖
原来是稀琳 楼主  L6  评论于
(0)  回复(0) 1#
且食物不会生成在蛇的身体上,
这句话我打错字了,实在抱歉,应该把“会”字删除。
还没注册帐号?快来注册社区帐号,和我们一起嗨起来!
关于本社区

集各类兴趣爱好于一身的轻量化交流社区,在此您可以和他人一起分享交流您觉得有价值的内容,社区鼓励大家发表原创内容,为社区添砖加瓦!

发帖奖励 → 社区版规 → 招聘版主 →
推荐版块
扫描二维码下载社区APP
回到顶部