Pygame做一期吃豆子游戏的示例代码

时间:2022-10-03 17:44:33

Pygame的历史

Pygame是一个利用SDL库的写就的游戏库,SDL呢,全名Simple DirectMedia Layer,是一位叫做Sam Lantinga的大牛写的,据说他为了让Loki(致力于向Linux上移植Windows的游戏的一家大好人公司,可惜已经倒闭,唉好人不长命啊……)更有效的工作,创造了这个东东。

SDL是用C写的,不过它也可以使用C++进行开发,当然还有很多其它的语言,Pygame就是Python中使用它的一个库。Pygame已经存在很多时间了,许多优秀的程序员加入其中,把Pygame做得越来越好。

开发工具:

Python版本:3.6.4
相关模块:
pygame模块;
以及一些Python自带的模块。

安装Python并添加到环境变量,
pip安装需要的相关模块即可。

游戏简介:

玩家通过↑↓←→键控制游戏的主角吃豆人吃掉藏在迷宫内的所有豆子,并且不能被鬼魂抓到。
若能顺利吃完迷宫内的所有豆子并且不被鬼魂抓到,则游戏胜利,否则游戏失败。

Step1:定义游戏精灵类

① 墙类:

Pygame做一期吃豆子游戏的示例代码

② 食物类:

Pygame做一期吃豆子游戏的示例代码

③ 角色类:

角色类包括吃豆人和鬼魂,鬼魂由电脑控制其运动轨迹,吃豆人由玩家控制其运动轨迹。
显然,其均需具备更新角色位置和改变角色运动方向的能力,其源代码如下:

Pygame做一期吃豆子游戏的示例代码

Step2:设计游戏地图

① 创建墙:

Pygame做一期吃豆子游戏的示例代码

② 创建门:

Pygame做一期吃豆子游戏的示例代码

③ 创建角色:

Pygame做一期吃豆子游戏的示例代码

④ 创建食物:

Pygame做一期吃豆子游戏的示例代码

Step3:设计游戏主循环

接下来开始设计游戏主循环。首先是初始化:

Pygame做一期吃豆子游戏的示例代码

然后定义主函数:

Pygame做一期吃豆子游戏的示例代码

其中startLevelGame函数用于开始某一关游戏,其源代码如下:

Pygame做一期吃豆子游戏的示例代码

showText函数用于在游戏结束或关卡切换时在游戏界面中显示提示性文字,其源代码如下:

Pygame做一期吃豆子游戏的示例代码

源代码:

  1. #吃豆子
  2. import os,sys
  3. import sys
  4. import pygame
  5. import random
  6. BLACK = (0, 0, 0)
  7. WHITE = (255, 255, 255)
  8. BLUE = (0, 0, 255)
  9. GREEN = (0, 255, 0)
  10. RED = (255, 0, 0)
  11. YELLOW = (255, 255, 0)
  12. PURPLE = (255, 0, 255)
  13. SKYBLUE = (0, 191, 255)
  14. if getattr(sys, 'frozen', False):
  15. cur_path = sys._MEIPASS
  16. else:
  17. cur_path = os.path.dirname(__file__)
  18. BGMPATH = os.path.join(cur_path, 'resources/sounds/bg.mp3')
  19. ICONPATH = os.path.join(cur_path,'resources/images/icon.png')
  20. FONTPATH = os.path.join(cur_path,'resources/font/ALGER.TTF')
  21. HEROPATH = os.path.join(cur_path,'resources/images/pacman.png')
  22. BlinkyPATH = os.path.join(cur_path,'resources/images/Blinky.png')
  23. ClydePATH = os.path.join(cur_path,'resources/images/Clyde.png')
  24. InkyPATH = os.path.join(cur_path,'resources/images/Inky.png')
  25. PinkyPATH = os.path.join(cur_path,'resources/images/Pinky.png')
  26. NUMLEVELS = 1
  27. class Wall(pygame.sprite.Sprite):
  28. def __init__(self, x, y, width, height, color, **kwargs):
  29. pygame.sprite.Sprite.__init__(self)
  30. self.image = pygame.Surface([width, height])
  31. self.image.fill(color)
  32. self.rect = self.image.get_rect()
  33. self.rect.left = x
  34. self.rect.top = y
  35. class Food(pygame.sprite.Sprite):
  36. def __init__(self, x, y, width, height, color, bg_color, **kwargs):
  37. pygame.sprite.Sprite.__init__(self)
  38. self.image = pygame.Surface([width, height])
  39. self.image.fill(bg_color)
  40. self.image.set_colorkey(bg_color)
  41. pygame.draw.ellipse(self.image, color, [0, 0, width, height])
  42. self.rect = self.image.get_rect()
  43. self.rect.left = x
  44. self.rect.top = y
  45. class Player(pygame.sprite.Sprite):
  46. def __init__(self, x, y, role_image_path):
  47. pygame.sprite.Sprite.__init__(self)
  48. self.role_name = role_image_path.split('/')[-1].split('.')[0]
  49. self.base_image = pygame.image.load(role_image_path).convert()
  50. self.image = self.base_image.copy()
  51. self.rect = self.image.get_rect()
  52. self.rect.left = x
  53. self.rect.top = y
  54. self.prev_x = x
  55. self.prev_y = y
  56. self.base_speed = [30, 30]
  57. self.speed = [0, 0]
  58. self.is_move = False
  59. self.tracks = []
  60. self.tracks_loc = [0, 0]
  61. def changeSpeed(self, direction):
  62. if direction[0] < 0:
  63. self.image = pygame.transform.flip(self.base_image, True, False)
  64. elif direction[0] > 0:
  65. self.image = self.base_image.copy()
  66. elif direction[1] < 0:
  67. self.image = pygame.transform.rotate(self.base_image, 90)
  68. elif direction[1] > 0:
  69. self.image = pygame.transform.rotate(self.base_image, -90)
  70. self.speed = [direction[0] * self.base_speed[0], direction[1] * self.base_speed[1]]
  71. return self.speed
  72. def update(self, wall_sprites, gate_sprites):
  73. if not self.is_move:
  74. return False
  75. x_prev = self.rect.left
  76. y_prev = self.rect.top
  77. self.rect.left += self.speed[0]
  78. self.rect.top += self.speed[1]
  79. is_collide = pygame.sprite.spritecollide(self, wall_sprites, False)
  80. if gate_sprites is not None:
  81. if not is_collide:
  82. is_collide = pygame.sprite.spritecollide(self, gate_sprites, False)
  83. if is_collide:
  84. self.rect.left = x_prev
  85. self.rect.top = y_prev
  86. return False
  87. return True
  88. def randomDirection(self):
  89. return random.choice([[-0.5, 0], [0.5, 0], [0, 0.5], [0, -0.5]])
  90. class Level1():
  91. def __init__(self):
  92. self.info = 'level1'
  93. def setupWalls(self, wall_color):
  94. self.wall_sprites = pygame.sprite.Group()
  95. wall_positions = [[0, 0, 6, 600],
  96. [0, 0, 600, 6],
  97. [0, 600, 606, 6],
  98. [600, 0, 6, 606],
  99. [300, 0, 6, 66],
  100. [60, 60, 186, 6],
  101. [360, 60, 186, 6],
  102. [60, 120, 66, 6],
  103. [60, 120, 6, 126],
  104. [180, 120, 246, 6],
  105. [300, 120, 6, 66],
  106. [480, 120, 66, 6],
  107. [540, 120, 6, 126],
  108. [120, 180, 126, 6],
  109. [120, 180, 6, 126],
  110. [360, 180, 126, 6],
  111. [480, 180, 6, 126],
  112. [180, 240, 6, 126],
  113. [180, 360, 246, 6],
  114. [420, 240, 6, 126],
  115. [240, 240, 42, 6],
  116. [324, 240, 42, 6],
  117. [240, 240, 6, 66],
  118. [240, 300, 126, 6],
  119. [360, 240, 6, 66],
  120. [0, 300, 66, 6],
  121. [540, 300, 66, 6],
  122. [60, 360, 66, 6],
  123. [60, 360, 6, 186],
  124. [480, 360, 66, 6],
  125. [540, 360, 6, 186],
  126. [120, 420, 366, 6],
  127. [120, 420, 6, 66],
  128. [480, 420, 6, 66],
  129. [180, 480, 246, 6],
  130. [300, 480, 6, 66],
  131. [120, 540, 126, 6],
  132. [360, 540, 126, 6]]
  133. for wall_position in wall_positions:
  134. wall = Wall(*wall_position, wall_color)
  135. self.wall_sprites.add(wall)
  136. return self.wall_sprites
  137. def setupGate(self, gate_color):
  138. self.gate_sprites = pygame.sprite.Group()
  139. self.gate_sprites.add(Wall(282, 242, 42, 2, gate_color))
  140. return self.gate_sprites
  141. def setupPlayers(self, hero_image_path, ghost_images_path):
  142. self.hero_sprites = pygame.sprite.Group()
  143. self.ghost_sprites = pygame.sprite.Group()
  144. self.hero_sprites.add(Player(287, 439, hero_image_path))
  145. for each in ghost_images_path:
  146. role_name = each.split('/')[-1].split('.')[0]
  147. if role_name == 'Blinky':
  148. player = Player(287, 199, each)
  149. player.is_move = True
  150. player.tracks = [[0, -0.5, 4], [0.5, 0, 9], [0, 0.5, 11], [0.5, 0, 3], [0, 0.5, 7], [-0.5, 0, 11], [0, 0.5, 3],
  151. [0.5, 0, 15], [0, -0.5, 15], [0.5, 0, 3], [0, -0.5, 11], [-0.5, 0, 3], [0, -0.5, 11], [-0.5, 0, 3],
  152. [0, -0.5, 3], [-0.5, 0, 7], [0, -0.5, 3], [0.5, 0, 15], [0, 0.5, 15], [-0.5, 0, 3], [0, 0.5, 3],
  153. [-0.5, 0, 3], [0, -0.5, 7], [-0.5, 0, 3], [0, 0.5, 7], [-0.5, 0, 11], [0, -0.5, 7], [0.5, 0, 5]]
  154. self.ghost_sprites.add(player)
  155. elif role_name == 'Clyde':
  156. player = Player(319, 259, each)
  157. player.is_move = True
  158. player.tracks = [[-1, 0, 2], [0, -0.5, 4], [0.5, 0, 5], [0, 0.5, 7], [-0.5, 0, 11], [0, -0.5, 7],
  159. [-0.5, 0, 3], [0, 0.5, 7], [-0.5, 0, 7], [0, 0.5, 15], [0.5, 0, 15], [0, -0.5, 3],
  160. [-0.5, 0, 11], [0, -0.5, 7], [0.5, 0, 3], [0, -0.5, 11], [0.5, 0, 9]]
  161. self.ghost_sprites.add(player)
  162. elif role_name == 'Inky':
  163. player = Player(255, 259, each)
  164. player.is_move = True
  165. player.tracks = [[1, 0, 2], [0, -0.5, 4], [0.5, 0, 10], [0, 0.5, 7], [0.5, 0, 3], [0, -0.5, 3],
  166. [0.5, 0, 3], [0, -0.5, 15], [-0.5, 0, 15], [0, 0.5, 3], [0.5, 0, 15], [0, 0.5, 11],
  167. [-0.5, 0, 3], [0, -0.5, 7], [-0.5, 0, 11], [0, 0.5, 3], [-0.5, 0, 11], [0, 0.5, 7],
  168. [-0.5, 0, 3], [0, -0.5, 3], [-0.5, 0, 3], [0, -0.5, 15], [0.5, 0, 15], [0, 0.5, 3],
  169. [-0.5, 0, 15], [0, 0.5, 11], [0.5, 0, 3], [0, -0.5, 11], [0.5, 0, 11], [0, 0.5, 3], [0.5, 0, 1]]
  170. self.ghost_sprites.add(player)
  171. elif role_name == 'Pinky':
  172. player = Player(287, 259, each)
  173. player.is_move = True
  174. player.tracks = [[0, -1, 4], [0.5, 0, 9], [0, 0.5, 11], [-0.5, 0, 23], [0, 0.5, 7], [0.5, 0, 3],
  175. [0, -0.5, 3], [0.5, 0, 19], [0, 0.5, 3], [0.5, 0, 3], [0, 0.5, 3], [0.5, 0, 3],
  176. [0, -0.5, 15], [-0.5, 0, 7], [0, 0.5, 3], [-0.5, 0, 19], [0, -0.5, 11], [0.5, 0, 9]]
  177. self.ghost_sprites.add(player)
  178. return self.hero_sprites, self.ghost_sprites
  179. def setupFood(self, food_color, bg_color):
  180. self.food_sprites = pygame.sprite.Group()
  181. for row in range(19):
  182. for col in range(19):
  183. if (row == 7 or row == 8) and (col == 8 or col == 9 or col == 10):
  184. continue
  185. else:
  186. food = Food(30*col+32, 30*row+32, 4, 4, food_color, bg_color)
  187. is_collide = pygame.sprite.spritecollide(food, self.wall_sprites, False)
  188. if is_collide:
  189. continue
  190. is_collide = pygame.sprite.spritecollide(food, self.hero_sprites, False)
  191. if is_collide:
  192. continue
  193. self.food_sprites.add(food)
  194. return self.food_sprites
  195. def startLevelGame(level, screen, font):
  196. clock = pygame.time.Clock()
  197. SCORE = 0
  198. wall_sprites = level.setupWalls(SKYBLUE)
  199. gate_sprites = level.setupGate(WHITE)
  200. hero_sprites, ghost_sprites = level.setupPlayers(HEROPATH, [BlinkyPATH, ClydePATH, InkyPATH, PinkyPATH])
  201. food_sprites = level.setupFood(YELLOW, WHITE)
  202. is_clearance = False
  203. while True:
  204. for event in pygame.event.get():
  205. if event.type == pygame.QUIT:
  206. pygame.quit()
  207. sys.exit(-1)
  208. if event.type == pygame.KEYDOWN:
  209. if event.key == pygame.K_LEFT:
  210. for hero in hero_sprites:
  211. hero.changeSpeed([-1, 0])
  212. hero.is_move = True
  213. elif event.key == pygame.K_RIGHT:
  214. for hero in hero_sprites:
  215. hero.changeSpeed([1, 0])
  216. hero.is_move = True
  217. elif event.key == pygame.K_UP:
  218. for hero in hero_sprites:
  219. hero.changeSpeed([0, -1])
  220. hero.is_move = True
  221. elif event.key == pygame.K_DOWN:
  222. for hero in hero_sprites:
  223. hero.changeSpeed([0, 1])
  224. hero.is_move = True
  225. if event.type == pygame.KEYUP:
  226. if (event.key == pygame.K_LEFT) or (event.key == pygame.K_RIGHT) or (event.key == pygame.K_UP) or (event.key == pygame.K_DOWN):
  227. hero.is_move = False
  228. screen.fill(BLACK)
  229. for hero in hero_sprites:
  230. hero.update(wall_sprites, gate_sprites)
  231. hero_sprites.draw(screen)
  232. for hero in hero_sprites:
  233. food_eaten = pygame.sprite.spritecollide(hero, food_sprites, True)
  234. SCORE += len(food_eaten)
  235. wall_sprites.draw(screen)
  236. gate_sprites.draw(screen)
  237. food_sprites.draw(screen)
  238. for ghost in ghost_sprites:
  239. if ghost.tracks_loc[1] < ghost.tracks[ghost.tracks_loc[0]][2]:
  240. ghost.changeSpeed(ghost.tracks[ghost.tracks_loc[0]][0: 2])
  241. ghost.tracks_loc[1] += 1
  242. else:
  243. if ghost.tracks_loc[0] < len(ghost.tracks) - 1:
  244. ghost.tracks_loc[0] += 1
  245. elif ghost.role_name == 'Clyde':
  246. ghost.tracks_loc[0] = 2
  247. else:
  248. ghost.tracks_loc[0] = 0
  249. ghost.changeSpeed(ghost.tracks[ghost.tracks_loc[0]][0: 2])
  250. ghost.tracks_loc[1] = 0
  251. if ghost.tracks_loc[1] < ghost.tracks[ghost.tracks_loc[0]][2]:
  252. ghost.changeSpeed(ghost.tracks[ghost.tracks_loc[0]][0: 2])
  253. else:
  254. if ghost.tracks_loc[0] < len(ghost.tracks) - 1:
  255. loc0 = ghost.tracks_loc[0] + 1
  256. elif ghost.role_name == 'Clyde':
  257. loc0 = 2
  258. else:
  259. loc0 = 0
  260. ghost.changeSpeed(ghost.tracks[loc0][0: 2])
  261. ghost.update(wall_sprites, None)
  262. ghost_sprites.draw(screen)
  263. score_text = font.render("Score: %s" % SCORE, True, RED)
  264. screen.blit(score_text, [10, 10])
  265. if len(food_sprites) == 0:
  266. is_clearance = True
  267. break
  268. if pygame.sprite.groupcollide(hero_sprites, ghost_sprites, False, False):
  269. is_clearance = False
  270. break
  271. pygame.display.flip()
  272. clock.tick(10)
  273. return is_clearance
  274. def showText(screen, font, is_clearance, flag=False):
  275. clock = pygame.time.Clock()
  276. msg = 'Game Over!' if not is_clearance else 'Congratulations, you won!'
  277. positions = [[235, 233], [65, 303], [170, 333]] if not is_clearance else [[145, 233], [65, 303], [170, 333]]
  278. surface = pygame.Surface((400, 200))
  279. surface.set_alpha(10)
  280. surface.fill((128, 128, 128))
  281. screen.blit(surface, (100, 200))
  282. texts = [font.render(msg, True, WHITE),
  283. font.render('Press ENTER to continue or play again.', True, WHITE),
  284. font.render('Press ESCAPE to quit.', True, WHITE)]
  285. while True:
  286. for event in pygame.event.get():
  287. if event.type == pygame.QUIT:
  288. pygame.quit()
  289. sys.exit(-1)
  290. if event.type == pygame.KEYDOWN:
  291. if event.key == pygame.K_RETURN:
  292. if is_clearance:
  293. if not flag:
  294. return
  295. else:
  296. main(initialize())
  297. else:
  298. main(initialize())
  299. elif event.key == pygame.K_ESCAPE:
  300. pygame.quit()
  301. sys.exit(-1)
  302. for idx, (text, position) in enumerate(zip(texts, positions)):
  303. screen.blit(text, position)
  304. pygame.display.flip()
  305. clock.tick(10)
  306.  
  307. def initialize():
  308. pygame.init()
  309. icon_image = pygame.image.load(ICONPATH)
  310. pygame.display.set_icon(icon_image)
  311. screen = pygame.display.set_mode([606, 606])
  312. pygame.display.set_caption('吃豆子')
  313. return screen
  314.  
  315. def main(screen):
  316. try:
  317. pygame.mixer.init()
  318. pygame.mixer.music.load(BGMPATH)
  319. pygame.mixer.music.play(-1, 0.0)
  320. except:
  321. pass
  322. pygame.font.init()
  323. font_small = pygame.font.Font(FONTPATH, 18)
  324. font_big = pygame.font.Font(FONTPATH, 24)
  325. for num_level in range(1, NUMLEVELS+1):
  326. if num_level == 1:
  327. level = Level1()
  328. is_clearance = startLevelGame(level, screen, font_small)
  329. if num_level == NUMLEVELS:
  330. showText(screen, font_big, is_clearance, True)
  331. else:
  332. showText(screen, font_big, is_clearance)
  333. if __name__ == "__main__":
  334. main(initialize())

到此这篇关于Pygame做一期吃豆子游戏的示例代码的文章就介绍到这了,更多相关Pygame 吃豆子内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/qq_45414559/article/details/105860034