经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Python » 查看文章
利用Pygame制作躲避僵尸游戏
来源:jb51  时间:2022/5/30 9:37:49  对本文有异议

游戏玩法

根据神庙逃亡,实现一个人躲避僵尸的小游戏,主要的是精灵、精灵组之间相撞、相交的处理。

游戏开始随机出现一定的僵尸,随机移动,玩家在一位置上,如果僵尸靠近玩家一定距离,则玩家持续掉血。玩家通过上下左右移动躲避僵尸,屏幕会随机刷新一个加血包,玩家吃了就会加一定的血,并在此刷新血包。

property()

这个函数在类中返回新的属性

  1. property(get,set,del,doc)

参数如上所示,get、set、del分别是获取设值删除调用的,doc是描述的。

精灵类

在原来的精灵类中添加方向和属性即可。

  1. class MySprite(pygame.sprite.Sprite):
  2. def __init__(self, target):
  3. pygame.sprite.Sprite.__init__(self)
  4. self.master_image = None
  5. self.frame = 0
  6. self.old_frame = -1
  7. self.frame_width = 1
  8. self.frame_height = 1
  9. self.first_frame = 0
  10. self.last_frame = 0
  11. self.columns = 1
  12. self.last_time = 0
  13. self.direction = 0
  14. self.classification = "玩家"
  15.  
  16. def load(self, filename, width, height, columns, direction, classification="玩家"):
  17. # 精灵的属性
  18. self.classification = classification
  19. # 方向
  20. self.direction = direction
  21. # 载入图片
  22. # 780 * 300
  23. self.master_image = pygame.image.load(filename).convert_alpha() # 载入图片
  24. self.frame_width = width
  25. self.frame_height = height
  26. self.rect = Rect(0, 0, width, height)
  27. self.columns = columns
  28. rect = self.master_image.get_rect()
  29. self.last_frame = (rect.width // width) * (rect.height // height) - 1
  30.  
  31. def update(self, current_time, rate=30): # current_time 更新频率 为30
  32. if current_time > self.last_time + rate: # 如果当前事件 大于 最后的时间 + 当前的节奏
  33. self.frame += 1 # 当前的帧数加一
  34. if self.frame > self.last_frame: # 当前最后一帧 则从第一帧开始
  35. self.frame = self.first_frame # 从0开始
  36. self.last_time = current_time # 将最后帧值为30
  37.  
  38. # build current frame only if it changed
  39. if self.frame != self.old_frame: # 当前帧数不等于老的一帧
  40. frame_x = (self.frame % self.columns) * self.frame_width
  41. frame_y = (self.frame // self.columns) * self.frame_height
  42. rect = (frame_x, frame_y, self.frame_width, self.frame_height) # 更新对应的位置
  43. self.image = self.master_image.subsurface(rect) # 循环箱已有的方向
  44. self.old_frame = self.frame
  45.  
  46. def __str__(self):
  47. return str(self.frame) + "," + str(self.first_frame) + "," + str(self.last_frame) + "," + str(self.frame_width) + "," + str(self.frame_height) + "," + str(self.columns)

初始画面

和原来一样,先建立简单的画面。

  1. import mySprite1
  2. import pygame, sys, random
  3. from pygame.locals import *
  4.  
  5.  
  6. def print_text(font, x, y, text, color=(255, 255, 255)):
  7. imgText = font.render(text, True, color)
  8. screen.blit(imgText, (x, y))
  9.  
  10.  
  11. # 设置窗口
  12. pygame.init()
  13. screen = pygame.display.set_mode((800, 600))
  14. pygame.display.set_caption("勇闯后半夜")
  15. font = pygame.font.Font(None, 30)
  16. timer = pygame.time.Clock()
  17.  
  18. while True:
  19. for event in pygame.event.get():
  20. if event.type == QUIT:
  21. sys.exit()
  22. key = pygame.key.get_pressed()
  23. if key[K_ESCAPE]:
  24. sys.exit()
  25.  
  26. screen.fill((50, 50, 100))
  27.  
  28. pygame.display.update()
  29.  

精灵移动函数

如果是僵尸遇到墙壁自动反方向走,根据方向改变对应的位置。

  1. def reversal_direction(mySprite):
  2. direction = mySprite.direction
  3. if direction == 0:
  4. direction = 4
  5. elif direction == 2:
  6. direction = 6
  7. elif direction == 4:
  8. direction = 0
  9. elif direction == 6:
  10. direction = 2
  11. mySprite.direction = direction
  12.  
  13.  
  14. def increment(mySprite, offset=1):
  15. # 上下左右
  16. direction = mySprite.direction
  17. rect = mySprite.rect
  18. if direction == 0:
  19. rect.y -= offset
  20. elif direction == 2:
  21. rect.x += offset
  22. elif direction == 4:
  23. rect.y += offset
  24. elif direction == 6:
  25. rect.x -= offset
  26. # 超出边界的处理
  27. # 超出边界flg
  28. boundary = False
  29. if rect.x < 0:
  30. rect.x = 0
  31. boundary = True
  32. if rect.x + mySprite.frame_width > 800:
  33. rect.x = 800 - mySprite.frame_width
  34. boundary = True
  35. if rect.y < 0:
  36. rect.y = 0
  37. boundary = True
  38. if rect.y + mySprite.frame_height > 600:
  39. rect.y = 600 - mySprite.frame_height
  40. boundary = True
  41. # 如果超出边界而且是僵尸的话 则反转方向
  42. if boundary and mySprite.classification == "僵尸":
  43. reversal_direction(mySprite)

加载玩家

这个是素材的图,如上所示,奇数行便是对应的方向移动。文件大小是768 * 768,可以分为96 * 96的8张。

加载玩家

  1. # 玩家
  2. play_group = pygame.sprite.Group()
  3.  
  4. play = mySprite1()
  5. play.load("farmer walk.png", 96, 96, 8)
  6. play.direction = -1
  7. play_group.rect.x = 96
  8. play_group.rect.y = 96
  9. play_group.add(play)
  10.  
  11. play_group.update(ticks, 50)
  12. screen.fill((50, 50, 100))
  13.  
  14. play_group.draw(screen)
  15. pygame.display.update()

通过改变帧数修改,根据游戏的结束或是否移动,改变对应的事件

  1. if not game_over:
  2. play.first_frame = play.direction * play.columns
  3. play.last_frame = play.first_frame + play.columns - 1
  4. if play.frame < play.first_frame:
  5. play.frame = play.first_frame
  6.  
  7. if not play_moving:
  8. play.frame = play.first_frame = play.last_frame
  9. else:
  10. increment(play)

控制交互

  1. if key[K_ESCAPE]:
  2. sys.exit()
  3. elif key[K_UP]:
  4. play.direction = 0
  5. play_moving = True
  6. elif key[K_DOWN]:
  7. play.direction = 4
  8. play_moving = True
  9. elif key[K_LEFT]:
  10. play.direction = 6
  11. play_moving = True
  12. elif key[K_RIGHT]:
  13. play.direction = 2
  14. play_moving = True
  15. else:
  16. play_moving = False

添加僵尸

  1. # 随机生成20个僵尸
  2. for n in range(0, 10):
  3. zombie = MySprite()
  4. random_direction = random.randint(0, 3) * 2
  5. zombie.load("zombie walk.png", 96, 96, 8, random_direction, "僵尸")
  6. zombie.rect.x = random.randint(0, 600)
  7. zombie.rect.y = random.randint(0, 500)
  8. print(zombie.rect)
  9. zombie_group.add(zombie)
  10. # 设置僵尸
  11. for z in zombie_group:
  12. z.first_frame = z.direction * z.columns
  13. z.last_frame = z.first_frame + z.columns - 1
  14. if z.frame < z.first_frame:
  15. z.frame = z.first_frame
  16. increment(z)

添加血包

血包就是单纯的一个图的展示。

  1. health = MySprite()
  2. health.load("health.png", 32, 32, 1)
  3. health.rect.x = random.randint(0, 600)
  4. health.rect.y = random.randint(0, 500)
  5. health_group.add(health)

精灵相互碰撞事件

主要是僵尸和人 、人和血包之间的相撞事件

  1. # 相撞事件
  2. attack = None
  3. attack = pygame.sprite.spritecollideany(play, zombie_group)
  4. if attack is not None:
  5. if pygame.sprite.collide_rect_ratio(0.5)(play, attack):
  6. play_health -= 10
  7. attack.rect.x = random.randint(0, 600)
  8. attack.rect.y = random.randint(0, 500)
  9. else:
  10. attack = None
  11.  
  12. if pygame.sprite.collide_rect_ratio(0.5)(play, health):
  13. play_health += 30
  14. if play_health > 100:
  15. play_health = 100
  16. health.rect.x = random.randint(0, 600)
  17. health.rect.y = random.randint(0, 500)
  18.  
  19. if play_health <= 0:
  20. game_over = True
  21. # 显示血量
  22. pygame.draw.rect(screen, (100, 200, 100, 180), Rect(300, 575, 200, 25))
  23. pygame.draw.rect(screen, (50, 150, 150, 180), Rect(300, 575, play_health * 2, 25))

完整代码

  1. import pygame, sys, random
  2. from pygame.locals import *
  3. from mySprite1 import *
  4.  
  5.  
  6. def print_text(font, x, y, text, color=(255, 255, 255)):
  7. imgText = font.render(text, True, color)
  8. screen.blit(imgText, (x, y))
  9.  
  10.  
  11. def reversal_direction(mySprite):
  12. direction = mySprite.direction
  13. if direction == 0:
  14. direction = 4
  15. elif direction == 2:
  16. direction = 6
  17. elif direction == 4:
  18. direction = 0
  19. elif direction == 6:
  20. direction = 2
  21. mySprite.direction = direction
  22.  
  23.  
  24. def increment(mySprite, offset=1):
  25. # 上下左右
  26. direction = mySprite.direction
  27. rect = mySprite.rect
  28. if direction == 0:
  29. rect.y -= offset
  30. elif direction == 2:
  31. rect.x += offset
  32. elif direction == 4:
  33. rect.y += offset
  34. elif direction == 6:
  35. rect.x -= offset
  36. # 超出边界的处理
  37. # 超出边界flg
  38. boundary = False
  39. if rect.x < 0:
  40. rect.x = 0
  41. boundary = True
  42. if rect.x + mySprite.frame_width > 800:
  43. rect.x = 800 - mySprite.frame_width
  44. boundary = True
  45. if rect.y < 0:
  46. rect.y = 0
  47. boundary = True
  48. if rect.y + mySprite.frame_height > 600:
  49. rect.y = 600 - mySprite.frame_height
  50. boundary = True
  51. # 如果超出边界而且是僵尸的话 则反转方向
  52. if boundary and mySprite.classification == "僵尸":
  53. reversal_direction(mySprite)
  54.  
  55.  
  56. # 设置窗口
  57. pygame.init()
  58. screen = pygame.display.set_mode((800, 600))
  59. pygame.display.set_caption("勇闯后半夜")
  60. font = pygame.font.Font(None, 30)
  61. timer = pygame.time.Clock()
  62. game_over = False
  63.  
  64. # 玩家
  65. play_group = pygame.sprite.Group()
  66.  
  67. play = MySprite()
  68. play.load("farmer walk.png", 96, 96, 8, 4)
  69. play.rect.x = 96
  70. play.rect.y = 96
  71. play_moving = False
  72. play_group.add(play)
  73. play_health = 100
  74.  
  75. # 僵尸
  76. zombie_group = pygame.sprite.Group()
  77.  
  78. # 随机生成20个僵尸
  79. for n in range(0, 10):
  80. zombie = MySprite()
  81. random_direction = random.randint(0, 3) * 2
  82. zombie.load("zombie walk.png", 96, 96, 8, random_direction, "僵尸")
  83. zombie.rect.x = random.randint(0, 600)
  84. zombie.rect.y = random.randint(0, 500)
  85. print(zombie.rect)
  86. zombie_group.add(zombie)
  87.  
  88. # 血包
  89. health_group = pygame.sprite.Group()
  90.  
  91. health = MySprite()
  92. health.load("health.png", 32, 32, 1)
  93. health.rect.x = random.randint(0, 600)
  94. health.rect.y = random.randint(0, 500)
  95. health_group.add(health)
  96.  
  97. while True:
  98. # 设置执行的频率
  99. timer.tick(30)
  100. ticks = pygame.time.get_ticks()
  101. for event in pygame.event.get():
  102. if event.type == QUIT:
  103. sys.exit()
  104. key = pygame.key.get_pressed()
  105. if key[K_ESCAPE]:
  106. sys.exit()
  107. elif key[K_UP]:
  108. play.direction = 0
  109. play_moving = True
  110. elif key[K_DOWN]:
  111. play.direction = 4
  112. play_moving = True
  113. elif key[K_LEFT]:
  114. play.direction = 6
  115. play_moving = True
  116. elif key[K_RIGHT]:
  117. play.direction = 2
  118. play_moving = True
  119. else:
  120. play_moving = False
  121.  
  122. if not game_over:
  123. # 设置玩家
  124. play.first_frame = play.direction * play.columns
  125. play.last_frame = play.first_frame + play.columns - 1
  126. if play.frame < play.first_frame:
  127. play.frame = play.first_frame
  128. # 设置僵尸
  129. for z in zombie_group:
  130. z.first_frame = z.direction * z.columns
  131. z.last_frame = z.first_frame + z.columns - 1
  132. if z.frame < z.first_frame:
  133. z.frame = z.first_frame
  134. increment(z)
  135.  
  136. if not play_moving:
  137. play.frame = play.first_frame = play.last_frame
  138. else:
  139. increment(play)
  140.  
  141. # 相撞事件
  142. attack = None
  143. attack = pygame.sprite.spritecollideany(play, zombie_group)
  144. if attack is not None:
  145. if pygame.sprite.collide_rect_ratio(0.5)(play, attack):
  146. play_health -= 10
  147. attack.rect.x = random.randint(0, 600)
  148. attack.rect.y = random.randint(0, 500)
  149. else:
  150. attack = None
  151.  
  152. if pygame.sprite.collide_rect_ratio(0.5)(play, health):
  153. play_health += 30
  154. if play_health > 100:
  155. play_health = 100
  156. health.rect.x = random.randint(0, 600)
  157. health.rect.y = random.randint(0, 500)
  158.  
  159. if play_health <= 0:
  160. game_over = True
  161.  
  162. play_group.update(ticks, 50)
  163. zombie_group.update(ticks, 50)
  164. health_group.update(ticks, 50)
  165. screen.fill((50, 50, 100))
  166.  
  167. play_group.draw(screen)
  168. zombie_group.draw(screen)
  169. health_group.draw(screen)
  170.  
  171. # 显示血量
  172. pygame.draw.rect(screen, (100, 200, 100, 180), Rect(300, 575, 200, 25))
  173. pygame.draw.rect(screen, (50, 150, 150, 180), Rect(300, 575, play_health * 2, 25))
  174.  
  175. if game_over:
  176. print_text(font, 300, 100, "GAME OVER!!!")
  177. pygame.display.update()
  178.  

到此这篇关于利用Pygame制作躲避僵尸游戏的文章就介绍到这了,更多相关Pygame躲避僵尸游戏内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持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号