在Snake类中添加了lives变量表示蛇的生命,当蛇撞墙或撞到自己时,减少一条命。当没有生命了,游戏结束。也添加了reset()函数,重新开始游戏。在主循环中添加了判断是否填满屏幕的条件,如果填满了则获胜并退出游戏。在move()函数中添加了让蛇可以穿过墙壁到达另一端的代码。在decision()函数中添加了根据食物位置决定移动方向的代码。在游戏循环中添加了判断是否使用AI控制蛇的代码,按下A键则启用AI控制,否则为手动控制。并且在decision()函数中添加了判断蛇不可以向身体后方移动的代码。
为了实现开始界面,我们添加了一个start_screen()函数,并在主程序中第一次调用这个函数,让玩家选择手动或者AI控制。当玩家按下M键,则返回False即为手动控制;当玩家按下A键,则返回True表示AI控制。主程序中的ai_control变量即为是否启用AI控制的标志。
import pygame
import random
# 初始化Pygame
pygame.init()
# 游戏设置
screen_width = 800
screen_height = 600
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("贪吃蛇")
# 颜色定义
black = (0, 0, 0)
white = (255, 255, 255)
red = (255, 0, 0)
# 蛇的方向定义
UP = 1
DOWN = 2
LEFT = 3
RIGHT = 4
# 定义蛇类
class Snake:
def __init__(self):
self.x = screen_width / 2
self.y = screen_height / 2
self.width = 20
self.height = 20
self.color = white
self.direction = random.choice([UP, DOWN, LEFT, RIGHT])
self.body = [(self.x, self.y)]
self.score = 0
self.lives = 3 # 添加三条命
def move(self):
# 根据方向移动蛇头
if self.direction == UP:
self.y -= self.height
elif self.direction == DOWN:
self.y += self.height
elif self.direction == LEFT:
self.x -= self.width
elif self.direction == RIGHT:
self.x += self.width
# 检查是否吃到食物
if self.body[0] == food.position:
food.reset()
self.score += 1
self.body.insert(0, (self.x, self.y))
else:
self.body.insert(0, (self.x, self.y))
self.body.pop()
# 让蛇可以穿过墙壁到达另一端
if self.x < 0:
self.x = screen_width - self.width
elif self.x > screen_width - self.width:
self.x = 0
elif self.y < 0:
self.y = screen_height - self.height
elif self.y > screen_height - self.height:
self.y = 0
# 检查是否碰到自己的身体或者没有生命了
if self.lives > 0 and self.body[0] in self.body[1:]:
self.lives -= 1 # 减少一条命
self.reset() # 重新开始游戏
elif self.lives == 0:
print("Game over!")
pygame.quit()
quit()
def decision(self):
# 获取蛇头和食物的位置
head_x, head_y = self.body[0]
food_x, food_y = food.position
# 判断上下左右哪个方向离食物最近,并决定移动的方向
if food_x < head_x:
if self.direction != RIGHT:
self.direction = LEFT
elif food_x > head_x:
if self.direction != LEFT:
self.direction = RIGHT
elif food_y < head_y:
if self.direction != DOWN:
self.direction = UP
elif food_y > head_y:
if self.direction != UP:
self.direction = DOWN
def reset(self):
self.x = screen_width / 2
self.y = screen_height / 2
self.direction = random.choice([UP, DOWN, LEFT, RIGHT])
self.body = [(self.x, self.y)]
self.score = 0
def draw(self):
for pos in self.body:
pygame.draw.rect(screen, self.color, (pos[0], pos[1], self.width, self.height))
# 定义食物类
class Food:
def __init__(self):
self.width = 20
self.height = 20
self.color = red
self.reset()
def reset(self):
self.position = (random.randint(0, (screen_width - self.width) / self.width) * self.width,
random.randint(0, (screen_height - self.height) / self.height) * self.height)
def draw(self):
pygame.draw.rect(screen, self.color, (self.position[0], self.position[1], self.width, self.height))
# 初始化蛇和食物
snake = Snake()
food = Food()
# 游戏循环
clock = pygame.time.Clock()
def start_screen():
# 添加开始界面,可以选择手动控制或者AI控制
font = pygame.font.Font(None, 36)
text_manual = font.render("Press M for Manual Control", True, white)
text_ai = font.render("Press A for AI Control", True, white)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
screen.fill(black)
screen.blit(text_manual, (screen_width/2-150, screen_height/2-50))
screen.blit(text_ai, (screen_width/2-120, screen_height/2))
pygame.display.update()
keys = pygame.key.get_pressed()
if keys[pygame.K_m]:
return False # 手动控制
elif keys[pygame.K_a]:
return True # AI控制
ai_control = start_screen()
while True:
# 监听事件
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
# 判断是否使用AI控制蛇
if ai_control:
snake.decision()
else:
keys = pygame.key.get_pressed()
if keys[pygame.K_UP]:
snake.direction = UP
elif keys[pygame.K_DOWN]:
snake.direction = DOWN
elif keys[pygame.K_LEFT]:
snake.direction = LEFT
elif keys[pygame.K_RIGHT]:
snake.direction = RIGHT
# 移动蛇
snake.move()
# 绘制蛇和食物
screen.fill(black)
snake.draw()
food.draw()
# 判断是否填满屏幕
if snake.score == (screen_width * screen_height) / (snake.width * snake.height):
print("You win!")
pygame.quit()
quit()
# 刷新屏幕
pygame.display.update()
# 控制帧率
clock.tick(10)