wordpress网站重新安装插件/发布外链
文章目录
- 1、项目说明
- 2、项目预览
- 3、开发必备
- 4、贪吃蛇代码实现
- 4.1、窗口和基本参数实现
- 4.2、绘制背景
- 4.3、绘制墙壁
- 4.4、绘制贪吃蛇
- 4.5、绘制食物
- 4.6、实现长度信息显示
- 4.7、定义游戏暂停界面
- 4.8、定义贪吃蛇死亡界面
- 4.9、实现贪吃蛇碰撞效果
- 4.10、实现添加食物功能
- 4.11、实现贪吃蛇身体增长功能
- 4.12、实现贪吃蛇吃食物功能
- 4.12、贪吃蛇死亡功能
- 4.13、实现键盘控制游戏
- 4.14、更新贪吃蛇位置功能
- 4.15、更新游戏画面和处理用户输入功能
- 5、结束
1、项目说明
介绍
贪吃蛇是我们小时候的一款经典游戏,毕竟在那个Nokia称霸的年代,这款游戏可是经典中的经典啊!而用Python(蛇)玩Snake(贪吃蛇),那再合适不过了。
需求分析
我们先来回顾下贪吃蛇中的游戏元素及游戏规则:
- 需要有贪吃蛇、有食物
- 需要能控制贪吃蛇来上下移动获取食物
- 贪吃蛇在吃取食物后,自身长度增加,同时食物消失并随机生成新的食物
- 如果贪吃蛇触碰到四周墙壁或是触碰到自己身体时,则游戏结束
2、项目预览
3、开发必备
游戏开发运行环境
- python3.7以上
- 开发工具PyCharm
- Python内置模块:random
- 第三方模块:pygame
4、贪吃蛇代码实现
4.1、窗口和基本参数实现
分析
我们首先需要初始化一些参数:游戏界面大小、蛇和食物的参数以及一些游戏边界和障碍的设置等等
- 初始化 Pygame 模块,让游戏程序能够使用 Pygame 提供的功能;
- 设置游戏窗口的大小;
- 定义两个字体对象,分别用于绘制不同大小的文字;
- 定义了一个方向列表,包含了贪吃蛇可能移动的四个方向;
- 定义了 X 和 Y 的坐标列表,方便后续使用;
- 定义了几种不同的食物颜色,用于给不同等级的食物染色;
- 定义了障碍物(墙)的位置和尺寸以及食物的初始位置和尺寸;
- 设置蛇的一些参数,如速度、长度、宽度和高度等;
- 设置游戏的等级和初始等待时间;
- 设置游戏窗口的标题和一些初始化的变量。
代码实现
import pygameif __name__ == "__main__":# 初始化pygamepygame.init()# 游戏界面大小GAME_SIZE = [900,900]SIZE = [GAME_SIZE[0],GAME_SIZE[1]+100]# 字体设置FONT_S = pygame.font.SysFont('Times', 50)FONT_M = pygame.font.SysFont('Times', 90)# 方向列表DIRECTION = ['up','right','down','left']# X 和 Y 坐标列表X_LIST = [x for x in range(GAME_SIZE[0])]Y_LIST = [y for y in range(GAME_SIZE[1])]# 食物颜色FOOD_COLORS = ((46,139,87),(199,21,133),(25,25,112),(255,215,0))# 墙wall_list = [[100,200],[600,500],[350,200],[500,800]]WALL_WIDTH,WALL_HEIGHT = 30,30# 食物food_list = [(150,200,1),(300,500,1),(740,542,1),(300,600,1),(700,600,1)]FOOD_WIDTH,FOOD_HEIGHT = 14,14# 创建游戏窗口 900*1000screen = pygame.display.set_mode(SIZE)# 蛇的参数snake_list = [[100+12*4,100],[100+12*3,100],[100+12*2,100],[100+12*1,100],[100,100]]SNAKE_WIDTH,SNAKE_HEIGHT = 12,12snake_v = 0count_time = 0# 等级frame = 0.05level = 1# 主循环running = Truepause = Falsedead = Falsehead = 'right'
4.2、绘制背景
分析
定义一个名为 draw_background()
的函数,它用来绘制游戏的背景。
具体的绘制过程如下:
screen.fill(COLORS['white'])
使用白色填充背景屏幕,将屏幕背景设置为白色。pygame.draw.rect(screen,COLORS['black'],(-100,GAME_SIZE[1],3000,200),0)
绘制一个长方形作为地面。该矩形的位置(x, y)
是(-100, GAME_SIZE[1])
,宽度为3000
,高度为200
。矩形的颜色是 COLORS 字典中的black
。
通过调用 draw_background()
函数,可以在游戏屏幕上绘制出白色的背景以及一个黑色的长方形作为地面
代码
def draw_background():# white backgroundscreen.fill(COLORS['white'])pygame.draw.rect(screen,COLORS['black'],(-100,GAME_SIZE[1],3000,200),0)
4.3、绘制墙壁
分析
定义一个名为 draw_wall()
的函数,它用来绘制游戏中的墙壁。
具体的绘制过程如下:
- 使用
for
循环遍历墙壁列表wall_list
中的每个元素,每个元素表示一个墙壁的位置。 - 对于每个墙壁位置,调用
pygame.draw.rect()
函数绘制一个矩形,位置(x, y)
是(xy[0]-WALL_WIDTH/2, xy[1]-WALL_WIDTH/2)
,宽度为WALL_WIDTH
,高度为WALL_HEIGHT
。矩形的颜色是 COLORS 字典中的darkgray
。
通过调用 draw_wall()
函数,可以在游戏屏幕上绘制出墙壁。每个墙壁由一个矩形组成,矩形的位置和大小均在调用时指定。注意,墙壁的位置需要减去一半的墙壁宽度和高度,以便将矩形的中心对齐到墙壁位置上。
代码
def draw_wall():for xy in wall_list:pygame.draw.rect(screen,COLORS['darkgray'],(xy[0]-WALL_WIDTH/2,xy[1]-WALL_WIDTH/2,WALL_WIDTH,WALL_HEIGHT),0)
4.4、绘制贪吃蛇
分析
定义一个名为 draw_snake()
的函数,它用来绘制游戏中的蛇。
具体的绘制过程如下:
- 使用
snake_list
列表中的第一个元素作为蛇头,调用pygame.draw.circle()
函数绘制一个圆作为蛇头。圆心的位置(x, y)
是(head[0], head[1])
,半径为SNAKE_WIDTH/2
。圆的颜色是 COLORS 字典中的darkred
。 - 对于蛇身上的其他部分(不包括蛇头),使用
for
循环遍历snake_list
中除了第一个元素以外的其他元素。对于每个元素,调用pygame.draw.rect()
函数绘制一个矩形,位置(x, y)
是(xy[0]-SNAKE_WIDTH/2, xy[1]-SNAKE_WIDTH/2)
,宽度为SNAKE_WIDTH
,高度为SNAKE_HEIGHT
,边框宽度为2
。矩形的颜色与圆的颜色相同。
通过调用 draw_snake()
函数,可以在游戏屏幕上绘制出蛇。蛇头使用一个圆表示,蛇身使用一系列矩形拼接而成,每个矩形的位置和大小均在调用时指定。注意,蛇头和蛇身分别使用了不同的绘制方式,因为它们形状不同。
代码
def draw_snake():head = snake_list[0]pygame.draw.circle(screen,COLORS['darkred'],(head[0],head[1]),int(SNAKE_WIDTH/2),0)for xy in snake_list[1:]:pygame.draw.rect(screen,COLORS['darkred'],(xy[0]-SNAKE_WIDTH/2,xy[1]-SNAKE_WIDTH/2,SNAKE_WIDTH,SNAKE_HEIGHT),2)
4.5、绘制食物
分析
定义一个名为 draw_food()
的函数,它用来绘制食物物品。
具体的绘制过程如下:
- 使用
for
循环遍历食物列表food_list
中的每个元素,每个元素表示一个食物的位置和类型。 - 对于每个食物位置,调用
pygame.draw.rect()
函数绘制一个矩形,位置(x, y)
是(xyz[0]-FOOD_WIDTH/2, xyz[1]-FOOD_WIDTH/2)
,宽度为FOOD_WIDTH
,高度为FOOD_HEIGHT
。矩形的颜色是FOOD_COLORS
列表中根据食物类型xyz[2]
所对应的颜色值。
通过调用 draw_food()
函数,可以在游戏屏幕上绘制出各种类型的食物。每个食物由一个矩形组成,矩形的位置和大小均在调用时指定。注意,食物的位置需要减去一半的食物宽度和高度,以便将矩形的中心对齐到食物位置上。
代码
# 绘制食物
def draw_food():# 遍历食物列表for xyz in food_list:# 获取食物位置和类型,绘制食物矩形pygame.draw.rect(screen, FOOD_COLORS[xyz[2]-1], (xyz[0] - FOOD_WIDTH/2, xyz[1] - FOOD_WIDTH/2, FOOD_WIDTH, FOOD_HEIGHT), 0)
4.6、实现长度信息显示
分析
定义一个名为 draw_context()
的函数,它用来绘制游戏的上下文信息。
具体的绘制过程如下:
- 创建一个文本对象
txt
,文本内容是 "Snake length: " 连接上蛇身长度len(snake_list)-1
。使用FONT_M
字体来渲染文本,文本颜色是 COLORS 字典中的lightblue
。 - 计算文本的位置
(x, y)
,其中x
的初始值为10
,y
的初始值为GAME_SIZE[1]+(int((SIZE[1]-GAME_SIZE[1])/2))
。接下来,将y
的值减去文本字体尺寸的一半,以实现垂直居中。 - 使用
screen.blit()
函数将文本对象绘制到屏幕上,位置为(x, y)
。
通过调用 draw_context()
函数,可以在游戏屏幕上绘制出游戏的上下文信息,包括蛇的长度
代码
# 绘制游戏上下文信息
def draw_context():# 创建文本对象,包括蛇的长度信息txt = FONT_M.render('Snake length: '+str(len(snake_list)-1),True,COLORS['lightblue'])# 计算文本位置x,y = 10,GAME_SIZE[1]+(int((SIZE[1]-GAME_SIZE[1])/2))y = int(y-FONT_M.size('Count')[1]/2)# 绘制文本screen.blit(txt,(x,y))
4.7、定义游戏暂停界面
分析
定义一个名为 draw_pause()
的函数,它用于在游戏暂停时绘制暂停界面。
具体的绘制过程如下:
- 创建一个透明表面
s
,大小与SIZE
相同,并填充为带有半透明的白色(255,255,255,220)
。 - 使用
screen.blit()
函数将表面s
绘制到屏幕上的位置(0, 0)
,实现背景的半透明效果。 - 创建一个文本对象
txt
,文本内容为 “PAUSE”,使用FONT_M
字体渲染文本,文本颜色为 COLORS 字典中的darkgray
。 - 计算文本的位置
(x, y)
,其中x
的初始值为SIZE[0]/2
,y
的初始值为SIZE[1]/2
。然后,将x
和y
的值减去文本字体尺寸的一半,以实现水平和垂直居中。 - 使用
screen.blit()
函数将文本对象绘制到屏幕上的位置(x, y)
。
通过调用 draw_pause()
函数,可以在游戏屏幕上绘制暂停界面。呈现为一个半透明的背景,并显示 “PAUSE” 文本在中间位置。注意,需要使用透明度为 220
的色彩值来填充表面,以实现半透明效果。
代码
# 绘制暂停界面
def draw_pause():# 创建一个带有半透明的透明表面s = pygame.Surface(SIZE, pygame.SRCALPHA)s.fill((255,255,255,220))# 将透明表面绘制到屏幕上screen.blit(s, (0,0))# 创建文本对象,显示 "PAUSE"txt = FONT_M.render('PAUSE',True,COLORS['darkgray'])# 计算文本的位置x,y = SIZE[0]/2,SIZE[1]/2x,y = int(x-FONT_M.size('PAUSE')[0]/2),int(y-FONT_M.size('PAUSE')[1]/2)# 绘制文本screen.blit(txt,(x,y))
4.8、定义贪吃蛇死亡界面
分析
定义一个名为 draw_dead()
的函数,用于在游戏中玩家死亡时绘制死亡界面。
具体的绘制过程如下:
- 创建一个透明表面
s
,大小与SIZE
相同,并填充为带有半透明的白色(255,255,255,240)
。 - 使用
screen.blit()
函数将表面s
绘制到屏幕上的位置(0, 0)
,实现背景的半透明效果。 - 创建一个文本对象
txt
,文本内容为 “YOU DEAD”,使用FONT_M
字体渲染文本,文本颜色为 COLORS 字典中的black
。 - 计算文本的位置
(x, y)
,其中x
的初始值为SIZE[0]/2
,y
的初始值为SIZE[1]/2
。然后,将x
和y
的值减去文本字体尺寸的一半,以实现水平和垂直居中。 - 使用
screen.blit()
函数将文本对象绘制到屏幕上的位置(x, y)
。
通过调用 draw_dead()
函数,可以在游戏屏幕上绘制死亡界面。呈现为一个更加明亮的背景,并显示 “YOU DEAD” 文本在中间位置。注意,需要使用透明度为 240
的色彩值来填充表面,以实现更明显的半透明效果。
代码
# 绘制死亡界面
def draw_dead():# 创建一个更明亮的带有半透明的透明表面s = pygame.Surface(SIZE, pygame.SRCALPHA)s.fill((255,255,255,240))# 将透明表面绘制到屏幕上screen.blit(s, (0,0))# 创建文本对象,显示 "YOU DEAD"txt = FONT_M.render('YOU DEAD',True,COLORS['black'])# 计算文本的位置x,y = SIZE[0]/2,SIZE[1]/2x,y = int(x-FONT_M.size('YOU DEAD')[0]/2),int(y-FONT_M.size('YOU DEAD')[1]/2)# 绘制文本screen.blit(txt,(x,y))
4.9、实现贪吃蛇碰撞效果
分析
定义一个名为 rect_cover(rect1,rect2)
的函数,用于判断两个矩形是否相交。
具体的判断过程如下:
- 将每个矩形的四个边界值提取出来,并转换为整数类型。其中,
left1
表示矩形rect1
左边界,right1
表示矩形rect1
右边界,up1
表示矩形rect1
上边界,down1
表示矩形rect1
下边界;同理,left2
、right2
、up2
、down2
分别为矩形rect2
的四个边界值。 - 如果矩形
rect1
和矩形rect2
相交,则它们的边界值应该满足下面的四种情况之一:
rect2
的右边界right2
小于或等于rect1
的左边界left1
rect2
的左边界left2
大于或等于rect1
的右边界right1
rect2
的下边界down2
小于或等于rect1
的上边界up1
rect2
的上边界up2
大于或等于rect1
的下边界down1
如果不满足上述四种情况,则认为它们相交,此时函数返回值为 True
;否则,返回值为 False
。
代码
# 判断两个矩形是否相交
def rect_cover(rect1, rect2):# 提取矩形1的边界值left1 = int(rect1[0])right1 = int(rect1[0] + rect1[2])up1 = int(rect1[1])down1 = int(rect1[1] + rect1[3])# 提取矩形2的边界值left2 = int(rect2[0])right2 = int(rect2[0] + rect2[2])up2 = int(rect2[1])down2 = int(rect2[1] + rect2[3])# 判断两个矩形是否相交if not (right2 <= left1 or left2 >= right1 or down2 <= up1 or up2 >= down1):return Truereturn False
4.10、实现添加食物功能
分析
定义一个名为 add_food()
的函数,用于向食物列表 food_list
中添加食物。
具体的过程如下:
- 进入一个无限循环
while(True)
。 - 在每次循环中,生成一个由随机选择的
X_LIST
中的元素、随机选择的Y_LIST
中的元素和随机选择的[1,2,3,4]
中的元素组成的列表xyz
。 - 检查
xyz
是否存在于墙壁列表wall_list
中。如果不存在,说明xyz
没有被墙壁占据,可以作为食物的位置。 - 将
xyz
添加到食物列表food_list
中,并使用break
语句跳出循环。
通过调用 add_food()
函数,可以在游戏中不断添加新的食物位置。在添加食物之前,会进行检查,确保新位置不与墙壁重叠。
代码
import random# 向食物列表中添加食物
def add_food():while True:# 随机选择X、Y和数值xyz = [random.choice(X_LIST),random.choice(Y_LIST),random.choice([1, 2, 3, 4])]# 检查食物位置是否与墙壁重叠if xyz not in wall_list:# 将食物位置添加到食物列表food_list.append(xyz)break # 跳出循环
4.11、实现贪吃蛇身体增长功能
分析
一个名为 add_body()
的函数,用于向蛇的身体列表 snake_list
中添加身体节。
具体的过程如下:
- 使用一个循环来控制添加的身体节的数量,循环的次数由参数
length
决定,默认为1。 - 在每次循环中,获取蛇身体列表
snake_list
中的倒数第二个和最后一个元素,并分别赋值给last2
和last1
。 - 检查最后两个身体节的相对位置:如果它们在垂直方向上相等,则代表这两节身体是竖直排列的;如果它们在水平方向上相等,则代表这两节身体是水平排列的。
- 根据身体节的相对位置,确定新的身体节的坐标。如果是竖直排列,根据最后一节的朝向选择向上或向下添加一节;如果是水平排列,根据最后一节的朝向选择向左或向右添加一节。
- 将新的身体节坐标添加到蛇的身体列表
snake_list
中。
通过调用 add_body()
函数,可以向蛇的身体列表中添加指定数量的身体节,以延长蛇的长度。
代码
# 向蛇的身体列表中添加身体节
def add_body(length=1):for c in range(length):# 获取最后两个身体节的坐标last2, last1 = snake_list[-2], snake_list[-1]if last2[0] == last1[0]: # 如果最后两节身体在垂直方向上相等if last2[1] > last1[1]: # 朝下# 向下添加一节身体snake_list.append([last1[0], last1[1] - SNAKE_WIDTH])else:# 向上添加一节身体snake_list.append([last1[0], last1[1] + SNAKE_WIDTH])else: # 如果最后两节身体在水平方向上相等if last2[0] > last1[0]: # 朝右# 向右添加一节身体snake_list.append([last1[0] - SNAKE_WIDTH, last1[1]])else:# 向左添加一节身体snake_list.append([last1[0] + SNAKE_WIDTH, last1[1]])
4.12、实现贪吃蛇吃食物功能
分析
定义一个检查蛇头是否与食物碰撞的函数。具体的实现逻辑如下:
- 首先获取蛇的头部坐标
snake_list[0]
,并计算出蛇头的矩形区域snake_head_rect
。矩形区域的坐标为(蛇头x坐标-SNAKE_WIDTH/2, 蛇头y坐标-SNAKE_WIDTH/2, SNAKE_WIDTH, SNAKE_HEIGHT)
。 - 遍历食物列表
food_list
,获取每个食物的坐标xyz
。再计算出食物的矩形区域food_rect
。矩形区域的坐标为(食物x坐标-FOOD_WIDTH/2, 食物y坐标-FOOD_WIDTH/2, FOOD_WIDTH, FOOD_HEIGHT)
。 - 调用
rect_cover
函数判断蛇头的矩形区域是否与当前食物的矩形区域重叠。如果重叠,则表示蛇头与该食物碰撞了。 - 如果蛇头与食物碰撞,则调用
add_body
函数将食物的类型xyz[2]
加入到蛇的身体中,并从食物列表中移除该食物。 - 最后返回一个布尔值,表示蛇头是否与任何食物碰撞。
代码
# 检查是否有食物被吃掉
def check_food():# 获取蛇头的位置first = snake_list[0]# 创建蛇头的矩形区域snake_head_rect = (first[0] - SNAKE_WIDTH/2, first[1] - SNAKE_WIDTH/2, SNAKE_WIDTH, SNAKE_HEIGHT)# 遍历食物列表for i in range(len(food_list)):xyz = food_list[i]# 创建食物的矩形区域food_rect = (xyz[0] - FOOD_WIDTH/2, xyz[1] - FOOD_WIDTH/2, FOOD_WIDTH, FOOD_HEIGHT)# 检查蛇头是否与食物重叠if rect_cover(snake_head_rect, food_rect):# 添加食物对应的身体节add_body(xyz[2])# 从食物列表中删除已被吃掉的食物del food_list[i]return Truereturn False
4.12、贪吃蛇死亡功能
分析
定义一个check_dead()
函数用于检查蛇是否死亡,即判断蛇头是否与边缘、墙壁或自身的身体发生碰撞。具体过程如下:
- 获取蛇头的位置,即蛇列表中的第一个元素。
- 创建蛇头的矩形区域,以便后续与边缘、墙壁或自身的身体进行碰撞检测。
- 检查蛇头是否与边缘发生碰撞,即蛇头是否超出了游戏区域的范围。如果超出范围,则视为蛇死亡,返回
True
。 - 遍历墙壁列表,获取每个墙壁的坐标。
- 创建墙壁的矩形区域,以便后续与蛇头的矩形区域进行碰撞检测。
- 检查蛇头是否与墙壁发生碰撞。如果发生碰撞,则视为蛇死亡,返回
True
。 - 遍历蛇列表中除蛇头外的元素,即蛇的身体。
- 创建身体节的矩形区域,以便后续与蛇头的矩形区域进行碰撞检测。
- 检查蛇头是否与自身的身体发生碰撞。如果发生碰撞,则视为蛇死亡,返回
True
。 - 如果以上都未发生,即蛇未死亡,返回
False
。
代码
# 检查蛇是否死亡
def check_dead():# 获取蛇头的位置first = snake_list[0]# 创建蛇头的矩形区域snake_head_rect = (first[0] - SNAKE_WIDTH/2, first[1] - SNAKE_WIDTH/2, SNAKE_WIDTH, SNAKE_HEIGHT)# 检查蛇头是否与边缘发生碰撞if first[0] < 0 or first[0] > GAME_SIZE[0] or first[1] < 0 or first[1] > GAME_SIZE[1]:return True# 检查蛇头是否与墙壁发生碰撞for xy in wall_list:wall_rect = (xy[0] - WALL_WIDTH/2, xy[1] - WALL_WIDTH/2, WALL_WIDTH, WALL_HEIGHT)if rect_cover(snake_head_rect, wall_rect):return True# 检查蛇头是否与自身的身体发生碰撞for xy in snake_list[1:]:body_rect = (xy[0] - SNAKE_WIDTH/2, xy[1] - SNAKE_WIDTH/2, SNAKE_WIDTH, SNAKE_HEIGHT)if rect_cover(snake_head_rect, body_rect):return Truereturn False
4.13、实现键盘控制游戏
分析
编写一个处理事件的循环,它的作用是根据用户的输入来控制游戏的行为。主要包含以下几个事件处理:
pygame.QUIT
事件:当用户点击窗口的关闭按钮时,这个事件会触发。在这段代码中,会将running
变量设置为False
,从而退出游戏循环。pygame.MOUSEBUTTONDOWN
事件:当用户点击鼠标按钮时,这个事件会触发。在这段代码中,每次点击鼠标按钮会切换pause
变量的状态,用来暂停游戏。pygame.KEYUP
事件:当用户松开键盘上的按键时,这个事件会触发。在这段代码中,根据松开的按键来控制蛇头的移动方向。具体的处理逻辑如下:- 如果松开的键是
K_LEFT
(即左箭头键),并且当前蛇头方向不是向右(head
不为 ‘right’),则将新的蛇头方向设置为向左(‘left’)。 - 如果松开的键是
K_RIGHT
(即右箭头键),并且当前蛇头方向不是向左(head
不为 ‘left’),则将新的蛇头方向设置为向右(‘right’)。 - 如果松开的键是
K_UP
(即上箭头键),并且当前蛇头方向不是向下(head
不为 ‘down’),则将新的蛇头方向设置为向上(‘up’)。 - 如果松开的键是
K_DOWN
(即下箭头键),并且当前蛇头方向不是向上(head
不为 ‘up’),则将新的蛇头方向设置为向下(‘down’)。
- 如果松开的键是
代码
# 事件循环
while running:# 获取所有事件并逐个处理for event in pygame.event.get():# 处理关闭窗口事件if event.type == pygame.QUIT:# 退出游戏循环running = Falsebreak# 处理鼠标点击事件elif event.type == pygame.MOUSEBUTTONDOWN:# 切换暂停状态(pause变量为True时暂停,为False时正常运行)pause = not pause# 处理按键松开事件elif event.type == pygame.KEYUP:# 如果松开的键是左箭头键,并且当前蛇头方向不是向右,则将新的蛇头方向设置为向左if event.key == K_LEFT:if head in ['up','down']:head = 'left'# 如果松开的键是右箭头键,并且当前蛇头方向不是向左,则将新的蛇头方向设置为向右elif event.key == K_RIGHT:if head in ['up','down']:head = 'right'# 如果松开的键是上箭头键,并且当前蛇头方向不是向下,则将新的蛇头方向设置为向上elif event.key == K_UP:if head in ['left','right']:head = 'up'# 如果松开的键是下箭头键,并且当前蛇头方向不是向上,则将新的蛇头方向设置为向下elif event.key == K_DOWN:if head in ['left','right']:head = 'down'
4.14、更新贪吃蛇位置功能
分析
在游戏不暂停且蛇没有死亡的情况下,更新蛇的位置。具体操作如下:
- 计算时间:根据帧率
frame
和游戏难度level
来计算游戏进行的时间。 - 获取蛇的头部位置:将蛇列表中的第一个元素作为蛇头的当前位置。
- 移动蛇身:将蛇列表中索引为1以及之后的元素赋值为索引减1以及之前的元素,即每个蛇身的位置向前移动一个单位。
- 根据当前头部的方向更新蛇头的位置:根据变量
head
的值,更新蛇头的位置。如果头部方向是 ‘up’,则将头部位置的纵坐标减去一个单位;如果方向是 ‘down’,则将纵坐标加上一个单位;如果方向是 ‘left’,则将横坐标减去一个单位;如果方向是 ‘right’,则将横坐标加上一个单位。
代码
# 如果游戏没有暂停,并且蛇没有死亡,则执行以下操作
if not pause and not dead:# 计算时间count_time += frame * level# 获取蛇的头部位置first = snake_list[0]# 将蛇身的每个部分向前移动一个单位snake_list[1:] = snake_list[:-1]# 根据当前头部的方向更新蛇头的位置if head == 'up':snake_list[0] = [first[0], first[1] - SNAKE_WIDTH]elif head == 'down':snake_list[0] = [first[0], first[1] + SNAKE_WIDTH]elif head == 'left':snake_list[0] = [first[0] - SNAKE_WIDTH, first[1]]elif head == 'right':snake_list[0] = [first[0] + SNAKE_WIDTH, first[1]]
4.15、更新游戏画面和处理用户输入功能
分析
负责更新游戏画面和处理用户输入,具体操作如下:
- 绘制背景:绘制游戏的背景。
- 绘制隧道:绘制游戏中的隧道。
- 选择物品:绘制游戏的角色,即蛇。
- 绘制食物:绘制游戏中的食物。
- 绘制得分:绘制游戏中的得分。
- 如果游戏暂停且蛇没有死亡,绘制暂停界面。
- 如果蛇死亡,绘制游戏结束界面。
- 刷新显示:更新显示,将绘制的内容显示在屏幕上。
- 暂停 20 毫秒:暂停游戏的执行一段时间,控制游戏的帧率。
- 检查是否死亡:检查当前游戏状态是否为死亡状态。
- 检查是否吃到食物:检查蛇是否吃到食物。
- 关闭 pygame:结束游戏。
代码
# 绘制背景
draw_background()# 绘制隧道
draw_wall()# 选择物品
draw_snake()# 绘制食物
draw_food()# 绘制得分
draw_context()# 如果游戏暂停且蛇没有死亡,绘制暂停界面
if not dead and pause:draw_pause()# 如果蛇死亡,绘制游戏结束界面
if dead:draw_dead()# 刷新显示
pygame.display.flip()# 暂停 20 毫秒
pygame.time.delay(int(frame/level*1000))# 检查是否死亡
dead = check_dead()# 检查是否吃到食物
if check_food():add_food()# 关闭 pygame
pygame.quit()
5、结束
需要源码留言
相关文章:

python实现贪吃蛇游戏
文章目录 1、项目说明2、项目预览3、开发必备4、贪吃蛇代码实现4.1、窗口和基本参数实现4.2、绘制背景4.3、绘制墙壁4.4、绘制贪吃蛇4.5、绘制食物4.6、实现长度信息显示4.7、定义游戏暂停界面4.8、定义贪吃蛇死亡界面4.9、实现贪吃蛇碰撞效果4.10、实现添加食物功能4.11、实现…...

ios备忘录怎么导入华为 方法介绍
作为一个常常需要在不同设备间切换的人,我深知备忘录的重要性。那些突如其来的灵感、重要的会议提醒、甚至是生活中的琐碎小事,我们都习惯性地记录在备忘录里。但当我决定从iPhone转向华为时,一个问题困扰了我:如何将那些珍贵的备…...

electron与cesium组件入门应用功能
electron与cesium组件入门应用功能 运行应用效果图: electron应用目录,需要包括三个文件: index.html main.js package.json (一)、创建一个新项目 目录名称:project_helloWolrd (二)、生成package.json文件 npm init --yes(三&#x…...

Jenkins Docker Cloud在Linux应用开发CI中的实践
Jenkins Docker Cloud在Linux应用开发CI中的实践 背景 通过代码提交自动触发CI自动构建、编译、打包是任何软件开发组织必不可少的基建,可以最大程度保证产物的一致性,方便跨组跨部门协作,代码MR等。 Docker在流水线中越来越重要ÿ…...

502 Bad Gateway with nginx + apache + subversion + ssl
svn commit的时候返回 unexpected http status 502 bad gateway on解决方法,参考:https://stackoverflow.com/questions/2479346/502-bad-gateway-with-nginx-apache-subversion-ssl-svn-copy 在nginx中代理svn中添加 location /svn {set $fixed_dest…...

【PostgreSQL内核学习(十八)—— 存储管理(存储管理的体系结构)】
存储管理 概述存储管理器的体系结构存储管理器的主要任务读写元组过程 声明:本文的部分内容参考了他人的文章。在编写过程中,我们尊重他人的知识产权和学术成果,力求遵循合理使用原则,并在适用的情况下注明引用来源。 本文主要参考…...

Android的组件、布局学习
介绍 公司组织架构调整,项目组需要承接其他项目组的android项目,负责维护和开发新需求,故学习下基础语法和项目开发。 组件学习 Toolbarheader布局部分 就是app最顶部的部分 他的显示与否,是与F:\androidProject\android_lear…...

【离散数学】——期末刷题题库(树其一)
🎃个人专栏: 🐬 算法设计与分析:算法设计与分析_IT闫的博客-CSDN博客 🐳Java基础:Java基础_IT闫的博客-CSDN博客 🐋c语言:c语言_IT闫的博客-CSDN博客 🐟MySQL:…...

光模块市场分析与发展趋势预测
光模块是光通信领域的重要组成部分,随着数字经济,大数据,云计算,人工智能等行业的兴起,光模块市场经历了快速发展,逐渐在数据中心、无线回传、电信传输等应用场景中得到广泛应用。本文将基于当前光模块全球…...

Python轴承故障诊断 (八)基于EMD-CNN-GRU并行模型的故障分类
目录 前言 1 经验模态分解EMD的Python示例 2 轴承故障数据的预处理 2.1 导入数据 2.2 制作数据集和对应标签 2.3 故障数据的EMD分解可视化 2.4 故障数据的EMD分解预处理 3 基于EMD-CNN-GRU并行模型的轴承故障诊断分类 3.1 训练数据、测试数据分组,数据分ba…...

鸿蒙实现年月日十分选择框,支持年月日、月日、日、年月日时分、时分切换
import DateTimeUtils from ./DateTimeUtils;CustomDialog export default struct RQPickerDialog {controller: CustomDialogControllertitle: string 这是标题TAG: string RQPickerDialog// 0 - 日期类型(年月日) 1 - 时间类型(时分&a…...

IntelliJ IDE 插件开发 | (三)消息通知与事件监听
系列文章 IntelliJ IDE 插件开发 |(一)快速入门IntelliJ IDE 插件开发 |(二)UI 界面与数据持久化IntelliJ IDE 插件开发 |(三)消息通知与事件监听 前言 在前两篇文章中讲解了关于插件开发的基础知识&…...

VUE小知识点
Vue 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化的编程模型,帮助你高效地开发用户界面。 Vue 的主要作用是帮助开发者构建现代 Web 应用程序。它允许前端开发人员专注于应用程序…...

深入了解常见的应用层网络协议
目录 1. HTTP协议 1.1. 工作原理 1.2. 应用场景 1.3. 安全性考虑 2. SMTP协议 2.1. 工作原理 2.2. 应用场景 2.3. 安全性考虑 3. FTP协议 3.1. 工作原理 3.2. 应用场景 3.3. 安全性考虑 4. DNS协议 4.1. 工作原理 4.2. 应用场景 4.3. 安全性考虑 5. 安全性考虑…...

网络爬虫 多任务采集
一、JSON文件存储 JSON,全称为 JavaScript 0bject Notation,也就是JavaSript 对象标记,它通过对象和数组的组合来表示数据,构造简洁但是结构化程度非常高,是一种轻量级的数据交换格式。本节中,我们就来了解如何利用 P…...

真实并发编程问题-1.钉钉面试题
👏作者简介:大家好,我是爱吃芝士的土豆倪,24届校招生Java选手,很高兴认识大家📕系列专栏:Spring源码、JUC源码、Kafka原理、分布式技术原理、数据库技术🔥如果感觉博主的文章还不错的…...

基于vue+element-plus+echarts制作动态绘图页面(柱状图,饼图和折线图)
前言 我们知道echarts是一个非常强大的绘图库,基于这个库,我们可以绘制出精美的图表。对于一张图来说,其实比较重要的就是配置项,填入不同的配置内容就可以呈现出不同的效果。 当然配置项中除了样式之外,最重要的就是…...

2312llvm,02前端
前端 编译器前端,在生成目标相关代码前,把源码变换为编译器的中间表示.因为语言有独特语法和语义,所以一般,前端只处理一个语言或一组类似语言. 比如Clang,处理C,C,objective-C源码. 介绍Clang Clang项目是C,C,Objective-C官方的LLVM前端.Clang的官方网站在此. 实际编译器(…...

【MATLAB源码-第101期】基于matlab的蝙蝠优化算BA)机器人栅格路径规划,输出做短路径图和适应度曲线。
操作环境: MATLAB 2022a 1、算法描述 蝙蝠算法(BA)是一种基于群体智能的优化算法,灵感来源于蝙蝠捕食时的回声定位行为。这种算法模拟蝙蝠使用回声定位来探测猎物、避开障碍物的能力。在蝙蝠算法中,每只虚拟蝙蝠代表…...

【数据结构】二叉树的模拟实现
前言:前面我们学习了堆的模拟实现,今天我们来进一步学习二叉树,当然了内容肯定是越来越难的,各位我们一起努力! 💖 博主CSDN主页:卫卫卫的个人主页 💞 👉 专栏分类:数据结构 👈 &…...

open3d bug:pcd转txt前后位姿发生改变
1、open3d bug:pcd转txt前后位姿发生改变 open3d会对原有结果进行一个微小位姿变换 import open3d as o3d import numpy as np# 读取PCD点云文件 pcd o3d.io.read_point_cloud(/newdisk/darren_pty/zoom_centered_s2.pcd)# 获取点云坐标 points pcd.points# 指定…...

持续集成交付CICD:Jenkins使用GitLab共享库实现基于Ansible的CD流水线部署前后端应用
目录 一、实验 1.部署Ansible自动化运维工具 2.K8S 节点安装nginx 3.Jenkins使用GitLab共享库实现基于Ansible的CD流水线部署前后端应用 二、问题 1.ansible安装报错 2.ansible远程ping失败 3. Jenkins流水线通过ansible命令直接ping多台机器的网络状态报错 一、实验 …...

OpenAI 疑似正在进行 GPT-4.5 灰度测试!
大家好,我是二狗。 今天,有网友爆料OpenAI疑似正在进行GPT-4.5灰度测试! 当网友询问ChatGPT API调用查询模型的确切名称是什么时? ChatGPT的回答竟然是 gpt-4.5-turbo。 也有网友测试之后发现仍然是GPT-4模型。 这是有网友指…...

DC-6靶场
DC-6靶场下载: https://www.five86.com/downloads/DC-6.zip 下载后解压会有一个DC-3.ova文件,直接在vm虚拟机点击左上角打开-->文件-->选中这个.ova文件就能创建靶场,kali和靶机都调整至NAT模式,即可开始渗透 首先进行主…...

单片机应用实例:LED显示电脑电子钟
本例介绍一种用LED制作的电脑电子钟(电脑万年历)。其制作完成装潢后的照片如下图: 上图中,年、月、日及时间选用的是1.2寸共阳数码管,星期选用的是2.3寸数码管,温度选用的是0.5寸数码管,也可根据…...

会议剪影 | 思腾合力受邀出席首届CCF数字医学学术年会
首届CCF数字医学学术年会(CCF Digital Medicine Symposium,DMS)于2023年12月15日-17日在苏州CCF业务总部召开。这次会议的成功召开,标志着数字医学领域进入了一个新的时代,计算机技术和人工智能在医学领域的应用和发展…...

node.js mongoose中间件(middleware)
目录 简介 定义模型 注册中间件 创建doc实例,并进行增删改查 方法名和注册的中间件名相匹配 执行结果 分析 错误处理中间件 手动抛出错误 注意点 简介 在mongoose中,中间件是一种允许在执行数据库操作前(pre)或后&…...

[Toolschain cpp ros cmakelist python vscode] 记录写每次项目重复的设置和配置 不断更新
写在前面 用以前的设置,快速配置项目,以防长久不用忘记,部分资料在资源文件里还没有整理 outline cmakelist 复用vscode 找到头文件vscode debug现有代码直接关联远端gitros杂记repo 杂记glog杂记 cmakelist 复用 包含了根据系统路径找库…...

【每日OJ—有效的括号(栈)】
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 1、有效的括号题目: 1.1方法讲解: 1.2代码实现: 总结 前言 世上有两种耀眼的光芒,一种是正在升起的太阳&#…...

.gitignore和git lfs学习
The ninth day——12.18 1. .gitignore 忽略规则优先级 从命令行中读取可用的忽略规则当前目录定义的规则父级目录定义的规则,依次递推$GIT_DIR/info/exclude 文件中定义的规则core.excludesfile中定义的全局规则 忽略规则匹配语法 空格不匹配任意文件ÿ…...