赞
踩
项目描述:
制作一款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图片存放位置
注意:按目录格式放好 运行即可
目录结构:
- # -*- 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()
- # -*- 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) # 游戏节奏加快的同时,提高每个外星飞船被击中的分数
- # -*- 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)
- # -*- 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中的颜色填充表示子弹的矩形占据的屏幕的部分
- # -*- 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 的值来更新 外星飞船的位置
- # -*- 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 # 初始玩家等级
- # -*- 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
- # -*- 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) # 设定好后 加入编组
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。