项目分析实现一个记分系统,实时地跟踪玩家的得分,并显示最高得分、当前等级和余下的
飞船数。
得分是游戏的一项统计信息,因此我们在GameStats中添加一个score属性:
game_stats.py
14.3.1显示得分
1.新建得分类
为在屏幕上显示得分,我们首先创建一个新类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
#显示得分信息时使用的字体设置
#准备初始得分图像
2.渲染文本
scoreboard.py
def prep_score(self):
'''将得分转换为一副渲染的图像'''
#将得分放在右上角
3.绘制文本
show_score()将得分图像显示到屏幕上,并将其放在score_rect指定的位置
scoreboard.py
def show_score(self):
"""在屏幕上显示得分"""
14.3.2创建记分牌
为显示得分,我们在alien_invasion.py中创建一个Scoreboard实例sb并将sb传递给update_screen(),让它能够在屏幕上显示得分。
alien_invasion.py
14.3.3在外星人被消灭时更新得分
为在屏幕上实时地显示得分,每当有外星人被击中时,我们都更新stats.score的值,再调用prep_score()更新得分图像。但在此之前,我们需要指定玩家每击落一个外星人都将得到50
个点:
1.指定得分
settings.py
def initialize_dynamic_settings(self):
--snip--
# 记分
self.alien_points = 50
2.更新得分
随着游戏的进行,我们将提高每个外星人值的点数。为确保每次开始新游戏时这个值都会被
重置,我们在initialize_dynamic_settings()中设置它。
在check_bullet_alien_collisions()中,每当有外星人被击落时,都更新得分:
game_function.py
def check_bullet_alien_collisions(ai_settings, screen, stats, sb, ship,
aliens, bullets):
"""响应子弹和外星人发生碰撞"""
# 删除发生碰撞的子弹和外星人
collisions = pygame.sprite.groupcollide(bullets, aliens, True, True)
if collisions:
#增加得分
#显示得分
--snip--
修改update_bullets()
14.3.4将消灭的每个外星人的点数都计入得分
调整检测子弹和外星人碰撞的方式来修复这种问题。在check_bullet_alien_collisions()中,与外星人碰撞的子弹都是字典collisions中的一个键;而与每颗子弹相关的值都是一个列表,其中包含该子弹撞到的外星人。我们遍历字典collisions,确保将消灭的每个外星人的点数都记入得分:
game_function.py
def check_bullet_alien_collisions(ai_settings, screen, stats, sb, ship,
aliens, bullets):
--snip--
if collisions:
#遍历collision的值,每个值都是一个列表存储了每个子弹撞击的外星人
for aliens in collisions.values():
#记入得分
sb.prep_score()
--snip--
14.3.5提高点数
玩家每提高一个等级,游戏都变得更难,因此处于较高的等级时,外星人的点数应更高。为实现这种功能,我们添加一些代码,以在游戏节奏加快时提高点数:
settings.py
class Settings():
"""存储游戏《外星人入侵》的所有设置的类"""
def __init__(self):
--snip--
# 加快游戏节奏的速度
self.speedup_scale = 1.1
# 外星人点数的提高速度1.5
self.initialize_dynamic_settings()
def increase_speed(self):
"""提高速度设置和外星人点数"""
self.ship_speed_factor *= self.speedup_scale
self.bullet_speed_factor *= self.speedup_scale
self.alien_speed_factor *= self.speedup_scale
#提升外星人点数
14.3.6将得分圆整
将得分显示为10的整数倍
设置得分的格式,在大数字中添加用逗号表示的千位分隔符
scoreboard.py
def prep_score(self):
"""将得分转换为渲染的图像"""
#将得分增加10倍
rounded_score = int(round(self.stats.score, -1))
#处使用了一个字符串格式设置指令,它让Python将数值转换为字符串时在其中插入逗号
score_str = "{:,}".format(rounded_score)
self.score_image = self.font.render(score_str, True, self.text_color,
self.ai_settings.bg_color)
--snip--
14.3.7最高得分
跟踪并显示最高得分,我们将最高得分存储在GameStats中。
1.设置最高得分
game_stats.py
def __init__(self, ai_settings):
--snip--
# 在任何情况下都不应重置最高得分
2.渲染最高得分图像
scoreboard.py
def __init__(self, ai_settings, screen, stats):
--snip--
# 准备当前得分的图像
self.prep_score()
#准备最高得分图像
self.prep_high_score()
def prep_high_score(self):
"""将最高得分转换为渲染的图像"""
#最高得分是score_points的10倍
#以千分位显示最高得分
#将high_score渲染为图片
#将最高得分放在屏幕顶部中央
3.绘制图像
在show_score()中绘制得分图像
4.检查是否产生最高得分
check_high_score(),只要碰撞就检测
game_function.py
def check_high_score(stats,sb):
"""检查是否诞生了新的最高得分"""
#r如果最高分发生改变修改重新渲染
if stats.score > stats.high_score:
stats.high_score = stats.score
sb.prep_high_score()
14.3.8显示等级
在GameStats中添加一个表示当前等级的属性。为确保每次开始新游戏时都重置等级在reset_stats()中初始化它:
game_stats.py
def reset_stats(self):
"""初始化随游戏进行可能变化的统计信息"""
self.ships_left = self.ai_settings.ship_limit
self.score = 0
self.level = 1
1.添加prep_level()
scoreboard.py
2.渲染游戏等级图像
scoreboard.py
def prep_level(self):
"""将等级转换为渲染的图像"""
self.level_image = self.font.render(str(self.stats.level), True,
self.text_color, self.ai_settings.bg_color)
# 将等级放在得分下方
self.level_rect = self.level_image.get_rect()
self.level_rect.right = self.score_rect.right
self.level_rect.top = self.score_rect.bottom + 10
3.显示等级
4.提升等级
当一群外星人被消灭后提升等级,提升等级后更新显示。
game_function.py
def check_bullet_alien_collisions(ai_settings, screen, stats, sb, ship,
aliens, bullets):
--snip--
if len(aliens) == 0:
# 如果整群外星人都被消灭,就提高一个等级
bullets.empty()
ai_settings.increase_speed()
#提高等级
create_fleet(ai_settings, screen, ship, aliens)
5.重置信息
为确保开始新游戏时更新记分和等级图像,在按钮Play被单击时触发重置。
game_function.py
def check_play_button(ai_settings, screen, stats, sb, play_button, ship,aliens, bullets, mouse_x, mouse_y):
"""在玩家单击Play按钮时开始新游戏"""
button_clicked = play_button.rect.collidepoint(mouse_x, mouse_y)
if button_clicked and not stats.game_active:
--snip--
# 重置游戏统计信息
stats.reset_stats()
stats.game_active = True
# 重置记分牌图像
# 清空外星人列表和子弹列表
aliens.empty()
bullets.empty()
--snip--
14.3.9显示余下的飞船数
显示玩家还有多少艘飞船,但使用图形而不是数字。为此,我们在屏幕左上角绘制飞船图像来指出还余下多少艘飞船。
1.继承Sprite
import pygame
from pygame.sprite import Sprite
class Ship():
def __init__(self, ai_settings, screen):
"""初始化飞船,并设置其起始位置"""
--snip--
2.飞船编组
scoreboard.py
import pygame.font
from pygame.sprite import Group
from ship import Ship
class Scoreboard():
"""报告得分信息的类"""
def __init__(self, ai_settings, screen, stats):
--snip--
self.prep_level()
#通过prep_ships()显示飞船
self.prep_ships()
--snip--
3.prep_ships()
scoreboard.py
def prep_ships(self):
"""显示还余下多少艘飞船"""
#创建飞船编组
#根据玩家剩余飞船数决定要绘制几个飞船
for ship_number in range(self.stats.ships_left):
#创建飞船实例
ship.rect.x = 10 + ship_number * ship.rect.width
ship.rect.y = 10
#将ship加入ships
4.绘制飞船
1.绘制初始
2.过程更新数量
①在游戏开始时让玩家知道他有多少艘飞船,我们在开始新游戏时调用prep_ships()
②在飞船被外星人撞到时调用prep_ships(),从而在玩家损失一艘飞船时更新飞船图像