文章目录

基本抽向和常量控制逻辑绘图初始化主循环

基本抽向和常量

贪吃蛇的逻辑很简单,就是一个连续方块组成的蛇,这条蛇可以向前走,也可以向两侧转弯。如果蛇的前面有一个食物,那么蛇吃掉食物后,身体会变长。

所以,贪吃蛇可以用一组

(

x

,

y

)

(x,y)

(x,y)坐标表示,每一个坐标都是一个方块,所有方块连在一起就是蛇的身体,同理,食物可用单个的

(

x

,

y

)

(x,y)

(x,y)表示。

在初始化过程中,

(

x

,

y

)

(x,y)

(x,y)虽然是随机生成,但需要有一个范围,最起码不能超过游戏窗口的边界。为此,可将游戏窗口的尺寸设为常量,同时需要设置方块的尺寸,并通过方块和窗口尺寸的关系,得到初始化的坐标范围。

import random

import pygame.font

# 游戏窗口设置

WIDTH, HEIGHT = 800, 500

SIZE = 10

WBOX, HBOX = WIDTH // SIZE, HEIGHT // SIZE

# 定义颜色

BLACK = (0, 51, 0) # 深绿色

GREEN = (0, 255, 0) # 亮绿色

RED = (255,0,0) # 红色

# 初始化位置

newBox = lambda: (random.randrange(1, WBOX) * SIZE,

random.randrange(1, HBOX) * SIZE)

控制逻辑

在未经交互的情况下,贪吃蛇每次向前走一步,所谓一步,可以理解为贪吃蛇最小方块单元的尺寸。由于贪吃蛇的前进方向不同,故而这恶脚步所对应的坐标变化

(

d

x

,

d

y

)

(dx,dy)

(dx,dy)是不同的。在平面上,总共有四分方向,从而对应四种脚步。而调整贪吃蛇前进方向,则可通过上下左右这几个方向键来实现。最终代码如下

# 按键对应的蛇的脚步

keyDct = {

pygame.K_UP : (0,-SIZE), pygame.K_DOWN: (0,SIZE),

pygame.K_LEFT: (-SIZE,0), pygame.K_RIGHT: (SIZE,0)

}

def updateStep(step, key):

nextStep = keyDct[key]

flag = nextStep[0]+step[0] or nextStep[1]+step[1]

return nextStep if flag else step

其中,keyDct是按键和脚步的对应关系,后者则根据按键来更新贪吃蛇的前进方向。此中需要做一个判断,即按键方向和当前方向是否相反,如果贪吃蛇正在向上走,那么没法控制它向下走。

绘图

绘图时需要一个绘图窗口,剩下的就几乎没有需要注意的了,贪吃蛇和食物的绘图逻辑如下。

def drawSnake(screen, snake, food, font):

for x,y in snake:

pygame.draw.rect(screen, GREEN, pygame.Rect(x, y, SIZE, SIZE))

pygame.draw.rect(screen, RED, pygame.Rect(food[0], food[1], SIZE, SIZE))

# 显示得分

text = font.render(f"蛇身长度: {len(snake)}", True, RED)

screen.blit(text, (10, 10))

除此之外,还需要绘制游戏结束时的窗口,主要就是显示一些文字。

def drawGamerOver(screen, font):

w, h = font.size('GAME OVER')

msg = font.render('GAME OVER', True, RED)

screen.blit(msg, ((WIDTH - w) // 2, (HEIGHT - h) // 2 - 40))

w, h = font.size('点击任意位置,再来一局')

msg = font.render('点击任意位置,再来一局', True, RED)

screen.blit(msg, ((WIDTH - w) // 2, (HEIGHT - h) // 2 + 40))

初始化

游戏只需要初始化三个东西,即食物位置、蛇的位置以及蛇的前进方向,故而封装一个init()函数,返回脚步、食物、蛇头以及蛇。

# 随机选择蛇的脚步

def init():

step = random.choice(list(keyDct.values()))

food, head = newBox(), newBox()

return step, food, head, [head]

# 初始化pygame

pygame.init()

screen = pygame.display.set_mode((WIDTH, HEIGHT))

pygame.display.set_caption("贪吃蛇游戏")

font = pygame.font.Font(r"./SimHei.ttf", 30)

step, food, head, snake = init()

running, gameOver = True, False

主循环

我们需要设置两个变量来调控循环,一个是是否继续游戏,另一个是游戏是否失败。二者分别用running和gameOver表示。

当游戏失败时,显示游戏失败的说明,同时,若按键盘怕或者点击鼠标,则游戏重新初始化;如果关闭窗口,则游戏结束。

代码如下

isMid = lambda x, L, R : x < L or x > R

running, gameOver = True, False

while running:

for event in pygame.event.get():

if event.type == pygame.QUIT:

pygame.quit()

running = False

if gameOver:

step, food, head, snake = init()

gameOver = False

# 监听键盘事件

if event.type == pygame.KEYDOWN and event.key in keyDct:

step = updateStep(step, event.key)

# 更新蛇的位置

head = (head[0]+step[0], head[1]+step[1])

# 蛇体增长

snake.insert(0, head)

if head == food:

food = newBox()

else:

snake.pop()

# 绘制游戏界面

screen.fill(BLACK)

if gameOver:

drawGamerOver(screen, font)

else:

drawSnake(screen, snake, food, font)

# 检测碰撞

gameOver = isMid(head[0], 0, WIDTH-1) or isMid(head[1], 0, HEIGHT-1) or head in snake[1:]

pygame.display.flip()

pygame.time.Clock().tick(10) # 控制游戏速度

游戏效果如下

参考文章

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: