当前位置:   article > 正文

Python小游戏 贪吃蛇(完整版) Pygame sys time_pygame 贪吃蛇

pygame 贪吃蛇

需要安装pip pygame 不会私 

  1. import random
  2. import pygame, sys,time
  3. # pygame.init()
  4. # 全局变量
  5. SCREEN_WIDTH = 640 # 屏幕宽度
  6. SCREEN_HEIGHT = 480 # 屏幕高度
  7. BLOCK_SIZE = 20 # 方格的宽、高长度
  8. COLOR_GRAY = (150, 150, 150) # 灰色
  9. COLOR_GREEN = (0, 150, 0) # 绿色
  10. COLOR_WHITE = (255, 255, 255) # 白色
  11. COLOR_RED = (255, 0, 0) # 红色
  12. # 控制方向
  13. DIRECTION_MOVE = {
  14. pygame.K_DOWN: (0, 1), # down
  15. pygame.K_RIGHT: (1, 0), # right
  16. pygame.K_UP: (0, -1), # up
  17. pygame.K_LEFT: (-1, 0) # left
  18. }
  19. # 头部图标旋转方向
  20. DIRECTION_HEAD_ANGLE = {
  21. pygame.K_DOWN: 0,
  22. pygame.K_RIGHT: 90,
  23. pygame.K_UP: 180,
  24. pygame.K_LEFT: 270
  25. }
  26. # 封装蛇初始位置
  27. class Snake():
  28. def __init__(self):
  29. self.direction = pygame.K_DOWN # 初始方向
  30. self.score = 0
  31. self.icon_direction = DIRECTION_HEAD_ANGLE[pygame.K_DOWN]
  32. print(self.icon_direction)
  33. print(DIRECTION_HEAD_ANGLE)
  34. self.snake_body = [ # 蛇的位置 self.snake_body.insert(0, new_node) 在第一位新增 新增完蛇头改变到新增的位置 原本第二位改变到蛇头的位置
  35. pygame.Rect(3 * BLOCK_SIZE, 3 * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE),
  36. pygame.Rect(2 * BLOCK_SIZE, 3 * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE),
  37. pygame.Rect(1 * BLOCK_SIZE, 3 * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE)
  38. ]
  39. self.sanke_img = pygame.image.load("res/head-red.png") # 加载蛇头图片
  40. self.sanke_direction = pygame.transform.rotate(self.sanke_img,self.icon_direction) # 旋转蛇头
  41. self.snake_head = pygame.transform.scale(self.sanke_direction,(BLOCK_SIZE,BLOCK_SIZE)) # 设置蛇头大小
  42. def draw(self,screen):
  43. for x in self.snake_body[1:]: # 遍历初始位置 给窗口画图 跳过第一个给蛇头留位置
  44. pygame.draw.rect(screen,COLOR_WHITE,x,border_radius=5) # 给窗口画图 (窗口 , 颜色 ,(x左边距离,y上边距离 ,宽,高),边框圆角 )
  45. snake_pos = self.snake_body[0] # 保存初始化第一个位置
  46. # print(snake_pos)
  47. screen.blit(self.snake_head,(snake_pos.x,snake_pos.y)) # 给窗口渲染蛇头图片 坐标是初始化第一个位置 <rect(60, 60, 20, 20)> snake_pos.x第一个 60 snake_pos.y第二个 60
  48. def move(self):
  49. # pygame.Rect.copy() — 拷贝Rect对象
  50. # pygame.Rect.move() — 移动Rect对象
  51. # pygame.Rect.move_ip() — 原地移动Rect对象
  52. # pygame.Rect.inflate() — 放大和缩小Rect对象的尺寸
  53. # pygame.Rect.inflate_ip() — 原地放大和缩小Rect对象的尺寸
  54. # pygame.Rect.clamp() — 将一个Rect对象移动到另一个Rect对象的中心
  55. # pygame.Rect.clamp_ip() — 原地将一个Rect对象移动到另一个Rect对象的中心
  56. new_node = self.snake_body[0].copy() # 复制一份 <rect(60, 60, 20, 20)>
  57. # print(new_node)
  58. # print(new_node.x)
  59. # print(new_node.y)
  60. pos = DIRECTION_MOVE[self.direction] # (1, 0) 保存方向
  61. new_node.x += (pos[0] * BLOCK_SIZE) # <rect(60, 60, 20, 20)> new_node.x第一个 60 pos(1, 0) 1
  62. new_node.y += (pos[1] * BLOCK_SIZE) # <rect(60, 60, 20, 20)> new_node.y第二个 60 pos(1, 0) 0
  63. self.snake_body.insert(0, new_node) # snake_body列表第一位 添加处理后的坐标 <rect(60+20, 60, 20, 20)> 列表第一位改变蛇头改变
  64. # print(self.snake_body)
  65. self.snake_body.pop() # 删除snake_body列表最后一项
  66. # 判断移动按键是否合法
  67. def is_direction_enable(self,event):
  68. if event not in DIRECTION_MOVE: # 如果按键 没有在 上下左右范围内 则无效
  69. return False
  70. LR = (pygame.K_LEFT,pygame.K_RIGHT) # ( 按键左 ,按键右)
  71. if event in LR and self.direction in LR: # 如果按键在左右 且蛇默认方向在左右 则按键无效
  72. return False
  73. UD = (pygame.K_UP ,pygame.K_DOWN) # ( 按键上 ,按键下)
  74. if event in UD and self.direction in UD: # 如果按键在上下 且蛇默认方向在上下 则按键无效
  75. return False
  76. return True
  77. # 修改方向默认值
  78. def update_direction(self,event):
  79. self.direction = event # 修改方向默认值
  80. self.icon_direction = DIRECTION_HEAD_ANGLE[event] # 修改蛇头图标方向默认值
  81. self.sanke_direction = pygame.transform.rotate(self.sanke_img, self.icon_direction) # 旋转蛇头
  82. self.snake_head = pygame.transform.scale(self.sanke_direction, (BLOCK_SIZE, BLOCK_SIZE)) # 设置蛇头大小
  83. def grow(self): # 添加尾巴
  84. end = self.snake_body[-1].copy() # 复制 蛇列表 最后一项
  85. self.snake_body.append(end) # 追加蛇列表
  86. self.score += 1
  87. # 封装随机出现的食物
  88. class Food():
  89. def __init__(self):
  90. self.x = random.randint(0,SCREEN_WIDTH//BLOCK_SIZE - 1) # 食物随机出现的x坐标 0~ (640//20)-1 = 31 先求出有几个格子 再乘以20就是真实坐标
  91. self.y = random.randint(0,SCREEN_HEIGHT//BLOCK_SIZE - 1) # 食物随机出现的x坐标 0~(480//20)-1 = 24
  92. self.f_rect = pygame.Rect(self.x * BLOCK_SIZE, self.y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE) # 保存食物位置
  93. def draw(self,screen): # 随机生成食物方法
  94. pygame.draw.rect(screen,COLOR_RED,(self.x * BLOCK_SIZE, self.y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE), border_radius = 5) # 给窗口画图 (窗口 , 颜色 ,(x左边距离,y上边距离 ,宽,高),边框圆角 )
  95. class Game():
  96. def __init__(self):
  97. pygame.init() # 初始化
  98. self.screen = pygame.display.set_mode((SCREEN_WIDTH,SCREEN_HEIGHT)) # 创建窗口 (640,480) 用一个screen变量保存 窗口对象
  99. pygame.display.set_caption("宝龙集团") # 给窗口添加标题
  100. img = pygame.image.load("res/snake_logo.png") # 加载图标
  101. pygame.display.set_icon(img) # 窗口添加图标
  102. bg_img = pygame.image.load("res/bg.png") # 加载背景图
  103. self.bg = pygame.transform.scale(bg_img,(SCREEN_WIDTH,SCREEN_HEIGHT)) # 背景图设置大小 (bg_img加载的背景图 ,(窗口宽640,窗口高480))
  104. def start(self): #启动方法
  105. s = Snake() # 实例化 蛇初始位置类
  106. f = Food() # 实例化 随机食物类
  107. # 获取clock
  108. clock = pygame.time.Clock() # 帧率
  109. while True:
  110. events = pygame.event.get() # 获取用户所有操作事件 (鼠标点击 键盘输入) 等
  111. for event in events: # 遍历事件 进行判断 触发哪些事件
  112. if event.type == pygame.QUIT: # 鼠标点击 ×号 pygame库 停止工作 关闭系统
  113. pygame.quit() # Pygame库停止工作
  114. sys.exit() # 退出系统
  115. elif event.type == pygame.KEYDOWN: # 判断按键是否合法
  116. # print(event.key)
  117. if s.is_direction_enable(event.key): # 判断移动按键是否合法
  118. # print(event.key)
  119. s.update_direction(event.key) # 改变方向默认值
  120. self.screen.blit(self.bg, (0, 0)) # 给窗口渲染背景图 (背景图,(初始位置x = 0,y = 0)) 需要写在循环里,否则删除的数据不会消失
  121. # 显示帧率 和 得分
  122. fps = clock.get_fps() # 获取 帧率
  123. font = pygame.font.SysFont("SimHei", 40) # 字体类型 字体大小
  124. txt = font.render(f"帧率:%.2f"%fps, True, COLOR_RED) # 帧率文字 (帧率 ture 颜色)
  125. self.screen.blit(txt, (0, 0)) # 窗口渲染颜色 (帧率文字 ,位置)
  126. txt = font.render(f"得分:{s.score}", True, COLOR_RED) # 得分文字 (得分 ture 颜色)
  127. self.screen.blit(txt, (0, 60)) # 窗口渲染颜色 (得分文字 ,位置)
  128. for y in range(0,SCREEN_HEIGHT , BLOCK_SIZE): # 画横线 x range (0,480,20) = 0 20 40 ....
  129. # 给窗口画横线 (窗口,线的颜色(150, 150, 150 灰色),(起点位置x距离左边多远,高度位置y左上边距离多远),(终点位置x距离右边多远,高度位置y下边距离多远))
  130. pygame.draw.line(self.screen,COLOR_GRAY,(0,y),(SCREEN_WIDTH,y))
  131. for x in range(0, SCREEN_WIDTH, BLOCK_SIZE): # 画纵线 y range (0,640,20) = 0 20 40 ....
  132. # 给窗口画纵线 (窗口,线的颜色(150, 150, 150 灰色),(起点x距离左边多远,高度y左上边距离多远),(终点位置x距离右边多远,高度位置y下边距离多远))
  133. pygame.draw.line(self.screen, COLOR_GRAY, (x, 0), (x,SCREEN_HEIGHT ))
  134. s.draw(self.screen) # 调用蛇初始位置方法 传个窗口
  135. f.draw(self.screen) # 调用随机食物生成
  136. s.move() # 默认向右走
  137. if s.snake_body[0] == f.f_rect: # 判断头是否等于食物位置
  138. f = Food() # 头等于食物位置 食物重新生成
  139. s.grow() # 调用添加尾巴方法(用变量拷贝蛇列表最后一项 再使用append 追加上去)
  140. pygame.display.update() # 刷新 (显示渲染的内容)
  141. # time.sleep(0.1) # 游戏节奏 0.1秒触发一次
  142. clock.tick(10) # 每秒10帧
  143. g = Game() # 实例化 贪吃蛇类
  144. g.start() # 启动贪吃蛇

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/IT小白/article/detail/937499
推荐阅读
相关标签
  

闽ICP备14008679号