目录
引言
贪吃蛇游戏是编程学习过程中的经典项目,它不仅能帮助初学者理解编程基础概念,还能提供游戏开发的实践经验。本文将详细介绍如何使用Python和Pygame库从零开始构建一个完整的贪吃蛇游戏。
贪吃蛇游戏最早出现在1970年代,由于其简单而有趣的游戏机制,迅速成为了经典。游戏的目标是控制一条蛇在有限的空间内移动,吃到食物后蛇身会变长,同时要避免撞到墙壁或自己的身体。这个看似简单的游戏实际上包含了多个重要的编程概念:循环、条件判断、列表操作、随机数生成、用户输入处理等。
在本教程中,我们将一步步构建这个游戏,从基础的环境设置到完整的游戏功能实现,最后还会探讨如何对游戏进行扩展和优化。无论你是编程新手还是想要了解游戏开发的爱好者,这篇教程都将为你提供有价值的指导。
游戏开发准备工作
安装Python和Pygame
在开始开发贪吃蛇游戏之前,我们需要确保已经安装了Python和Pygame库。Python是一种易于学习且功能强大的编程语言,而Pygame则是专为游戏开发设计的Python库,它提供了绘图、声音、输入处理等功能。
-
安装Python:
<ul><li>访问<a data-link-icon="https://csdnimg.cn/release/blog_editor_html/release2.3.8/ckeditor/plugins/CsdnLink/icons/icon-default.png?t=P1C7" data-link-title="Python官网" href="https://www.python.org/downloads/" title="Python官网">Python官网</a>下载最新版本的Python</li><li>安装时勾选"Add Python to PATH"选项,以便在命令行中直接使用Python</li></ul></li><li><p><strong>安装Pygame</strong>:</p><ul><li>打开命令提示符或终端</li><li>输入以下命令安装Pygame:<pre>pip install pygame
- 等待安装完成
-
验证安装:
<ul><li>在Python环境中输入以下代码验证Pygame是否安装成功:<p>python</p><pre>import pygame print(pygame.ver)
- 如果显示Pygame的版本号,则表示安装成功
了解游戏基本原理
在开始编码之前,让我们先了解贪吃蛇游戏的基本原理和核心机制:
-
游戏元素:
<ul><li>蛇:由多个连续的方块组成,随着玩家的控制移动</li><li>食物:随机出现在游戏区域内,蛇吃到后会变长</li><li>游戏区域:有边界的平面,蛇需要在其中移动</li></ul></li><li><p><strong>游戏规则</strong>:</p><ul><li>蛇可以上、下、左、右四个方向移动</li><li>蛇吃到食物后,长度增加,分数增加</li><li>蛇撞到墙壁或自己的身体,游戏结束</li><li>玩家的目标是尽可能地获得高分</li></ul></li><li><p><strong>技术实现要点</strong>:</p><ul><li>使用列表存储蛇的身体位置</li><li>使用随机数生成食物位置</li><li>使用游戏循环不断更新游</li></ul></li>
游戏基础架构
初始化游戏环境
任何Pygame游戏的第一步都是初始化游戏环境。这包括初始化Pygame库本身以及设置一些基本参数。
python
import pygame
import time
import random
# 初始化pygame
pygame.init()
初始化Pygame是创建游戏的第一步,它会启动Pygame的各个模块,为后续的游戏开发做好准备。pygame.init()
函数会返回成功初始化的模块数量和失败的模块数量,但在大多数情况下,我们不需要关注这个返回值。
除了Pygame,我们还导入了time
模块用于控制游戏速度,以及random
模块用于生成随机的食物位置。这三个模块构成了我们贪吃蛇游戏的基础依赖。
设置游戏窗口
游戏窗口是玩家与游戏交互的界面,我们需要设置窗口的大小和标题。
python
# 设置屏幕大小
display_width = 800
display_height = 600
# 创建游戏窗口
dis = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption('贪吃蛇游戏')
在这段代码中,我们首先定义了游戏窗口的宽度和高度,分别为800像素和600像素。然后使用pygame.display.set_mode()
函数创建了一个游戏窗口,并将其赋值给变量dis
(display的缩写)。最后,我们使用pygame.display.set_caption()
函数设置了窗口的标题为"贪吃蛇游戏"。
游戏窗口的大小可以根据需要进行调整。较大的窗口可以提供更大的游戏空间,但也可能需要更多的计算资源。对于贪吃蛇这样的简单游戏,800x600的分辨率已经足够了。
定义颜色和常量
在游戏开发中,我们经常需要使用不同的颜色来绘制游戏元素。在Pygame中,颜色通常用RGB(红、绿、蓝)值表示。
python
# 定义颜色
white = (255, 255, 255)
black = (0, 0, 0)
red = (213, 50, 80)
green = (0, 255, 0)
blue = (50, 153, 213)
# 蛇的大小和速度
snake_block = 10
snake_speed = 15
# 设置游戏时钟
clock = pygame.time.Clock()
在这段代码中,我们定义了几种常用的颜色:白色、黑色、红色、绿色和蓝色。每种颜色都由一个三元组表示,分别对应RGB值。例如,白色的RGB值为(255, 255, 255),表示红、绿、蓝三种颜色都达到最大值。
除了颜色,我们还定义了两个重要的游戏常量:
snake_block
:表示蛇的每个方块的大小,单位为像素snake_speed
:表示蛇的移动速度,单位为帧率(FPS)
最后,我们创建了一个游戏时钟对象clock
,它将用于控制游戏的帧率,确保游戏在不同性能的计算机上运行速度一致。
核心游戏元素
蛇的设计与实现
蛇是贪吃蛇游戏的主角,它由一系列连续的方块组成。在我们的实现中,蛇的身体将使用一个列表来表示,列表中的每个元素都是一个包含x和y坐标的列表。
python
# 绘制蛇
def our_snake(snake_block, snake_list):
for x in snake_list:
pygame.draw.rect(dis, green, [x[0], x[1], snake_block, snake_block])
our_snake
函数接受两个参数:snake_block
表示蛇的每个方块的大小,snake_list
是一个列表,包含蛇身体的所有部分的坐标。函数遍历蛇身体的每个部分,并使用pygame.draw.rect()
函数绘制一个绿色的矩形。
在游戏主循环中,我们将创建并维护snake_List
变量,它将存储蛇的所有身体部分的坐标。当蛇移动时,我们会在列表的末尾添加新的头部位置,并根据蛇的长度决定是否删除列表开头的元素(蛇尾)。
食物系统
食物是贪吃蛇游戏的另一个重要元素。食物会随机出现在游戏区域内,当蛇吃到食物后,蛇的长度会增加,同时食物会在新的随机位置重新生成。
python
# 随机生成食物位置
foodx = round(random.randrange(0, display_width - snake_block) / 10.0) * 10.0
foody = round(random.randrange(0, display_height - snake_block) / 10.0) * 10.0
在这段代码中,我们使用random.randrange()
函数生成随机的x和y坐标,确保食物出现在游戏区域内。为了使食物对齐到网格,我们将随机生成的坐标除以10,四舍五入,然后再乘以10。这样可以确保食物的位置总是10的倍数,与蛇的移动步长一致。
在游戏主循环中,我们会检查蛇是否吃到了食物,如果是,则增加蛇的长度并生成新的食物:
python
# 检查是否吃到食物
if x1 == foodx and y1 == foody:
foodx = round(random.randrange(0, display_width - snake_block) / 10.0) * 10.0
foody = round(random.randrange(0, display_height - snake_block) / 10.0) * 10.0
Length_of_snake += 1
碰撞检测
碰撞检测是贪吃蛇游戏的关键部分,它决定了游戏何时结束。我们需要检测两种类型的碰撞:蛇与墙壁的碰撞和蛇与自身的碰撞。
python
# 检查是否撞墙
if x1 >= display_width or x1 < 0 or y1 >= display_height or y1 < 0:
game_close = True
# 检查是否撞到自己
for x in snake_List[:-1]:
if x == snake_Head:
game_close = True
在第一段代码中,我们检查蛇头的x坐标是否超出了游戏区域的左右边界,或者y坐标是否超出了上下边界。如果是,则将game_close
设置为True
,表示游戏结束。
在第二段代码中,我们遍历蛇身体的所有部分(除了头部),检查是否有任何部分与头部位置相同。如果是,则表示蛇撞到了自己,游戏结束。
游戏控制与交互
键盘输入处理
玩家通过键盘控制蛇的移动方向。在Pygame中,我们可以使用事件系统来捕获键盘输入。
python
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_over = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x1_change = -snake_block
y1_change = 0
elif event.key == pygame.K_RIGHT:
x1_change = snake_block
y1_change = 0
elif event.key == pygame.K_UP:
y1_change = -snake_block
x1_change = 0
elif event.key == pygame.K_DOWN:
y1_change = snake_block
x1_change = 0
在这段代码中,我们使用pygame.event.get()
函数获取所有待处理的事件,然后遍历这些事件。如果事件类型是pygame.QUIT
(例如,玩家点击窗口的关闭按钮),则将game_over
设置为True
,表示游戏结束。
如果事件类型是pygame.KEYDOWN
(玩家按下了键盘上的某个键),我们会检查按下的是哪个键,并相应地更新蛇的移动方向。例如,如果玩家按下了左方向键,我们将x1_change
设置为负的snake_block
(向左移动),并将y1_change
设置为0(不上下移动)。
移动机制
蛇的移动是通过更新蛇头的位置,然后添加新的头部位置到蛇身体列表中来实现的。
python
# 更新蛇的位置
x1 += x1_change
y1 += y1_change
snake_Head = []
snake_Head.append(x1)
snake_Head.append(y1)
snake_List.append(snake_Head)
# 删除多余的蛇身体部分
if len(snake_List) > Length_of_snake:
del snake_List[0]
在这段代码中,我们首先根据当前的移动方向更新蛇头的位置。然后创建一个新的列表snake_Head
,包含蛇头的x和y坐标,并将其添加到snake_List
的末尾。
如果蛇身体的长度超过了应有的长度(由Length_of_snake
变量控制),我们会删除snake_List
的第一个元素,即蛇尾。这样,蛇就会向前移动,同时保持其长度不变。
当蛇吃到食物时,我们会增加Length_of_snake
的值,这样在下一次移动时,蛇尾就不会被删除,从而使蛇的长度增加。
游戏界面设计
分数显示
在游戏中显示当前的分数可以让玩家了解自己的游戏进度。我们可以使用Pygame的文本渲染功能来实现这一点。
python
# 设置字体
font_style = pygame.font.SysFont("bahnschrift", 25)
score_font = pygame.font.SysFont("comicsansms", 35)
# 显示得分
def your_score(score):
value = score_font.render("得分: " + str(score), True, black)
dis.blit(value, [0, 0])
在这段代码中,我们首先创建了两种字体:一种用于普通文本,另一种用于显示分数。然后定义了your_score
函数,它接受一个参数score
,表示当前的分数。
函数使用score_font.render()
方法将分数文本转换为可渲染的表面,然后使用dis.blit()
方法将这个表面绘制到游戏窗口的左上角。
在游戏主循环中,我们会在每一帧调用这个函数,传入当前的分数(即蛇的长度减1):
your_score(Length_of_snake - 1)
游戏消息
在游戏开始、结束或其他重要时刻,我们可能需要向玩家显示一些消息。我们可以使用与分数显示类似的方法来实现这一点。
python
# 显示消息
def message(msg, color):
mesg = font_style.render(msg, True, color)
dis.blit(mesg, [display_width / 6, display_height / 3])
message
函数接受两个参数:msg
表示要显示的消息文本,color
表示文本的颜色。函数使用font_style.render()
方法将消息文本转换为可渲染的表面,然后使用dis.blit()
方法将这个表面绘制到游戏窗口的中央位置。
在游戏结束时,我们会使用这个函数显示一条消息,告诉玩家游戏结束,并提供重新开始或退出的选项:
python
message("你输了! 按Q退出或按C重新开始", red)
游戏循环与状态管理
主游戏循环
游戏循环是游戏的核心部分,它负责不断更新游戏状态并重新绘制游戏界面。在Pygame中,游戏循环通常由一个while
循环实现。
python
# 游戏主循环
def gameLoop():
game_over = False
game_close = False
# 初始化蛇的位置
x1 = display_width / 2
y1 = display_height / 2
# 初始化蛇的移动方向
x1_change = 0
y1_change = 0
# 初始化蛇的身体
snake_List = []
Length_of_snake = 1
# 随机生成食物位置
foodx = round(random.randrange(0, display_width - snake_block) / 10.0) * 10.0
foody = round(random.randrange(0, display_height - snake_block) / 10.0) * 10.0
while not game_over:
# 游戏逻辑代码
# ...
clock.tick(snake_speed)
pygame.quit()
quit()
在这段代码中,我们定义了gameLoop
函数,它包含了整个游戏的逻辑。函数首先初始化了一些游戏变量,包括游戏状态标志、蛇的位置和移动方向、蛇的身体列表以及食物的位置。
然后,函数进入主游戏循环,只要game_over
为False
,循环就会继续执行。在循环的最后,我们调用clock.tick(snake_speed)
来控制游戏的帧率,确保游戏在不同性能的计算机上运行速度一致。
当游戏结束时(game_over
变为True
),函数会调用pygame.quit()
和quit()
来关闭Pygame并退出程序。
游戏状态转换
在游戏中,我们需要管理不同的游戏状态,例如游戏运行中、游戏暂停、游戏结束等。在我们的贪吃蛇游戏中,我们使用两个变量来管理游戏状态:game_over
和game_close
。
python
while game_close == True:
dis.fill(white)
message("你输了! 按Q退出或按C重新开始", red)
your_score(Length_of_snake - 1)
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
game_over = True
game_close = False
if event.key == pygame.K_c:
gameLoop()
当蛇撞到墙壁或自己的身体时,game_close
会被设置为True
,游戏进入"游戏结束"状态。在这个状态下,我们会显示一条消息,告诉玩家游戏结束,并提供重新开始或退出的选项。
如果玩家按下Q键,game_over
会被设置为True
,game_close
会被设置为False
,这会导致主游戏循环结束,程序退出。
如果玩家按下C键,我们会调用gameLoop()
函数重新开始游戏。这会创建一个新的游戏实例,重置所有游戏变量,包括蛇的位置、长度和食物的位置。
这种状态管理方式允许我们在不同的游戏状态之间平滑地转换,提供良好的用户体验。
完整代码解析
现在,让我们来看一下贪吃蛇游戏的完整代码,并逐段进行解析:
python
import pygame
import time
import random
# 初始化pygame
pygame.init()
# 定义颜色
white = (255, 255, 255)
black = (0, 0, 0)
red = (213, 50, 80)
green = (0, 255, 0)
blue = (50, 153, 213)
# 设置屏幕大小
display_width = 800
display_height = 600
# 创建游戏窗口
dis = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption('贪吃蛇游戏')
# 设置游戏时钟
clock = pygame.time.Clock()
# 蛇的大小和速度
snake_block = 10
snake_speed = 15
# 设置字体
font_style = pygame.font.SysFont("bahnschrift", 25)
score_font = pygame.font.SysFont("comicsansms", 35)
这部分代码包含了游戏的初始化和基本设置。我们导入了必要的模块,初始化了Pygame,定义了颜色常量,设置了游戏窗口的大小和标题,创建了游戏时钟,并定义了蛇的大小和速度以及游戏中使用的字体。
python
# 显示得分
def your_score(score):
value = score_font.render("得分: " + str(score), True, black)
dis.blit(value, [0, 0])
# 绘制蛇
def our_snake(snake_block, snake_list):
for x in snake_list:
pygame.draw.rect(dis, green, [x[0], x[1], snake_block, snake_block])
# 显示消息
def message(msg, color):
mesg = font_style.render(msg, True, color)
dis.blit(mesg, [display_width / 6, display_height / 3])
这部分代码定义了三个辅助函数:
your_score
:显示当前的分数our_snake
:绘制蛇的身体message
:显示游戏消息
这些函数封装了游戏界面的绘制逻辑,使主游戏循环更加清晰和简洁。
python
# 游戏主循环
def gameLoop():
game_over = False
game_close = False
# 初始化蛇的位置
x1 = display_width / 2
y1 = display_height / 2
# 初始化蛇的移动方向
x1_change = 0
y1_change = 0
# 初始化蛇的身体
snake_List = []
Length_of_snake = 1
# 随机生成食物位置
foodx = round(random.randrange(0, display_width - snake_block) / 10.0) * 10.0
foody = round(random.randrange(0, display_height - snake_block) / 10.0) * 10.0
这部分代码是gameLoop
函数的开始部分,它初始化了游戏的各种变量,包括游戏状态标志、蛇的位置和移动方向、蛇的身体列表以及食物的位置。
python
while not game_over:
while game_close == True:
dis.fill(white)
message("你输了! 按Q退出或按C重新开始", red)
your_score(Length_of_snake - 1)
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
game_over = True
game_close = False
if event.key == pygame.K_c:
gameLoop()
这部分代码处理游戏结束的情况。当game_close
为True
时,游戏会显示一条消息,告诉玩家游戏结束,并提供重新开始或退出的选项。
python
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_over = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x1_change = -snake_block
y1_change = 0
elif event.key == pygame.K_RIGHT:
x1_change = snake_block
y1_change = 0
elif event.key == pygame.K_UP:
y1_change = -snake_block
x1_change = 0
elif event.key == pygame.K_DOWN:
y1_change = snake_block
x1_change = 0
这部分代码处理玩家的输入。它检查是否有退出事件(例如,玩家点击窗口的关闭按钮)或键盘按键事件,并相应地更新蛇的移动方向。
python
# 检查是否撞墙
if x1 >= display_width or x1 < 0 or y1 >= display_height or y1 < 0:
game_close = True
# 更新蛇的位置
x1 += x1_change
y1 += y1_change
dis.fill(white)
pygame.draw.rect(dis, red, [foodx, foody, snake_block, snake_block])
这部分代码首先检查蛇是否撞到了墙壁,如果是,则将game_close
设置为True
,表示游戏结束。然后,它根据当前的移动方向更新蛇头的位置,清空游戏窗口(填充白色),并绘制食物(红色方块)。
python
snake_Head = []
snake_Head.append(x1)
snake_Head.append(y1)
snake_List.append(snake_Head)
# 删除多余的蛇身体部分
if len(snake_List) > Length_of_snake:
del snake_List[0]
# 检查是否撞到自己
for x in snake_List[:-1]:
if x == snake_Head:
game_close = True
这部分代码更新蛇的身体。它创建一个新的列表snake_Head
,包含蛇头的x和y坐标,并将其添加到snake_List
的末尾。如果蛇身体的长度超过了应有的长度,它会删除snake_List
的第一个元素,即蛇尾。然后,它检查蛇是否撞到了自己,如果是,则将game_close
设置为True
,表示游戏结束。
python
our_snake(snake_block, snake_List)
your_score(Length_of_snake - 1)
pygame.display.update()
# 检查是否吃到食物
if x1 == foodx and y1 == foody:
foodx = round(random.randrange(0, display_width - snake_block) / 10.0) * 10.0
foody = round(random.randrange(0, display_height - snake_block) / 10.0) * 10.0
Length_of_snake += 1
clock.tick(snake_speed)
这部分代码绘制蛇的身体,显示当前的分数,并更新游戏窗口。然后,它检查蛇是否吃到了食物,如果是,则生成新的食物并增加蛇的长度。最后,它调用clock.tick(snake_speed)
来控制游戏的帧率。
python
pygame.quit()
quit()
# 启动游戏
gameLoop()
这部分代码是gameLoop
函数的结束部分。当游戏结束时(game_over
为True
),它会调用pygame.quit()
和quit()
来关闭Pygame并退出程序。最后,它调用gameLoop()
函数来启动游戏。
游戏扩展与优化
现在我们已经实现了一个基本的贪吃蛇游戏,但还有很多方面可以进行扩展和优化。以下是一些可能的改进方向:
增加难度系统
目前,游戏的难度是固定的,蛇的移动速度由snake_speed
变量控制。我们可以添加一个难度系统,允许玩家选择不同的难度级别,或者随着游戏的进行自动增加难度。
python
# 难度系统
def set_difficulty(difficulty):
if difficulty == "easy":
return 10
elif difficulty == "medium":
return 15
elif difficulty == "hard":
return 20
else:
return 15 # 默认中等难度
# 在游戏开始前选择难度
def choose_difficulty():
difficulty = ""
while difficulty not in ["easy", "medium", "hard"]:
dis.fill(white)
message("选择难度: E-简单, M-中等, H-困难", black)
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_e:
difficulty = "easy"
elif event.key == pygame.K_m:
difficulty = "medium"
elif event.key == pygame.K_h:
difficulty = "hard"
return set_difficulty(difficulty)
# 在游戏主循环中使用
def gameLoop():
# ...
snake_speed = choose_difficulty()
# ...
这段代码添加了两个新函数:set_difficulty
和choose_difficulty
。set_difficulty
函数根据难度级别返回相应的蛇移动速度,choose_difficulty
函数显示一个难度选择界面,让玩家选择难度级别。在游戏主循环中,我们调用choose_difficulty
函数来设置蛇的移动速度。
添加音效
音效可以增强游戏的沉浸感和反馈感。我们可以在蛇吃到食物、撞到墙壁或自己的身体时播放不同的音效。
python
# 加载音效
pygame.mixer.init()
eat_sound = pygame.mixer.Sound("eat.wav")
crash_sound = pygame.mixer.Sound("crash.wav")
# 在游戏主循环中播放音效
def gameLoop():
# ...
# 检查是否吃到食物
if x1 == foodx and y1 == foody:
eat_sound.play() # 播放吃食物的音效
# ...
# 检查是否撞墙或撞到自己
if x1 >= display_width or x1 < 0 or y1 >= display_height or y1 < 0:
crash_sound.play() # 播放撞墙的音效
# ...
for x in snake_List[:-1]:
if x == snake_Head:
crash_sound.play() # 播放撞到自己的音效
# ...
# ...
这段代码首先初始化Pygame的混音器模块,然后加载两个音效文件:eat.wav
和crash.wav
。在游戏主循环中,当蛇吃到食物时,我们播放eat_sound
;当蛇撞到墙壁或自己的身体时,我们播放crash_sound
。
优化游戏界面
我们可以通过添加背景图像、改进蛇和食物的外观以及添加更多的视觉效果来优化游戏界面。
python
# 加载图像
background_img = pygame.image.load("background.jpg")
food_img = pygame.image.load("food.png")
snake_head_img = pygame.image.load("snake_head.png")
snake_body_img = pygame.image.load("snake_body.png")
# 在游戏主循环中使用图像
def gameLoop():
# ...
# 绘制背景
dis.blit(background_img, (0, 0))
# 绘制食物
dis.blit(food_img, (foodx, foody))
# 绘制蛇
for i, x in enumerate(snake_List):
if i == len(snake_List) - 1: # 蛇头
dis.blit(snake_head_img, (x[0], x[1]))
else: # 蛇身
dis.blit(snake_body_img, (x[0], x[1]))
# ...
这段代码加载了四个图像文件:背景图像、食物图像、蛇头图像和蛇身图像。在游戏主循环中,我们使用这些图像来绘制游戏界面,而不是简单的彩色矩形。
添加障碍物
为了增加游戏的挑战性,我们可以添加障碍物,蛇需要避开这些障碍物。
python
# 初始化障碍物
obstacles = []
for i in range(5): # 创建5个障碍物
obstacle_x = round(random.randrange(0, display_width - snake_block) / 10.0) * 10.0
obstacle_y = round(random.randrange(0, display_height - snake_block) / 10.0) * 10.0
obstacles.append([obstacle_x, obstacle_y])
# 在游戏主循环中检查是否撞到障碍物
def gameLoop():
# ...
# 绘制障碍物
for obstacle in obstacles:
pygame.draw.rect(dis, blue, [obstacle[0], obstacle[1], snake_block, snake_block])
# 检查是否撞到障碍物
for obstacle in obstacles:
if x1 == obstacle[0] and y1 == obstacle[1]:
game_close = True
# ...
这段代码创建了一个包含5个障碍物的列表,每个障碍物都有一个随机的位置。在游戏主循环中,我们绘制这些障碍物,并检查蛇是否撞到了它们。如果是,则游戏结束。
总代码
import pygame
import time
import random
# 初始化pygame
pygame.init()
# 定义颜色
white = (255, 255, 255)
black = (0, 0, 0)
red = (213, 50, 80)
green = (0, 255, 0)
blue = (50, 153, 213)
# 设置屏幕大小
display_width = 800
display_height = 600
# 创建游戏窗口
dis = pygame.display.set_mode((display_width, display_height))
pygame.display.set_caption('贪吃蛇游戏')
# 设置游戏时钟
clock = pygame.time.Clock()
# 蛇的大小和速度
snake_block = 10
snake_speed = 15
# 设置字体
font_style = pygame.font.SysFont("bahnschrift", 25)
score_font = pygame.font.SysFont("comicsansms", 35)
# 显示得分
def your_score(score):
value = score_font.render("得分: " + str(score), True, black)
dis.blit(value, [0, 0])
# 绘制蛇
def our_snake(snake_block, snake_list):
for x in snake_list:
pygame.draw.rect(dis, green, [x[0], x[1], snake_block, snake_block])
# 显示消息
def message(msg, color):
mesg = font_style.render(msg, True, color)
dis.blit(mesg, [display_width / 6, display_height / 3])
# 游戏主循环
def gameLoop():
game_over = False
game_close = False
# 初始化蛇的位置
x1 = display_width / 2
y1 = display_height / 2
# 初始化蛇的移动方向
x1_change = 0
y1_change = 0
# 初始化蛇的身体
snake_List = []
Length_of_snake = 1
# 随机生成食物位置
foodx = round(random.randrange(0, display_width - snake_block) / 10.0) * 10.0
foody = round(random.randrange(0, display_height - snake_block) / 10.0) * 10.0
while not game_over:
while game_close == True:
dis.fill(white)
message("你输了! 按Q退出或按C重新开始", red)
your_score(Length_of_snake - 1)
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_q:
game_over = True
game_close = False
if event.key == pygame.K_c:
gameLoop()
for event in pygame.event.get():
if event.type == pygame.QUIT:
game_over = True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
x1_change = -snake_block
y1_change = 0
elif event.key == pygame.K_RIGHT:
x1_change = snake_block
y1_change = 0
elif event.key == pygame.K_UP:
y1_change = -snake_block
x1_change = 0
elif event.key == pygame.K_DOWN:
y1_change = snake_block
x1_change = 0
# 检查是否撞墙
if x1 >= display_width or x1 < 0 or y1 >= display_height or y1 < 0:
game_close = True
# 更新蛇的位置
x1 += x1_change
y1 += y1_change
dis.fill(white)
pygame.draw.rect(dis, red, [foodx, foody, snake_block, snake_block])
snake_Head = []
snake_Head.append(x1)
snake_Head.append(y1)
snake_List.append(snake_Head)
# 删除多余的蛇身体部分
if len(snake_List) > Length_of_snake:
del snake_List[0]
# 检查是否撞到自己
for x in snake_List[:-1]:
if x == snake_Head:
game_close = True
our_snake(snake_block, snake_List)
your_score(Length_of_snake - 1)
pygame.display.update()
# 检查是否吃到食物
if x1 == foodx and y1 == foody:
foodx = round(random.randrange(0, display_width - snake_block) / 10.0) * 10.0
foody = round(random.randrange(0, display_height - snake_block) / 10.0) * 10.0
Length_of_snake += 1
clock.tick(snake_speed)
pygame.quit()
quit()
# 启动游戏
gameLoop()
运行结果
总结与心得
通过本教程,我们从零开始构建了一个完整的贪吃蛇游戏。我们学习了如何使用Python和Pygame库来创建游戏窗口、处理用户输入、绘制游戏元素、实现游戏逻辑以及管理游戏状态。
贪吃蛇游戏虽然简单,但它包含了许多游戏开发的基本概念和技术,例如:
- 游戏循环和帧率控制
- 用户输入处理
- 碰撞检测
- 随机数生成
- 游戏状态管理
- 图形绘制和界面设计
这些概念和技术在更复杂的游戏开发中也是非常重要的。通过学习和实践这个项目,我们不仅掌握了如何创建一个经典的贪吃蛇游戏,还为进一步学习游戏开发打下了坚实的基础。
在开发过程中,我们可能会遇到各种挑战和问题,例如如何处理蛇的移动、如何检测碰撞、如何生成食物等。通过解决这些问题,我们不仅提高了编程技能,还培养了解决问题的能力和创造性思维。
最后,游戏开发是一个充满乐趣和挑战的领域。希望这个教程能够激发你对游戏开发的兴趣,并鼓励你继续探索和学习。无论你是想成为一名专业的游戏开发者,还是只是想为自己或朋友创建一些有趣的游戏,这个教程都是一个很好的起点。
祝你在游戏开发的道路上取得成功!