经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Python » 查看文章
忆童年!用Python实现愤怒的小鸟游戏
来源:jb51  时间:2021/6/7 9:22:26  对本文有异议

开发工具

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

环境搭建

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

原理介绍

这里简单介绍一下游戏的实现原理呗。首先是游戏的开始界面,大概是长这样的,比较简约:

在这里插入图片描述

主要包括两个部分,即游戏的标题和游戏的开始以及退出按钮,这两部分的代码实现如下:

  1. '''按钮类'''
  2. class Button(pygame.sprite.Sprite):
  3. def __init__(self, screen, x, y, width, height, action=None, color_not_active=(189, 195, 199), color_active=(189, 195, 199)):
  4. pygame.sprite.Sprite.__init__(self)
  5. self.x = x
  6. self.y = y
  7. self.width = width
  8. self.height = height
  9. self.action = action
  10. self.screen = screen
  11. self.color_active = color_active
  12. self.color_not_active = color_not_active
  13. '''添加文字'''
  14. def addtext(self, text, size=20, font='Times New Roman', color=(0, 0, 0)):
  15. self.font = pygame.font.Font(font, size)
  16. self.text = self.font.render(text, True, color)
  17. self.text_pos = self.text.get_rect()
  18. self.text_pos.center = (self.x + self.width / 2, self.y + self.height / 2)
  19. '''是否被鼠标选中'''
  20. def selected(self):
  21. pos = pygame.mouse.get_pos()
  22. if (self.x < pos[0] < self.x + self.width) and (self.y < pos[1] < self.y + self.height):
  23. return True
  24. return False
  25. '''画到屏幕上'''
  26. def draw(self):
  27. if self.selected():
  28. pygame.draw.rect(self.screen, self.color_active, (self.x, self.y, self.width, self.height))
  29. else:
  30. pygame.draw.rect(self.screen, self.color_not_active, (self.x, self.y, self.width, self.height))
  31. if hasattr(self, 'text'):
  32. self.screen.blit(self.text, self.text_pos)
  33.  
  34.  
  35. '''文字标签类'''
  36. class Label(pygame.sprite.Sprite):
  37. def __init__(self, screen, x, y, width, height):
  38. pygame.sprite.Sprite.__init__(self)
  39. self.x = x
  40. self.y = y
  41. self.width = width
  42. self.height = height
  43. self.screen = screen
  44. '''添加文字'''
  45. def addtext(self, text, size=20, font='Times New Roman', color=(0, 0, 0)):
  46. self.font = pygame.font.Font(font, size)
  47. self.text = self.font.render(text, True, color)
  48. self.text_pos = self.text.get_rect()
  49. self.text_pos.center = (self.x + self.width / 2, self.y + self.height / 2)
  50. '''画到屏幕上'''
  51. def draw(self):
  52. if hasattr(self, 'text'):
  53. self.screen.blit(self.text, self.text_pos)

实现起来其实都比较简单,按钮类就是多了一个被鼠标选中之后(也就是鼠标的位置落在按钮的区域范围内时)改变颜色以直观地告诉玩家该按钮已经被选中了的功能。

如果玩家点击退出键(QUIT),则退出游戏:

  1. def quitgame():
  2. pygame.quit()
  3. sys.exit()

若点击开始游戏按钮,则开始游戏:

  1. def startgame():
  2. game_levels = GameLevels(cfg, screen)
  3. game_levels.start()

游戏界面大概长这样:

在这里插入图片描述

玩家获胜的方法就是操作有限数量的小鸟将所有入侵的猪干掉,换句话说就是利用弹弓发射小鸟,让小鸟击中场上的所有猪。若小鸟全部发射完之后场上仍然有猪没有被击中,则玩家失败。判断游戏胜负关系的代码实现起来其实蛮简单的,大概是这样的:

  1. '''游戏状态'''
  2. def status(self, pigs, birds):
  3. status_codes = {
  4. 'gaming': 0,
  5. 'failure': 1,
  6. 'victory': 2,
  7. }
  8. if len(pigs) == 0: return status_codes['victory']
  9. elif len(birds) == 0: return status_codes['failure']
  10. else: return status_codes['gaming']

接着,为了实现游戏,我们先定义一下所有我们需要的游戏精灵类。首先,是我们的主角,愤怒的小鸟:

  1. '''小鸟'''
  2. class Bird(pygame.sprite.Sprite):
  3. def __init__(self, screen, imagepaths, loc_info, velocity=None, color=(255, 255, 255), **kwargs):
  4. pygame.sprite.Sprite.__init__(self)
  5. assert len(loc_info) == 3
  6. assert len(imagepaths) == 1
  7. # 设置必要的属性常量
  8. self.color = color
  9. self.screen = screen
  10. self.loc_info = list(loc_info)
  11. self.imagepaths = imagepaths
  12. self.velocity = VelocityVector() if velocity is None else velocity
  13. self.type = 'bird'
  14. self.fly_path = []
  15. self.is_dead = False
  16. self.elasticity = 0.8
  17. self.is_loaded = False
  18. self.is_selected = False
  19. self.inverse_friction = 0.99
  20. self.gravity = VelocityVector(0.2, math.pi)
  21. # 屏幕大小
  22. self.screen_size = screen.get_rect().size
  23. self.screen_size = (self.screen_size[0], self.screen_size[1] - 50)
  24. # 导入图像
  25. self.image = pygame.image.load(imagepaths[0])
  26. '''画到屏幕上'''
  27. def draw(self):
  28. if not self.is_loaded:
  29. for point in self.fly_path:
  30. pygame.draw.ellipse(self.screen, self.color, (point[0], point[1], 3, 3), 1)
  31. position = self.loc_info[0] - self.loc_info[2], self.loc_info[1] - self.loc_info[2]
  32. self.screen.blit(self.image, position)
  33. '''判断有没有被鼠标选中'''
  34. def selected(self):
  35. pos = pygame.mouse.get_pos()
  36. dx, dy = pos[0] - self.loc_info[0], pos[1] - self.loc_info[1]
  37. dist = math.hypot(dy, dx)
  38. if dist < self.loc_info[2]:
  39. return True
  40. return False
  41. '''加载到弹弓上'''
  42. def load(self, slingshot):
  43. self.loc_info[0], self.loc_info[1] = slingshot.x, slingshot.y
  44. self.is_loaded = True
  45. '''重新设置位置'''
  46. def reposition(self, slingshot):
  47. pos = pygame.mouse.get_pos()
  48. if self.selected:
  49. self.loc_info[0], self.loc_info[1] = pos[0], pos[1]
  50. dx, dy = slingshot.x - self.loc_info[0], slingshot.y - self.loc_info[1]
  51. self.velocity.magnitude = min(int(math.hypot(dx, dy) / 2), 80)
  52. self.velocity.angle = math.pi / 2 + math.atan2(dy, dx)
  53. '''显示发射小鸟的路径'''
  54. def projectpath(self):
  55. if self.is_loaded:
  56. path = []
  57. bird = Bird(self.screen, self.imagepaths, self.loc_info, velocity=self.velocity)
  58. for i in range(30):
  59. bird.move()
  60. if i % 5 == 0: path.append((bird.loc_info[0], bird.loc_info[1]))
  61. for point in path:
  62. pygame.draw.ellipse(self.screen, self.color, (point[0], point[1], 2, 2))
  63. '''移动小鸟'''
  64. def move(self):
  65. # 根据重力改变小鸟的速度向量
  66. self.velocity = VectorAddition(self.velocity, self.gravity)
  67. self.loc_info[0] += self.velocity.magnitude * math.sin(self.velocity.angle)
  68. self.loc_info[1] -= self.velocity.magnitude * math.cos(self.velocity.angle)
  69. self.velocity.magnitude *= self.inverse_friction
  70. # 宽度超出屏幕
  71. if self.loc_info[0] > self.screen_size[0] - self.loc_info[2]:
  72. self.loc_info[0] = 2 * (self.screen_size[0] - self.loc_info[2]) - self.loc_info[0]
  73. self.velocity.angle *= -1
  74. self.velocity.magnitude *= self.elasticity
  75. elif self.loc_info[0] < self.loc_info[2]:
  76. self.loc_info[0] = 2 * self.loc_info[2] - self.loc_info[0]
  77. self.velocity.angle *= -1
  78. self.velocity.magnitude *= self.elasticity
  79. # 高度超出屏幕
  80. if self.loc_info[1] > self.screen_size[1] - self.loc_info[2]:
  81. self.loc_info[1] = 2 * (self.screen_size[1] - self.loc_info[2]) - self.loc_info[1]
  82. self.velocity.angle = math.pi - self.velocity.angle
  83. self.velocity.magnitude *= self.elasticity
  84. elif self.loc_info[1] < self.loc_info[2]:
  85. self.loc_info[1] = 2 * self.loc_info[2] - self.loc_info[1]
  86. self.velocity.angle = math.pi - self.velocity.angle
  87. self.velocity.magnitude *= self.elasticity

实现它主要需要考虑的是小鸟其实存在五种状态:

  • 排队状态,即在左下角等待进入弹弓时的状态,静止不动即可;
  • 就绪状态,即进入弹弓准备被发射的状态,其需要跟着鼠标不断地移动,使得玩家知道自己目前调整小鸟所到的位置被发射出去之后大概会是 什么样的角度和路径;
  • 飞行状态,即被弹弓发射出去之后的状态,需要根据重力和小鸟的初速度来计算其飞行路径并不断地移动;
  • 碰撞状态,即在飞行过程中撞击到其他物体例如小猪和木桩等时,运动状态发生了改变;
  • 静止状态,即小鸟完成飞行状态之后最终静止时的状态。

接着来实现一下小猪:

  1. '''猪'''
  2. class Pig(pygame.sprite.Sprite):
  3. def __init__(self, screen, imagepaths, loc_info, velocity=None, **kwargs):
  4. pygame.sprite.Sprite.__init__(self)
  5. assert len(loc_info) == 3
  6. assert len(imagepaths) == 3
  7. # 设置必要的属性常量
  8. self.screen = screen
  9. self.loc_info = list(loc_info)
  10. self.imagepaths = imagepaths
  11. self.velocity = VelocityVector() if velocity is None else velocity
  12. self.type = 'pig'
  13. self.is_dead = False
  14. self.elasticity = 0.8
  15. self.switch_freq = 20
  16. self.animate_count = 0
  17. self.inverse_friction = 0.99
  18. self.gravity = VelocityVector(0.2, math.pi)
  19. # 屏幕大小
  20. self.screen_size = screen.get_rect().size
  21. self.screen_size = (self.screen_size[0], self.screen_size[1] - 50)
  22. # 导入图像
  23. self.pig_images = []
  24. for imagepath in imagepaths: self.pig_images.append(pygame.image.load(imagepath))
  25. # 设置当前图像
  26. self.image = random.choice(self.pig_images[:2])
  27. '''画到屏幕上'''
  28. def draw(self):
  29. self.animate_count += 1
  30. if (self.animate_count % self.switch_freq == 0) and (not self.is_dead):
  31. self.animate_count = 0
  32. self.image = random.choice(self.pig_images[:2])
  33. position = self.loc_info[0] - self.loc_info[2], self.loc_info[1] - self.loc_info[2]
  34. self.screen.blit(self.image, position)
  35. '''移动猪'''
  36. def move(self):
  37. # 根据重力改变猪的速度向量
  38. self.velocity = VectorAddition(self.velocity, self.gravity)
  39. self.loc_info[0] += self.velocity.magnitude * math.sin(self.velocity.angle)
  40. self.loc_info[1] -= self.velocity.magnitude * math.cos(self.velocity.angle)
  41. self.velocity.magnitude *= self.inverse_friction
  42. # 宽度超出屏幕
  43. if self.loc_info[0] > self.screen_size[0] - self.loc_info[2]:
  44. self.loc_info[0] = 2 * (self.screen_size[0] - self.loc_info[2]) - self.loc_info[0]
  45. self.velocity.angle *= -1
  46. self.velocity.magnitude *= self.elasticity
  47. elif self.loc_info[0] < self.loc_info[2]:
  48. self.loc_info[0] = 2 * self.loc_info[2] - self.loc_info[0]
  49. self.velocity.angle *= -1
  50. self.velocity.magnitude *= self.elasticity
  51. # 高度超出屏幕
  52. if self.loc_info[1] > self.screen_size[1] - self.loc_info[2]:
  53. self.loc_info[1] = 2 * (self.screen_size[1] - self.loc_info[2]) - self.loc_info[1]
  54. self.velocity.angle = math.pi - self.velocity.angle
  55. self.velocity.magnitude *= self.elasticity
  56. elif self.loc_info[1] < self.loc_info[2]:
  57. self.loc_info[1] = 2 * self.loc_info[2] - self.loc_info[1]
  58. self.velocity.angle = math.pi - self.velocity.angle
  59. self.velocity.magnitude *= self.elasticity
  60. '''猪死掉了'''
  61. def setdead(self):
  62. self.is_dead = True
  63. self.image = self.pig_images[-1]

猪在游戏中主要包括三种状态:

  • 静止状态,即未被击中时静止在某处的状态;
  • 被击中后的运动状态,即被其他物体击中之后根据动量守恒原理也一起运行时的状态;
  • 被击中后的静止状态,即因为被击中而产生运动之后又恢复静止时的状态、

游戏中的木块实现原理与小猪类似:

  1. ''地图里的木块'''
  2. class Block(pygame.sprite.Sprite):
  3. def __init__(self, screen, imagepaths, loc_info, velocity=None, **kwargs):
  4. pygame.sprite.Sprite.__init__(self)
  5. assert len(loc_info) == 3
  6. assert len(imagepaths) == 2
  7. # 设置必要的属性常量
  8. self.type = 'block'
  9. self.screen = screen
  10. self.loc_info = list(loc_info)
  11. self.imagepaths = imagepaths
  12. self.velocity = VelocityVector() if velocity is None else velocity
  13. self.elasticity = 0.7
  14. self.is_destroyed = False
  15. self.inverse_friction = 0.99
  16. self.gravity = VelocityVector(0.2, math.pi)
  17. # 导入图像
  18. self.block_images = []
  19. for imagepath in imagepaths: self.block_images.append(pygame.transform.scale(pygame.image.load(imagepath), (100, 100)))
  20. # 屏幕大小
  21. self.screen_size = screen.get_rect().size
  22. self.screen_size = (self.screen_size[0], self.screen_size[1] - 50)
  23. # 设置当前图像
  24. self.image = self.block_images[0]
  25. self.rect = self.image.get_rect()
  26. self.rotate_angle = math.radians(0)
  27. '''画到屏幕上'''
  28. def draw(self):
  29. pygame.transform.rotate(self.image, self.rotate_angle)
  30. self.screen.blit(self.image, (self.loc_info[0] - self.rect.width // 2, self.loc_info[1]))
  31. '''设置为损坏状态'''
  32. def setdestroy(self):
  33. self.is_destroyed = True
  34. self.image = self.block_images[1]
  35. '''移动木块'''
  36. def move(self):
  37. # 根据重力改变木块的速度向量
  38. self.velocity = VectorAddition(self.velocity, self.gravity)
  39. self.loc_info[0] += self.velocity.magnitude * math.sin(self.velocity.angle)
  40. self.loc_info[1] -= self.velocity.magnitude * math.cos(self.velocity.angle)
  41. self.velocity.magnitude *= self.inverse_friction
  42. # 宽度超出屏幕
  43. if self.loc_info[0] > self.screen_size[0] - self.rect.width:
  44. self.loc_info[0] = 2 * (self.screen_size[0] - self.rect.width) - self.loc_info[0]
  45. self.velocity.angle *= -1
  46. self.rotate_angle = -self.velocity.angle
  47. self.velocity.magnitude *= self.elasticity
  48. elif self.loc_info[0] < self.rect.width:
  49. self.loc_info[0] = 2 * self.rect.width - self.loc_info[0]
  50. self.velocity.angle *= -1
  51. self.rotate_angle = -self.velocity.angle
  52. self.velocity.magnitude *= self.elasticity
  53. # 高度超出屏幕
  54. if self.loc_info[1] > self.screen_size[1] - self.rect.height:
  55. self.loc_info[1] = 2 * (self.screen_size[1] - self.rect.height) - self.loc_info[1]
  56. self.velocity.angle = math.pi - self.velocity.angle
  57. self.rotate_angle = math.pi - self.velocity.angle
  58. self.velocity.magnitude *= self.elasticity
  59. elif self.loc_info[1] < self.rect.height:
  60. self.loc_info[1] = 2 * self.rect.height - self.loc_info[1]
  61. self.velocity.angle = math.pi - self.velocity.angle
  62. self.rotate_angle = math.pi - self.velocity.angle
  63. self.velocity.magnitude *= self.elasticity

最后,我们来实现一下墙和弹弓就可以啦:

  1. '''弹弓'''
  2. class Slingshot(pygame.sprite.Sprite):
  3. def __init__(self, screen, x, y, width, height, color=(66, 73, 73), line_color=(100, 30, 22), **kwargs):
  4. pygame.sprite.Sprite.__init__(self)
  5. self.x = x
  6. self.y = y
  7. self.color = color
  8. self.width = width
  9. self.height = height
  10. self.screen = screen
  11. self.line_color = line_color
  12. self.type = 'slingshot'
  13. '''画到屏幕上'''
  14. def draw(self, bird=None):
  15. pygame.draw.rect(self.screen, self.color, (self.x, self.y + self.height * 1 / 3, self.width, self.height * 2 / 3))
  16. if bird is not None and bird.is_loaded:
  17. pygame.draw.line(self.screen, self.line_color, (self.x, self.y + self.height / 6), (bird.loc_info[0], bird.loc_info[1] + bird.loc_info[2] / 2), 10)
  18. pygame.draw.line(self.screen, self.line_color, (self.x + self.width, self.y + self.height / 6), (bird.loc_info[0] + bird.loc_info[2], bird.loc_info[1] + bird.loc_info[2] / 2), 10)
  19. pygame.draw.rect(self.screen, self.color, (self.x - self.width / 4, self.y, self.width / 2, self.height / 3), 5)
  20. pygame.draw.rect(self.screen, self.color, (self.x + self.width * 3 / 4, self.y, self.width / 2, self.height / 3), 5)
  21.  
  22.  
  23. '''墙'''
  24. class Slab(pygame.sprite.Sprite):
  25. def __init__(self, screen, imagepaths, x, y, width, height, color=(255, 255, 255)):
  26. pygame.sprite.Sprite.__init__(self)
  27. self.x = x
  28. self.y = y
  29. self.color = color
  30. self.width = width
  31. self.height = height
  32. self.screen = screen
  33. self.imagepaths = imagepaths
  34. if self.width > self.height:
  35. self.image = pygame.image.load(self.imagepaths[0])
  36. else:
  37. self.image = pygame.image.load(self.imagepaths[1])
  38. self.image = pygame.transform.scale(self.image, (self.width, self.height))
  39. self.type = 'wall'
  40. '''画到屏幕上'''
  41. def draw(self):
  42. self.screen.blit(self.image, (self.x, self.y))

由此,我们完成了所有游戏精灵的定义,可以开始实现游戏的主循环啦,具体的代码实现如下:

  1. '''开始游戏'''
  2. def start(self):
  3. # 导入所有游戏精灵
  4. game_sprites = self.loadlevelmap()
  5. birds, pigs, blocks, walls = game_sprites['birds'], game_sprites['pigs'], game_sprites['blocks'], game_sprites['walls']
  6. slingshot = Slingshot(self.screen, 200, self.screen_size[1] - 200, 30, 200)
  7. birds[0].load(slingshot)
  8. score_label = Label(self.screen, 50, 10, 100, 50)
  9. score_label.addtext(f'SCORE: {self.score}', 25, self.cfg.FONTPATH['Comic_Kings'], (236, 240, 241))
  10. birds_remaining_label = Label(self.screen, 120, 50, 100, 50)
  11. birds_remaining_label.addtext(f"BIRDS REMAINING: {len(birds)}", 25, self.cfg.FONTPATH['Comic_Kings'], (236, 240, 241))
  12. pigs_remaining_label = Label(self.screen, 110, 90, 100, 50)
  13. pigs_remaining_label.addtext(f"PIGS REMAINING: {len(pigs)}", 25, self.cfg.FONTPATH['Comic_Kings'], (236, 240, 241))
  14. carles_label = Label(self.screen, self.screen_size[0] - 270, self.screen_size[1] - 20, 300, 100)
  15. carles_label.addtext('CARLES', 60, self.cfg.FONTPATH['arfmoochikncheez'], (113, 125, 126))
  16. # 游戏主循环
  17. clock = pygame.time.Clock()
  18. blocks_to_remove, pigs_to_remove = [], []
  19. while True:
  20. # --按键检测
  21. for event in pygame.event.get():
  22. if event.type == pygame.QUIT:
  23. self.quitgame()
  24. elif event.type == pygame.KEYDOWN:
  25. if event.key == pygame.K_q:
  26. self.quitgame()
  27. elif event.key == pygame.K_r:
  28. self.start()
  29. elif event.key == pygame.K_p or event.key == pygame.K_ESCAPE:
  30. self.pauseinterface()
  31. elif event.type == pygame.MOUSEBUTTONDOWN:
  32. if birds[0].selected():
  33. birds[0].is_selected = True
  34. elif event.type == pygame.MOUSEBUTTONUP:
  35. if birds[0].is_selected:
  36. birds[0].is_selected = False
  37. birds[0].start_flying = True
  38. # --背景颜色填充
  39. color = self.cfg.BACKGROUND_COLOR
  40. for i in range(3):
  41. color = (color[0] + 5, color[1] + 5, color[2] + 5)
  42. pygame.draw.rect(self.screen, color, (0, i * 300, self.screen_size[0], 300))
  43. pygame.draw.rect(self.screen, (77, 86, 86), (0, self.screen_size[1], self.screen_size[0], 50))
  44. # --判断游戏是否结束,若没有则导入新的小鸟
  45. if (not birds[0].is_loaded) and self.still(pigs + birds + blocks):
  46. birds.pop(0)
  47. if self.status(pigs, birds) == 2:
  48. self.score += len(birds) * 100
  49. self.switchlevelinterface()
  50. elif self.status(pigs, birds) == 1:
  51. self.failureinterface()
  52. birds[0].load(slingshot)
  53. birds[0].start_flying = False
  54. # --重置小鸟的位置
  55. if birds[0].is_selected:
  56. birds[0].reposition(slingshot)
  57. if hasattr(birds[0], 'start_flying') and birds[0].start_flying:
  58. birds[0].is_loaded = False
  59. # --弹弓
  60. slingshot.draw(birds[0])
  61. # --判断猪是否撞上木桩
  62. for i in range(len(pigs)):
  63. for j in range(len(blocks)):
  64. pig_magnitude_1, block_magnitude_1 = pigs[i].velocity.magnitude, blocks[j].velocity.magnitude
  65. pigs[i], blocks[j], is_collision = self.collision(pigs[i], blocks[j])
  66. pig_magnitude_2, block_magnitude_2 = pigs[i].velocity.magnitude, blocks[j].velocity.magnitude
  67. if is_collision:
  68. if abs(pig_magnitude_2 - pig_magnitude_2) > 2:
  69. blocks_to_remove.append(blocks[j])
  70. blocks[j].setdestroy()
  71. if abs(block_magnitude_2 - block_magnitude_1) > 2:
  72. pigs_to_remove.append(pigs[i])
  73. pigs[i].setdead()
  74. # --判断鸟是否撞上木桩
  75. for i in range(len(birds)):
  76. if not (birds[i].is_loaded or birds[i].velocity.magnitude == 0):
  77. for j in range(len(blocks)):
  78. bird_magnitude_1, block_magnitude_1 = birds[i].velocity.magnitude, blocks[j].velocity.magnitude
  79. birds[i], blocks[j], is_collision = self.collision(birds[i], blocks[j])
  80. bird_magnitude_2, block_magnitude_2 = birds[i].velocity.magnitude, blocks[j].velocity.magnitude
  81. if is_collision:
  82. if abs(bird_magnitude_1 - bird_magnitude_2) > 2:
  83. if blocks[j] not in blocks_to_remove:
  84. blocks_to_remove.append(blocks[j])
  85. blocks[j].setdestroy()
  86. # --判断猪是否撞上猪或者猪撞墙
  87. for i in range(len(pigs)):
  88. pigs[i].move()
  89. for j in range(i+1, len(pigs)):
  90. pig1_magnitude_1, pig2_magnitude_1 = pigs[i].velocity.magnitude, pigs[j].velocity.magnitude
  91. pigs[i], pigs[j], is_collision = self.collision(pigs[i], pigs[j])
  92. pig1_magnitude_2, pig2_magnitude_2 = pigs[i].velocity.magnitude, pigs[j].velocity.magnitude
  93. if abs(pig1_magnitude_1 - pig1_magnitude_2) > 2:
  94. if pigs[j] not in pigs_to_remove:
  95. pigs_to_remove.append(pigs[j])
  96. pigs[j].setdead()
  97. if abs(pig2_magnitude_1 - pig2_magnitude_2) > 2:
  98. if pigs[i] not in pigs_to_remove:
  99. pigs_to_remove.append(pigs[i])
  100. pigs[i].setdead()
  101. for wall in walls: pigs[i] = self.collision(pigs[i], wall)[0]
  102. pigs[i].draw()
  103. # --判断鸟是否撞到猪或者鸟是否撞到墙
  104. for i in range(len(birds)):
  105. if (not birds[i].is_loaded) and (birds[i].velocity.magnitude):
  106. birds[i].move()
  107. for j in range(len(pigs)):
  108. bird_magnitude_1, pig_magnitude_1 = birds[i].velocity.magnitude, pigs[j].velocity.magnitude
  109. birds[i], pigs[j], is_collision = self.collision(birds[i], pigs[j])
  110. bird_magnitude_2, pig_magnitude_2 = birds[i].velocity.magnitude, pigs[j].velocity.magnitude
  111. if is_collision:
  112. if abs(bird_magnitude_2 - bird_magnitude_1) > 2:
  113. if pigs[j] not in pigs_to_remove:
  114. pigs_to_remove.append(pigs[j])
  115. pigs[j].setdead()
  116. if birds[i].is_loaded: birds[i].projectpath()
  117. for wall in walls: birds[i] = self.collision(birds[i], wall)[0]
  118. birds[i].draw()
  119. # --判断木桩是否撞到了木桩或者木桩撞到墙
  120. for i in range(len(blocks)):
  121. for j in range(i+1, len(blocks)):
  122. block1_magnitude_1, block2_magnitude_1 = blocks[i].velocity.magnitude, blocks[j].velocity.magnitude
  123. blocks[i], blocks[j], is_collision = self.collision(blocks[i], blocks[j])
  124. block1_magnitude_2, block2_magnitude_2 = blocks[i].velocity.magnitude, blocks[j].velocity.magnitude
  125. if is_collision:
  126. if abs(block1_magnitude_2 - block1_magnitude_1) > 2:
  127. if blocks[j] not in blocks_to_remove:
  128. blocks_to_remove.append(blocks[j])
  129. blocks[j].setdestroy()
  130. if abs(block2_magnitude_2 - block2_magnitude_1) > 2:
  131. if blocks[i] not in blocks_to_remove:
  132. blocks_to_remove.append(blocks[i])
  133. blocks[i].setdestroy()
  134. blocks[i].move()
  135. for wall in walls: blocks[i] = self.collision(blocks[i], wall)[0]
  136. blocks[i].draw()
  137. # --墙
  138. for wall in walls: wall.draw()
  139. # --显示文字
  140. score_label.addtext(f'SCORE: {self.score}', 25, self.cfg.FONTPATH['Comic_Kings'], (236, 240, 241))
  141. score_label.draw()
  142. birds_remaining_label.addtext(f"BIRDS REMAINING: {len(birds)}", 25, self.cfg.FONTPATH['Comic_Kings'], (236, 240, 241))
  143. birds_remaining_label.draw()
  144. pigs_remaining_label.addtext(f"PIGS REMAINING: {len(pigs)}", 25, self.cfg.FONTPATH['Comic_Kings'], (236, 240, 241))
  145. pigs_remaining_label.draw()
  146. carles_label.draw()
  147. # --画面刷新
  148. pygame.display.update()
  149. clock.tick(self.cfg.FPS)
  150. # --删除无效的元素
  151. if self.still(birds + pigs + blocks):
  152. for pig in pigs_to_remove:
  153. if pig in pigs:
  154. pigs.remove(pig)
  155. self.score += 100
  156. for block in blocks_to_remove:
  157. if block in blocks:
  158. blocks.remove(block)
  159. self.score += 50
  160. pigs_to_remove = []
  161. blocks_to_remove = []

其实就是一些按键检测和碰撞检测以及一些分数之类的游戏状态实时更新,感觉没啥好讲的,总之,就这么简单就完事啦~

到此这篇关于忆童年!用Python实现愤怒的小鸟游戏的文章就介绍到这了,更多相关Python愤怒的小鸟内容请搜索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号