经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » 游戏设计 » 查看文章
PyGame贪吃蛇的实现代码示例
来源:jb51  时间:2018/11/22 9:59:16  对本文有异议

最近帮人做了个贪吃蛇的游戏(交作业用),很简单,界面如下:

开始界面:

游戏中界面:

是不是很简单、朴素。(欢迎大家访问GitHub

游戏是基于PyGame框架制作的,程序核心逻辑如下:

  • 游戏界面分辨率是640*480,蛇和食物都是由1个或多个20*20像素的正方形块儿(为了方便,下文用点表示20*20像素的正方形块儿)组成,这样共有32*24个点,使用pygame.draw.rect来绘制每一个点;
  • 初始化时蛇的长度是3,食物是1个点,蛇初始的移动的方向是右,用一个数组代表蛇,数组的每个元素是蛇每个点的坐标,因此数组的第一个坐标是蛇尾,最后一个坐标是蛇头;
  • 游戏开始后,根据蛇的当前移动方向,将蛇运动方向的前方的那个点append到蛇数组的末位,再把蛇尾去掉,蛇的坐标数组就相当于往前挪了一位;
  • 如果蛇吃到了食物,即蛇头的坐标等于食物的坐标,那么在第2点中蛇尾就不用去掉,就产生了蛇长度增加的效果;食物被吃掉后,随机在空的位置(不能与蛇的身体重合)再生成一个;
  • 通过PyGame的event监控按键,改变蛇的方向,例如当蛇向右时,下一次改变方向只能向上或者向下;
  • 当蛇撞上自身或墙壁,游戏结束,蛇头装上自身,那么蛇坐标数组里就有和舌头坐标重复的数据,撞上墙壁则是蛇头坐标超过了边界,都很好判断;
  • 其他细节:做了个开始的欢迎界面;食物的颜色随机生成;吃到实物的时候有声音提示等。

代码:

  1. #!/usr/bin/env python
  2. # -*- coding:utf-8 -*-
  3.  
  4. """
  5. @version: v1.0
  6. @author: Harp
  7. @contact: liutao25@baidu.com
  8. @software: PyCharm
  9. @file: MySnake.py
  10. @time: 2018/1/15 0015 23:40
  11. """
  12.  
  13.  
  14. import pygame
  15. from os import path
  16. from sys import exit
  17. from time import sleep
  18. from random import choice
  19. from itertools import product
  20. from pygame.locals import QUIT, KEYDOWN
  21.  
  22.  
  23. def direction_check(moving_direction, change_direction):
  24. directions = [['up', 'down'], ['left', 'right']]
  25. if moving_direction in directions[0] and change_direction in directions[1]:
  26. return change_direction
  27. elif moving_direction in directions[1] and change_direction in directions[0]:
  28. return change_direction
  29. return moving_direction
  30.  
  31.  
  32. class Snake:
  33.  
  34. colors = list(product([0, 64, 128, 192, 255], repeat=3))[1:-1]
  35.  
  36. def __init__(self):
  37. self.map = {(x, y): 0 for x in range(32) for y in range(24)}
  38. self.body = [[100, 100], [120, 100], [140, 100]]
  39. self.head = [140, 100]
  40. self.food = []
  41. self.food_color = []
  42. self.moving_direction = 'right'
  43. self.speed = 4
  44. self.generate_food()
  45. self.game_started = False
  46.  
  47. def check_game_status(self):
  48. if self.body.count(self.head) > 1:
  49. return True
  50. if self.head[0] < 0 or self.head[0] > 620 or self.head[1] < 0 or self.head[1] > 460:
  51. return True
  52. return False
  53.  
  54. def move_head(self):
  55. moves = {
  56. 'right': (20, 0),
  57. 'up': (0, -20),
  58. 'down': (0, 20),
  59. 'left': (-20, 0)
  60. }
  61. step = moves[self.moving_direction]
  62. self.head[0] += step[0]
  63. self.head[1] += step[1]
  64.  
  65. def generate_food(self):
  66. self.speed = len(self.body) // 16 if len(self.body) // 16 > 4 else self.speed
  67. for seg in self.body:
  68. x, y = seg
  69. self.map[x//20, y//20] = 1
  70. empty_pos = [pos for pos in self.map.keys() if not self.map[pos]]
  71. result = choice(empty_pos)
  72. self.food_color = list(choice(self.colors))
  73. self.food = [result[0]*20, result[1]*20]
  74.  
  75.  
  76. def main():
  77. key_direction_dict = {
  78. 119: 'up', # W
  79. 115: 'down', # S
  80. 97: 'left', # A
  81. 100: 'right', # D
  82. 273: 'up', # UP
  83. 274: 'down', # DOWN
  84. 276: 'left', # LEFT
  85. 275: 'right', # RIGHT
  86. }
  87.  
  88. fps_clock = pygame.time.Clock()
  89. pygame.init()
  90. pygame.mixer.init()
  91. snake = Snake()
  92. sound = False
  93. if path.exists('eat.wav'):
  94. sound_wav = pygame.mixer.Sound("eat.wav")
  95. sound = True
  96. title_font = pygame.font.SysFont('arial', 32)
  97. welcome_words = title_font.render('Welcome to My Snake', True, (0, 0, 0), (255, 255, 255))
  98. tips_font = pygame.font.SysFont('arial', 24)
  99. start_game_words = tips_font.render('Click to Start Game', True, (0, 0, 0), (255, 255, 255))
  100. close_game_words = tips_font.render('Press ESC to Close', True, (0, 0, 0), (255, 255, 255))
  101. gameover_words = title_font.render('GAME OVER', True, (205, 92, 92), (255, 255, 255))
  102. win_words = title_font.render('THE SNAKE IS LONG ENOUGH AND YOU WIN!', True, (0, 0, 205), (255, 255, 255))
  103. screen = pygame.display.set_mode((640, 480), 0, 32)
  104. pygame.display.set_caption('My Snake')
  105. new_direction = snake.moving_direction
  106. while 1:
  107. for event in pygame.event.get():
  108. if event.type == QUIT:
  109. exit()
  110. elif event.type == KEYDOWN:
  111. if event.key == 27:
  112. exit()
  113. if snake.game_started and event.key in key_direction_dict:
  114. direction = key_direction_dict[event.key]
  115. new_direction = direction_check(snake.moving_direction, direction)
  116. elif (not snake.game_started) and event.type == pygame.MOUSEBUTTONDOWN:
  117. x, y = pygame.mouse.get_pos()
  118. if 213 <= x <= 422 and 304 <= y <= 342:
  119. snake.game_started = True
  120. screen.fill((255, 255, 255))
  121. if snake.game_started:
  122. snake.moving_direction = new_direction # 在这里赋值,而不是在event事件的循环中赋值,避免按键太快
  123. snake.move_head()
  124. snake.body.append(snake.head[:])
  125. if snake.head == snake.food:
  126. if sound:
  127. sound_wav.play()
  128. snake.generate_food()
  129. else:
  130. snake.body.pop(0)
  131. for seg in snake.body:
  132. pygame.draw.rect(screen, [0, 0, 0], [seg[0], seg[1], 20, 20], 0)
  133. pygame.draw.rect(screen, snake.food_color, [snake.food[0], snake.food[1], 20, 20], 0)
  134. if snake.check_game_status():
  135. screen.blit(gameover_words, (241, 310))
  136. pygame.display.update()
  137. snake = Snake()
  138. new_direction = snake.moving_direction
  139. sleep(3)
  140. elif len(snake.body) == 512:
  141. screen.blit(win_words, (33, 210))
  142. pygame.display.update()
  143. snake = Snake()
  144. new_direction = snake.moving_direction
  145. sleep(3)
  146. else:
  147. screen.blit(welcome_words, (188, 100))
  148. screen.blit(start_game_words, (236, 310))
  149. screen.blit(close_game_words, (233, 350))
  150. pygame.display.update()
  151. fps_clock.tick(snake.speed)
  152.  
  153.  
  154. if __name__ == '__main__':
  155. main()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持w3xue。

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号