Pygame小游戏练习五

@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中保持一下。

效果图

猜你喜欢

转载自www.cnblogs.com/gg12138/p/11368208.html