贪吃蛇是一个经典的游戏,它的简单和耐玩性让它成为了许多人最喜欢的游戏之一。而且,利用Python语言来开发贪吃蛇游戏,是一个非常有趣的学习项目。在本篇文章中,我将指导你如何用Python打造自己的贪吃蛇游戏。
本项目所需的库
首先,我们需要导入Python中的pygame库,因为pygame库可以帮助我们在屏幕上绘制图形和处理用户的输入。我们可以通过以下代码,下载并安装pygame库:
pip install pygame
游戏的设计
接下来,我们需要考虑游戏中的一些重要组件。考虑到贪吃蛇游戏的基本玩法,我们需要以下内容:
- 一个贪吃蛇
- 食物
- 游戏界面
- 得分系统
构建一个贪吃蛇类
现在,我们可以着手构建一个贪吃蛇类。这个类的工作就是创建贪吃蛇的实例,并且你可以控制贪吃蛇的移动和蛇身的增长。
除了使用pygame库外,我们还将需要使用另一个Python库,该库名为random库。Random库可以生成随机数,使每个新生成的食物在游戏界面上的位置都不重复。
首先,我们定义贪吃蛇的实例,然后初始化函数参数涉及到的变量:
class Snake:
def __init__(self):
self.length = 1
self.positions = [(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2)]
self.direction = RIGHT_DIRECTION
self.color = (17, 24, 47)
接下来,我们就需要创造一个函数,它可以使我们的贪吃蛇移动,并且实现了贪吃蛇的蛇身增长的效果:
def crawl(self):
head_x, head_y = self.positions[0]
if self.direction == RIGHT_DIRECTION:
new_head_position = (head_x + GRID_SIZE, head_y)
elif self.direction == LEFT_DIRECTION:
new_head_position = (head_x - GRID_SIZE, head_y)
elif self.direction == DOWN_DIRECTION:
new_head_position = (head_x, head_y + GRID_SIZE)
elif self.direction == UP_DIRECTION:
new_head_position = (head_x, head_y - GRID_SIZE)
self.positions = [new_head_position] + self.positions[:-1]
return new_head_position
def grow(self):
self.length += 1
self.positions = [self.positions[0]] + self.positions
def collide_with_wall(self):
return (self.positions[0][0] in (0, SCREEN_WIDTH - GRID_SIZE) or
self.positions[0][1] in (0, SCREEN_HEIGHT - GRID_SIZE))
def collide_with_self(self):
return any(segment == self.positions[0] for segment in self.positions[1:])
def reset(self):
self.length = 1
self.positions = [(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2)]
self.direction = RIGHT_DIRECTION
def draw(self, surface):
for position in self.positions:
r = pygame.Rect((position[0], position[1]), (GRID_SIZE, GRID_SIZE))
pygame.draw.rect(surface, self.color, r)
pygame.draw.rect(surface, (93, 216, 228), r, 1)
我们定义了一些贪吃蛇的行为,包括:
- 爬行
- 成长
- 碰撞墙壁
- 碰撞自己
- 重置
- 绘制
现在我们的贪吃蛇基础代码已经可以运行了,但是还缺少以下两点:
- 我们还没有在游戏主循环中对用户输入进行响应。
- 我们还没有在“碰撞食物”的函数中引入食物。
手动操控贪吃蛇
让我们来看看如何响应玩家的输入。为此,我们需要在游戏主循环中添加一些代码来监听玩家的键盘输入。我们将做出以下四个方向的控制:
def handle_events(self):
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == KEYDOWN:
if event.key == K_RIGHT:
self.direction = RIGHT_DIRECTION
elif event.key == K_LEFT:
self.direction = LEFT_DIRECTION
elif event.key == K_DOWN:
self.direction = DOWN_DIRECTION
elif event.key == K_UP:
self.direction = UP_DIRECTION
每当玩家按下键盘上的方向键时,我们都会更新贪吃蛇的方向。
还要在主循环中调用handle_events()函数,这样我们贪吃蛇实例的属性(比如它的方向)就可以根据玩家的输入作出相应的调整。
while True:
snake.handle_events()
draw_grid(surface)
snake.move()
food.draw(surface)
snake.draw(surface)
如果我们现在运行程序,我们的贪吃蛇已经可以经由键盘控制移动了!
吃掉食物
我们还缺了一个关键的功能: 更新得分板和随机生成食物。我们有一个需要做的工作是在如何响应食物与贪吃蛇相撞时添加一些特定行为。
当食物得到贪吃蛇时,我们需要做三件事:
- 更新分数
- 控制贪吃蛇成长
- 随机生成新的食物
碰撞检测应该在贪吃蛇的移动函数中调用。如果发生碰撞,该函数将返回一个布尔值 True。
def is_collision(self, position):
return position in self.positions[1:]
现在,我们可以将Is_collision()函数用于将食物加入随机生成的代码中。要做到这一点,我们给食物一个新的位置,如果它的位置与贪吃蛇的身体段重叠的话,我们就需要重新生成一个位置。否则,我们就使食物的位置等于新的食物位置。
food_position = self.get_random_food_position()
while snake.is_collision(food_position):
food_position = self.get_random_food_position()
food.set_position(food_position)
一个函数贯穿整个程序 —— 游戏循环
所以,到目前为止,我们已经写了游戏程序的所有关键组成,但是我们还需要把这些组成连接起来,以建立一个连续的游戏循环。我们需要在程序中实现一个很重要的函数,这个函数叫作主循环(main loop )。 它会不停地运行,直到玩家这个程序或程序出错停止。
在我们的主循环中,我们需要重复执行以下任务:
- 响应用户的输入。
- 在屏幕上更新各个图像的位置。
- 碰撞检测。
- 在屏幕上显示和更新得分。
在Python中,我们可以使用while循环重复执行这个循环,直到某个条件满足。
while True:
snake.handle_events()
draw_grid(surface)
snake.move()
if snake.is_collision(food.position):
snake.grow()
food.set_position(snake)
draw_score(surface)
snake.draw(surface)
food.draw(surface)
if snake.collide_with_wall() or snake.collide_with_self():
game_over(surface)
reset_game(snake, food)
draw_score(surface)
pygame.display.update()
clock.tick(15)
我们的主函数需要做的最后一件事,是依照上述代码进行画面更新(pygame.display.update())和主循环时钟计数器的更新(clock.tick(15))。pygame.display.update()是Pygame的函数,它可以更新游戏屏幕上的画面。pygame.Clock.tick()函数用于控制循环帧的速率。 ‘15’是定义游戏的速度。
总结
我们已经在这篇文章中构建了一个完整的 Python 贪吃蛇游戏。通过使用 Pygame 库和随机库来完成这个项目,了解了如何使用 Python 语言编写游戏以及我们有关条件语句,库函数,函数参数,工作流程与方法的知识。这是Python游戏开发的一个非常好的入门项目。