项目描述:
制作一款2D的游戏飞机大战,在游戏中,玩家控制一艘飞船最初出现在屏幕底部中央的飞船。玩家可以使用箭头左右移动飞船,空格射击。游戏开始,一群不明生物飞在天空,并像屏幕下方移动,玩家需要击杀这些不明生物,随着击杀的次数,不明生物的移动生物速度更快,只要有生物撞到玩家或达到底部,玩家损失一艘飞船,损失你三艘飞船以后,游戏结束。
软件描述:
pycharm 2022.2 专业版
python3.10(pygame)
游戏效果预览:
注意以下代码只用来学习 借鉴 !自娱自乐ha !
图片素材请自取: 图片有水印 如果需要没有水印的请私聊我 ~
目录
3、飞船 文件: aircraft_battle_ship.py
环境安装:
安装pygame
1、在pycharm打开终端(在右下角)输入一下命令安装
python3 -m pip install --user pygame
代码:
主运行文件:aircraft_battle.py
设置文件:aircraft_battle_set.py
飞船 文件: aircraft_battle_ship.py
子弹文件: aircraft_bullet.py
外星飞船文件:Alien_spacecraft.py
游戏统计文件:game_stats.py
游戏按键文件:button.py
游戏计分文件:scoreboard.py
images图片存放位置
注意:按目录格式放好 运行即可
目录结构:
1、主文件: aircraft_battle.py
# -*- coding: GBK -*-
import sys, pygame, time
from aircraft_battle_set import Settings
from aircraft_battle_ship import Ship
from aircraft_bullet import *
from Alien_spacecraft import *
from game_stats import *
from button import *
from scoreboard import *
class AircraftBattle:
"""管理游戏资源和行为的类"""
def __init__(self):
"""初始化游戏资源"""
pygame.init() # 初始化背景设置
self.settings = Settings()
self.screen = pygame.display.set_mode(
(self.settings.screen_width, self.settings.screen_height)) # 创建显示窗口 单位为px(像素)1200px宽 200px高
pygame.display.set_caption("飞机大战") # 窗口标题
# 创建一个用于存储游戏统计信息的实例
self.stats = GameStats(self)
# 创建计分器
self.sb = Scoreboard(self)
self.ship = Ship(self)
self.bullets = pygame.sprite.Group() # 编组 用于存储所有有效子弹
self.aliens = pygame.sprite.Group()
self._create_fleet()
# 创建 Play 按钮
self.play_button = Button(self, "Play")
if not self.stats.game_active:
self.play_button.draw_button()
def Fullscreen(self):
# 全屏运行全屏模式下不支持鼠标点击退出,只能输入Q退出
# 全屏与小窗口来回切换会发生外星飞船位置错乱
self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN) # 传入0,0参数以及FULLSCREEN:覆盖整个显示器
self.settings.screen_width = self.screen.get_rect().width # 由于无法估计屏幕大小所以使用width与height来更新设置
self.settings.screen_height = self.screen.get_rect().height
self.ship = Ship(self)
self.bullets = pygame.sprite.Group() # 编组 用于存储所有有效子弹
self.aliens = pygame.sprite.Group()
self._create_fleet()
# 创建 Play 按钮
self.play_button = Button(self, "Play")
def _check_events(self):
"""响应按键与鼠标响应"""
for event in pygame.event.get(): # 循环事件
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
self._check_keydown_events(event)
elif event.type == pygame.KEYUP:
self._check_keyup_events(event)
elif event.type == pygame.MOUSEBUTTONDOWN: # 检测与按钮相关的鼠标事件
mouse_pos = pygame.mouse.get_pos() # pygame.mouse.get_pos() 将返回一个元组,其中包含x,y的坐标
self._check_play_button(mouse_pos) # 将返回的值传给_check_play_button方法
def _check_play_button(self, mouse_pos):
"""在玩家单机Play按钮时开始新游戏"""
button_clicked = self.play_button.rect.collidepoint(mouse_pos)
# collidepoint 这个方法检测鼠标单击位置是否在play按钮的矩形内,如果是就设置为True 开始游戏
if button_clicked and not self.stats.game_active:
self.stats.game_active = True
# 重置游戏统计信息
self.settings.initialize_dynamic_settings()
self.stats.reset_stats() # 重置信息,并提供给玩家三架飞机
# 方法代码执行完毕后,运行游戏
# 清空剩余子弹以及外星飞船 # 游戏开始后清空编组
self.aliens.empty() # 清空外星飞船编组
self.bullets.empty() # 清空子弹编组
# 创建一群新的外星飞船并让飞船居中
self._create_fleet()
self.ship.center_ship()
# 游戏开始时,更新等级图像
self.sb.prep_score()
self.sb.prep_level()
self.sb.prep_ships()
# 隐藏光标
pygame.mouse.set_visible(False)
def _check_keydown_events(self, event): # 响应按键
if event.key == pygame.K_RIGHT:
# 向右移动飞船
self.ship.moving_right = True
# 向左移动
elif event.key == pygame.K_LEFT:
self.ship.moving_left = True
# 向下移动
elif event.key == pygame.K_DOWN:
self.ship.moving_xia = True
# 向上移动
elif event.key == pygame.K_UP:
self.ship.moving_shang = True
# 空格发射子弹
elif event.key == pygame.K_SPACE:
self._fire_bullet()
# 如果用户摁倒Q 既退出
elif event.key == pygame.K_q:
sys.exit()
# 按键 1 控制全屏 # 注意在操作的时候 飞机会恢复到初始位置
elif event.key == pygame.K_1:
self.Fullscreen()
# 按键 2 控制窗口化 # 注意在操作的时候 飞机会恢复到初始位置
# elif event.key == pygame.K_2:
# self.windows()
def _check_keyup_events(self, event):
# 松开按键以后改为FALSE 停止移动
if event.key == pygame.K_RIGHT: # 松开按键以后停止向右移动
self.ship.moving_right = False
elif event.key == pygame.K_LEFT: # 松开按键以后停止向左移动
self.ship.moving_left = False
# elif event.key == pygame.K_DOWN: # 松开按键以后停止向下移动
# self.ship.moving_xia = False
# elif event.key == pygame.K_UP: # 松开按键以后停止向上移动
# self.ship.moving_shang = False
def _fire_bullet(self):
"""创建一颗子弹,并将其加入到编组bullets中"""
if len(self.bullets) < self.settings.bullet_allowed: # 判断 bullets的长度,如果小于10 就创建一颗新子弹,但如果有未消失的三颗子弹,按下空格后不触发子弹
new_bullet = Bullet(self) # 定义子弹
self.bullets.add(new_bullet) # 将子弹 加入编组当中
def _ship_hit(self):
"""响应飞船被撞击"""
if self.stats.ship_left > 0:
# 将 ships_left 减一 并更新记牌器
self.stats.ship_left -= 1 # 飞船撞到外星飞船以后数量 - 1
self.sb.prep_ships()
# 清空余下的外星飞船和子弹 , 因为是编组的形式,所以直接清空编组
self.aliens.empty()
self.bullets.empty()
# 创建一批新的外星飞船,并将飞船恢复到初始化位置
self._create_fleet()
self.ship.center_ship()
# 暂停
time.sleep(0.5) # 暂停0.5 能让玩家看到被撞击
else:
self.stats.game_active = False
pygame.mouse.set_visible(True) # 鼠标光标
def _update_bullets(self):
"""更新子弹位置并删除消失的子弹"""
self.bullets.update()
# 删除消失的子弹
# 子弹 在到达屏幕顶端后消失,是因为pygame无法在屏幕外绘制,但出去的子弹依然存在,它们将继续消耗你内存和cpu,需要将屏幕外的子弹删除
for bullet in self.bullets.copy(): # 因为不能从for循环遍历的列表中删除元素,所以必须遍历编组的副本,所以我们用copy俩循环
if bullet.rect.bottom <= 0: # 如果子弹从顶部消失,y的值就为负数或者0 ,就将其从列表中删除
self.bullets.remove(bullet)
# print(len(self.bullets)) # 查看屏幕内子弹存在的数量
self._check_bullet_alien_collisions()
# 检测外星飞船与 飞船之间的碰撞
if pygame.sprite.spritecollideany(self.ship, self.aliens):
self._ship_hit() # 将方法加入到这个碰撞判断中
# 检查是否有外星飞船达到了屏幕底端
self._check_aliens_bottom()
def _check_aliens_bottom(self):
"""检查外星飞船是否到达底部"""
screen_rect = self.screen.get_rect()
for alien in self.aliens.sprites():
if alien.rect.bottom >= screen_rect.bottom:
# 像飞船被 碰撞一样 处理掉
self._ship_hit()
break
def _check_bullet_alien_collisions(self):
# 检查子弹是否击中外星飞船
# 如果是,就删除对应的子弹和外星飞船
collisions = pygame.sprite.groupcollide(self.bullets, self.aliens, True, True)
# sprite.groupcollide 将一个编组中每个元素的rect同另一个编组中的每个元素rect进行比较。
if collisions:
# 与外星飞船碰撞的子弹都是字典 collisions 中的一个键,每颗子弹相关的值都是一个列表,其中包含该子弹击中的外星人
for aliens in collisions.values(): # 循环 字典 collisions 确保每个消灭的都进入得分
self.stats.score += self.settings.alien_points * len(aliens)
# 每个值都是一个列表,包含被同一颗子弹击中的所有外星飞船,对于每个列表,都将其包含的外星人数量乘以一个外星人的分数,并将分数加入当前得分
self.sb.prep_score()
self.sb.check_high_score()
if not self.aliens:
# 删除现有的子弹并新建外星飞船
self.bullets.empty()
self._create_fleet() # 重新创建外星飞船群
self.settings.increase_speed()
# 提高等级 # 当消灭一群外星飞船的时候等级加一
self.stats.level += 1
self.sb.prep_level()
def _update_screen(self):
"""更新屏幕上的图像,并切换到新屏幕"""
# 每次循环时都重绘屏幕。
self.screen.fill(self.settings.bg_color)
self.ship.blitme()
for bullet in self.bullets.sprites(): # 方法 bullets.sprites 返回的是一个列表,遍历编组中的内容并对每部分内容调用draw_bullet,形成子弹样式
bullet.draw_bullet()
self.aliens.draw(self.screen) # 外星飞船编组调用 draw方法
# 显示得分
self.sb.show_score()
# 如果游戏处于非活动状态下,就绘制Play按钮
if not self.stats.game_active:
self.play_button.draw_button()
pygame.display.flip()
def _create_fleet(self):
"""创建外星人飞船群"""
# 创建一个外星人飞船并计算一行可容纳多少个
alien = Alien(self)
alien_width, alien_height = alien.rect.size # 使用属性size,该属性为一个元组,包含rect对象的宽度与高度
# 计算两边空白宽度 (屏幕两边留下一定的边距,将其设置为外星飞船的宽度,因有两个边距,所以用于存放外星飞船的水平空间 = 屏幕宽度 - 外星飞船宽度的两倍)
available_space_x = self.settings.screen_width - (2 * alien_width)
# 计算外星飞船之间的间距 (外星飞船所需要的间距为外星飞船的两倍,一个宽度存放外星飞船,另一个存放飞船间距)
# 为确定一行可容纳多少飞船,将空间 除以 外星飞船宽度的两倍, 这里用的 “//" 为整除运算符
number_aliens_x = available_space_x // (2 * alien_width)
# 计算屏幕可容纳多少外星飞船
ship_height = self.ship.rect.height
# 计算可用垂直空间 = 屏幕高度 - 第一行外星飞船的上边距(外星飞船高度)、飞船高度以及飞船群最初与飞船之间的间距(外星人高度的两倍)
available_space_y = (self.settings.screen_height - (3 * alien_height) - ship_height)
# 每行下方留出一定的空白区域,计算可容纳行数,将可用的垂直空间 除以 外星飞船高度的两倍(行数只能是整数)
number_rows = available_space_y // (2 * alien_height)
# 创建外星飞船群
for row_number in range(number_rows): # 将上述计算出来的高度变为一个循环的数,用来创建多行外星飞船
# 创建第一行外星人飞船
for alien_number in range(number_aliens_x): # 内部循环用来创建一行循环
self._create_alien(alien_number, row_number) # row_number 传递一个行号实参,将每行都沿屏幕依次向下放置
def _create_alien(self, alien_number, row_number):
# 创建一个外星人飞船并将其加入当前行
alien = Alien(self) # 创建 单个 外星飞船
alien_width, alien_height = alien.rect.size
# 通过 x 坐标 将其加入当前行,将每个 外星飞船往右推一个飞船宽度,在将外星飞船宽度乘以2,得到每个外星飞船占据的空间,包括飞船的间距
alien.x = alien_width + 2 * alien_width * alien_number
# 在据此计算当前外星飞船当前位置,使用 飞船的 x 属性来设置其位置
alien.rect.x = alien.x
# 修改 外星飞船的 y 坐标 并在第一行外星飞船上方流出与外星飞船等高的空白区域
# 相邻外星飞船 行的y 坐标 相差 外星飞船的两倍,因此高度乘以2 在乘以行号,第一行为0 因此第一行不变
alien.rect.y = alien.rect.height + 2 * alien.rect.height * row_number
self.aliens.add(alien) # 最后将所有创建的外星飞船 加入到编组当中
def _update_aliens(self):
"""更新外星飞船舰群中所有外星飞船的位置"""
self._check_fleet_edges()
self.aliens.update()
def _check_fleet_edges(self):
"""外星飞船到达边缘采取措施"""
for alien in self.aliens.sprites():
if alien.check_edges():
self._change_fleet_direction()
break
def _change_fleet_direction(self):
"""将整群外星飞船向下移动,并改变方向"""
for alien in self.aliens.sprites():
alien.rect.y += self.settings.fleet_drop_speed
self.settings.fleet_direction *= -1 # 这里-1 是向左移动
def run_game(self):
"""开始游戏的主循环"""
while True:
self._check_events()
if self.stats.game_active: # stats.game_active 为真的时候游戏继续,否则不运行游戏
self.ship.update()
self._update_bullets()
self._update_screen()
# 调用更新外星飞船位置的方法
self._update_aliens()
# 让最近绘制的屏幕可见
pygame.display.flip()
if __name__ == "__main__":
# 创建实例并运行游戏
ai = AircraftBattle()
ai.run_game()
2、设置文件:aircraft_battle_set.py
# -*- coding: GBK -*-
class Settings:
"""存储游戏中所有的设置类"""
def __init__(self):
"""初始化游戏设置"""
# 屏幕设置
self.screen_width = 1200
self.screen_height = 800
# 设置背景颜色
self.bg_color = (230, 230, 230)
# 飞船移动速度设置 #每次移动 1.5个像素 px
self.ship_speed = 1.5
# 飞船设置
self.ship_limit = 3 # 创建飞船数量
# 子弹设置
self.bullet_speed = 1.5 # 设置子弹速度
self.bullet_width = 3 # 设置子弹像素宽为3
self.bullet_height = 15 # 设置子弹像素高为 15
self.bullet_color = (121, 176, 214) # 设置子弹颜色
self.bullet_allowed = 20 # 限制同屏子弹最大数量为 10
# 外星飞船设置
self.alien_speed = 1.0 # 飞船移动速度
self.fleet_drop_speed = 10 # 飞船每次向下移动的像素
# fleet_direction 为 1 表示向右移动 为 -1 表示向左移动
self.fleet_direction = 1
# 加快游戏节奏的速度
self.speedup_scale = 1.1 # 控制游戏节奏的加快速度
# 分数越高 便提升速度
self.score_scale = 1.5 # 将分数提高速度设置为1.5
self.initialize_dynamic_settings() # 玩家每提高一级 游戏的节奏就翻倍
def initialize_dynamic_settings(self):
"""初始化随游戏进行而变化设置"""
self.ship_seed = 1.5
self.bullet_speed = 3
self.alien_speed = 1.0
# fleet_direction 为1 表示向右移动 为 -1 向左移动
self.fleet_direction = 1
# 外星飞船击落计分
self.alien_points = 50 # 随着游戏的进行 将提高分数,确保每次开启新游戏 都重置此分数 设定alien_plints
def increase_speed(self):
"""提高速度设置和击中外星飞船分数"""
self.ship_speed *= self.speedup_scale
self.bullet_speed *= self.speedup_scale
self.alien_speed *= self.speedup_scale
self.alien_points = int(self.alien_points * self.score_scale) # 游戏节奏加快的同时,提高每个外星飞船被击中的分数
3、飞船 文件: aircraft_battle_ship.py
# -*- coding: GBK -*-
import pygame
from pygame.sprite import Sprite
class Ship(Sprite):
"""管理飞船的类"""
def __init__(self, ai_game):
"""初始化飞船并设置其初始化位置"""
super().__init__()
self.screen = ai_game.screen
self.settings = ai_game.settings
self.screen_rect = ai_game.screen.get_rect() # 使用方法get_rect()访问屏幕的属性rect,并赋给.self.screen_rect,这样就能够将飞船放到屏幕中央
# 加载飞船图像并获取外连接矩形
self.image = pygame.image.load('images/ship.png') # 加载图像
self.rect = self.image.get_rect() # 指定飞船位置,用get_rect获取屏幕属性没用来指定飞船位置
# 对于每艘飞船,都将其放在屏幕底部的中央
self.rect.midbottom = self.screen_rect.midbottom
# 在飞船的属性x,y中存储小数值
self.x = float(self.rect.x)
self.y = float(self.rect.y)
# 移动标志
self.moving_right = False # 向右移动
self.moving_left = False # 向左移动
self.moving_shang = False # 向上移动
self.moving_xia = False # 向下移动
def update(self):
"""根据移动标志调整飞船的位置"""
# 限制飞船活动范围
if self.moving_right and self.rect.right < self.screen_rect.right:
self.x += self.settings.ship_speed # 向右移动
if self.moving_left and self.rect.left > 0:
self.x -= self.settings.ship_speed # 向左移动
# if self.moving_shang and self.rect.top > 0:
# self.y -= self.settings.ship_speed # 向上移动
# if self.moving_xia and self.rect.bottom < self.screen_rect.bottom:
# self.y += self.settings.ship_speed # 向下移动
# 根据self.x更新rect对象
self.rect.x = self.x
self.rect.y = self.y
def blitme(self):
"""在指定位置绘画飞船"""
self.screen.blit(self.image, self.rect)
# 处理rect对象时,可以使用矩形四角和中心的x坐标和y坐标。可通过设置这些值来指定矩形位置。要让游戏元素居中,可以
def center_ship(self):
"""让飞船在屏幕底端居中"""
self.rect.midbottom = self.screen_rect.midbottom
self.x = float(self.rect.x)
4、子弹文件: aircraft_bullet.py
# -*- coding: GBK -*-
import pygame
from pygame.sprite import Sprite
class Bullet(Sprite):
"""管理飞机所发射子弹的类"""
def __init__(self, ai_game):
"""在飞机当前位置创建一个子弹对象"""
super().__init__()
self.screen = ai_game.screen
self.settings = ai_game.settings
self.color = self.settings.bullet_color
# 在(0,0)处创建一个表示子弹的矩形,在设置正确的位置
self.rect = pygame.Rect(0, 0, self.settings.bullet_width,
self.settings.bullet_height) # 创建子弹的属性rect,子弹并非基于图像,因此必须用pygame.Rect创建一个矩形
self.rect.midtop = ai_game.ship.rect.midtop # 将子弹的rect.midtop设置为飞船的rect.midtop
# 存储用小数表示子弹位置
self.y = float(self.rect.y)
def update(self):
"""向上移动子弹"""
# 更新 子弹位置的小数点
self.y -= self.settings.bullet_speed # 子弹发射后向上移动,意味着y坐标将不断减小,并更新子弹位置
# 更新 子弹 的 rect 位置
self.rect.y = self.y # 更新子弹矩形的位置
def draw_bullet(self):
"""在屏幕上绘制子弹"""
pygame.draw.rect(self.screen, self.color, self.rect) # draw.rect 函数使用存储在self.color中的颜色填充表示子弹的矩形占据的屏幕的部分
5、外星飞船文件:Alien_spacecraft.py
# -*- coding: GBK -*-
import pygame
from pygame.sprite import Sprite
class Alien(Sprite):
"""表示单个外星人的类"""
def __init__(self, ai_game):
"""初始化外星人飞船位置"""
super().__init__()
self.screen = ai_game.screen
self.settings = ai_game.settings
# 加载外星人图像冰着吃其 rect 属性
self.image = pygame.image.load("images/alien.png")
self.rect = self.image.get_rect()
# 每个外星飞船最初都在屏幕左上角附近
self.rect.x = self.rect.width
self.rect.y = self.rect.height
# 存储外星人的精准水平位置
self.x = float(self.rect.x)
def check_edges(self):
"""
检查外星飞船是否撞到了屏幕边缘
如果外星飞船位于屏幕边缘就返回True
"""
screen_rect = self.screen.get_rect()
# 如果 rect 的属性 right大于屏幕的rect 的 right属性,就说明外星飞船位于右边缘,反之在左边
if self.rect.right >= screen_rect.right or self.rect.left <= 0:
return True
def update(self):
"""向右移动外星飞船"""
self.x += (self.settings.alien_speed * self.settings.fleet_direction) # 使用属性 self.x 跟踪外星飞船的准确位置
self.rect.x = self.x # self.x 的值来更新 外星飞船的位置
6、游戏统计文件:game_stats.py
# -*- coding: GBK -*-
class GameStats:
"""跟踪游戏的统计信息"""
def __init__(self, ai_game):
"""初始化信息统计表"""
self.settings = ai_game.settings
self.reset_stats()
self.game_active = False # 让游戏一开始处于非活动状态
# # 游戏结束设置
# # 游戏刚启动时设置为 True
# self.game_active = True
# 最高分初始化值
self.high_score = 0
def reset_stats(self):
"""初始化在游戏运行期间可能变化的统计信息"""
self.ship_left = self.settings.ship_limit
self.score = 0 # 初始化分数
# 玩家等级
self.level = 1 # 初始玩家等级
7、游戏按键文件:button.py
# -*- coding: GBK -*-
import pygame.font
class Button:
def __init__(self, ai_game, msg):
"""
初始化按钮的属性
msg 按钮中显示文本
"""
self.screen = ai_game.screen
self.screen_rect = self.screen.get_rect()
# 设置按钮的尺寸和其他属性
self.width, self.height = 200, 50 # 设置按钮尺寸
self.button_color = (0, 255, 0) # 按钮背景颜色
self.text_color = (255, 255, 255) # 按钮文本颜色
self.font = pygame.font.SysFont(None, 48) # pygame.font 函数可以将文本渲染到屏幕上,SysFont 指定字体
# None 表示使用默认字体 , 48 表示文本的字号
# 创建按钮的rect对象,并使其居中
self.rect = pygame.Rect(0, 0, self.width, self.height) # 居中
self.rect.center = self.screen_rect.center
# 按钮的标签只需创建一次
self._prep_msg(msg) # 调用函数进行渲染
# pygame处理文本的方式就是将要显示的字符串渲染为图像
def _prep_msg(self, msg): # 接受实参self 以及要渲染为图像的文本msg
"""将msg渲染为图像,并使其在按钮上居中"""
# font.renderc 函数: 将存储在msg中的文本转为图,在括号内的参数中布尔值(True)作用就是指定开启还是关闭反锯齿功能
# text_color 文本颜色
# button_color 背景色
self.msg_image = self.font.render(msg, True, self.text_color, self.button_color)
self.msg_image_rect = self.msg_image.get_rect() # 根据文本图像创建一个矩形,并将其中心点 设置为中心点
self.msg_image_rect.center = self.rect.center # 让文本上居中
def draw_button(self):
# 绘制一个用颜色填充的按钮,在绘制文本
self.screen.fill(self.button_color, self.rect) # 使用 screen.fill绘制按钮的矩形
self.screen.blit(self.msg_image, self.msg_image_rect) # 在使用 screen.blit 在调用函数并向它传递一副图像以及与该图相关联的rect
8、游戏计分文件:scoreboard.py
# -*- coding: GBK -*-
import pygame.font
from pygame.sprite import Group
from aircraft_battle_ship import Ship
class Scoreboard:
"""显示得分信息的类"""
def __init__(self, ai_game):
"""初始化显示得分涉及的属性"""
self.screen = ai_game.screen
self.ai_game = ai_game
self.screen_rect = self.screen.get_rect()
self.settings = ai_game.settings
self.stats = ai_game.stats
# 显示得分信息时使用的字体设置
self.text_color = (30, 30, 30) # 设置文本颜色
self.font = pygame.font.SysFont(None, 48) # 设置字体,以及字体大小
# 准备初始得分图像
self.prep_score()
self.prep_heigh_score()
self.prep_level()
self.prep_ships()
def prep_score(self):
"""将得分转换为渲染图"""
rounded_score = round(self.stats.score, - 1)
# round 函数 让小数精确到小数点后的某一位,其中小数点位数是由第二个实参指定,然而为负数,round将舍入到最近的10倍,如10,100,1000等
score_str = "{:,}".format(rounded_score)
# score_str = str(self.stats.score) # 将数值转换为字符串
self.score_image = self.font.render(score_str, True, self.text_color, self.settings.bg_color)
# 在屏幕右上角显示得分
# 将得分放置屏幕又上角,并在得分增大导致数变宽时让其向右延伸
self.score_rect = self.score_image.get_rect() # 确保得分始终锚定在屏幕右边,定义一个score_rect
self.score_rect.right = self.screen_rect.right - 20 # 屏幕右边缘相距20 px
self.score_rect.top = 20 # 让其边缘与屏幕边缘也相距20px
def show_score(self):
"""在屏幕上显示得分、等级和剩余飞船"""
self.screen.blit(self.score_image, self.score_rect) # 得分
self.screen.blit(self.high_score_image, self.high_score_rect) # 最高分
self.screen.blit(self.level_image, self.level_rect) # 等级
self.ships.draw(self.screen) # 剩余飞船
def prep_heigh_score(self):
"""将最高得分转换为渲染的图像"""
high_score = 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.settings.bg_color)
# 将最高得分放在屏幕顶部中央
self.high_score_rect = self.high_score_image.get_rect()
self.high_score_rect.centerx = self.screen_rect.centerx
self.high_score_rect.top = self.score_rect.top
def check_high_score(self):
"""检查是否诞生了新的最高分"""
if self.stats.score > self.stats.high_score: # 如果得的分数大于 最高分则替换最高分的值
self.stats.high_score = self.stats.score
self.prep_heigh_score()
def prep_level(self):
"""将等级转为渲染图片"""
level_str = str(self.stats.level)
self.level_image = self.font.render(level_str, True, self.text_color, self.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 # 与上面图像的属性大于10 px 以便得分和等级之间留出一定缝隙
def prep_ships(self):
"""显示剩余飞船"""
self.ships = Group() # 创建一个空编组
for ship_number in range(self.stats.ship_left): # 根据玩家剩余飞船运行一个循环
ship = Ship(self.ai_game) # 设定一个需要添加编组的值
ship.rect.x = 10 + ship_number * ship.rect.width # 将飞船放置屏幕左上角,并设置每艘飞船左边距为 10 px
ship.rect.y = 10 # 在设置飞船距离 y 坐标距离屏幕上方10px
self.ships.add(ship) # 设定好后 加入编组