赞
踩
对于项目一,确实有些杂,但是我们只要理清其中的思路即可。毕竟第一次的项目,往后要不断回顾才是。
这样吧,我附上整个项目的代码。有什么不懂的地方可以留言问我。
- # 02 import sys
- import pygame
- from settings import Setting # 01
- from ship import Ship # 01
- import game_function as gf # 02
- from pygame.sprite import Group # 03 pygame.sprite.Group 类类似于列表,但提供了有助于开发游戏的额外功能
- # from aliens import Alien # 04
- from game_stats import GameStats # 04
- from button import Button # 05
- from scoreboard import Scoreboard # 05
-
-
- def run_game(): # 初始化游戏,并且创建一个屏幕对象
- pygame.init() # 初始化背景设置,让Pygame能够正确地工作
- # 01 screen = pygame.display.set_mode((1200, 800)) # 创建一个名为screen 的显示窗口,括号里是元组!!!
- # 01 # 这个游戏的所有图形元素都将在其中绘制
- ai_set = Setting() # 因为导入类而做了代码替换
- screen = pygame.display.set_mode(
- (ai_set.screen_width, ai_set.screen_height)
- )
- # 01 bg_color = (230,230,230) # 设置背景颜色
-
- pygame.display.set_caption('外星人入侵')
- # 创建一个play按钮
- play_button = Button(ai_set, screen, 'Play')
- # 创建一个用于存储游戏统计信息的实例 并【创建记分牌】
- stats = GameStats(ai_set)
- sb = Scoreboard(ai_set, screen, stats)
-
- # 创建一艘飞船对象
- ship = Ship(ai_set, screen)
- # 03 导入Group类并且创建一个Group实例,用于存储子弹的编组
- bullets = Group()
- # 04 创建一个外星人,编组
- # alien = Alien(ai_set,screen)
- aliens = Group()
- # 04 创建外星人群
- gf.create_fleet(ai_set, screen, ship, aliens)
-
- # 为让程序响应事件,我们编写一个事件循环,以侦听事件,并根据发生的事件执行相应的任务。
- while True: # 游戏的主循环
- # 02 for event in pygame.event.get(): # 监视键盘和鼠标
- # 02 if event.type == pygame.QUIT: #编写一系列的if 语句来检测并响应特定的事件
- # 02 sys.exit() # 我们调用sys.exit() 来退出游戏
- gf.check_event(ai_set, screen, stats, sb, play_button, ship, aliens, bullets) # 02 03 05 06
- if stats.game_active:
- ship.update() # 02
-
- gf.update_bullet(ai_set, screen, stats, sb, ship, aliens, bullets) # 03 04 05
- gf.update_aliens(ai_set, screen, stats, sb, ship, aliens, bullets) # 04 06
- # 03 bullets.update() # 03
- # # 03 删除已经消失,看不到的子弹
- # for bull in bullets.copy():
- # if bull.rect.bottom <= 0:
- # bullets.remove(bull)
- # print(len(bullets))
-
- # 01screen.fill(bg_color) # 每次循环都重绘屏幕
- # 02 screen.fill(ai_set.bg_color)
- # 02 ship.blitme() # 调用blitme函数,使飞船出现
- # 02 pygame.display.flip() # 让最近绘制的屏幕可见
-
- gf.update_screen(ai_set, screen, stats, sb, ship, aliens, bullets, play_button) # 02 03 04 05
-
-
- run_game()
- input()

- import sys
- import pygame
- from settings import Setting
- from bullet import Bullet # 03
- from aliens import Alien # 04
- from time import sleep # 04
- from game_stats import GameStats # 05
-
-
- # 响应按键 03
- def check_keydown(event, ai_settings, screen, ship, bullets):
- if event.key == pygame.K_RIGHT:
- # 向右移动飞船
- ship.moving_right = True
- # ship.rect.centerx += 10
-
- elif event.key == pygame.K_LEFT:
- # 向左移动飞船
- # ship.rect.centerx -= 10
- ship.moving_left = True
-
- # 03 创建一颗子弹,并将其加入到编组bullets中
- elif event.key == pygame.K_SPACE:
- if len(bullets) < ai_settings.bullet_allowed: # 限制三个子弹
- # 玩家按空格键时,创建一颗新子弹(一个名为new_bullet 的Bullet 实例),
- new_bullet = Bullet(ai_settings, screen, ship)
- # 并使用方法add() 将其加入到编组bullets中
- bullets.add(new_bullet)
-
- # 04 按q结束
- elif event.key == pygame.K_q:
- sys.exit()
-
-
- # 响应松开 03
- def check_keyup(event, ship):
- if event.key == pygame.K_RIGHT:
- ship.moving_right = False
- elif event.key == pygame.K_LEFT:
- ship.moving_left = False
-
-
- # 响应按键和鼠标事件
- def check_event(ai_setting, screen, stats, sb, play_button, ship, aliens, bullets): # 03
-
- for i in pygame.event.get():
- if i.type == pygame.QUIT:
- sys.exit()
-
- elif i.type == pygame.KEYDOWN:
- check_keydown(i, ai_setting, screen, ship, bullets) # 重构
- # 03 if i.key == pygame.K_RIGHT:
- # 03 # 向右移动飞船
- # 03 ship.moving_right = True
- # 03 # ship.rect.centerx += 10
- # 03 elif i.key == pygame.K_LEFT:
- # 03 # 向左移动飞船
- # 03 # ship.rect.centerx -= 10
- # 03 ship.moving_left = True
-
- elif i.type == pygame.KEYUP:
- check_keyup(i, ship) # 重构
- # 03 if i.key == pygame.K_RIGHT:
- # 03 ship.moving_right = False
- # 03 elif i.key == pygame.K_LEFT:
- # 03 ship.moving_left = False
-
- # 05 鼠标点击事件
- elif i.type == pygame.MOUSEBUTTONDOWN:
- # 无论玩家单击屏幕的什么地方,Pygame都将检测到一个MOUSEBUTTONDOWN 事件
- # 但我们只想让这个游戏在玩家用鼠标单击Play按钮时作出响应
- # 为此,我们使用了pygame.mouse.get_pos() ,它返回一个元组,其中包含玩家单击时鼠标的x 和y 坐标
- mouse_x, mouse_y = pygame.mouse.get_pos()
- # 我们将这些值传递给函数check_play_button()
- # 而这个函数使用collidepoint() 检查鼠标单击位置是否在Play按钮的rect 内
- check_play_button(ai_setting, screen, stats, sb, play_button, ship, aliens, bullets, mouse_x, mouse_y)
-
-
- # 05 在玩家单击play按钮时开始新的游戏
- def check_play_button(ai_setting, screen, stats, sb, play_button, ship, aliens, bullets, mouse_x, mouse_y):
- # 仅当玩家单击了Play按钮且 游戏当前处于非活动状态时,游戏才重新开始
- # collidepoint() 检查鼠标单击位置是否在Play按钮的rect 内
- button_clicked = play_button.rect.collidepoint(mouse_x, mouse_y)
-
- if button_clicked and not stats.game_active: # 控制仅仅在按钮区域,且 游戏停止状态 才会重置
-
- # 重置游戏的设置,如初始速度等
- ai_setting.initialize_dynamic_settings()
-
- # 隐藏光标,直到游戏重开时出现,修改visible状态的代码写到ship_hit()中
- pygame.mouse.set_visible(False)
- # 重置游戏统计信息
- stats.reset_stats()
- stats.game_active = True
-
- # 06 为确保开始新游戏时更新记分和等级图像,在按钮Play被单击时触发重置
- sb.prep_score()
- sb.prep_high_score()
- sb.prep_level()
- # 06 我们在开始新游戏时调用prep_ships()
- sb.prep_ship()
-
- # 清空外星人列表和子弹列表
- aliens.empty()
- bullets.empty()
-
- # 创建一群新的外星人,并让飞船居中
- create_fleet(ai_setting, screen, ship, aliens)
- ship.center_ship() # ship.py中的函数
-
-
- # -------------------------------------更新屏幕-------------------------------------
- # 更新屏幕上的图像,并切换到新屏幕
- def update_screen(ai_setting, screen, stats, sb, ship, aliens, bullets, play_button):
- # 每次循环时都重绘屏幕
- screen.fill(ai_setting.bg_color)
- # 03 在飞船和外星人后面重绘所有子弹
- # 为在屏幕上绘制发射的所有子弹,我们遍历编组bullets 中的精灵,并对每个精灵都调用draw_bullet()
- for bullet in bullets.sprites():
- bullet.draw_bullet()
- ship.blitme()
- # 04 alien.blitme()
- aliens.draw(screen) # 04 绘制外星人,使用的是内置draw函数
-
- # 06 显示得分
- sb.show_score()
-
- # 05 如果处于非游戏状态,就绘制play按钮
- if not stats.game_active:
- play_button.draw_button() # 此函数在button.py文件
- # 让最近绘制的屏幕可见
- pygame.display.flip()
-
-
- # -------------------------------------以下是子弹----------------------------------------------
-
- # 03 更新子弹位置,并删除已经消失的子弹
- def update_bullet(ai_setting, screen, stats, sb, ship, aliens, bullets): # 05
- bullets.update() # 更新子弹位置
-
- # 03 删除已经消失,看不到的子弹
- for bull in bullets.copy():
- if bull.rect.bottom <= 0:
- bullets.remove(bull)
- print(len(bullets))
- # ----- 04 检查是否碰撞-------
- check_bullet_alien_collision(ai_setting, screen, stats, sb, ship, aliens, bullets) # 05
-
-
- # 检查子弹和外星人是否碰撞
- def check_bullet_alien_collision(ai_setting, screen, stats, sb, ship, aliens, bullets):
- # 方法sprite.groupcollide() 将每颗子弹的rect 同每个外星人的rect 进行比较,并返回一个字典,
- # 其中包含发生了碰撞的子弹和外星人。在这个字典中,每个键都是一颗子弹,而相应的值都是被击中的外星人
- # 检查是否有子弹击中了外星人
- # 如果是这样,就删除相应的子弹和外星人
- collisions = pygame.sprite.groupcollide(bullets, aliens, True, True)
-
- # 05 若碰撞则加分
- if collisions:
- # 如果字典collisions 存在,我们就遍历其中的所有值。
- # 别忘了,每个值都是一个列表,包含被同一颗子弹击中的所有外星人。
- # 对于每个列表,都将一个外星人的点数乘以其中包含的外星人数量,并将结果加入到当前得分中
- for alie in collisions.values():
- # 有子弹撞到时,Pygame返回一个字典(collisions )。
- # 我们检查这个字典是否存在,如果存在,就将得分加上一个外星人值的点数
- stats.score += ai_setting.alien_point * len(alie)
- sb.prep_score() # 此函数在scoreboard.py文件中
- check_high_score(stats, sb) # 此函数在本页最后
-
- # 如果外星人编组为空,则删除现有子弹并新建一群外星人
- # 06 如果整群外星人都被消灭,就提高一个等级
- if len(aliens) == 0:
- bullets.empty()
- ai_setting.increase_speed() # 增加游戏节奏
-
- # 06 提高等级
- stats.level += 1
- sb.prep_level()
-
- create_fleet(ai_setting, screen, ship, aliens)
- # ai_setting.fleet_drop_speed += 20 # 自己加的----------------------------------------------------
-
-
- # -------------------------------------以下是外星人 04 --------------------------------------------
- # 04 创建外星人群
- def create_fleet(ai_setting, screen, ship, aliens):
- # 创建一个外星人,并计算一行可容纳多少个外星人
- # 外星人间距为外星人宽度
-
- # 我们先创建一个外星人,这个外星人不是外星人群的成员,因此没有将它加入到编组aliens 中
- ali = Alien(ai_setting, screen)
- number_alien_x = get_number_aliens_x(ai_setting, ali.rect.width) # 04 重构create_fleet
- number_rows = get_number_row(ai_setting, ship.rect.height, ali.rect.height)
- # 04 # 我们从外星人的rect 属性中获取外星人宽度,并将这个值存储到alien_width 中,以免反复访问属性rect
- # 04 ali_width = ali.rect.width
- # 04 # 我们计算可用于放置外星人的水平空间,以及其中可容纳多少个外星人。
- # 04 available_space_x = ai_setting.screen_width - 2 * ali_width
- # 04 number_alien_x = int(available_space_x / (2 * ali_width))
-
- # 创建第一行外星人
- for row_num in range(number_rows):
- for ali_num in range(number_alien_x):
- # 创建一个外星人,并加入当前行
- # alien = Alien(ai_setting,screen) # 通过设置x 坐标将其加入当前行
- # alien.x = ali_width + 2 * ali_width * ali_num
- # alien.rect.x = alien.x
- # aliens.add(alien)
- create_alien(ai_setting, screen, aliens, ali_num, row_num) # 04 重构create_fleet
-
-
- # 计算每行可容纳多少个外星人
- def get_number_aliens_x(ai_setting, alien_width):
- available_space_x = ai_setting.screen_width - 2 * alien_width
- number_alien_x = int(available_space_x / (2 * alien_width))
- return number_alien_x
-
-
- # 计算屏幕可容纳多少行外星人
- def get_number_row(ai_setting, ship_height, alien_height):
- available_space_y = (ai_setting.screen_height - (3 * alien_height) - 3.5 * ship_height)
- number_rows = int(available_space_y / (2 * alien_height))
- return number_rows
-
-
- # 创建一个外星人并将其放在当前行
- def create_alien(ai_setting, screen, aliens, alien_number, row_number):
- alien = Alien(ai_setting, screen) # 通过设置x 坐标将其加入当前行
- alien_width = alien.rect.width
- alien.x = alien_width + 2 * alien_width * alien_number
- alien.rect.x = alien.x
- alien.rect.y = alien.rect.height + 2 * alien.rect.height * row_number # 创建时,计算y的坐标
- aliens.add(alien)
-
-
- # 更新外星人群中所有外星人位置
- def update_aliens(ai_set, screen, stats, sb, ship, alie, bullets):
- # 检查是否有外星人到达屏幕边,然后更新所有外星人的位置
- check_fleet_edges(ai_set, alie)
- alie.update()
- # 04 检测外星人和飞船之间的碰撞
- # 方法spritecollideany() 接受两个实参:一个精灵和一个编组。
- # 它检查编组是否有成员与精灵发生了碰撞,并在找到与精灵发生了碰撞的成员后就停止遍历编组。
- if pygame.sprite.spritecollideany(ship, alie):
- ship_hit(ai_set, screen, stats, sb, ship, alie, bullets)
-
- # 检测是否有外星人到达屏幕底部
- check_aliens_bottom(ai_set, screen, stats, sb, ship, alie, bullets)
-
-
- # 检测是否有外星人到达的屏幕底端
- def check_aliens_bottom(ai_setting, screen, stats, sb, ship, aliens, bullets):
- screen_rect = screen.get_rect()
- for ali in aliens.sprites():
- if ali.rect.bottom >= screen_rect.bottom:
- # 像飞船撞到外星人一样处理
- ship_hit(ai_setting, screen, stats, sb, ship, aliens, bullets)
- break
-
-
- # 响应被外星人撞到的飞船
- def ship_hit(ai_setting, screen, stats, sb, ship, aliens, bullets):
- if stats.ships_left > 0:
- # 将ships_left减一
- stats.ships_left -= 1
-
- # 我们还在飞船被外星人撞到时调用prep_ships() ,从而在玩家损失一艘飞船时更新飞船图像:
- sb.prep_ship()
-
- # 清空外星人和子弹列表
- aliens.empty()
- bullets.empty()
- # 重新创建一群新的外星人,并将飞船放到屏幕底部
- create_fleet(ai_setting, screen, ship, aliens)
- ship.center_ship() # ship.py中的函数
- # 暂停0.5秒
- sleep(0.5)
- else:
- stats.game_active = False
- # 使光标出现
- pygame.mouse.set_visible(True)
-
-
- # 有外星人到达边缘时,采取相应的措施
- def check_fleet_edges(ai_setting, aliens):
- for ali in aliens.sprites(): # 我们遍历外星人群,并对其中的每个外星人调用check_edge()
- if ali.check_edge(): # aliens.py中有此函数
- change_fleet_direction(ai_setting, aliens)
- break
-
-
- # 将整群外星人下移,并改变它们的方向
- def change_fleet_direction(ai_set, aliens):
- for ali in aliens.sprites():
- ali.rect.y += ai_set.fleet_drop_speed
- ai_set.fleet_direction *= -1
-
-
- # ---------------------------------------以下是检测是否诞生最高分----------------------------------------
- def check_high_score(stats, sb):
- if stats.score > stats.high_score:
- stats.high_score = stats.score
- sb.prep_high_score()

- import pygame
- from pygame.sprite import Sprite # 06
-
-
- class Ship(Sprite):
- def __init__(self, ai_setting, screen): # 初始化飞船,并设置初始位置
- super().__init__() # 06 继承初始化
- self.screen = screen
- self.ai_setting = ai_setting # 02
- # 加载飞船图像并获取其外接矩形
- self.image = pygame.image.load('.\\feii.bmp')
- self.rect = self.image.get_rect() # 我们使用get_rect() 获取相应surface的属性rect
- self.screen_rect = self.screen.get_rect()
-
- # 将每艘新飞船放在屏幕底部中央
- # 要将游戏元素居中,可设置相应rect 对象的属性center 、centerx 或centery 。
- self.rect.centerx = self.screen_rect.centerx
- # 要让游戏元素与屏幕边缘对齐,可使用属性top 、bottom 、left 或right ;
- # 要调整游戏元素的水平或垂直位置,可使用属性x 和y ,它们分别是相应矩形左上角的 x 和 y 坐标。
- self.rect.bottom = self.screen_rect.bottom
- # 在飞船的属性center中存储小数数值
- self.center = float(self.rect.centerx) # 小数形式的位移可以更好的控制飞船移动
-
- # 移动标志,# 02
- # 飞船不动时,标志moving_right将为False 。
- # 玩家按下右箭头键时,我们将这个标志设置为True ;而玩家松开时,我们将这个标志重新设置为False
- self.moving_right = False
- self.moving_left = False
- self.moving_up = False
- self.moving_down = False
-
- # 根据移动标志,移动飞船 # 02
- def update(self):
- if self.moving_right and self.rect.right < self.screen_rect.right: # 控制飞船移动的左右范围
- # 02 self.rect.centerx += 1
- # 02 更新飞船的center值,而不是rect
- self.center += self.ai_setting.ship_speed_factor
- if self.moving_left and self.rect.left > 0:
- # 02 self.rect.centerx -= 1
- self.center -= self.ai_setting.ship_speed_factor
-
- # 根据self.center更新rect对象
- self.rect.centerx = self.center
-
- # 我们定义了方法blitme() ,它根据self.rect 指定的位置将图像绘制到屏幕上
- # 在指定位置绘制飞船
- def blitme(self):
- self.screen.blit(self.image, self.rect) # 把image这个surface对象贴到rect的位置
-
- # 让飞船在屏幕上居中
- def center_ship(self):
- self.center = self.screen_rect.centerx

- import pygame
- from pygame.sprite import Sprite
-
-
- # 表示单个外星人的类
- class Alien(Sprite):
- # 初始化外星人并设置其起始位置
- def __init__(self, ai_setting, screen):
- super().__init__()
- self.screen = screen
- self.ai_setting = ai_setting
-
- # 加载外星人图形,并设置其rect属性
- self.image = pygame.image.load(r'.\\alien-1.bmp')
- 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 blitme(self):
- self.screen.blit(self.image, self.rect)
-
- # 如果外星人处于屏幕边缘,就返回True,此函数会在game_function中用到
- # 如果外星人处于屏幕边缘,就返回True,此函数会在game_function中用到
- def check_edge(self):
- screen_rect = self.screen.get_rect()
- if self.rect.right >= screen_rect.right:
- return True
- elif self.rect.left <= screen_rect.left:
- return True
-
- # 向左或向右移动外星人
- def update(self, *args):
- self.x += self.ai_setting.alien_speed_factor * self.ai_setting.fleet_direction
- self.rect.x = self.x

- import pygame
- from pygame.sprite import Sprite # 导入精灵
-
-
- # 一个对飞船发射的子弹进行管理的类
- class Bullet(Sprite):
- def __init__(self, ai_setting, screen, ship):
- # 在飞船所处的位置创建一个子弹对象
- super().__init__() # 初始化父类 2.7写法super(Bullet,self).__init__()
- self.screen = screen
-
- # 在(0,0)处创建一个表示子弹的矩形,再设置正确的位置
- # 我们创建了子弹的属性rect 。子弹并非基于图像的,因此我们必须使用pygame.Rect()类从空白开始创建一个矩形
- # 我们在(0, 0)处创建这个矩形,但接下来的两行代码将其移到了正确的位置
- # self.rect = pygame.Rect(0,0,ai_setting.bullet_width,ai_setting.bullet_height)-------原版,下两行DIY-------
- self.image = pygame.image.load('.\\Heart7.bmp')
- self.rect = self.image.get_rect()
- # 我们将子弹的centerx设置为飞船的rect.centerx 。
- # 子弹应从飞船顶部射出,因此我们将表示子弹的rect的top属性设置为飞船的rect的top属性,
- # 让子弹看起来像是从飞船中射出的
- self.rect.centerx = ship.rect.centerx
- self.rect.top = ship.rect.top
-
- # 存储用小数表示的子弹位置
- self.y = float(self.rect.y)
-
- self.color = ai_setting.bullet_color
- self.speed = ai_setting.bullet_speed_factor
-
- # 向上移动子弹
- def update(self, *args):
- # 更新表示子弹位置的小数值
- self.y -= self.speed / 2
- # 更新表示子弹位置的rect的位置
- self.rect.y = self.y
-
- # 在屏幕上绘制子弹
- def draw_bullet(self):
- # 函数draw.rect()使用存储在self.color中的颜色填充表示子弹的rect占据的屏幕部分
- # pygame.draw.rect(self.screen,self.color,self.rect)-----------------------原版,下一行DIY-------------------
- self.screen.blit(self.image, self.rect)

- import pygame.sysfont
-
-
- class Button():
- # 初始化按钮属性
- def __init__(self, ai_setting, screen, msg):
- self.screen = screen
- self.screen_rect = screen.get_rect()
-
- # 设置按钮的尺寸和其他属性
- self.width, self.height = 200, 50
- self.button_color = (0, 255, 0)
- self.text_color = (255, 255, 255)
- self.font = pygame.sysfont.SysFont('arial', 48)
-
- # 创建按钮的rect对象,并使其居中
- # 为让按钮在屏幕上居中,我们创建一个表示按钮的rect 对象
- # 并将其center 属性设置为屏幕的center 属性
- self.rect = pygame.Rect(0, 0, self.width, self.height)
- self.rect.center = self.screen_rect.center
-
- # 按钮的标签只需创建一次
- # Pygame通过将你要显示的字符串渲染为图像来处理文本。我们调用prep_msg() 来处理这样的渲染
- self.prep_msg(msg)
-
- # 将msg渲染为图像,并使其在按钮上居中
- def prep_msg(self, msg):
- 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
-
- # 最后,我们创建方法draw_button() ,通过调用它可将这个按钮显示到屏幕上
- def draw_button(self):
- # 绘制一个用颜色填充的按钮,再绘制文本
- self.screen.fill(self.button_color, self.rect)
- self.screen.blit(self.msg_image, self.msg_image_rect)

- # 跟踪游戏的统计信息
- class GameStats():
- # 初始化统计信息
- def __init__(self, ai_setting):
- self.ai_setting = ai_setting
- self.reset_stats()
- # # 游戏刚开始时处于活动状态
- # self.game_active = True
- # 游戏刚开始时处于停止状态,直到play按钮按下
- self.game_active = False # 05
-
- # 在任何情况下都不重置最高分
- self.high_score = 0
-
- # 初始化在游戏运行期间可能变化的统计信息
- def reset_stats(self):
- self.ships_left = self.ai_setting.ship_limit
- self.score = 0 # 05 记分,在每次游戏开始时,重置记分
- self.level = 1 # 06 等级

- import pygame.sysfont
- from pygame.sprite import Group # 06
- from ship import Ship # 06
-
-
- # 显示得分信息的类
- class Scoreboard():
-
- # 初始化显示涉及得分的属性
- def __init__(self, ai_setting, screen, stats):
- self.screen = screen
- self.screen_rect = screen.get_rect()
- self.ai_setting = ai_setting
- self.stats = stats
-
- # 显示得分信息时使用的字体设置
- self.text_color = (30, 30, 30)
- self.font = pygame.sysfont.SysFont('arial', 48)
-
- # 准备初始得分图像
- self.prep_score() # 为将要显示的文本转换为图像
- # 准备最高分的图像
- self.prep_high_score()
- # 06 准备显示等级的图像
- self.prep_level()
- # 06 准备显示剩余飞船的图像
- self.prep_ship()
-
- # 将得分转换为一副渲染的图像
- def prep_score(self):
- round_score = round(self.stats.score)
- score_str = '{:,}'.format(round_score)
- self.score_image = self.font.render(score_str, True, self.text_color, self.ai_setting.bg_color)
-
- # 将得分放到屏幕右上角
- self.score_rect = self.score_image.get_rect()
- self.score_rect.right = self.screen_rect.right - 20
- self.score_rect.top = 20 # 让其上边缘与屏幕上边缘也相距20像素
-
- # 将最高分渲染为图像
- def prep_high_score(self):
- high_score = round(self.stats.high_score)
- high_score_str = '{:,}'.format(high_score)
- self.high_score_image = self.font.render(high_score_str, True, self.text_color, self.ai_setting.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.screen_rect.top
-
- # 06 等级渲染为图像
- def prep_level(self):
- self.leve_image = self.font.render(str(self.stats.level), True, self.text_color, self.ai_setting.bg_color)
-
- # 将等级放在得分下方
- self.level_rect = self.leve_image.get_rect()
- self.level_rect.right = self.screen_rect.right - 20
- self.level_rect.top = self.score_rect.bottom + 10
-
- # 06 显示剩余多少飞船
- def prep_ship(self):
- # 方法prep_ships() 创建一个空编组self.ships ,用于存储飞船实例
- self.ships = Group()
- # 为填充这个编组,根据玩家还有多少艘飞船运行一个循环相应的次数
- for ship_num in range(self.stats.ships_left):
- # 在这个循环中,我们创建一艘新飞船,并设置其x 坐标,
- # 让整个飞船编组都位于屏幕左边,且每艘飞船的左边距都为10像素
- # 我们还将y 坐标设置为离屏幕上边缘10像素,让所有飞船都与得分图像对齐
- ship = Ship(self.ai_setting, self.screen)
- ship.rect.x = 10 + ship_num * ship.rect.width
- ship.rect.y = 10
- # 最后,我们将每艘新飞船都添加到编组ships 中
- self.ships.add(ship)
-
- # 在屏幕上显示得分
- def show_score(self):
- # 这个方法将得分图像显示到屏幕上,并将其放在score_rect 指定的位置
- self.screen.blit(self.score_image, self.score_rect)
- self.screen.blit(self.high_score_image, self.high_score_rect)
- self.screen.blit(self.leve_image, self.level_rect) # 06
-
- # 为在屏幕上显示飞船,我们对编组调用了draw() 。Pygame将绘制每艘飞船。
- self.ships.draw(self.screen)

- class Setting(): # 存储《外星人入侵》中所有的设置类
- def __init__(self): # 初始化游戏设置
- self.screen_width = 1200 # 屏幕设置
- self.screen_height = 800
- self.bg_color = (230, 230, 230)
-
- # self.ship_speed_factor = 2.5 # 02 设置飞船速度
-
- # 03 子弹设置
- # 05 self.bullet_speed_factor = 3 # 子弹速度
- self.bullet_width = 500 # 子弹宽度
- self.bullet_height = 3 # 子弹长度
- self.bullet_color = 60, 60, 60 # 子弹颜色
- self.bullet_allowed = 3 # 限制子弹数量为3
-
- # 04 外星人设置
- # 05 self.alien_speed_factor = 1
- self.fleet_drop_speed = 10
- # 05 # fleet_direction为1表示向右移动,为-1表示向左移动
- # self.fleet_direction = 1
-
- # 04 飞船设置
- self.ship_limit = 2
-
- # 以什么样的速度加快游戏节奏
- self.speedup_scale = 1.1
- # 玩家每提高一个等级,游戏都变得更难,因此处于较高的等级时,外星人的点数应更高。
- # 外星人点数的提高速度
- self.score_scale = 1.5
-
- # 05 我们将动态变量 和 静态变量分开
- # 调用initialize_dynamic_settings() ,以初始化随游戏进行而变化的属性
- self.initialize_dynamic_settings()
-
- # 05 初始化随游戏进行而变化的设置
- def initialize_dynamic_settings(self):
- self.bullet_speed_factor = 3 # 子弹速度
- self.alien_speed_factor = 0.8
- self.ship_speed_factor = 1.5 # 02 设置飞船速度
-
- # fleet_direction为1表示向右移动,为-1表示向左移动
- self.fleet_direction = 1
-
- # 05 记分
- # 随着游戏的进行,我们将提高每个外星人值的点数。
- # 为确保每次开始新游戏时这个值都会被重置,我们在initialize_dynamic_settings() 中设置它。
- self.alien_point = 50
-
- # 05 每当玩家提高一个等级时,我们都使用increase_speed() 来提高飞船、子弹和外星人的速度
- # 提高速度
- def increase_speed(self):
- self.ship_speed_factor *= self.speedup_scale
- self.alien_speed_factor *= self.speedup_scale
- self.ship_speed_factor *= self.speedup_scale
-
- self.alien_point = int(self.alien_point * self.score_scale)

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。