目录
引言
游戏开发准备工作
安装Python和Pygame
了解游戏基本原理
游戏基础架构
初始化游戏环境
设置游戏窗口
定义颜色和常量
核心游戏元素
蛇的设计与实现
食物系统
碰撞检测
游戏控制与交互
键盘输入处理
移动机制
游戏界面设计
分数显示
游戏消息
游戏循环与状态管理
主游戏循环
游戏状态转换
完整代码解析
游戏扩展与优化
增加难度系统
添加音效
优化游戏界面
添加障碍物
总代码
总结与心得
引言
贪吃蛇游戏是编程学习过程中的经典项目,它不仅能帮助初学者理解编程基础概念,还能提供游戏开发的实践经验。本文将详细介绍如何使用Python和Pygame库从零开始构建一个完整的贪吃蛇游戏。
贪吃蛇游戏最早出现在1970年代,由于其简单而有趣的游戏机制,迅速成为了经典。游戏的目标是控制一条蛇在有限的空间内移动,吃到食物后蛇身会变长,同时要避免撞到墙壁或自己的身体。这个看似简单的游戏实际上包含了多个重要的编程概念:循环、条件判断、列表操作、随机数生成、用户输入处理等。
在本教程中,我们将一步步构建这个游戏,从基础的环境设置到完整的游戏功能实现,最后还会探讨如何对游戏进行扩展和优化。无论你是编程新手还是想要了解游戏开发的爱好者,这篇教程都将为你提供有价值的指导。
游戏开发准备工作
安装Python和Pygame
在开始开发贪吃蛇游戏之前,我们需要确保已经安装了Python和Pygame库。Python是一种易于学习且功能强大的编程语言,而Pygame则是专为游戏开发设计的Python库,它提供了绘图、声音、输入处理等功能。
安装Python :
访问Python官网 下载最新版本的Python
安装时勾选"Add Python to PATH"选项,以便在命令行中直接使用Python
安装Pygame :
打开命令提示符或终端
输入以下命令安装Pygame:
验证安装 :
在Python环境中输入以下代码验证Pygame是否安装成功:
python
1 2 import pygame print (pygame.ver)
了解游戏基本原理
在开始编码之前,让我们先了解贪吃蛇游戏的基本原理和核心机制:
游戏元素 :
蛇:由多个连续的方块组成,随着玩家的控制移动
食物:随机出现在游戏区域内,蛇吃到后会变长
游戏区域:有边界的平面,蛇需要在其中移动
游戏规则 :
蛇可以上、下、左、右四个方向移动
蛇吃到食物后,长度增加,分数增加
蛇撞到墙壁或自己的身体,游戏结束
玩家的目标是尽可能地获得高分
技术实现要点 :
使用列表存储蛇的身体位置
使用随机数生成食物位置
使用游戏循环不断更新游戏状态
游戏基础架构
初始化游戏环境
任何Pygame游戏的第一步都是初始化游戏环境。这包括初始化Pygame库本身以及设置一些基本参数。
python
1 2 3 4 5 6 import pygameimport timeimport random# 初始化pygame pygame .init()
初始化Pygame是创建游戏的第一步,它会启动Pygame的各个模块,为后续的游戏开发做好准备。pygame.init()
函数会返回成功初始化的模块数量和失败的模块数量,但在大多数情况下,我们不需要关注这个返回值。
除了Pygame,我们还导入了time
模块用于控制游戏速度,以及random
模块用于生成随机的食物位置。这三个模块构成了我们贪吃蛇游戏的基础依赖。
设置游戏窗口
游戏窗口是玩家与游戏交互的界面,我们需要设置窗口的大小和标题。
python
1 2 3 4 5 6 7 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
1 2 3 4 5 6 7 8 9 10 11 12 13 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
1 2 3 4 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
1 2 3 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
1 2 3 4 5 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
1 2 3 4 5 6 7 8 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 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
1 2 3 4 5 6 7 8 9 10 11 12 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
1 2 3 4 5 6 7 8 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):
1 your_score (Length_of_snake - 1 )
游戏消息
在游戏开始、结束或其他重要时刻,我们可能需要向玩家显示一些消息。我们可以使用与分数显示类似的方法来实现这一点。
python
1 2 3 4 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
1 message ("你输了! 按Q退出或按C重新开始" , red)
游戏循环与状态管理
主游戏循环
游戏循环是游戏的核心部分,它负责不断更新游戏状态并重新绘制游戏界面。在Pygame中,游戏循环通常由一个while
循环实现。
python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 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
1 2 3 4 5 6 7 8 9 10 11 12 13 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 import pygameimport timeimport randompygame .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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 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
1 2 3 4 5 6 7 8 9 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
1 2 3 4 5 6 7 8 9 10 11 12 13 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
1 2 3 4 5 6 7 8 9 10 11 12 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
1 2 3 4 5 pygame.quit () quit () # 启动游戏 gameLoop ()
这部分代码是gameLoop
函数的结束部分。当游戏结束时(game_over
为True
),它会调用pygame.quit()
和quit()
来关闭Pygame并退出程序。最后,它调用gameLoop()
函数来启动游戏。
游戏扩展与优化
现在我们已经实现了一个基本的贪吃蛇游戏,但还有很多方面可以进行扩展和优化。以下是一些可能的改进方向:
增加难度系统
目前,游戏的难度是固定的,蛇的移动速度由snake_speed
变量控制。我们可以添加一个难度系统,允许玩家选择不同的难度级别,或者随着游戏的进行自动增加难度。
python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 # 难度系统 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 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个障碍物的列表,每个障碍物都有一个随机的位置。在游戏主循环中,我们绘制这些障碍物,并检查蛇是否撞到了它们。如果是,则游戏结束。
总代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 import pygameimport timeimport randompygame.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库来创建游戏窗口、处理用户输入、绘制游戏元素、实现游戏逻辑以及管理游戏状态。
贪吃蛇游戏虽然简单,但它包含了许多游戏开发的基本概念和技术,例如:
游戏循环和帧率控制
用户输入处理
碰撞检测
随机数生成
游戏状态管理
图形绘制和界面设计
这些概念和技术在更复杂的游戏开发中也是非常重要的。通过学习和实践这个项目,我们不仅掌握了如何创建一个经典的贪吃蛇游戏,还为进一步学习游戏开发打下了坚实的基础。
在开发过程中,我们可能会遇到各种挑战和问题,例如如何处理蛇的移动、如何检测碰撞、如何生成食物等。通过解决这些问题,我们不仅提高了编程技能,还培养了解决问题的能力和创造性思维。
最后,游戏开发是一个充满乐趣和挑战的领域。希望这个教程能够激发你对游戏开发的兴趣,并鼓励你继续探索和学习。无论你是想成为一名专业的游戏开发者,还是只是想为自己或朋友创建一些有趣的游戏,这个教程都是一个很好的起点。
祝你在游戏开发的道路上取得成功!