@Python编程从入门到实践 Python项目练习
十一、显示游戏得分及最高分
创建新类Scoreboard,用以显示得分和最高分。
# scoreboard.py import pygame.font class Scoreboard(): """显示得分信息的类""" def __init__(self, ai_settings, screen, stats): """初始化显示得分涉及的属性""" self.screen = screen self.screen_rect = screen.get_rect() self.ai_settings = ai_settings self.stats = stats # 显示得分信息时使用的字体设置 self.text_color = (30, 30, 30) self.font = pygame.font.SysFont(None, 48) # 准备初始得分图像 self.prep_score() # 准备最高得分 self.prep_high_score() def prep_score(self): """将得分转换为一幅渲染的图像""" rounded_score = int(round(self.stats.score, -1)) score_str = "{:,}".format(rounded_score) self.score_image = self.font.render(score_str, True, self.text_color, self.ai_settings.bg_color) # 将得分放在屏幕右上角 self.score_rect = self.score_image.get_rect() self.score_rect.right = self.screen_rect.right - 20 self.score_rect.top = 10 def prep_high_score(self): """将最高得分转为一幅渲染都图像""" # 将得分圆整 high_score = int(round(self.stats.high_score, -1)) high_score_str = "{:,}".format(high_score) self.high_score_image = self.font.render(high_score_str, True, self.text_color, self.ai_settings.bg_color) # 将得分放在屏幕顶部中央 self.high_score_rect = self.score_image.get_rect() self.high_score_rect.centerx = self.screen_rect.centerx self.high_score_rect.top = 10 def show_score(self): """在屏幕上显示得分""" self.screen.blit(self.score_image, self.score_rect) self.screen.blit(self.high_score_image, self.high_score_rect)
在game_stats中添加score属性,为每次重新开始都可以重置分数。
# game_stats.py # def __init__(self, ai_settings): # """初始化统计信息""" # self.ai_settings = ai_settings # self.reset_stats() # self.game_active = False # 在任何情况下都不应该重置最高分 self.high_score = 0 # def reset_stats(self): # """初始化在游戏运行期间可能变化的统计信息""" # self.ships_left = self.ai_settings.ship_limit self.score = 0
在alien_invasion.py 中创建一个Scoreboard实例,并通过update_screen()函数在每次消灭乘客后更新分数。
# alien_inavsion.py from scoreboard import Scoreboard # --snip-- # 创建记分牌 sb = Scoreboard(ai_settings, screen, stats) #while True: # --snip-- gf.update_bullet_group(ai_settings, screen, stats, sb, ship, passenger_group, bullet_group) # 每次循环重绘窗口并更新屏幕 gf.update_screen(ai_settings, screen, stats, sb, ship, passenger_group, bullet_group, play_button) # --snip--
在settings.py中设定外星人的分数,并根据游戏难度的提高,提高外星人的分值
# settings.py # 乘客点数的提高速度 self.score_scale = 1.5 # def initialize_dynamic_settings(self): # """初始化随游戏进行而变化的动态设置""" # 记分 self.passenger_points = 50 # def increase_speed(self): # """提高速度的设置,同时提高乘客的分数""" self.passenger_points = int(self.passenger_points * self.score_scale)
发生碰撞即遍历字典collisions中的一个键,确保每个子弹击中的乘客都有分数
# game_functions.py def check_bullet_passenger_collisions(ai_settings, screen, stats, sb, ship, passenger_group, bullet_group): # # 检查是否有子弹击中了乘客 # # 如果是这样,就删除相应的子弹和乘客 # # groupcollide()返回字典,实参为True即删除发生碰撞的子弹或外星人 # collisions = pygame.sprite.groupcollide(bullet_group, passenger_group, False, True) # if collisions: for passenger_group in collisions.values(): stats.score += ai_settings.passenger_points * len(passenger_group) sb.prep_score() check_high_score(stats, sb) def check_high_score(stats, sb): """检查是否诞生了新的最高分""" if stats.score > stats.high_score: stats.high_score = stats.score sb.prep_high_score()
十二、显示飞机数量
首先,让Ship类继承Sprite,以便创建飞船编组。
# ship.py from pygame.sprite import Sprite #class Ship(Sprite): # def __init__(self, ai_settings, screen): # """初始化飞船并设置其初始位置""" super(Ship, self).__init__() def blitme_s(self): """在绘制剩余飞机数量""" self.image = pygame.transform.scale(self.image, (37, 34)) self.screen.blit(self.image, self.rect)
修改scoreboard.py,创建一个可供显示的飞船编组,并绘制。
from pygame.sprite import Group from ship import Ship # 准备船的图像 self.prep_ships() def prep_ships(self): """显示还余下多少艘飞船""" self.ships = Group() for ship_number in range(self.stats.ships_left): ship = Ship(self.ai_settings, self.screen) ship.rect.x = 10 + ship_number * ship.rect.width / 2 ship.rect.y = 10 self.ships.add(ship) # def show_score(self): # """在屏幕上显示得分""" # self.screen.blit(self.score_image, self.score_rect) # self.screen.blit(self.high_score_image, self.high_score_rect) for ship in self.ships: ship.blitme_s()
修改game_functions.py,确保游戏开始时显示飞船图像,在撞击之后损失一艘飞船图像。
# game_functions.py def check_play_button(ai_settings, screen, stats, sb, play_button, ship, passenger_group, bullet_group, mouse_x, mouse_y): # """在玩家单击Play按钮时开始游戏""" # 重置记分牌图像 sb.prep_score() sb.prep_high_score() sb.prep_ships() def ship_hit(ai_settings, stats, sb, screen, ship, passenger_group, bullet_group): # """响应被乘客撞到的飞船""" # if stats.ships_left > 0: # # 讲ship_left减一 # stats.ships_left -= 1 # 更新记分牌 sb.prep_ships()
注意修改alien_invasion.py中函数参数与game_functions.py中保持一下。