当前位置:   article > 正文

Python14_项目一 :外星人入侵游戏05 06(增加play按钮,增加记分牌,并且使外星人移动等级提升)_bullets.add

bullets.add

这两天的真的很忙。。

就一直没有更新博客。今天抽时间,整理一下项目一所剩余的部分。

对于项目一,确实有些杂,但是我们只要理清其中的思路即可。毕竟第一次的项目,往后要不断回顾才是。

这样吧,我附上整个项目的代码。有什么不懂的地方可以留言问我。

alien_invasion.py代码

  1. # 02 import sys
  2. import pygame
  3. from settings import Setting # 01
  4. from ship import Ship # 01
  5. import game_function as gf # 02
  6. from pygame.sprite import Group # 03 pygame.sprite.Group 类类似于列表,但提供了有助于开发游戏的额外功能
  7. # from aliens import Alien # 04
  8. from game_stats import GameStats # 04
  9. from button import Button # 05
  10. from scoreboard import Scoreboard # 05
  11. def run_game(): # 初始化游戏,并且创建一个屏幕对象
  12. pygame.init() # 初始化背景设置,让Pygame能够正确地工作
  13. # 01 screen = pygame.display.set_mode((1200, 800)) # 创建一个名为screen 的显示窗口,括号里是元组!!!
  14. # 01 # 这个游戏的所有图形元素都将在其中绘制
  15. ai_set = Setting() # 因为导入类而做了代码替换
  16. screen = pygame.display.set_mode(
  17. (ai_set.screen_width, ai_set.screen_height)
  18. )
  19. # 01 bg_color = (230,230,230) # 设置背景颜色
  20. pygame.display.set_caption('外星人入侵')
  21. # 创建一个play按钮
  22. play_button = Button(ai_set, screen, 'Play')
  23. # 创建一个用于存储游戏统计信息的实例 并【创建记分牌】
  24. stats = GameStats(ai_set)
  25. sb = Scoreboard(ai_set, screen, stats)
  26. # 创建一艘飞船对象
  27. ship = Ship(ai_set, screen)
  28. # 03 导入Group类并且创建一个Group实例,用于存储子弹的编组
  29. bullets = Group()
  30. # 04 创建一个外星人,编组
  31. # alien = Alien(ai_set,screen)
  32. aliens = Group()
  33. # 04 创建外星人群
  34. gf.create_fleet(ai_set, screen, ship, aliens)
  35. # 为让程序响应事件,我们编写一个事件循环,以侦听事件,并根据发生的事件执行相应的任务。
  36. while True: # 游戏的主循环
  37. # 02 for event in pygame.event.get(): # 监视键盘和鼠标
  38. # 02 if event.type == pygame.QUIT: #编写一系列的if 语句来检测并响应特定的事件
  39. # 02 sys.exit() # 我们调用sys.exit() 来退出游戏
  40. gf.check_event(ai_set, screen, stats, sb, play_button, ship, aliens, bullets) # 02 03 05 06
  41. if stats.game_active:
  42. ship.update() # 02
  43. gf.update_bullet(ai_set, screen, stats, sb, ship, aliens, bullets) # 03 04 05
  44. gf.update_aliens(ai_set, screen, stats, sb, ship, aliens, bullets) # 04 06
  45. # 03 bullets.update() # 03
  46. # # 03 删除已经消失,看不到的子弹
  47. # for bull in bullets.copy():
  48. # if bull.rect.bottom <= 0:
  49. # bullets.remove(bull)
  50. # print(len(bullets))
  51. # 01screen.fill(bg_color) # 每次循环都重绘屏幕
  52. # 02 screen.fill(ai_set.bg_color)
  53. # 02 ship.blitme() # 调用blitme函数,使飞船出现
  54. # 02 pygame.display.flip() # 让最近绘制的屏幕可见
  55. gf.update_screen(ai_set, screen, stats, sb, ship, aliens, bullets, play_button) # 02 03 04 05
  56. run_game()
  57. input()

game_function.py代码

  1. import sys
  2. import pygame
  3. from settings import Setting
  4. from bullet import Bullet # 03
  5. from aliens import Alien # 04
  6. from time import sleep # 04
  7. from game_stats import GameStats # 05
  8. # 响应按键 03
  9. def check_keydown(event, ai_settings, screen, ship, bullets):
  10. if event.key == pygame.K_RIGHT:
  11. # 向右移动飞船
  12. ship.moving_right = True
  13. # ship.rect.centerx += 10
  14. elif event.key == pygame.K_LEFT:
  15. # 向左移动飞船
  16. # ship.rect.centerx -= 10
  17. ship.moving_left = True
  18. # 03 创建一颗子弹,并将其加入到编组bullets中
  19. elif event.key == pygame.K_SPACE:
  20. if len(bullets) < ai_settings.bullet_allowed: # 限制三个子弹
  21. # 玩家按空格键时,创建一颗新子弹(一个名为new_bullet 的Bullet 实例),
  22. new_bullet = Bullet(ai_settings, screen, ship)
  23. # 并使用方法add() 将其加入到编组bullets中
  24. bullets.add(new_bullet)
  25. # 04 按q结束
  26. elif event.key == pygame.K_q:
  27. sys.exit()
  28. # 响应松开 03
  29. def check_keyup(event, ship):
  30. if event.key == pygame.K_RIGHT:
  31. ship.moving_right = False
  32. elif event.key == pygame.K_LEFT:
  33. ship.moving_left = False
  34. # 响应按键和鼠标事件
  35. def check_event(ai_setting, screen, stats, sb, play_button, ship, aliens, bullets): # 03
  36. for i in pygame.event.get():
  37. if i.type == pygame.QUIT:
  38. sys.exit()
  39. elif i.type == pygame.KEYDOWN:
  40. check_keydown(i, ai_setting, screen, ship, bullets) # 重构
  41. # 03 if i.key == pygame.K_RIGHT:
  42. # 03 # 向右移动飞船
  43. # 03 ship.moving_right = True
  44. # 03 # ship.rect.centerx += 10
  45. # 03 elif i.key == pygame.K_LEFT:
  46. # 03 # 向左移动飞船
  47. # 03 # ship.rect.centerx -= 10
  48. # 03 ship.moving_left = True
  49. elif i.type == pygame.KEYUP:
  50. check_keyup(i, ship) # 重构
  51. # 03 if i.key == pygame.K_RIGHT:
  52. # 03 ship.moving_right = False
  53. # 03 elif i.key == pygame.K_LEFT:
  54. # 03 ship.moving_left = False
  55. # 05 鼠标点击事件
  56. elif i.type == pygame.MOUSEBUTTONDOWN:
  57. # 无论玩家单击屏幕的什么地方,Pygame都将检测到一个MOUSEBUTTONDOWN 事件
  58. # 但我们只想让这个游戏在玩家用鼠标单击Play按钮时作出响应
  59. # 为此,我们使用了pygame.mouse.get_pos() ,它返回一个元组,其中包含玩家单击时鼠标的x 和y 坐标
  60. mouse_x, mouse_y = pygame.mouse.get_pos()
  61. # 我们将这些值传递给函数check_play_button()
  62. # 而这个函数使用collidepoint() 检查鼠标单击位置是否在Play按钮的rect 内
  63. check_play_button(ai_setting, screen, stats, sb, play_button, ship, aliens, bullets, mouse_x, mouse_y)
  64. # 05 在玩家单击play按钮时开始新的游戏
  65. def check_play_button(ai_setting, screen, stats, sb, play_button, ship, aliens, bullets, mouse_x, mouse_y):
  66. # 仅当玩家单击了Play按钮且 游戏当前处于非活动状态时,游戏才重新开始
  67. # collidepoint() 检查鼠标单击位置是否在Play按钮的rect 内
  68. button_clicked = play_button.rect.collidepoint(mouse_x, mouse_y)
  69. if button_clicked and not stats.game_active: # 控制仅仅在按钮区域,且 游戏停止状态 才会重置
  70. # 重置游戏的设置,如初始速度等
  71. ai_setting.initialize_dynamic_settings()
  72. # 隐藏光标,直到游戏重开时出现,修改visible状态的代码写到ship_hit()中
  73. pygame.mouse.set_visible(False)
  74. # 重置游戏统计信息
  75. stats.reset_stats()
  76. stats.game_active = True
  77. # 06 为确保开始新游戏时更新记分和等级图像,在按钮Play被单击时触发重置
  78. sb.prep_score()
  79. sb.prep_high_score()
  80. sb.prep_level()
  81. # 06 我们在开始新游戏时调用prep_ships()
  82. sb.prep_ship()
  83. # 清空外星人列表和子弹列表
  84. aliens.empty()
  85. bullets.empty()
  86. # 创建一群新的外星人,并让飞船居中
  87. create_fleet(ai_setting, screen, ship, aliens)
  88. ship.center_ship() # ship.py中的函数
  89. # -------------------------------------更新屏幕-------------------------------------
  90. # 更新屏幕上的图像,并切换到新屏幕
  91. def update_screen(ai_setting, screen, stats, sb, ship, aliens, bullets, play_button):
  92. # 每次循环时都重绘屏幕
  93. screen.fill(ai_setting.bg_color)
  94. # 03 在飞船和外星人后面重绘所有子弹
  95. # 为在屏幕上绘制发射的所有子弹,我们遍历编组bullets 中的精灵,并对每个精灵都调用draw_bullet()
  96. for bullet in bullets.sprites():
  97. bullet.draw_bullet()
  98. ship.blitme()
  99. # 04 alien.blitme()
  100. aliens.draw(screen) # 04 绘制外星人,使用的是内置draw函数
  101. # 06 显示得分
  102. sb.show_score()
  103. # 05 如果处于非游戏状态,就绘制play按钮
  104. if not stats.game_active:
  105. play_button.draw_button() # 此函数在button.py文件
  106. # 让最近绘制的屏幕可见
  107. pygame.display.flip()
  108. # -------------------------------------以下是子弹----------------------------------------------
  109. # 03 更新子弹位置,并删除已经消失的子弹
  110. def update_bullet(ai_setting, screen, stats, sb, ship, aliens, bullets): # 05
  111. bullets.update() # 更新子弹位置
  112. # 03 删除已经消失,看不到的子弹
  113. for bull in bullets.copy():
  114. if bull.rect.bottom <= 0:
  115. bullets.remove(bull)
  116. print(len(bullets))
  117. # ----- 04 检查是否碰撞-------
  118. check_bullet_alien_collision(ai_setting, screen, stats, sb, ship, aliens, bullets) # 05
  119. # 检查子弹和外星人是否碰撞
  120. def check_bullet_alien_collision(ai_setting, screen, stats, sb, ship, aliens, bullets):
  121. # 方法sprite.groupcollide() 将每颗子弹的rect 同每个外星人的rect 进行比较,并返回一个字典,
  122. # 其中包含发生了碰撞的子弹和外星人。在这个字典中,每个键都是一颗子弹,而相应的值都是被击中的外星人
  123. # 检查是否有子弹击中了外星人
  124. # 如果是这样,就删除相应的子弹和外星人
  125. collisions = pygame.sprite.groupcollide(bullets, aliens, True, True)
  126. # 05 若碰撞则加分
  127. if collisions:
  128. # 如果字典collisions 存在,我们就遍历其中的所有值。
  129. # 别忘了,每个值都是一个列表,包含被同一颗子弹击中的所有外星人。
  130. # 对于每个列表,都将一个外星人的点数乘以其中包含的外星人数量,并将结果加入到当前得分中
  131. for alie in collisions.values():
  132. # 有子弹撞到时,Pygame返回一个字典(collisions )。
  133. # 我们检查这个字典是否存在,如果存在,就将得分加上一个外星人值的点数
  134. stats.score += ai_setting.alien_point * len(alie)
  135. sb.prep_score() # 此函数在scoreboard.py文件中
  136. check_high_score(stats, sb) # 此函数在本页最后
  137. # 如果外星人编组为空,则删除现有子弹并新建一群外星人
  138. # 06 如果整群外星人都被消灭,就提高一个等级
  139. if len(aliens) == 0:
  140. bullets.empty()
  141. ai_setting.increase_speed() # 增加游戏节奏
  142. # 06 提高等级
  143. stats.level += 1
  144. sb.prep_level()
  145. create_fleet(ai_setting, screen, ship, aliens)
  146. # ai_setting.fleet_drop_speed += 20 # 自己加的----------------------------------------------------
  147. # -------------------------------------以下是外星人 04 --------------------------------------------
  148. # 04 创建外星人群
  149. def create_fleet(ai_setting, screen, ship, aliens):
  150. # 创建一个外星人,并计算一行可容纳多少个外星人
  151. # 外星人间距为外星人宽度
  152. # 我们先创建一个外星人,这个外星人不是外星人群的成员,因此没有将它加入到编组aliens 中
  153. ali = Alien(ai_setting, screen)
  154. number_alien_x = get_number_aliens_x(ai_setting, ali.rect.width) # 04 重构create_fleet
  155. number_rows = get_number_row(ai_setting, ship.rect.height, ali.rect.height)
  156. # 04 # 我们从外星人的rect 属性中获取外星人宽度,并将这个值存储到alien_width 中,以免反复访问属性rect
  157. # 04 ali_width = ali.rect.width
  158. # 04 # 我们计算可用于放置外星人的水平空间,以及其中可容纳多少个外星人。
  159. # 04 available_space_x = ai_setting.screen_width - 2 * ali_width
  160. # 04 number_alien_x = int(available_space_x / (2 * ali_width))
  161. # 创建第一行外星人
  162. for row_num in range(number_rows):
  163. for ali_num in range(number_alien_x):
  164. #  创建一个外星人,并加入当前行
  165. # alien = Alien(ai_setting,screen) # 通过设置x 坐标将其加入当前行
  166. # alien.x = ali_width + 2 * ali_width * ali_num
  167. # alien.rect.x = alien.x
  168. # aliens.add(alien)
  169. create_alien(ai_setting, screen, aliens, ali_num, row_num) # 04 重构create_fleet
  170. # 计算每行可容纳多少个外星人
  171. def get_number_aliens_x(ai_setting, alien_width):
  172. available_space_x = ai_setting.screen_width - 2 * alien_width
  173. number_alien_x = int(available_space_x / (2 * alien_width))
  174. return number_alien_x
  175. # 计算屏幕可容纳多少行外星人
  176. def get_number_row(ai_setting, ship_height, alien_height):
  177. available_space_y = (ai_setting.screen_height - (3 * alien_height) - 3.5 * ship_height)
  178. number_rows = int(available_space_y / (2 * alien_height))
  179. return number_rows
  180. # 创建一个外星人并将其放在当前行
  181. def create_alien(ai_setting, screen, aliens, alien_number, row_number):
  182. alien = Alien(ai_setting, screen) # 通过设置x 坐标将其加入当前行
  183. alien_width = alien.rect.width
  184. alien.x = alien_width + 2 * alien_width * alien_number
  185. alien.rect.x = alien.x
  186. alien.rect.y = alien.rect.height + 2 * alien.rect.height * row_number # 创建时,计算y的坐标
  187. aliens.add(alien)
  188. # 更新外星人群中所有外星人位置
  189. def update_aliens(ai_set, screen, stats, sb, ship, alie, bullets):
  190. # 检查是否有外星人到达屏幕边,然后更新所有外星人的位置
  191. check_fleet_edges(ai_set, alie)
  192. alie.update()
  193. # 04 检测外星人和飞船之间的碰撞
  194. # 方法spritecollideany() 接受两个实参:一个精灵和一个编组。
  195. # 它检查编组是否有成员与精灵发生了碰撞,并在找到与精灵发生了碰撞的成员后就停止遍历编组。
  196. if pygame.sprite.spritecollideany(ship, alie):
  197. ship_hit(ai_set, screen, stats, sb, ship, alie, bullets)
  198. # 检测是否有外星人到达屏幕底部
  199. check_aliens_bottom(ai_set, screen, stats, sb, ship, alie, bullets)
  200. # 检测是否有外星人到达的屏幕底端
  201. def check_aliens_bottom(ai_setting, screen, stats, sb, ship, aliens, bullets):
  202. screen_rect = screen.get_rect()
  203. for ali in aliens.sprites():
  204. if ali.rect.bottom >= screen_rect.bottom:
  205. # 像飞船撞到外星人一样处理
  206. ship_hit(ai_setting, screen, stats, sb, ship, aliens, bullets)
  207. break
  208. # 响应被外星人撞到的飞船
  209. def ship_hit(ai_setting, screen, stats, sb, ship, aliens, bullets):
  210. if stats.ships_left > 0:
  211. # 将ships_left减一
  212. stats.ships_left -= 1
  213. # 我们还在飞船被外星人撞到时调用prep_ships() ,从而在玩家损失一艘飞船时更新飞船图像:
  214. sb.prep_ship()
  215. # 清空外星人和子弹列表
  216. aliens.empty()
  217. bullets.empty()
  218. # 重新创建一群新的外星人,并将飞船放到屏幕底部
  219. create_fleet(ai_setting, screen, ship, aliens)
  220. ship.center_ship() # ship.py中的函数
  221. # 暂停0.5秒
  222. sleep(0.5)
  223. else:
  224. stats.game_active = False
  225. # 使光标出现
  226. pygame.mouse.set_visible(True)
  227. # 有外星人到达边缘时,采取相应的措施
  228. def check_fleet_edges(ai_setting, aliens):
  229. for ali in aliens.sprites(): # 我们遍历外星人群,并对其中的每个外星人调用check_edge()
  230. if ali.check_edge(): # aliens.py中有此函数
  231. change_fleet_direction(ai_setting, aliens)
  232. break
  233. # 将整群外星人下移,并改变它们的方向
  234. def change_fleet_direction(ai_set, aliens):
  235. for ali in aliens.sprites():
  236. ali.rect.y += ai_set.fleet_drop_speed
  237. ai_set.fleet_direction *= -1
  238. # ---------------------------------------以下是检测是否诞生最高分----------------------------------------
  239. def check_high_score(stats, sb):
  240. if stats.score > stats.high_score:
  241. stats.high_score = stats.score
  242. sb.prep_high_score()

 ship.py代码

  1. import pygame
  2. from pygame.sprite import Sprite # 06
  3. class Ship(Sprite):
  4. def __init__(self, ai_setting, screen): # 初始化飞船,并设置初始位置
  5. super().__init__() # 06 继承初始化
  6. self.screen = screen
  7. self.ai_setting = ai_setting # 02
  8. # 加载飞船图像并获取其外接矩形
  9. self.image = pygame.image.load('.\\feii.bmp')
  10. self.rect = self.image.get_rect() # 我们使用get_rect() 获取相应surface的属性rect
  11. self.screen_rect = self.screen.get_rect()
  12. # 将每艘新飞船放在屏幕底部中央
  13. # 要将游戏元素居中,可设置相应rect 对象的属性center 、centerx 或centery 。
  14. self.rect.centerx = self.screen_rect.centerx
  15. # 要让游戏元素与屏幕边缘对齐,可使用属性top 、bottom 、left 或right ;
  16. # 要调整游戏元素的水平或垂直位置,可使用属性x 和y ,它们分别是相应矩形左上角的 x 和 y 坐标。
  17. self.rect.bottom = self.screen_rect.bottom
  18. # 在飞船的属性center中存储小数数值
  19. self.center = float(self.rect.centerx) # 小数形式的位移可以更好的控制飞船移动
  20. # 移动标志,# 02
  21. # 飞船不动时,标志moving_right将为False 。
  22. # 玩家按下右箭头键时,我们将这个标志设置为True ;而玩家松开时,我们将这个标志重新设置为False
  23. self.moving_right = False
  24. self.moving_left = False
  25. self.moving_up = False
  26. self.moving_down = False
  27. # 根据移动标志,移动飞船 # 02
  28. def update(self):
  29. if self.moving_right and self.rect.right < self.screen_rect.right: # 控制飞船移动的左右范围
  30. # 02 self.rect.centerx += 1
  31. # 02 更新飞船的center值,而不是rect
  32. self.center += self.ai_setting.ship_speed_factor
  33. if self.moving_left and self.rect.left > 0:
  34. # 02 self.rect.centerx -= 1
  35. self.center -= self.ai_setting.ship_speed_factor
  36. # 根据self.center更新rect对象
  37. self.rect.centerx = self.center
  38. # 我们定义了方法blitme() ,它根据self.rect 指定的位置将图像绘制到屏幕上
  39. # 在指定位置绘制飞船
  40. def blitme(self):
  41. self.screen.blit(self.image, self.rect) # 把image这个surface对象贴到rect的位置
  42. # 让飞船在屏幕上居中
  43. def center_ship(self):
  44. self.center = self.screen_rect.centerx

aliens.py代码

  1. import pygame
  2. from pygame.sprite import Sprite
  3. # 表示单个外星人的类
  4. class Alien(Sprite):
  5. # 初始化外星人并设置其起始位置
  6. def __init__(self, ai_setting, screen):
  7. super().__init__()
  8. self.screen = screen
  9. self.ai_setting = ai_setting
  10. # 加载外星人图形,并设置其rect属性
  11. self.image = pygame.image.load(r'.\\alien-1.bmp')
  12. self.rect = self.image.get_rect()
  13. # 每个外星人都在屏幕左上角附近
  14. self.rect.x = self.rect.width
  15. self.rect.y = self.rect.height
  16. # 存储外星人的准确位置
  17. self.x = float(self.rect.x)
  18. # 在指定位置绘制外星人
  19. def blitme(self):
  20. self.screen.blit(self.image, self.rect)
  21. # 如果外星人处于屏幕边缘,就返回True,此函数会在game_function中用到
  22. # 如果外星人处于屏幕边缘,就返回True,此函数会在game_function中用到
  23. def check_edge(self):
  24. screen_rect = self.screen.get_rect()
  25. if self.rect.right >= screen_rect.right:
  26. return True
  27. elif self.rect.left <= screen_rect.left:
  28. return True
  29. # 向左或向右移动外星人
  30. def update(self, *args):
  31. self.x += self.ai_setting.alien_speed_factor * self.ai_setting.fleet_direction
  32. self.rect.x = self.x

 bullet.py代码

  1. import pygame
  2. from pygame.sprite import Sprite # 导入精灵
  3. # 一个对飞船发射的子弹进行管理的类
  4. class Bullet(Sprite):
  5. def __init__(self, ai_setting, screen, ship):
  6. # 在飞船所处的位置创建一个子弹对象
  7. super().__init__() # 初始化父类 2.7写法super(Bullet,self).__init__()
  8. self.screen = screen
  9. # 在(0,0)处创建一个表示子弹的矩形,再设置正确的位置
  10. # 我们创建了子弹的属性rect 。子弹并非基于图像的,因此我们必须使用pygame.Rect()类从空白开始创建一个矩形
  11. # 我们在(0, 0)处创建这个矩形,但接下来的两行代码将其移到了正确的位置
  12. # self.rect = pygame.Rect(0,0,ai_setting.bullet_width,ai_setting.bullet_height)-------原版,下两行DIY-------
  13. self.image = pygame.image.load('.\\Heart7.bmp')
  14. self.rect = self.image.get_rect()
  15. # 我们将子弹的centerx设置为飞船的rect.centerx 。
  16. # 子弹应从飞船顶部射出,因此我们将表示子弹的rect的top属性设置为飞船的rect的top属性,
  17. # 让子弹看起来像是从飞船中射出的
  18. self.rect.centerx = ship.rect.centerx
  19. self.rect.top = ship.rect.top
  20. # 存储用小数表示的子弹位置
  21. self.y = float(self.rect.y)
  22. self.color = ai_setting.bullet_color
  23. self.speed = ai_setting.bullet_speed_factor
  24. # 向上移动子弹
  25. def update(self, *args):
  26. # 更新表示子弹位置的小数值
  27. self.y -= self.speed / 2
  28. # 更新表示子弹位置的rect的位置
  29. self.rect.y = self.y
  30. # 在屏幕上绘制子弹
  31. def draw_bullet(self):
  32. # 函数draw.rect()使用存储在self.color中的颜色填充表示子弹的rect占据的屏幕部分
  33. # pygame.draw.rect(self.screen,self.color,self.rect)-----------------------原版,下一行DIY-------------------
  34. self.screen.blit(self.image, self.rect)

 button.py代码

  1. import pygame.sysfont
  2. class Button():
  3. # 初始化按钮属性
  4. def __init__(self, ai_setting, screen, msg):
  5. self.screen = screen
  6. self.screen_rect = screen.get_rect()
  7. # 设置按钮的尺寸和其他属性
  8. self.width, self.height = 200, 50
  9. self.button_color = (0, 255, 0)
  10. self.text_color = (255, 255, 255)
  11. self.font = pygame.sysfont.SysFont('arial', 48)
  12. # 创建按钮的rect对象,并使其居中
  13. # 为让按钮在屏幕上居中,我们创建一个表示按钮的rect 对象
  14. # 并将其center 属性设置为屏幕的center 属性
  15. self.rect = pygame.Rect(0, 0, self.width, self.height)
  16. self.rect.center = self.screen_rect.center
  17. # 按钮的标签只需创建一次
  18. # Pygame通过将你要显示的字符串渲染为图像来处理文本。我们调用prep_msg() 来处理这样的渲染
  19. self.prep_msg(msg)
  20. # 将msg渲染为图像,并使其在按钮上居中
  21. def prep_msg(self, msg):
  22. self.msg_image = self.font.render(msg, True, self.text_color, self.button_color)
  23. self.msg_image_rect = self.msg_image.get_rect()
  24. self.msg_image_rect.center = self.rect.center
  25. # 最后,我们创建方法draw_button() ,通过调用它可将这个按钮显示到屏幕上
  26. def draw_button(self):
  27. # 绘制一个用颜色填充的按钮,再绘制文本
  28. self.screen.fill(self.button_color, self.rect)
  29. self.screen.blit(self.msg_image, self.msg_image_rect)

game_stats.py代码

  1. # 跟踪游戏的统计信息
  2. class GameStats():
  3. # 初始化统计信息
  4. def __init__(self, ai_setting):
  5. self.ai_setting = ai_setting
  6. self.reset_stats()
  7. # # 游戏刚开始时处于活动状态
  8. # self.game_active = True
  9. # 游戏刚开始时处于停止状态,直到play按钮按下
  10. self.game_active = False # 05
  11. # 在任何情况下都不重置最高分
  12. self.high_score = 0
  13. # 初始化在游戏运行期间可能变化的统计信息
  14. def reset_stats(self):
  15. self.ships_left = self.ai_setting.ship_limit
  16. self.score = 0 # 05 记分,在每次游戏开始时,重置记分
  17. self.level = 1 # 06 等级

scoreboard.py代码

  1. import pygame.sysfont
  2. from pygame.sprite import Group # 06
  3. from ship import Ship # 06
  4. # 显示得分信息的类
  5. class Scoreboard():
  6. # 初始化显示涉及得分的属性
  7. def __init__(self, ai_setting, screen, stats):
  8. self.screen = screen
  9. self.screen_rect = screen.get_rect()
  10. self.ai_setting = ai_setting
  11. self.stats = stats
  12. # 显示得分信息时使用的字体设置
  13. self.text_color = (30, 30, 30)
  14. self.font = pygame.sysfont.SysFont('arial', 48)
  15. # 准备初始得分图像
  16. self.prep_score() # 为将要显示的文本转换为图像
  17. # 准备最高分的图像
  18. self.prep_high_score()
  19. # 06 准备显示等级的图像
  20. self.prep_level()
  21. # 06 准备显示剩余飞船的图像
  22. self.prep_ship()
  23. # 将得分转换为一副渲染的图像
  24. def prep_score(self):
  25. round_score = round(self.stats.score)
  26. score_str = '{:,}'.format(round_score)
  27. self.score_image = self.font.render(score_str, True, self.text_color, self.ai_setting.bg_color)
  28. # 将得分放到屏幕右上角
  29. self.score_rect = self.score_image.get_rect()
  30. self.score_rect.right = self.screen_rect.right - 20
  31. self.score_rect.top = 20 # 让其上边缘与屏幕上边缘也相距20像素
  32. # 将最高分渲染为图像
  33. def prep_high_score(self):
  34. high_score = round(self.stats.high_score)
  35. high_score_str = '{:,}'.format(high_score)
  36. self.high_score_image = self.font.render(high_score_str, True, self.text_color, self.ai_setting.bg_color)
  37. # 将最高分放在屏幕顶部中央
  38. self.high_score_rect = self.high_score_image.get_rect()
  39. self.high_score_rect.centerx = self.screen_rect.centerx
  40. self.high_score_rect.top = self.screen_rect.top
  41. # 06 等级渲染为图像
  42. def prep_level(self):
  43. self.leve_image = self.font.render(str(self.stats.level), True, self.text_color, self.ai_setting.bg_color)
  44. # 将等级放在得分下方
  45. self.level_rect = self.leve_image.get_rect()
  46. self.level_rect.right = self.screen_rect.right - 20
  47. self.level_rect.top = self.score_rect.bottom + 10
  48. # 06 显示剩余多少飞船
  49. def prep_ship(self):
  50. # 方法prep_ships() 创建一个空编组self.ships ,用于存储飞船实例
  51. self.ships = Group()
  52. # 为填充这个编组,根据玩家还有多少艘飞船运行一个循环相应的次数
  53. for ship_num in range(self.stats.ships_left):
  54. # 在这个循环中,我们创建一艘新飞船,并设置其x 坐标,
  55. # 让整个飞船编组都位于屏幕左边,且每艘飞船的左边距都为10像素
  56. # 我们还将y 坐标设置为离屏幕上边缘10像素,让所有飞船都与得分图像对齐
  57. ship = Ship(self.ai_setting, self.screen)
  58. ship.rect.x = 10 + ship_num * ship.rect.width
  59. ship.rect.y = 10
  60. # 最后,我们将每艘新飞船都添加到编组ships 中
  61. self.ships.add(ship)
  62. # 在屏幕上显示得分
  63. def show_score(self):
  64. # 这个方法将得分图像显示到屏幕上,并将其放在score_rect 指定的位置
  65. self.screen.blit(self.score_image, self.score_rect)
  66. self.screen.blit(self.high_score_image, self.high_score_rect)
  67. self.screen.blit(self.leve_image, self.level_rect) # 06
  68. # 为在屏幕上显示飞船,我们对编组调用了draw() 。Pygame将绘制每艘飞船。
  69. self.ships.draw(self.screen)

settings.py代码

  1. class Setting(): # 存储《外星人入侵》中所有的设置类
  2. def __init__(self): # 初始化游戏设置
  3. self.screen_width = 1200 # 屏幕设置
  4. self.screen_height = 800
  5. self.bg_color = (230, 230, 230)
  6. # self.ship_speed_factor = 2.5 # 02 设置飞船速度
  7. # 03 子弹设置
  8. # 05 self.bullet_speed_factor = 3 # 子弹速度
  9. self.bullet_width = 500 # 子弹宽度
  10. self.bullet_height = 3 # 子弹长度
  11. self.bullet_color = 60, 60, 60 # 子弹颜色
  12. self.bullet_allowed = 3 # 限制子弹数量为3
  13. # 04 外星人设置
  14. # 05 self.alien_speed_factor = 1
  15. self.fleet_drop_speed = 10
  16. # 05 # fleet_direction为1表示向右移动,为-1表示向左移动
  17. # self.fleet_direction = 1
  18. # 04 飞船设置
  19. self.ship_limit = 2
  20. # 以什么样的速度加快游戏节奏
  21. self.speedup_scale = 1.1
  22. # 玩家每提高一个等级,游戏都变得更难,因此处于较高的等级时,外星人的点数应更高。
  23. # 外星人点数的提高速度
  24. self.score_scale = 1.5
  25. # 05 我们将动态变量 和 静态变量分开
  26. # 调用initialize_dynamic_settings() ,以初始化随游戏进行而变化的属性
  27. self.initialize_dynamic_settings()
  28. # 05 初始化随游戏进行而变化的设置
  29. def initialize_dynamic_settings(self):
  30. self.bullet_speed_factor = 3 # 子弹速度
  31. self.alien_speed_factor = 0.8
  32. self.ship_speed_factor = 1.5 # 02 设置飞船速度
  33. # fleet_direction为1表示向右移动,为-1表示向左移动
  34. self.fleet_direction = 1
  35. # 05 记分
  36. # 随着游戏的进行,我们将提高每个外星人值的点数。
  37. # 为确保每次开始新游戏时这个值都会被重置,我们在initialize_dynamic_settings() 中设置它。
  38. self.alien_point = 50
  39. # 05 每当玩家提高一个等级时,我们都使用increase_speed() 来提高飞船、子弹和外星人的速度
  40. # 提高速度
  41. def increase_speed(self):
  42. self.ship_speed_factor *= self.speedup_scale
  43. self.alien_speed_factor *= self.speedup_scale
  44. self.ship_speed_factor *= self.speedup_scale
  45. self.alien_point = int(self.alien_point * self.score_scale)

 

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

闽ICP备14008679号