计分和游戏控制

我们在玩游戏时,都有计分的制度,随着分数的增长,玩家玩游戏的精神也在增长,哈哈。
并且游戏都有一个控制按钮,比如开始,或者结束。

1.添加Play按钮

我们先让游戏一开始处于非活动状态,并提示玩家单击Play按钮来开始游戏。为此,在game_stats.py中添加代码:
game_stats.py

class GameStats():"""跟踪游戏的统计信息"""def __init__(self,ai_settings):"""初始化统计信息"""self.ai_settings = ai_settingsself.reset_stats()#游戏刚开始处于非活动状态self.game_active = Falsedef reset_stats(self):"""初始化在游戏运行期间可能变化的统计信息"""self.ships_left = self.ai_settings.ship_limit

1.1 创建Button类

由于Pygame没有内置创建按钮的方法,我们创建一个Button类,用于创建带标签的实心矩形,可以使用这些代码来创建任何按钮。我们保存文件名为button.py

import pygame.font #导入模块pygame.font,它让Pygame能够将文本渲染到屏幕上class Button():def __init__(self,ai_settings,screen,msg):"""初始化按钮的属性"""self.screen = screenself.screen_rect = screen.get_rect()#设置按钮的尺寸和其他属性self.width,self.height = 200, 50self.button_color = (0,255,0)self.text_color = (255,255,255)self.font = pygame.font.SysFont(None,48)#我们使用字体来渲染渲染文本,实参None让Pygame使用默认字体,而48指定了文本的字号#创建按钮的rect对象,并使其居中self.rect = pygame.Rect(0,0,self.width,self.height)self.rect.center = self.screen_rect.center#按钮的标签只需创建一次self.prep_msg(msg)#Pygame通过将你要显示的字符串渲染为图像来处理文本

然后完成prep_msg的代码:
button.py

import pygame.fontclass Button():def __init__(self,ai_settings,screen,msg):"""初始化按钮的属性"""self.screen = screenself.screen_rect = screen.get_rect()#设置按钮的尺寸和其他属性self.width,self.height = 200, 50self.button_color = (0,255,0)self.text_color = (255,255,255)self.font = 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)def prep_msg(self,msg):"""将msg渲染为图像,并使其在按钮上居中"""#msg 要渲染为图像的文本#font.render()将存储在msg中的文本转换为图像,然后存储在msg_image中,第二个实参指定是否开启反锯齿功能#反锯齿功能:让文本的边缘更平滑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(),通过调用它来将按钮显示到屏幕上:
button.py

import pygame.fontclass Button():def __init__(self,ai_settings,screen,msg):"""初始化按钮的属性"""self.screen = screenself.screen_rect = screen.get_rect()#设置按钮的尺寸和其他属性self.width,self.height = 200, 50self.button_color = (0,255,0)self.text_color = (255,255,255)self.font = 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)def prep_msg(self,msg):"""将msg渲染为图像,并使其在按钮上居中"""#msg 要渲染为图像的文本#font.render()将存储在msg中的文本转换为图像,然后存储在msg_image中,第二个实参指定是否开启反锯齿功能#反锯齿功能:让文本的边缘更平滑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.centerdef draw_button(self):#绘制一个用颜色填充的按钮,在绘制文本self.screen.fill(self.button_color,self.rect)  #h绘制按钮的矩形self.screen.blit(self.msg_image,self.msg_image_rect) #传递一幅图像与该图像关联的rect对象

1.2 在屏幕上绘制按钮

接下来我们就是用button类来创建一个play按钮,在alien_invasion.py中直接创建

import pygame
from settings import Settings
from game_stats import GameStats
from ship import Ship
from alien import Alien
import game_functions as gf
from pygame.sprite import Group
from button import Button  #导入button类def run_game():#初始化游戏并创建一个屏幕对象pygame.init()ai_settings = Settings()screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))pygame.display.set_caption("Alien Invasion")#创建Play按钮,并创建一个button实例play_button = Button(ai_settings,screen,"play") #创建一个外星人alien = Alien(ai_settings,screen)#创建一个用于存储游戏统计信息的实例stats = GameStats(ai_settings)#创建一艘非飞船ship = Ship(ai_settings,screen)#创建一个用于存储子弹的编组bullets = Group()aliens = Group()#创建外星人群gf.create_fleet(ai_settings,screen,ship,aliens)#开始游戏的主循环while True:sys.pause()#监视键盘和鼠标事件gf.check_events(ai_settings,screen,ship,bullets)if stats.game_active:ship.update()gf.update_bullets(ai_settings,screen,ship,aliens,bullets)gf.update_aliens(ai_settings,stats,screen,ship,aliens,bullets)gf.update_screen(ai_settings,screen,stats,ship,bullets,aliens,play_button)run_game()

接下来需要修改update_screen方法。
game_functions.py

import sys
import pygame
from bullet import Bullet
from alien import Alien
from time import sleepdef check_keydown_events(event,ai_settings,screen, ship,bullets):"""响应按键"""if event.key == pygame.K_RIGHT:ship.moving_right = Trueelif event.key == pygame.K_LEFT:ship.moving_left = Trueelif event.key == pygame.K_SPACE:fire_bullet(ai_settings,screen,ship,bullets)elif event.key == pygame.K_q:sys.exit(0)def check_keyup_events(event,ship):"""响应松开"""if event.key == pygame.K_RIGHT:ship.moving_right = Falseif event.key == pygame.K_LEFT:ship.moving_left = Falsedef check_events(ai_settings,screen, ship, bullets):"""响应按键和鼠标事件"""for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit(0)  #在这里的exit()中需要传递参数,他么的,竟然这么坑吗?elif event.type == pygame.KEYDOWN:check_keydown_events(event, ai_settings,screen,ship, bullets)elif event.type == pygame.KEYUP:check_keyup_events(event,ship)def update_screen(ai_settings,screen,stats,ship,bullets,aliens,play_button):"""更新屏幕上的图像,并切换到新屏幕"""#每次循环时都重绘屏幕screen.fill(ai_settings.bg_color)#在飞船和外星人后面重绘所有子弹for bullet in bullets.sprites():bullet.draw_bullet()ship.blitme()aliens.draw(screen)#如果游戏处于非活动状态,就绘制Play按钮if not stats.game_active:play_button.draw_button()#让最近绘制的屏幕可见pygame.display.flip()def update_bullets(ai_settings,screen,ship,aliens,bullets):"""更新子弹的位置,并删除已销失的子弹"""#更新子弹的位置bullets.update()#删除已销失的子弹for bullet in bullets.copy():if bullet.rect.bottom <= 0:bullets.remove(bullet)if len(bullets) != 0:print(len(bullets))#检查是否有子弹击中了外星人#如果这样,就删除相应的子弹和外星人check_bullet_alien_collisions(ai_settings,screen,ship,aliens,bullets)def check_bullet_alien_collisions(ai_settings,screen,ship,aliens,bullets):"""响应子弹和外星人的碰撞"""#删除发生碰撞的子弹和外星人collisions = pygame.sprite.groupcollide(bullets,aliens,True,True)if len(aliens) == 0:#删除现有的子弹并新建一群外星人bullets.empty()create_fleet(ai_settings,screen,ship,aliens)def fire_bullet(ai_settings,screen,ship,bullets):"""如果还没有到达限制,就发射一颗子弹"""#创建新子弹,并将其加入到编组bullets中if len(bullets) < ai_settings.bullets_allowed:new_bullet = Bullet(ai_settings,screen,ship)bullets.add(new_bullet)def get_number_aliens_x(ai_settings,alien_width):"""计算每行可容纳多少外星人"""available_space_x = ai_settings.screen_width - 2 * alien_widthnumber_alien_x = int(available_space_x / (2 * alien_width))return number_alien_xdef get_number_rows(ai_settings,ship_height,alien_height):"""计算屏幕可容纳多少行外星人"""available_space_y = (ai_settings.screen_height - (3 * alien_height) - ship_height)number_rows = int(available_space_y / (2 * alien_height))return number_rowsdef create_alien(ai_settings,screen,aliens,alien_number,row_number):"""创建一个外星人并将其加入当前行"""alien = Alien(ai_settings,screen)alien_width = alien.rect.widthalien.x = alien_width + 2 * alien_width * alien_numberalien.rect.x = alien.xalien.rect.y = alien.rect.height + 2 * alien.rect.height * row_numberaliens.add(alien)def create_fleet(ai_settings,screen,ship,aliens):"""创建外星人"""#创建一个外星人,并计算一行可容纳多少外星人#外星人间距为外星人宽度alien = Alien(ai_settings,screen)number_aliens_x = get_number_aliens_x(ai_settings,alien.rect.width)number_rows = get_number_rows(ai_settings,ship.rect.height,alien.rect.height)#创建第一行外星人for row_number in range(number_rows):for alien_number in range(number_aliens_x):create_alien(ai_settings,screen,aliens,alien_number,row_number)def update_aliens(ai_settings,ship,aliens):"""更新外星人群中所有外星人的位置"""aliens.update()#检测外星人和飞船之间的碰撞if pygame.sprite.spritescollideany(ship,aliens):print("Ship hit!!!")def check_fleet_edges(ai_settings,aliens):"""有外星人到达边缘时采取相应的措施"""for alien in aliens.sprites():if alien.check_edges():change_fleet_direction(ai_settings,aliens)breakdef change_fleet_direction(ai_settings,aliens):"""将整群外星人下移,并改变它们的方向"""for alien in aliens.sprites():alien.rect.y += ai_settings.fleet_drop_speedai_settings.fleet_direction *= -1def ship_hit(ai_settings,stats,screen,ship,aliens,bullets):"""相应被外星人撞到的飞船"""if stats.ships_left > 0:#将ships_left 减1stats.ships_left -= 1#清空外星人到列表和子弹列表aliens.empty()bullets.empty()#创建一群外星人,并将飞船放到屏幕底端中央create_fleet(ai_settings,screen,ship,aliens)ship.center_ship()#暂停sleep(0.5)sys.exit(0)else:stats.game_active = Falsedef check_aliens_bottom(ai_settings,stats,screen,ship,aliens,bullets):"""检查是否有外星人到达了屏幕底端"""screen_rect = screen.get_rect()for alien in aliens.sprites():if alien.rect.bottom >= screen_rect.bottom:#像飞船被撞到一样进行处理ship_hit(ai_settings,stats,screen,ship,aliens,bullets)breakdef update_aliens(ai_settings,stats,screen,ship,aliens,bullets):"""检查是否有外星人位于屏幕边缘,并更新整群外星人的位置"""check_fleet_edges(ai_settings,aliens)aliens.update()if pygame.sprite.spritecollideany(ship,aliens):ship_hit(ai_settings,stats,screen,ship,aliens,bullets)#检查是否有外星人到达屏幕底端check_aliens_bottom(ai_settings,stats,screen,ship,aliens,bullets)

在这里插入图片描述

1.3 开始游戏

现在屏幕上面已经有了,play按钮,但当点击play按钮开始游戏,还需添加一些代码,以监视与这个按钮相关的鼠标事件:
game_functions.py

import sys
import pygame
from bullet import Bullet
from alien import Alien
from time import sleepdef check_keydown_events(event,ai_settings,screen, ship,bullets):"""响应按键"""if event.key == pygame.K_RIGHT:ship.moving_right = Trueelif event.key == pygame.K_LEFT:ship.moving_left = Trueelif event.key == pygame.K_SPACE:fire_bullet(ai_settings,screen,ship,bullets)elif event.key == pygame.K_q:sys.exit(0)def check_keyup_events(event,ship):"""响应松开"""if event.key == pygame.K_RIGHT:ship.moving_right = Falseif event.key == pygame.K_LEFT:ship.moving_left = Falsedef check_events(ai_settings,screen, stats, play_button,ship,bullets):"""响应按键和鼠标事件"""for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit(0)  #在这里的exit()中需要传递参数,他么的,竟然这么坑吗?elif event.type == pygame.KEYDOWN:check_keydown_events(event, ai_settings,screen,ship, bullets)elif event.type == pygame.KEYUP:check_keyup_events(event,ship)elif event.type == pygame.MOUSEBUTTONDOWN:mouse_x, mouse_y = pygame.mouse.get_pos()check_play_button(stats,play_button,mouse_x,mouse_y)def check_play_button(stats,play_button,mouse_x,mouse_y):"""在玩家单击Play按钮时开始游戏"""if play_button.rect.collidepoint(mouse_x,mouse_y):stats.game_active = Truedef update_screen(ai_settings,screen,stats,ship,bullets,aliens,play_button):"""更新屏幕上的图像,并切换到新屏幕"""#每次循环时都重绘屏幕screen.fill(ai_settings.bg_color)#在飞船和外星人后面重绘所有子弹for bullet in bullets.sprites():bullet.draw_bullet()ship.blitme()aliens.draw(screen)#如果游戏处于非活动状态,就绘制Play按钮if not stats.game_active:play_button.draw_button()#让最近绘制的屏幕可见pygame.display.flip()def update_bullets(ai_settings,screen,ship,aliens,bullets):"""更新子弹的位置,并删除已销失的子弹"""#更新子弹的位置bullets.update()#删除已销失的子弹for bullet in bullets.copy():if bullet.rect.bottom <= 0:bullets.remove(bullet)if len(bullets) != 0:print(len(bullets))#检查是否有子弹击中了外星人#如果这样,就删除相应的子弹和外星人check_bullet_alien_collisions(ai_settings,screen,ship,aliens,bullets)def check_bullet_alien_collisions(ai_settings,screen,ship,aliens,bullets):"""响应子弹和外星人的碰撞"""#删除发生碰撞的子弹和外星人collisions = pygame.sprite.groupcollide(bullets,aliens,True,True)if len(aliens) == 0:#删除现有的子弹并新建一群外星人bullets.empty()create_fleet(ai_settings,screen,ship,aliens)def fire_bullet(ai_settings,screen,ship,bullets):"""如果还没有到达限制,就发射一颗子弹"""#创建新子弹,并将其加入到编组bullets中if len(bullets) < ai_settings.bullets_allowed:new_bullet = Bullet(ai_settings,screen,ship)bullets.add(new_bullet)def get_number_aliens_x(ai_settings,alien_width):"""计算每行可容纳多少外星人"""available_space_x = ai_settings.screen_width - 2 * alien_widthnumber_alien_x = int(available_space_x / (2 * alien_width))return number_alien_xdef get_number_rows(ai_settings,ship_height,alien_height):"""计算屏幕可容纳多少行外星人"""available_space_y = (ai_settings.screen_height - (3 * alien_height) - ship_height)number_rows = int(available_space_y / (2 * alien_height))return number_rowsdef create_alien(ai_settings,screen,aliens,alien_number,row_number):"""创建一个外星人并将其加入当前行"""alien = Alien(ai_settings,screen)alien_width = alien.rect.widthalien.x = alien_width + 2 * alien_width * alien_numberalien.rect.x = alien.xalien.rect.y = alien.rect.height + 2 * alien.rect.height * row_numberaliens.add(alien)def create_fleet(ai_settings,screen,ship,aliens):"""创建外星人"""#创建一个外星人,并计算一行可容纳多少外星人#外星人间距为外星人宽度alien = Alien(ai_settings,screen)number_aliens_x = get_number_aliens_x(ai_settings,alien.rect.width)number_rows = get_number_rows(ai_settings,ship.rect.height,alien.rect.height)#创建第一行外星人for row_number in range(number_rows):for alien_number in range(number_aliens_x):create_alien(ai_settings,screen,aliens,alien_number,row_number)def update_aliens(ai_settings,ship,aliens):"""更新外星人群中所有外星人的位置"""aliens.update()#检测外星人和飞船之间的碰撞if pygame.sprite.spritescollideany(ship,aliens):print("Ship hit!!!")def check_fleet_edges(ai_settings,aliens):"""有外星人到达边缘时采取相应的措施"""for alien in aliens.sprites():if alien.check_edges():change_fleet_direction(ai_settings,aliens)breakdef change_fleet_direction(ai_settings,aliens):"""将整群外星人下移,并改变它们的方向"""for alien in aliens.sprites():alien.rect.y += ai_settings.fleet_drop_speedai_settings.fleet_direction *= -1def ship_hit(ai_settings,stats,screen,ship,aliens,bullets):"""相应被外星人撞到的飞船"""if stats.ships_left > 0:#将ships_left 减1stats.ships_left -= 1#清空外星人到列表和子弹列表aliens.empty()bullets.empty()#创建一群外星人,并将飞船放到屏幕底端中央create_fleet(ai_settings,screen,ship,aliens)ship.center_ship()#暂停sleep(0.5)sys.exit(0)else:stats.game_active = Falsedef check_aliens_bottom(ai_settings,stats,screen,ship,aliens,bullets):"""检查是否有外星人到达了屏幕底端"""screen_rect = screen.get_rect()for alien in aliens.sprites():if alien.rect.bottom >= screen_rect.bottom:#像飞船被撞到一样进行处理ship_hit(ai_settings,stats,screen,ship,aliens,bullets)breakdef update_aliens(ai_settings,stats,screen,ship,aliens,bullets):"""检查是否有外星人位于屏幕边缘,并更新整群外星人的位置"""check_fleet_edges(ai_settings,aliens)aliens.update()if pygame.sprite.spritecollideany(ship,aliens):ship_hit(ai_settings,stats,screen,ship,aliens,bullets)#检查是否有外星人到达屏幕底端check_aliens_bottom(ai_settings,stats,screen,ship,aliens,bullets)

alien_invasion.py

import pygame
from settings import Settings
from game_stats import GameStats
from ship import Ship
from alien import Alien
import game_functions as gf
from pygame.sprite import Group
from button import Button  #导入button类def run_game():#初始化游戏并创建一个屏幕对象pygame.init()ai_settings = Settings()screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))pygame.display.set_caption("Alien Invasion")#创建Play按钮,并创建一个button实例play_button = Button(ai_settings,screen,"play") #创建一个外星人alien = Alien(ai_settings,screen)#创建一个用于存储游戏统计信息的实例stats = GameStats(ai_settings)#创建一艘非飞船ship = Ship(ai_settings,screen)#创建一个用于存储子弹的编组bullets = Group()aliens = Group()#创建外星人群gf.create_fleet(ai_settings,screen,ship,aliens)#开始游戏的主循环while True:#   sys.pause()#监视键盘和鼠标事件gf.check_events(ai_settings,screen,stats,play_button,ship,bullets)if stats.game_active:ship.update()gf.update_bullets(ai_settings,screen,ship,aliens,bullets)gf.update_aliens(ai_settings,stats,screen,ship,aliens,bullets)gf.update_screen(ai_settings,screen,stats,ship,bullets,aliens,play_button)run_game()

在这里插入图片描述

1.4 重置游戏

前面编写的代码只处理了玩家第一次单击Play按钮的情况,而没有处理游戏结束的情况,因为没有重置导致游戏结束的条件。
为在玩家每次单击Play按钮时都重置游戏,需要重置统计信息,删除现有的外星人和子弹,创建一群新的外星人,并让飞船居中。
game_functions.py

import sys
import pygame
from bullet import Bullet
from alien import Alien
from time import sleepdef check_keydown_events(event,ai_settings,screen, ship,bullets):"""响应按键"""if event.key == pygame.K_RIGHT:ship.moving_right = Trueelif event.key == pygame.K_LEFT:ship.moving_left = Trueelif event.key == pygame.K_SPACE:fire_bullet(ai_settings,screen,ship,bullets)elif event.key == pygame.K_q:sys.exit(0)def check_keyup_events(event,ship):"""响应松开"""if event.key == pygame.K_RIGHT:ship.moving_right = Falseif event.key == pygame.K_LEFT:ship.moving_left = Falsedef check_events(ai_settings,screen, stats, play_button,ship,aliens,bullets):"""响应按键和鼠标事件"""for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit(0)  #在这里的exit()中需要传递参数,他么的,竟然这么坑吗?elif event.type == pygame.KEYDOWN:check_keydown_events(event, ai_settings,screen,ship, bullets)elif event.type == pygame.KEYUP:check_keyup_events(event,ship)elif event.type == pygame.MOUSEBUTTONDOWN:mouse_x, mouse_y = pygame.mouse.get_pos()check_play_button(ai_settings,screen,stats,play_button,ship,aliens,bullets,mouse_x,mouse_y)def check_play_button(ai_settings,screen,stats,play_button,ship,aliens,bullets,mouse_x,mouse_y):"""在玩家单击Play按钮时开始游戏"""if play_button.rect.collidepoint(mouse_x,mouse_y):#重置游戏统计信息stats.reset_status()stats.game_active = True#清空外星人列表和子弹列表aliens.empty()bullets.empty()#创建一群新的外星人,并让飞船居中create_fleet(ai_settings,screen,ship,aliens)ship.center_ship()def update_screen(ai_settings,screen,stats,ship,bullets,aliens,play_button):"""更新屏幕上的图像,并切换到新屏幕"""#每次循环时都重绘屏幕screen.fill(ai_settings.bg_color)#在飞船和外星人后面重绘所有子弹for bullet in bullets.sprites():bullet.draw_bullet()ship.blitme()aliens.draw(screen)#如果游戏处于非活动状态,就绘制Play按钮if not stats.game_active:play_button.draw_button()#让最近绘制的屏幕可见pygame.display.flip()def update_bullets(ai_settings,screen,ship,aliens,bullets):"""更新子弹的位置,并删除已销失的子弹"""#更新子弹的位置bullets.update()#删除已销失的子弹for bullet in bullets.copy():if bullet.rect.bottom <= 0:bullets.remove(bullet)if len(bullets) != 0:print(len(bullets))#检查是否有子弹击中了外星人#如果这样,就删除相应的子弹和外星人check_bullet_alien_collisions(ai_settings,screen,ship,aliens,bullets)def check_bullet_alien_collisions(ai_settings,screen,ship,aliens,bullets):"""响应子弹和外星人的碰撞"""#删除发生碰撞的子弹和外星人collisions = pygame.sprite.groupcollide(bullets,aliens,True,True)if len(aliens) == 0:#删除现有的子弹并新建一群外星人bullets.empty()create_fleet(ai_settings,screen,ship,aliens)def fire_bullet(ai_settings,screen,ship,bullets):"""如果还没有到达限制,就发射一颗子弹"""#创建新子弹,并将其加入到编组bullets中if len(bullets) < ai_settings.bullets_allowed:new_bullet = Bullet(ai_settings,screen,ship)bullets.add(new_bullet)def get_number_aliens_x(ai_settings,alien_width):"""计算每行可容纳多少外星人"""available_space_x = ai_settings.screen_width - 2 * alien_widthnumber_alien_x = int(available_space_x / (2 * alien_width))return number_alien_xdef get_number_rows(ai_settings,ship_height,alien_height):"""计算屏幕可容纳多少行外星人"""available_space_y = (ai_settings.screen_height - (3 * alien_height) - ship_height)number_rows = int(available_space_y / (2 * alien_height))return number_rowsdef create_alien(ai_settings,screen,aliens,alien_number,row_number):"""创建一个外星人并将其加入当前行"""alien = Alien(ai_settings,screen)alien_width = alien.rect.widthalien.x = alien_width + 2 * alien_width * alien_numberalien.rect.x = alien.xalien.rect.y = alien.rect.height + 2 * alien.rect.height * row_numberaliens.add(alien)def create_fleet(ai_settings,screen,ship,aliens):"""创建外星人"""#创建一个外星人,并计算一行可容纳多少外星人#外星人间距为外星人宽度alien = Alien(ai_settings,screen)number_aliens_x = get_number_aliens_x(ai_settings,alien.rect.width)number_rows = get_number_rows(ai_settings,ship.rect.height,alien.rect.height)#创建第一行外星人for row_number in range(number_rows):for alien_number in range(number_aliens_x):create_alien(ai_settings,screen,aliens,alien_number,row_number)def update_aliens(ai_settings,ship,aliens):"""更新外星人群中所有外星人的位置"""aliens.update()#检测外星人和飞船之间的碰撞if pygame.sprite.spritescollideany(ship,aliens):print("Ship hit!!!")def check_fleet_edges(ai_settings,aliens):"""有外星人到达边缘时采取相应的措施"""for alien in aliens.sprites():if alien.check_edges():change_fleet_direction(ai_settings,aliens)breakdef change_fleet_direction(ai_settings,aliens):"""将整群外星人下移,并改变它们的方向"""for alien in aliens.sprites():alien.rect.y += ai_settings.fleet_drop_speedai_settings.fleet_direction *= -1def ship_hit(ai_settings,stats,screen,ship,aliens,bullets):"""相应被外星人撞到的飞船"""if stats.ships_left > 0:#将ships_left 减1stats.ships_left -= 1#清空外星人到列表和子弹列表aliens.empty()bullets.empty()#创建一群外星人,并将飞船放到屏幕底端中央create_fleet(ai_settings,screen,ship,aliens)ship.center_ship()#暂停sleep(0.5)sys.exit(0)else:stats.game_active = Falsedef check_aliens_bottom(ai_settings,stats,screen,ship,aliens,bullets):"""检查是否有外星人到达了屏幕底端"""screen_rect = screen.get_rect()for alien in aliens.sprites():if alien.rect.bottom >= screen_rect.bottom:#像飞船被撞到一样进行处理ship_hit(ai_settings,stats,screen,ship,aliens,bullets)breakdef update_aliens(ai_settings,stats,screen,ship,aliens,bullets):"""检查是否有外星人位于屏幕边缘,并更新整群外星人的位置"""check_fleet_edges(ai_settings,aliens)aliens.update()if pygame.sprite.spritecollideany(ship,aliens):ship_hit(ai_settings,stats,screen,ship,aliens,bullets)#检查是否有外星人到达屏幕底端check_aliens_bottom(ai_settings,stats,screen,ship,aliens,bullets)

alien_invasion.py

import pygame
from settings import Settings
from game_stats import GameStats
from ship import Ship
from alien import Alien
import game_functions as gf
from pygame.sprite import Group
from button import Button  #导入button类def run_game():#初始化游戏并创建一个屏幕对象pygame.init()ai_settings = Settings()screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))pygame.display.set_caption("Alien Invasion")#创建Play按钮,并创建一个button实例play_button = Button(ai_settings,screen,"play") #创建一个外星人alien = Alien(ai_settings,screen)#创建一个用于存储游戏统计信息的实例stats = GameStats(ai_settings)#创建一艘非飞船ship = Ship(ai_settings,screen)#创建一个用于存储子弹的编组bullets = Group()aliens = Group()#创建外星人群gf.create_fleet(ai_settings,screen,ship,aliens)#开始游戏的主循环while True:#   sys.pause()#监视键盘和鼠标事件gf.check_events(ai_settings,screen,stats,play_button,ship,aliens,bullets)if stats.game_active:ship.update()gf.update_bullets(ai_settings,screen,ship,aliens,bullets)gf.update_aliens(ai_settings,stats,screen,ship,aliens,bullets)gf.update_screen(ai_settings,screen,stats,ship,bullets,aliens,play_button)run_game()

1.5 将Play按钮切换到非活动状态

当前的play按钮存在一个问题,那就是即便Play按钮不可见,玩家单击其原来所在区域时,游戏依然会做出响应。游戏开始后,如果玩家不小心单击了Play按钮原来所处的区域,游戏将重新开始。
那怎么修改这个bug呢?我们让游戏在game_active为False时才开始:
game_functions.py

import sys
import pygame
from bullet import Bullet
from alien import Alien
from time import sleepdef check_keydown_events(event,ai_settings,screen, ship,bullets):"""响应按键"""if event.key == pygame.K_RIGHT:ship.moving_right = Trueelif event.key == pygame.K_LEFT:ship.moving_left = Trueelif event.key == pygame.K_SPACE:fire_bullet(ai_settings,screen,ship,bullets)elif event.key == pygame.K_q:sys.exit(0)def check_keyup_events(event,ship):"""响应松开"""if event.key == pygame.K_RIGHT:ship.moving_right = Falseif event.key == pygame.K_LEFT:ship.moving_left = Falsedef check_events(ai_settings,screen, stats, play_button,ship,aliens,bullets):"""响应按键和鼠标事件"""for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit(0)  #在这里的exit()中需要传递参数,他么的,竟然这么坑吗?elif event.type == pygame.KEYDOWN:check_keydown_events(event, ai_settings,screen,ship, bullets)elif event.type == pygame.KEYUP:check_keyup_events(event,ship)elif event.type == pygame.MOUSEBUTTONDOWN:mouse_x, mouse_y = pygame.mouse.get_pos()check_play_button(ai_settings,screen,stats,play_button,ship,aliens,bullets,mouse_x,mouse_y)def check_play_button(ai_settings,screen,stats,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:#隐藏光标pygame.mouse.set_visible(False)#重置游戏统计信息stats.reset_stats()stats.game_active = True#清空外星人列表和子弹列表aliens.empty()bullets.empty()#创建一群新的外星人,并让飞船居中create_fleet(ai_settings,screen,ship,aliens)ship.center_ship()def update_screen(ai_settings,screen,stats,ship,bullets,aliens,play_button):"""更新屏幕上的图像,并切换到新屏幕"""#每次循环时都重绘屏幕screen.fill(ai_settings.bg_color)#在飞船和外星人后面重绘所有子弹for bullet in bullets.sprites():bullet.draw_bullet()ship.blitme()aliens.draw(screen)#如果游戏处于非活动状态,就绘制Play按钮if not stats.game_active:play_button.draw_button()#让最近绘制的屏幕可见pygame.display.flip()def update_bullets(ai_settings,screen,ship,aliens,bullets):"""更新子弹的位置,并删除已销失的子弹"""#更新子弹的位置bullets.update()#删除已销失的子弹for bullet in bullets.copy():if bullet.rect.bottom <= 0:bullets.remove(bullet)if len(bullets) != 0:print(len(bullets))#检查是否有子弹击中了外星人#如果这样,就删除相应的子弹和外星人check_bullet_alien_collisions(ai_settings,screen,ship,aliens,bullets)def check_bullet_alien_collisions(ai_settings,screen,ship,aliens,bullets):"""响应子弹和外星人的碰撞"""#删除发生碰撞的子弹和外星人collisions = pygame.sprite.groupcollide(bullets,aliens,True,True)if len(aliens) == 0:#删除现有的子弹并新建一群外星人bullets.empty()create_fleet(ai_settings,screen,ship,aliens)def fire_bullet(ai_settings,screen,ship,bullets):"""如果还没有到达限制,就发射一颗子弹"""#创建新子弹,并将其加入到编组bullets中if len(bullets) < ai_settings.bullets_allowed:new_bullet = Bullet(ai_settings,screen,ship)bullets.add(new_bullet)def get_number_aliens_x(ai_settings,alien_width):"""计算每行可容纳多少外星人"""available_space_x = ai_settings.screen_width - 2 * alien_widthnumber_alien_x = int(available_space_x / (2 * alien_width))return number_alien_xdef get_number_rows(ai_settings,ship_height,alien_height):"""计算屏幕可容纳多少行外星人"""available_space_y = (ai_settings.screen_height - (3 * alien_height) - ship_height)number_rows = int(available_space_y / (2 * alien_height))return number_rowsdef create_alien(ai_settings,screen,aliens,alien_number,row_number):"""创建一个外星人并将其加入当前行"""alien = Alien(ai_settings,screen)alien_width = alien.rect.widthalien.x = alien_width + 2 * alien_width * alien_numberalien.rect.x = alien.xalien.rect.y = alien.rect.height + 2 * alien.rect.height * row_numberaliens.add(alien)def create_fleet(ai_settings,screen,ship,aliens):"""创建外星人"""#创建一个外星人,并计算一行可容纳多少外星人#外星人间距为外星人宽度alien = Alien(ai_settings,screen)number_aliens_x = get_number_aliens_x(ai_settings,alien.rect.width)number_rows = get_number_rows(ai_settings,ship.rect.height,alien.rect.height)#创建第一行外星人for row_number in range(number_rows):for alien_number in range(number_aliens_x):create_alien(ai_settings,screen,aliens,alien_number,row_number)def update_aliens(ai_settings,ship,aliens):"""更新外星人群中所有外星人的位置"""aliens.update()#检测外星人和飞船之间的碰撞if pygame.sprite.spritescollideany(ship,aliens):print("Ship hit!!!")def check_fleet_edges(ai_settings,aliens):"""有外星人到达边缘时采取相应的措施"""for alien in aliens.sprites():if alien.check_edges():change_fleet_direction(ai_settings,aliens)breakdef change_fleet_direction(ai_settings,aliens):"""将整群外星人下移,并改变它们的方向"""for alien in aliens.sprites():alien.rect.y += ai_settings.fleet_drop_speedai_settings.fleet_direction *= -1def ship_hit(ai_settings,stats,screen,ship,aliens,bullets):"""相应被外星人撞到的飞船"""if stats.ships_left > 0:#将ships_left 减1stats.ships_left -= 1#清空外星人到列表和子弹列表aliens.empty()bullets.empty()#创建一群外星人,并将飞船放到屏幕底端中央create_fleet(ai_settings,screen,ship,aliens)ship.center_ship()#暂停sleep(0.5)sys.exit(0)else:stats.game_active = Falsedef check_aliens_bottom(ai_settings,stats,screen,ship,aliens,bullets):"""检查是否有外星人到达了屏幕底端"""screen_rect = screen.get_rect()for alien in aliens.sprites():if alien.rect.bottom >= screen_rect.bottom:#像飞船被撞到一样进行处理ship_hit(ai_settings,stats,screen,ship,aliens,bullets)breakdef update_aliens(ai_settings,stats,screen,ship,aliens,bullets):"""检查是否有外星人位于屏幕边缘,并更新整群外星人的位置"""check_fleet_edges(ai_settings,aliens)aliens.update()if pygame.sprite.spritecollideany(ship,aliens):ship_hit(ai_settings,stats,screen,ship,aliens,bullets)#检查是否有外星人到达屏幕底端check_aliens_bottom(ai_settings,stats,screen,ship,aliens,bullets)

在这里插入图片描述

2. 提高等级

下面为游戏添加点有趣的玩法:每当玩家将屏幕上的外星人都消灭干净后,加快游戏的节奏,让游戏玩起来更难。

2.1 修改速度设置

我们首先需要重新组织settings类,将游戏设置划分成静态的和动态的两组。对于随着游戏进行而变化的设置,我们还确保它们在开始新游戏时被重置。
settings.py

class Settings():"""存储<<外星人入侵>>的所有设置的类"""def __init__(self):"""初始化游戏的设置"""#屏幕设置self.screen_width = 800self.screen_height = 600self.bg_color = (230,230,230)#飞船的设置self.ship_speed_factor = 1.5self.ship_limit = 3#子弹设置self.bullet_speed_factor = 3self.bullet_width = 3self.bullet_height = 15self.bullet_color = (60 , 60 , 60)self.bullets_allowed = 5   #将在屏幕内可以存在的子弹限制为3颗#外星人设置self.alien_speed_factor = 1self.fleet_drop_speed = 10#以什么样的速度加快游戏节奏self.speedup_scale = 1.1self.initialize_dynamic_settings()def initialize_dynamic_settings(self):"""初始化随游戏进行而变化的设置"""#该方法设置了飞船、子弹和外星人的初始速度self.ship_speed_factor = 1.5self.bullet_speed_factor = 3self.alien_speed_factor = 1#fleet_direction为1表示向右移,为-1表示向左移self.fleet_direction = 1def increase_speed(self):"""提高速度设置"""#使用该方法在玩家提高一个等级时,来提高飞船、子弹和外星人的速度self.ship_speed_factor *= self.speedup_scaleself.bullet_speed_factor *= self.speedup_scaleself.alien_speed_factor *=self.speedup_scale

game_functions.py

import sys
import pygame
from bullet import Bullet
from alien import Alien
from time import sleepdef check_keydown_events(event,ai_settings,screen, ship,bullets):"""响应按键"""if event.key == pygame.K_RIGHT:ship.moving_right = Trueelif event.key == pygame.K_LEFT:ship.moving_left = Trueelif event.key == pygame.K_SPACE:fire_bullet(ai_settings,screen,ship,bullets)elif event.key == pygame.K_q:sys.exit(0)def check_keyup_events(event,ship):"""响应松开"""if event.key == pygame.K_RIGHT:ship.moving_right = Falseif event.key == pygame.K_LEFT:ship.moving_left = Falsedef check_events(ai_settings,screen, stats, play_button,ship,aliens,bullets):"""响应按键和鼠标事件"""for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit(0)  #在这里的exit()中需要传递参数,他么的,竟然这么坑吗?elif event.type == pygame.KEYDOWN:check_keydown_events(event, ai_settings,screen,ship, bullets)elif event.type == pygame.KEYUP:check_keyup_events(event,ship)elif event.type == pygame.MOUSEBUTTONDOWN:mouse_x, mouse_y = pygame.mouse.get_pos()check_play_button(ai_settings,screen,stats,play_button,ship,aliens,bullets,mouse_x,mouse_y)def check_play_button(ai_settings,screen,stats,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:#隐藏光标pygame.mouse.set_visible(False)#重置游戏统计信息stats.reset_stats()stats.game_active = True#清空外星人列表和子弹列表aliens.empty()bullets.empty()#创建一群新的外星人,并让飞船居中create_fleet(ai_settings,screen,ship,aliens)ship.center_ship()def update_screen(ai_settings,screen,stats,ship,bullets,aliens,play_button):"""更新屏幕上的图像,并切换到新屏幕"""#每次循环时都重绘屏幕screen.fill(ai_settings.bg_color)#在飞船和外星人后面重绘所有子弹for bullet in bullets.sprites():bullet.draw_bullet()ship.blitme()aliens.draw(screen)#如果游戏处于非活动状态,就绘制Play按钮if not stats.game_active:play_button.draw_button()#让最近绘制的屏幕可见pygame.display.flip()def update_bullets(ai_settings,screen,ship,aliens,bullets):"""更新子弹的位置,并删除已销失的子弹"""#更新子弹的位置bullets.update()#删除已销失的子弹for bullet in bullets.copy():if bullet.rect.bottom <= 0:bullets.remove(bullet)if len(bullets) != 0:print(len(bullets))#检查是否有子弹击中了外星人#如果这样,就删除相应的子弹和外星人check_bullet_alien_collisions(ai_settings,screen,ship,aliens,bullets)def check_bullet_alien_collisions(ai_settings,screen,ship,aliens,bullets):"""响应子弹和外星人的碰撞"""#删除发生碰撞的子弹和外星人collisions = pygame.sprite.groupcollide(bullets,aliens,True,True)if len(aliens) == 0:#删除现有的子弹并新建一群外星人#删除现有的子弹,加快游戏节奏,并创建一群新的外星人bullets.empty()ai_settings.increase_speed()create_fleet(ai_settings,screen,ship,aliens)def fire_bullet(ai_settings,screen,ship,bullets):"""如果还没有到达限制,就发射一颗子弹"""#创建新子弹,并将其加入到编组bullets中if len(bullets) < ai_settings.bullets_allowed:new_bullet = Bullet(ai_settings,screen,ship)bullets.add(new_bullet)def get_number_aliens_x(ai_settings,alien_width):"""计算每行可容纳多少外星人"""available_space_x = ai_settings.screen_width - 2 * alien_widthnumber_alien_x = int(available_space_x / (2 * alien_width))return number_alien_xdef get_number_rows(ai_settings,ship_height,alien_height):"""计算屏幕可容纳多少行外星人"""available_space_y = (ai_settings.screen_height - (3 * alien_height) - ship_height)number_rows = int(available_space_y / (2 * alien_height))return number_rowsdef create_alien(ai_settings,screen,aliens,alien_number,row_number):"""创建一个外星人并将其加入当前行"""alien = Alien(ai_settings,screen)alien_width = alien.rect.widthalien.x = alien_width + 2 * alien_width * alien_numberalien.rect.x = alien.xalien.rect.y = alien.rect.height + 2 * alien.rect.height * row_numberaliens.add(alien)def create_fleet(ai_settings,screen,ship,aliens):"""创建外星人"""#创建一个外星人,并计算一行可容纳多少外星人#外星人间距为外星人宽度alien = Alien(ai_settings,screen)number_aliens_x = get_number_aliens_x(ai_settings,alien.rect.width)number_rows = get_number_rows(ai_settings,ship.rect.height,alien.rect.height)#创建第一行外星人for row_number in range(number_rows):for alien_number in range(number_aliens_x):create_alien(ai_settings,screen,aliens,alien_number,row_number)def update_aliens(ai_settings,ship,aliens):"""更新外星人群中所有外星人的位置"""aliens.update()#检测外星人和飞船之间的碰撞if pygame.sprite.spritescollideany(ship,aliens):print("Ship hit!!!")def check_fleet_edges(ai_settings,aliens):"""有外星人到达边缘时采取相应的措施"""for alien in aliens.sprites():if alien.check_edges():change_fleet_direction(ai_settings,aliens)breakdef change_fleet_direction(ai_settings,aliens):"""将整群外星人下移,并改变它们的方向"""for alien in aliens.sprites():alien.rect.y += ai_settings.fleet_drop_speedai_settings.fleet_direction *= -1def ship_hit(ai_settings,stats,screen,ship,aliens,bullets):"""相应被外星人撞到的飞船"""if stats.ships_left > 0:#将ships_left 减1stats.ships_left -= 1#清空外星人到列表和子弹列表aliens.empty()bullets.empty()#创建一群外星人,并将飞船放到屏幕底端中央create_fleet(ai_settings,screen,ship,aliens)ship.center_ship()#暂停sleep(0.5)sys.exit(0)else:stats.game_active = Falsepygame.mouse.set_visible(True)def check_aliens_bottom(ai_settings,stats,screen,ship,aliens,bullets):"""检查是否有外星人到达了屏幕底端"""screen_rect = screen.get_rect()for alien in aliens.sprites():if alien.rect.bottom >= screen_rect.bottom:#像飞船被撞到一样进行处理ship_hit(ai_settings,stats,screen,ship,aliens,bullets)breakdef update_aliens(ai_settings,stats,screen,ship,aliens,bullets):"""检查是否有外星人位于屏幕边缘,并更新整群外星人的位置"""check_fleet_edges(ai_settings,aliens)aliens.update()if pygame.sprite.spritecollideany(ship,aliens):ship_hit(ai_settings,stats,screen,ship,aliens,bullets)#检查是否有外星人到达屏幕底端check_aliens_bottom(ai_settings,stats,screen,ship,aliens,bullets)

2.2 重置速度

每当玩家开始新游戏时,都需要将发生了变化的设置重置为初始值,否则新游戏开始时,速度设置将是前一次游戏增加了的值:
game_functions.py

import sys
import pygame
from bullet import Bullet
from alien import Alien
from time import sleepdef check_keydown_events(event,ai_settings,screen, ship,bullets):"""响应按键"""if event.key == pygame.K_RIGHT:ship.moving_right = Trueelif event.key == pygame.K_LEFT:ship.moving_left = Trueelif event.key == pygame.K_SPACE:fire_bullet(ai_settings,screen,ship,bullets)elif event.key == pygame.K_q:sys.exit(0)def check_keyup_events(event,ship):"""响应松开"""if event.key == pygame.K_RIGHT:ship.moving_right = Falseif event.key == pygame.K_LEFT:ship.moving_left = Falsedef check_events(ai_settings,screen, stats, play_button,ship,aliens,bullets):"""响应按键和鼠标事件"""for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit(0)  #在这里的exit()中需要传递参数,他么的,竟然这么坑吗?elif event.type == pygame.KEYDOWN:check_keydown_events(event, ai_settings,screen,ship, bullets)elif event.type == pygame.KEYUP:check_keyup_events(event,ship)elif event.type == pygame.MOUSEBUTTONDOWN:mouse_x, mouse_y = pygame.mouse.get_pos()check_play_button(ai_settings,screen,stats,play_button,ship,aliens,bullets,mouse_x,mouse_y)def check_play_button(ai_settings,screen,stats,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:#重置游戏设置ai_settings.initialize_dynamic_settings()#隐藏光标pygame.mouse.set_visible(False)#重置游戏统计信息stats.reset_stats()stats.game_active = True#清空外星人列表和子弹列表aliens.empty()bullets.empty()#创建一群新的外星人,并让飞船居中create_fleet(ai_settings,screen,ship,aliens)ship.center_ship()def update_screen(ai_settings,screen,stats,ship,bullets,aliens,play_button):"""更新屏幕上的图像,并切换到新屏幕"""#每次循环时都重绘屏幕screen.fill(ai_settings.bg_color)#在飞船和外星人后面重绘所有子弹for bullet in bullets.sprites():bullet.draw_bullet()ship.blitme()aliens.draw(screen)#如果游戏处于非活动状态,就绘制Play按钮if not stats.game_active:play_button.draw_button()#让最近绘制的屏幕可见pygame.display.flip()def update_bullets(ai_settings,screen,ship,aliens,bullets):"""更新子弹的位置,并删除已销失的子弹"""#更新子弹的位置bullets.update()#删除已销失的子弹for bullet in bullets.copy():if bullet.rect.bottom <= 0:bullets.remove(bullet)if len(bullets) != 0:print(len(bullets))#检查是否有子弹击中了外星人#如果这样,就删除相应的子弹和外星人check_bullet_alien_collisions(ai_settings,screen,ship,aliens,bullets)def check_bullet_alien_collisions(ai_settings,screen,ship,aliens,bullets):"""响应子弹和外星人的碰撞"""#删除发生碰撞的子弹和外星人collisions = pygame.sprite.groupcollide(bullets,aliens,True,True)if len(aliens) == 0:#删除现有的子弹并新建一群外星人#删除现有的子弹,加快游戏节奏,并创建一群新的外星人bullets.empty()ai_settings.increase_speed()create_fleet(ai_settings,screen,ship,aliens)def fire_bullet(ai_settings,screen,ship,bullets):"""如果还没有到达限制,就发射一颗子弹"""#创建新子弹,并将其加入到编组bullets中if len(bullets) < ai_settings.bullets_allowed:new_bullet = Bullet(ai_settings,screen,ship)bullets.add(new_bullet)def get_number_aliens_x(ai_settings,alien_width):"""计算每行可容纳多少外星人"""available_space_x = ai_settings.screen_width - 2 * alien_widthnumber_alien_x = int(available_space_x / (2 * alien_width))return number_alien_xdef get_number_rows(ai_settings,ship_height,alien_height):"""计算屏幕可容纳多少行外星人"""available_space_y = (ai_settings.screen_height - (3 * alien_height) - ship_height)number_rows = int(available_space_y / (2 * alien_height))return number_rowsdef create_alien(ai_settings,screen,aliens,alien_number,row_number):"""创建一个外星人并将其加入当前行"""alien = Alien(ai_settings,screen)alien_width = alien.rect.widthalien.x = alien_width + 2 * alien_width * alien_numberalien.rect.x = alien.xalien.rect.y = alien.rect.height + 2 * alien.rect.height * row_numberaliens.add(alien)def create_fleet(ai_settings,screen,ship,aliens):"""创建外星人"""#创建一个外星人,并计算一行可容纳多少外星人#外星人间距为外星人宽度alien = Alien(ai_settings,screen)number_aliens_x = get_number_aliens_x(ai_settings,alien.rect.width)number_rows = get_number_rows(ai_settings,ship.rect.height,alien.rect.height)#创建第一行外星人for row_number in range(number_rows):for alien_number in range(number_aliens_x):create_alien(ai_settings,screen,aliens,alien_number,row_number)def update_aliens(ai_settings,ship,aliens):"""更新外星人群中所有外星人的位置"""aliens.update()#检测外星人和飞船之间的碰撞if pygame.sprite.spritescollideany(ship,aliens):print("Ship hit!!!")def check_fleet_edges(ai_settings,aliens):"""有外星人到达边缘时采取相应的措施"""for alien in aliens.sprites():if alien.check_edges():change_fleet_direction(ai_settings,aliens)breakdef change_fleet_direction(ai_settings,aliens):"""将整群外星人下移,并改变它们的方向"""for alien in aliens.sprites():alien.rect.y += ai_settings.fleet_drop_speedai_settings.fleet_direction *= -1def ship_hit(ai_settings,stats,screen,ship,aliens,bullets):"""相应被外星人撞到的飞船"""if stats.ships_left > 0:#将ships_left 减1stats.ships_left -= 1#清空外星人到列表和子弹列表aliens.empty()bullets.empty()#创建一群外星人,并将飞船放到屏幕底端中央create_fleet(ai_settings,screen,ship,aliens)ship.center_ship()#暂停sleep(0.5)sys.exit(0)else:stats.game_active = Falsepygame.mouse.set_visible(True)def check_aliens_bottom(ai_settings,stats,screen,ship,aliens,bullets):"""检查是否有外星人到达了屏幕底端"""screen_rect = screen.get_rect()for alien in aliens.sprites():if alien.rect.bottom >= screen_rect.bottom:#像飞船被撞到一样进行处理ship_hit(ai_settings,stats,screen,ship,aliens,bullets)breakdef update_aliens(ai_settings,stats,screen,ship,aliens,bullets):"""检查是否有外星人位于屏幕边缘,并更新整群外星人的位置"""check_fleet_edges(ai_settings,aliens)aliens.update()if pygame.sprite.spritecollideany(ship,aliens):ship_hit(ai_settings,stats,screen,ship,aliens,bullets)#检查是否有外星人到达屏幕底端check_aliens_bottom(ai_settings,stats,screen,ship,aliens,bullets)

然后我们运行程序后,就会发现,随着消灭的外星人越多,游戏的节奏越来越快,也越来越紧张…

3 记分

下面为游戏添加一个计分系统,来实时地跟踪玩家的得分,并显示最高得分、当前等级和余下的飞船数。
得分是游戏的一项统计信息,因此我们在GameStats中添加一个score属性:
game_stats.py

class GameStats():"""跟踪游戏的统计信息"""def __init__(self,ai_settings):"""初始化统计信息"""self.ai_settings = ai_settingsself.reset_stats()#游戏刚开始处于非活动状态self.game_active = Falsedef reset_stats(self):"""初始化在游戏运行期间可能变化的统计信息"""self.ships_left = self.ai_settings.ship_limitself.score = 0

3.1 显示得分

为了在屏幕上显示得分,我们创建一个新类Scoreboard,保存在scoreboard.py中:
scoreboard.py

import pygame.fontclass Scoreboard():"""显示得分信息的类"""def __init__(self,ai_settings,screen,stats):"""初始化显示得分涉及的属性"""self.screen  = screenself.screen_rect = screen.get_rect()self.ai_settings = ai_settingsself.stats = stats#显示得分信息时使用的字体设置self.text_color = (30,30,30)self.font = pygame.font.SysFont(None,48)#准备初始得分图像self.prep_score()def prep_score(self):"""将得分转换为一副渲染的图像"""score_str = str(self.stats.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 - 20self.score_rect.top = 20def show_score(self):"""在屏幕上显示得分"""#这个方法把得分图像显示在屏幕上self.screen.blit(self.score_image,self.score_rect)

3.2 创建记分牌

为显示得分,我们在alien_invasion.py中创建一个Scoreboard实例:
alien_invasion.py

import pygame
from settings import Settings
from game_stats import GameStats
from ship import Ship
from alien import Alien
import game_functions as gf
from pygame.sprite import Group
from button import Button  #导入button类
from scoreboard import Scoreboarddef run_game():#初始化游戏并创建一个屏幕对象pygame.init()ai_settings = Settings()screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))pygame.display.set_caption("Alien Invasion")#创建Play按钮,并创建一个button实例play_button = Button(ai_settings,screen,"play") #创建一个外星人alien = Alien(ai_settings,screen)#创建一个用于存储游戏统计信息的实例,并创建记分牌stats = GameStats(ai_settings)sb = Scoreboard(ai_settings,screen,stats)#创建一艘非飞船ship = Ship(ai_settings,screen)#创建一个用于存储子弹的编组bullets = Group()aliens = Group()#创建外星人群gf.create_fleet(ai_settings,screen,ship,aliens)#开始游戏的主循环while True:#   sys.pause()#监视键盘和鼠标事件gf.check_events(ai_settings,screen,stats,play_button,ship,aliens,bullets)if stats.game_active:ship.update()gf.update_bullets(ai_settings,screen,ship,aliens,bullets)gf.update_aliens(ai_settings,stats,screen,ship,aliens,bullets)gf.update_screen(ai_settings,screen,stats,sb,ship,bullets,aliens,play_button)run_game()

还需要修改update_screen()
game_functions.py

import sys
import pygame
from bullet import Bullet
from alien import Alien
from time import sleepdef check_keydown_events(event,ai_settings,screen, ship,bullets):"""响应按键"""if event.key == pygame.K_RIGHT:ship.moving_right = Trueelif event.key == pygame.K_LEFT:ship.moving_left = Trueelif event.key == pygame.K_SPACE:fire_bullet(ai_settings,screen,ship,bullets)elif event.key == pygame.K_q:sys.exit(0)def check_keyup_events(event,ship):"""响应松开"""if event.key == pygame.K_RIGHT:ship.moving_right = Falseif event.key == pygame.K_LEFT:ship.moving_left = Falsedef check_events(ai_settings,screen, stats, play_button,ship,aliens,bullets):"""响应按键和鼠标事件"""for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit(0)  #在这里的exit()中需要传递参数,他么的,竟然这么坑吗?elif event.type == pygame.KEYDOWN:check_keydown_events(event, ai_settings,screen,ship, bullets)elif event.type == pygame.KEYUP:check_keyup_events(event,ship)elif event.type == pygame.MOUSEBUTTONDOWN:mouse_x, mouse_y = pygame.mouse.get_pos()check_play_button(ai_settings,screen,stats,play_button,ship,aliens,bullets,mouse_x,mouse_y)def check_play_button(ai_settings,screen,stats,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:#重置游戏设置ai_settings.initialize_dynamic_settings()#隐藏光标pygame.mouse.set_visible(False)#重置游戏统计信息stats.reset_stats()stats.game_active = True#清空外星人列表和子弹列表aliens.empty()bullets.empty()#创建一群新的外星人,并让飞船居中create_fleet(ai_settings,screen,ship,aliens)ship.center_ship()def update_screen(ai_settings,screen,stats,sb,ship,bullets,aliens,play_button):"""更新屏幕上的图像,并切换到新屏幕"""#每次循环时都重绘屏幕screen.fill(ai_settings.bg_color)#在飞船和外星人后面重绘所有子弹for bullet in bullets.sprites():bullet.draw_bullet()ship.blitme()aliens.draw(screen)#显示得分sb.show_score()#如果游戏处于非活动状态,就绘制Play按钮if not stats.game_active:play_button.draw_button()#让最近绘制的屏幕可见pygame.display.flip()def update_bullets(ai_settings,screen,ship,aliens,bullets):"""更新子弹的位置,并删除已销失的子弹"""#更新子弹的位置bullets.update()#删除已销失的子弹for bullet in bullets.copy():if bullet.rect.bottom <= 0:bullets.remove(bullet)if len(bullets) != 0:print(len(bullets))#检查是否有子弹击中了外星人#如果这样,就删除相应的子弹和外星人check_bullet_alien_collisions(ai_settings,screen,ship,aliens,bullets)def check_bullet_alien_collisions(ai_settings,screen,ship,aliens,bullets):"""响应子弹和外星人的碰撞"""#删除发生碰撞的子弹和外星人collisions = pygame.sprite.groupcollide(bullets,aliens,True,True)if len(aliens) == 0:#删除现有的子弹并新建一群外星人#删除现有的子弹,加快游戏节奏,并创建一群新的外星人bullets.empty()ai_settings.increase_speed()create_fleet(ai_settings,screen,ship,aliens)def fire_bullet(ai_settings,screen,ship,bullets):"""如果还没有到达限制,就发射一颗子弹"""#创建新子弹,并将其加入到编组bullets中if len(bullets) < ai_settings.bullets_allowed:new_bullet = Bullet(ai_settings,screen,ship)bullets.add(new_bullet)def get_number_aliens_x(ai_settings,alien_width):"""计算每行可容纳多少外星人"""available_space_x = ai_settings.screen_width - 2 * alien_widthnumber_alien_x = int(available_space_x / (2 * alien_width))return number_alien_xdef get_number_rows(ai_settings,ship_height,alien_height):"""计算屏幕可容纳多少行外星人"""available_space_y = (ai_settings.screen_height - (3 * alien_height) - ship_height)number_rows = int(available_space_y / (2 * alien_height))return number_rowsdef create_alien(ai_settings,screen,aliens,alien_number,row_number):"""创建一个外星人并将其加入当前行"""alien = Alien(ai_settings,screen)alien_width = alien.rect.widthalien.x = alien_width + 2 * alien_width * alien_numberalien.rect.x = alien.xalien.rect.y = alien.rect.height + 2 * alien.rect.height * row_numberaliens.add(alien)def create_fleet(ai_settings,screen,ship,aliens):"""创建外星人"""#创建一个外星人,并计算一行可容纳多少外星人#外星人间距为外星人宽度alien = Alien(ai_settings,screen)number_aliens_x = get_number_aliens_x(ai_settings,alien.rect.width)number_rows = get_number_rows(ai_settings,ship.rect.height,alien.rect.height)#创建第一行外星人for row_number in range(number_rows):for alien_number in range(number_aliens_x):create_alien(ai_settings,screen,aliens,alien_number,row_number)def update_aliens(ai_settings,ship,aliens):"""更新外星人群中所有外星人的位置"""aliens.update()#检测外星人和飞船之间的碰撞if pygame.sprite.spritescollideany(ship,aliens):print("Ship hit!!!")def check_fleet_edges(ai_settings,aliens):"""有外星人到达边缘时采取相应的措施"""for alien in aliens.sprites():if alien.check_edges():change_fleet_direction(ai_settings,aliens)breakdef change_fleet_direction(ai_settings,aliens):"""将整群外星人下移,并改变它们的方向"""for alien in aliens.sprites():alien.rect.y += ai_settings.fleet_drop_speedai_settings.fleet_direction *= -1def ship_hit(ai_settings,stats,screen,ship,aliens,bullets):"""相应被外星人撞到的飞船"""if stats.ships_left > 0:#将ships_left 减1stats.ships_left -= 1#清空外星人到列表和子弹列表aliens.empty()bullets.empty()#创建一群外星人,并将飞船放到屏幕底端中央create_fleet(ai_settings,screen,ship,aliens)ship.center_ship()#暂停sleep(0.5)sys.exit(0)else:stats.game_active = Falsepygame.mouse.set_visible(True)def check_aliens_bottom(ai_settings,stats,screen,ship,aliens,bullets):"""检查是否有外星人到达了屏幕底端"""screen_rect = screen.get_rect()for alien in aliens.sprites():if alien.rect.bottom >= screen_rect.bottom:#像飞船被撞到一样进行处理ship_hit(ai_settings,stats,screen,ship,aliens,bullets)breakdef update_aliens(ai_settings,stats,screen,ship,aliens,bullets):"""检查是否有外星人位于屏幕边缘,并更新整群外星人的位置"""check_fleet_edges(ai_settings,aliens)aliens.update()if pygame.sprite.spritecollideany(ship,aliens):ship_hit(ai_settings,stats,screen,ship,aliens,bullets)#检查是否有外星人到达屏幕底端check_aliens_bottom(ai_settings,stats,screen,ship,aliens,bullets)

在这里插入图片描述
运行游戏发现屏幕右上角显示0.

3.3 在外星人被消灭时更新得分

为在屏幕上实时地显示得分,每当有外星人被击中时,我们都更新stats.score的值,在调用prep_score()更新得分图像。
settings.py

class Settings():"""存储<<外星人入侵>>的所有设置的类"""def __init__(self):"""初始化游戏的设置"""#屏幕设置self.screen_width = 800self.screen_height = 600self.bg_color = (230,230,230)#飞船的设置self.ship_speed_factor = 1.5self.ship_limit = 3#子弹设置self.bullet_speed_factor = 3self.bullet_width = 3self.bullet_height = 15self.bullet_color = (60 , 60 , 60)self.bullets_allowed = 5   #将在屏幕内可以存在的子弹限制为3颗#外星人设置self.alien_speed_factor = 1self.fleet_drop_speed = 10#以什么样的速度加快游戏节奏self.speedup_scale = 1.1self.initialize_dynamic_settings()def initialize_dynamic_settings(self):"""初始化随游戏进行而变化的设置"""#该方法设置了飞船、子弹和外星人的初始速度self.ship_speed_factor = 1.5self.bullet_speed_factor = 3self.alien_speed_factor = 1#fleet_direction为1表示向右移,为-1表示向左移self.fleet_direction = 1#计分self.alien_points = 50def increase_speed(self):"""提高速度设置"""#使用该方法在玩家提高一个等级时,来提高飞船、子弹和外星人的速度self.ship_speed_factor *= self.speedup_scaleself.bullet_speed_factor *= self.speedup_scaleself.alien_speed_factor *=self.speedup_scale

也就是每击落一个外星人得50分。
在check_bullet_alien_collisions()中,每当有外星人被击落时,都更新得分:
game_functions.py

import sys
import pygame
from bullet import Bullet
from alien import Alien
from time import sleepdef check_keydown_events(event,ai_settings,screen, ship,bullets):"""响应按键"""if event.key == pygame.K_RIGHT:ship.moving_right = Trueelif event.key == pygame.K_LEFT:ship.moving_left = Trueelif event.key == pygame.K_SPACE:fire_bullet(ai_settings,screen,ship,bullets)elif event.key == pygame.K_q:sys.exit(0)def check_keyup_events(event,ship):"""响应松开"""if event.key == pygame.K_RIGHT:ship.moving_right = Falseif event.key == pygame.K_LEFT:ship.moving_left = Falsedef check_events(ai_settings,screen, stats, play_button,ship,aliens,bullets):"""响应按键和鼠标事件"""for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit(0)  #在这里的exit()中需要传递参数,他么的,竟然这么坑吗?elif event.type == pygame.KEYDOWN:check_keydown_events(event, ai_settings,screen,ship, bullets)elif event.type == pygame.KEYUP:check_keyup_events(event,ship)elif event.type == pygame.MOUSEBUTTONDOWN:mouse_x, mouse_y = pygame.mouse.get_pos()check_play_button(ai_settings,screen,stats,play_button,ship,aliens,bullets,mouse_x,mouse_y)def check_play_button(ai_settings,screen,stats,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:#重置游戏设置ai_settings.initialize_dynamic_settings()#隐藏光标pygame.mouse.set_visible(False)#重置游戏统计信息stats.reset_stats()stats.game_active = True#清空外星人列表和子弹列表aliens.empty()bullets.empty()#创建一群新的外星人,并让飞船居中create_fleet(ai_settings,screen,ship,aliens)ship.center_ship()def update_screen(ai_settings,screen,stats,sb,ship,bullets,aliens,play_button):"""更新屏幕上的图像,并切换到新屏幕"""#每次循环时都重绘屏幕screen.fill(ai_settings.bg_color)#在飞船和外星人后面重绘所有子弹for bullet in bullets.sprites():bullet.draw_bullet()ship.blitme()aliens.draw(screen)#显示得分sb.show_score()#如果游戏处于非活动状态,就绘制Play按钮if not stats.game_active:play_button.draw_button()#让最近绘制的屏幕可见pygame.display.flip()def update_bullets(ai_settings,screen,ship,aliens,bullets):"""更新子弹的位置,并删除已销失的子弹"""#更新子弹的位置bullets.update()#删除已销失的子弹for bullet in bullets.copy():if bullet.rect.bottom <= 0:bullets.remove(bullet)if len(bullets) != 0:print(len(bullets))#检查是否有子弹击中了外星人#如果这样,就删除相应的子弹和外星人check_bullet_alien_collisions(ai_settings,screen,stats,sb,ship,aliens,bullets)def check_bullet_alien_collisions(ai_settings,screen,stats,sb,ship,aliens,bullets):"""响应子弹和外星人的碰撞"""#删除发生碰撞的子弹和外星人collisions = pygame.sprite.groupcollide(bullets,aliens,True,True)if collisions:stats.score += ai_settings.alien_pointssb.prep_score()if len(aliens) == 0:#删除现有的子弹并新建一群外星人#删除现有的子弹,加快游戏节奏,并创建一群新的外星人bullets.empty()ai_settings.increase_speed()create_fleet(ai_settings,screen,ship,aliens)def fire_bullet(ai_settings,screen,ship,bullets):"""如果还没有到达限制,就发射一颗子弹"""#创建新子弹,并将其加入到编组bullets中if len(bullets) < ai_settings.bullets_allowed:new_bullet = Bullet(ai_settings,screen,ship)bullets.add(new_bullet)def get_number_aliens_x(ai_settings,alien_width):"""计算每行可容纳多少外星人"""available_space_x = ai_settings.screen_width - 2 * alien_widthnumber_alien_x = int(available_space_x / (2 * alien_width))return number_alien_xdef get_number_rows(ai_settings,ship_height,alien_height):"""计算屏幕可容纳多少行外星人"""available_space_y = (ai_settings.screen_height - (3 * alien_height) - ship_height)number_rows = int(available_space_y / (2 * alien_height))return number_rowsdef create_alien(ai_settings,screen,aliens,alien_number,row_number):"""创建一个外星人并将其加入当前行"""alien = Alien(ai_settings,screen)alien_width = alien.rect.widthalien.x = alien_width + 2 * alien_width * alien_numberalien.rect.x = alien.xalien.rect.y = alien.rect.height + 2 * alien.rect.height * row_numberaliens.add(alien)def create_fleet(ai_settings,screen,ship,aliens):"""创建外星人"""#创建一个外星人,并计算一行可容纳多少外星人#外星人间距为外星人宽度alien = Alien(ai_settings,screen)number_aliens_x = get_number_aliens_x(ai_settings,alien.rect.width)number_rows = get_number_rows(ai_settings,ship.rect.height,alien.rect.height)#创建第一行外星人for row_number in range(number_rows):for alien_number in range(number_aliens_x):create_alien(ai_settings,screen,aliens,alien_number,row_number)def update_aliens(ai_settings,ship,aliens):"""更新外星人群中所有外星人的位置"""aliens.update()#检测外星人和飞船之间的碰撞if pygame.sprite.spritescollideany(ship,aliens):print("Ship hit!!!")def check_fleet_edges(ai_settings,aliens):"""有外星人到达边缘时采取相应的措施"""for alien in aliens.sprites():if alien.check_edges():change_fleet_direction(ai_settings,aliens)breakdef change_fleet_direction(ai_settings,aliens):"""将整群外星人下移,并改变它们的方向"""for alien in aliens.sprites():alien.rect.y += ai_settings.fleet_drop_speedai_settings.fleet_direction *= -1def ship_hit(ai_settings,stats,screen,ship,aliens,bullets):"""相应被外星人撞到的飞船"""if stats.ships_left > 0:#将ships_left 减1stats.ships_left -= 1#清空外星人到列表和子弹列表aliens.empty()bullets.empty()#创建一群外星人,并将飞船放到屏幕底端中央create_fleet(ai_settings,screen,ship,aliens)ship.center_ship()#暂停sleep(0.5)sys.exit(0)else:stats.game_active = Falsepygame.mouse.set_visible(True)def check_aliens_bottom(ai_settings,stats,screen,ship,aliens,bullets):"""检查是否有外星人到达了屏幕底端"""screen_rect = screen.get_rect()for alien in aliens.sprites():if alien.rect.bottom >= screen_rect.bottom:#像飞船被撞到一样进行处理ship_hit(ai_settings,stats,screen,ship,aliens,bullets)breakdef update_aliens(ai_settings,stats,screen,ship,aliens,bullets):"""检查是否有外星人位于屏幕边缘,并更新整群外星人的位置"""check_fleet_edges(ai_settings,aliens)aliens.update()if pygame.sprite.spritecollideany(ship,aliens):ship_hit(ai_settings,stats,screen,ship,aliens,bullets)#检查是否有外星人到达屏幕底端check_aliens_bottom(ai_settings,stats,screen,ship,aliens,bullets)

有子弹撞到外星人时,Pygame返回一个字典(collisions)。然后检查这个字典是否存在,如果存在,就将得分加上一个外星人值的点数,接下来调用prep_score()来创建一副显示最新得分的新图像。
game_functions.py

import sys
import pygame
from bullet import Bullet
from alien import Alien
from time import sleepdef check_keydown_events(event,ai_settings,screen, ship,bullets):"""响应按键"""if event.key == pygame.K_RIGHT:ship.moving_right = Trueelif event.key == pygame.K_LEFT:ship.moving_left = Trueelif event.key == pygame.K_SPACE:fire_bullet(ai_settings,screen,ship,bullets)elif event.key == pygame.K_q:sys.exit(0)def check_keyup_events(event,ship):"""响应松开"""if event.key == pygame.K_RIGHT:ship.moving_right = Falseif event.key == pygame.K_LEFT:ship.moving_left = Falsedef check_events(ai_settings,screen, stats, play_button,ship,aliens,bullets):"""响应按键和鼠标事件"""for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit(0)  #在这里的exit()中需要传递参数,他么的,竟然这么坑吗?elif event.type == pygame.KEYDOWN:check_keydown_events(event, ai_settings,screen,ship, bullets)elif event.type == pygame.KEYUP:check_keyup_events(event,ship)elif event.type == pygame.MOUSEBUTTONDOWN:mouse_x, mouse_y = pygame.mouse.get_pos()check_play_button(ai_settings,screen,stats,play_button,ship,aliens,bullets,mouse_x,mouse_y)def check_play_button(ai_settings,screen,stats,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:#重置游戏设置ai_settings.initialize_dynamic_settings()#隐藏光标pygame.mouse.set_visible(False)#重置游戏统计信息stats.reset_stats()stats.game_active = True#清空外星人列表和子弹列表aliens.empty()bullets.empty()#创建一群新的外星人,并让飞船居中create_fleet(ai_settings,screen,ship,aliens)ship.center_ship()def update_screen(ai_settings,screen,stats,sb,ship,bullets,aliens,play_button):"""更新屏幕上的图像,并切换到新屏幕"""#每次循环时都重绘屏幕screen.fill(ai_settings.bg_color)#在飞船和外星人后面重绘所有子弹for bullet in bullets.sprites():bullet.draw_bullet()ship.blitme()aliens.draw(screen)#显示得分sb.show_score()#如果游戏处于非活动状态,就绘制Play按钮if not stats.game_active:play_button.draw_button()#让最近绘制的屏幕可见pygame.display.flip()def update_bullets(ai_settings,screen,stats,sb,ship,aliens,bullets):"""更新子弹的位置,并删除已销失的子弹"""#更新子弹的位置bullets.update()#删除已销失的子弹for bullet in bullets.copy():if bullet.rect.bottom <= 0:bullets.remove(bullet)if len(bullets) != 0:print(len(bullets))#检查是否有子弹击中了外星人#如果这样,就删除相应的子弹和外星人check_bullet_alien_collisions(ai_settings,screen,stats,sb,ship,aliens,bullets)def check_bullet_alien_collisions(ai_settings,screen,stats,sb,ship,aliens,bullets):"""响应子弹和外星人的碰撞"""#删除发生碰撞的子弹和外星人collisions = pygame.sprite.groupcollide(bullets,aliens,True,True)if collisions:stats.score += ai_settings.alien_pointssb.prep_score()if len(aliens) == 0:#删除现有的子弹并新建一群外星人#删除现有的子弹,加快游戏节奏,并创建一群新的外星人bullets.empty()ai_settings.increase_speed()create_fleet(ai_settings,screen,ship,aliens)def fire_bullet(ai_settings,screen,ship,bullets):"""如果还没有到达限制,就发射一颗子弹"""#创建新子弹,并将其加入到编组bullets中if len(bullets) < ai_settings.bullets_allowed:new_bullet = Bullet(ai_settings,screen,ship)bullets.add(new_bullet)def get_number_aliens_x(ai_settings,alien_width):"""计算每行可容纳多少外星人"""available_space_x = ai_settings.screen_width - 2 * alien_widthnumber_alien_x = int(available_space_x / (2 * alien_width))return number_alien_xdef get_number_rows(ai_settings,ship_height,alien_height):"""计算屏幕可容纳多少行外星人"""available_space_y = (ai_settings.screen_height - (3 * alien_height) - ship_height)number_rows = int(available_space_y / (2 * alien_height))return number_rowsdef create_alien(ai_settings,screen,aliens,alien_number,row_number):"""创建一个外星人并将其加入当前行"""alien = Alien(ai_settings,screen)alien_width = alien.rect.widthalien.x = alien_width + 2 * alien_width * alien_numberalien.rect.x = alien.xalien.rect.y = alien.rect.height + 2 * alien.rect.height * row_numberaliens.add(alien)def create_fleet(ai_settings,screen,ship,aliens):"""创建外星人"""#创建一个外星人,并计算一行可容纳多少外星人#外星人间距为外星人宽度alien = Alien(ai_settings,screen)number_aliens_x = get_number_aliens_x(ai_settings,alien.rect.width)number_rows = get_number_rows(ai_settings,ship.rect.height,alien.rect.height)#创建第一行外星人for row_number in range(number_rows):for alien_number in range(number_aliens_x):create_alien(ai_settings,screen,aliens,alien_number,row_number)def update_aliens(ai_settings,ship,aliens):"""更新外星人群中所有外星人的位置"""aliens.update()#检测外星人和飞船之间的碰撞if pygame.sprite.spritescollideany(ship,aliens):print("Ship hit!!!")def check_fleet_edges(ai_settings,aliens):"""有外星人到达边缘时采取相应的措施"""for alien in aliens.sprites():if alien.check_edges():change_fleet_direction(ai_settings,aliens)breakdef change_fleet_direction(ai_settings,aliens):"""将整群外星人下移,并改变它们的方向"""for alien in aliens.sprites():alien.rect.y += ai_settings.fleet_drop_speedai_settings.fleet_direction *= -1def ship_hit(ai_settings,stats,screen,ship,aliens,bullets):"""相应被外星人撞到的飞船"""if stats.ships_left > 0:#将ships_left 减1stats.ships_left -= 1#清空外星人到列表和子弹列表aliens.empty()bullets.empty()#创建一群外星人,并将飞船放到屏幕底端中央create_fleet(ai_settings,screen,ship,aliens)ship.center_ship()#暂停sleep(0.5)sys.exit(0)else:stats.game_active = Falsepygame.mouse.set_visible(True)def check_aliens_bottom(ai_settings,stats,screen,ship,aliens,bullets):"""检查是否有外星人到达了屏幕底端"""screen_rect = screen.get_rect()for alien in aliens.sprites():if alien.rect.bottom >= screen_rect.bottom:#像飞船被撞到一样进行处理ship_hit(ai_settings,stats,screen,ship,aliens,bullets)breakdef update_aliens(ai_settings,stats,screen,ship,aliens,bullets):"""检查是否有外星人位于屏幕边缘,并更新整群外星人的位置"""check_fleet_edges(ai_settings,aliens)aliens.update()if pygame.sprite.spritecollideany(ship,aliens):ship_hit(ai_settings,stats,screen,ship,aliens,bullets)#检查是否有外星人到达屏幕底端check_aliens_bottom(ai_settings,stats,screen,ship,aliens,bullets)

alien_invasion.py中也应该更新:

import pygame
from settings import Settings
from game_stats import GameStats
from ship import Ship
from alien import Alien
import game_functions as gf
from pygame.sprite import Group
from button import Button  #导入button类
from scoreboard import Scoreboarddef run_game():#初始化游戏并创建一个屏幕对象pygame.init()ai_settings = Settings()screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))pygame.display.set_caption("Alien Invasion")#创建Play按钮,并创建一个button实例play_button = Button(ai_settings,screen,"play") #创建一个外星人alien = Alien(ai_settings,screen)#创建一个用于存储游戏统计信息的实例,并创建记分牌stats = GameStats(ai_settings)sb = Scoreboard(ai_settings,screen,stats)#创建一艘非飞船ship = Ship(ai_settings,screen)#创建一个用于存储子弹的编组bullets = Group()aliens = Group()#创建外星人群gf.create_fleet(ai_settings,screen,ship,aliens)#开始游戏的主循环while True:#   sys.pause()#监视键盘和鼠标事件gf.check_events(ai_settings,screen,stats,play_button,ship,aliens,bullets)if stats.game_active:ship.update()gf.update_bullets(ai_settings,screen,stats,sb,ship,aliens,bullets)gf.update_aliens(ai_settings,stats,screen,ship,aliens,bullets)gf.update_screen(ai_settings,screen,stats,sb,ship,bullets,aliens,play_button)run_game()

在这里插入图片描述

3.4 将消灭的每个外星人的点数都计入得分

目前的计分值会遗漏被消灭的外星人。为了解决这个bug,我们来调整检测子弹和外星人碰撞的方式。
在check_bullet_alien_collisions()中,与外星人碰撞的子弹是字典collisions中的一个键;而与每颗子弹相关的值都是一个列表,其中包含该子弹撞到的外星人。我们遍历字典collisions,确保将消灭的每个外星人的点数都计入得分:
game_functions.py

import sys
import pygame
from bullet import Bullet
from alien import Alien
from time import sleepdef check_keydown_events(event,ai_settings,screen, ship,bullets):"""响应按键"""if event.key == pygame.K_RIGHT:ship.moving_right = Trueelif event.key == pygame.K_LEFT:ship.moving_left = Trueelif event.key == pygame.K_SPACE:fire_bullet(ai_settings,screen,ship,bullets)elif event.key == pygame.K_q:sys.exit(0)def check_keyup_events(event,ship):"""响应松开"""if event.key == pygame.K_RIGHT:ship.moving_right = Falseif event.key == pygame.K_LEFT:ship.moving_left = Falsedef check_events(ai_settings,screen, stats, play_button,ship,aliens,bullets):"""响应按键和鼠标事件"""for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit(0)  #在这里的exit()中需要传递参数,他么的,竟然这么坑吗?elif event.type == pygame.KEYDOWN:check_keydown_events(event, ai_settings,screen,ship, bullets)elif event.type == pygame.KEYUP:check_keyup_events(event,ship)elif event.type == pygame.MOUSEBUTTONDOWN:mouse_x, mouse_y = pygame.mouse.get_pos()check_play_button(ai_settings,screen,stats,play_button,ship,aliens,bullets,mouse_x,mouse_y)def check_play_button(ai_settings,screen,stats,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:#重置游戏设置ai_settings.initialize_dynamic_settings()#隐藏光标pygame.mouse.set_visible(False)#重置游戏统计信息stats.reset_stats()stats.game_active = True#清空外星人列表和子弹列表aliens.empty()bullets.empty()#创建一群新的外星人,并让飞船居中create_fleet(ai_settings,screen,ship,aliens)ship.center_ship()def update_screen(ai_settings,screen,stats,sb,ship,bullets,aliens,play_button):"""更新屏幕上的图像,并切换到新屏幕"""#每次循环时都重绘屏幕screen.fill(ai_settings.bg_color)#在飞船和外星人后面重绘所有子弹for bullet in bullets.sprites():bullet.draw_bullet()ship.blitme()aliens.draw(screen)#显示得分sb.show_score()#如果游戏处于非活动状态,就绘制Play按钮if not stats.game_active:play_button.draw_button()#让最近绘制的屏幕可见pygame.display.flip()def update_bullets(ai_settings,screen,stats,sb,ship,aliens,bullets):"""更新子弹的位置,并删除已销失的子弹"""#更新子弹的位置bullets.update()#删除已销失的子弹for bullet in bullets.copy():if bullet.rect.bottom <= 0:bullets.remove(bullet)if len(bullets) != 0:print(len(bullets))#检查是否有子弹击中了外星人#如果这样,就删除相应的子弹和外星人check_bullet_alien_collisions(ai_settings,screen,stats,sb,ship,aliens,bullets)def check_bullet_alien_collisions(ai_settings,screen,stats,sb,ship,aliens,bullets):"""响应子弹和外星人的碰撞"""#删除发生碰撞的子弹和外星人collisions = pygame.sprite.groupcollide(bullets,aliens,True,True)if collisions:for aliens in collisions.values():stats.score += ai_settings.alien_pointssb.prep_score()if len(aliens) == 0:#删除现有的子弹并新建一群外星人#删除现有的子弹,加快游戏节奏,并创建一群新的外星人bullets.empty()ai_settings.increase_speed()create_fleet(ai_settings,screen,ship,aliens)def fire_bullet(ai_settings,screen,ship,bullets):"""如果还没有到达限制,就发射一颗子弹"""#创建新子弹,并将其加入到编组bullets中if len(bullets) < ai_settings.bullets_allowed:new_bullet = Bullet(ai_settings,screen,ship)bullets.add(new_bullet)def get_number_aliens_x(ai_settings,alien_width):"""计算每行可容纳多少外星人"""available_space_x = ai_settings.screen_width - 2 * alien_widthnumber_alien_x = int(available_space_x / (2 * alien_width))return number_alien_xdef get_number_rows(ai_settings,ship_height,alien_height):"""计算屏幕可容纳多少行外星人"""available_space_y = (ai_settings.screen_height - (3 * alien_height) - ship_height)number_rows = int(available_space_y / (2 * alien_height))return number_rowsdef create_alien(ai_settings,screen,aliens,alien_number,row_number):"""创建一个外星人并将其加入当前行"""alien = Alien(ai_settings,screen)alien_width = alien.rect.widthalien.x = alien_width + 2 * alien_width * alien_numberalien.rect.x = alien.xalien.rect.y = alien.rect.height + 2 * alien.rect.height * row_numberaliens.add(alien)def create_fleet(ai_settings,screen,ship,aliens):"""创建外星人"""#创建一个外星人,并计算一行可容纳多少外星人#外星人间距为外星人宽度alien = Alien(ai_settings,screen)number_aliens_x = get_number_aliens_x(ai_settings,alien.rect.width)number_rows = get_number_rows(ai_settings,ship.rect.height,alien.rect.height)#创建第一行外星人for row_number in range(number_rows):for alien_number in range(number_aliens_x):create_alien(ai_settings,screen,aliens,alien_number,row_number)def update_aliens(ai_settings,ship,aliens):"""更新外星人群中所有外星人的位置"""aliens.update()#检测外星人和飞船之间的碰撞if pygame.sprite.spritescollideany(ship,aliens):print("Ship hit!!!")def check_fleet_edges(ai_settings,aliens):"""有外星人到达边缘时采取相应的措施"""for alien in aliens.sprites():if alien.check_edges():change_fleet_direction(ai_settings,aliens)breakdef change_fleet_direction(ai_settings,aliens):"""将整群外星人下移,并改变它们的方向"""for alien in aliens.sprites():alien.rect.y += ai_settings.fleet_drop_speedai_settings.fleet_direction *= -1def ship_hit(ai_settings,stats,screen,ship,aliens,bullets):"""相应被外星人撞到的飞船"""if stats.ships_left > 0:#将ships_left 减1stats.ships_left -= 1#清空外星人到列表和子弹列表aliens.empty()bullets.empty()#创建一群外星人,并将飞船放到屏幕底端中央create_fleet(ai_settings,screen,ship,aliens)ship.center_ship()#暂停sleep(0.5)sys.exit(0)else:stats.game_active = Falsepygame.mouse.set_visible(True)def check_aliens_bottom(ai_settings,stats,screen,ship,aliens,bullets):"""检查是否有外星人到达了屏幕底端"""screen_rect = screen.get_rect()for alien in aliens.sprites():if alien.rect.bottom >= screen_rect.bottom:#像飞船被撞到一样进行处理ship_hit(ai_settings,stats,screen,ship,aliens,bullets)breakdef update_aliens(ai_settings,stats,screen,ship,aliens,bullets):"""检查是否有外星人位于屏幕边缘,并更新整群外星人的位置"""check_fleet_edges(ai_settings,aliens)aliens.update()if pygame.sprite.spritecollideany(ship,aliens):ship_hit(ai_settings,stats,screen,ship,aliens,bullets)#检查是否有外星人到达屏幕底端check_aliens_bottom(ai_settings,stats,screen,ship,aliens,bullets)

3.5 提高点数

settings.py

class Settings():"""存储<<外星人入侵>>的所有设置的类"""def __init__(self):"""初始化游戏的设置"""#屏幕设置self.screen_width = 800self.screen_height = 600self.bg_color = (230,230,230)#飞船的设置self.ship_speed_factor = 1.5self.ship_limit = 3#子弹设置self.bullet_speed_factor = 3self.bullet_width = 3self.bullet_height = 15self.bullet_color = (60 , 60 , 60)self.bullets_allowed = 5   #将在屏幕内可以存在的子弹限制为3颗#外星人设置self.alien_speed_factor = 1self.fleet_drop_speed = 10#以什么样的速度加快游戏节奏self.speedup_scale = 1.1#外星人点数的提高速度self.score_scale = 1.5self.initialize_dynamic_settings()def initialize_dynamic_settings(self):"""初始化随游戏进行而变化的设置"""#该方法设置了飞船、子弹和外星人的初始速度self.ship_speed_factor = 1.5self.bullet_speed_factor = 3self.alien_speed_factor = 1#fleet_direction为1表示向右移,为-1表示向左移self.fleet_direction = 1#计分self.alien_points = 50def increase_speed(self):"""提高速度设置"""#使用该方法在玩家提高一个等级时,来提高飞船、子弹和外星人的速度self.ship_speed_factor *= self.speedup_scaleself.bullet_speed_factor *= self.speedup_scaleself.alien_speed_factor *=self.speedup_scaleself.alien_points = int(self.alien_points * self.score_scales)print(self.alien_points)

3.6 将得分圆整

大多数街机风格的射击游戏都将得分显示为10的整数倍,我们的计分系统也将遵循这个原则,在设置一些规则,在大数字中添加用逗号表示的千位分隔符,我们在scoreboard.py中修改
scoreboard.py

import pygame.fontclass Scoreboard():"""显示得分信息的类"""def __init__(self,ai_settings,screen,stats):"""初始化显示得分涉及的属性"""self.screen  = screenself.screen_rect = screen.get_rect()self.ai_settings = ai_settingsself.stats = stats#显示得分信息时使用的字体设置self.text_color = (30,30,30)self.font = pygame.font.SysFont(None,48)#准备初始得分图像self.prep_score()def prep_score(self):"""将得分转换为一副渲染的图像"""rounded_score = int(round(self.stats.score, -1))score_str = "{:,}".format(rounded_score)#score_str = str(self.stats.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 - 20self.score_rect.top = 20def show_score(self):"""在屏幕上显示得分"""self.screen.blit(self.score_image,self.score_rect)

注意:在python2.7中,round()总是返回一个小数值,因此我们使用int()来确保报告的得分为整数。如果在python3中,可省略对int()的调用

在这里插入图片描述

3.7 最高得分

我们将最高得分存储在GameStats中:
game_stats.py

class GameStats():"""跟踪游戏的统计信息"""def __init__(self,ai_settings):"""初始化统计信息"""self.ai_settings = ai_settingsself.reset_stats()#游戏刚开始处于非活动状态self.game_active = False#在任何情况下都不应该重置最高得分self.high_score = 0def reset_stats(self):"""初始化在游戏运行期间可能变化的统计信息"""self.ships_left = self.ai_settings.ship_limitself.score = 0

下面来修改Scoreboard以显示最高分
scoreboard.py

import pygame.fontclass Scoreboard():"""显示得分信息的类"""def __init__(self,ai_settings,screen,stats):"""初始化显示得分涉及的属性"""self.screen  = screenself.screen_rect = screen.get_rect()self.ai_settings = ai_settingsself.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)#score_str = str(self.stats.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 - 20self.score_rect.top = 20def show_score(self):"""在屏幕上显示得分"""self.screen.blit(self.score_image,self.score_rect)self.screen.blit(self.high_score_image,self.high_score_rect)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.high_score_image.get_rect()self.high_score_rect.centerx = self.screen_rect.centerxself.high_score_rect.top = self.score_rect.top

根据最高分生成一幅图像,使其水平居中,将其top属性设置为当前得分图像的top属性。
现在方法show_score()在屏幕右上角显示当前得分,并在屏幕顶部中央显示最高得分。
为了检查是否诞生新的最高分,我们在game_functions.py中添加一个新函数check_high_score():
game_function.py

import sys
import pygame
from bullet import Bullet
from alien import Alien
from time import sleepdef check_keydown_events(event,ai_settings,screen, ship,bullets):"""响应按键"""if event.key == pygame.K_RIGHT:ship.moving_right = Trueelif event.key == pygame.K_LEFT:ship.moving_left = Trueelif event.key == pygame.K_SPACE:fire_bullet(ai_settings,screen,ship,bullets)elif event.key == pygame.K_q:sys.exit(0)def check_keyup_events(event,ship):"""响应松开"""if event.key == pygame.K_RIGHT:ship.moving_right = Falseif event.key == pygame.K_LEFT:ship.moving_left = Falsedef check_events(ai_settings,screen, stats, play_button,ship,aliens,bullets):"""响应按键和鼠标事件"""for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit(0)  #在这里的exit()中需要传递参数,他么的,竟然这么坑吗?elif event.type == pygame.KEYDOWN:check_keydown_events(event, ai_settings,screen,ship, bullets)elif event.type == pygame.KEYUP:check_keyup_events(event,ship)elif event.type == pygame.MOUSEBUTTONDOWN:mouse_x, mouse_y = pygame.mouse.get_pos()check_play_button(ai_settings,screen,stats,play_button,ship,aliens,bullets,mouse_x,mouse_y)def check_play_button(ai_settings,screen,stats,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:#重置游戏设置ai_settings.initialize_dynamic_settings()#隐藏光标pygame.mouse.set_visible(False)#重置游戏统计信息stats.reset_stats()stats.game_active = True#清空外星人列表和子弹列表aliens.empty()bullets.empty()#创建一群新的外星人,并让飞船居中create_fleet(ai_settings,screen,ship,aliens)ship.center_ship()def update_screen(ai_settings,screen,stats,sb,ship,bullets,aliens,play_button):"""更新屏幕上的图像,并切换到新屏幕"""#每次循环时都重绘屏幕screen.fill(ai_settings.bg_color)#在飞船和外星人后面重绘所有子弹for bullet in bullets.sprites():bullet.draw_bullet()ship.blitme()aliens.draw(screen)#显示得分sb.show_score()#如果游戏处于非活动状态,就绘制Play按钮if not stats.game_active:play_button.draw_button()#让最近绘制的屏幕可见pygame.display.flip()def update_bullets(ai_settings,screen,stats,sb,ship,aliens,bullets):"""更新子弹的位置,并删除已销失的子弹"""#更新子弹的位置bullets.update()#删除已销失的子弹for bullet in bullets.copy():if bullet.rect.bottom <= 0:bullets.remove(bullet)if len(bullets) != 0:print(len(bullets))#检查是否有子弹击中了外星人#如果这样,就删除相应的子弹和外星人check_bullet_alien_collisions(ai_settings,screen,stats,sb,ship,aliens,bullets)def check_bullet_alien_collisions(ai_settings,screen,stats,sb,ship,aliens,bullets):"""响应子弹和外星人的碰撞"""#删除发生碰撞的子弹和外星人collisions = pygame.sprite.groupcollide(bullets,aliens,True,True)if collisions:for aliens in collisions.values():stats.score += ai_settings.alien_pointssb.prep_score()check_high_score(stats,sb)if len(aliens) == 0:#删除现有的子弹并新建一群外星人#删除现有的子弹,加快游戏节奏,并创建一群新的外星人bullets.empty()ai_settings.increase_speed()create_fleet(ai_settings,screen,ship,aliens)def fire_bullet(ai_settings,screen,ship,bullets):"""如果还没有到达限制,就发射一颗子弹"""#创建新子弹,并将其加入到编组bullets中if len(bullets) < ai_settings.bullets_allowed:new_bullet = Bullet(ai_settings,screen,ship)bullets.add(new_bullet)def get_number_aliens_x(ai_settings,alien_width):"""计算每行可容纳多少外星人"""available_space_x = ai_settings.screen_width - 2 * alien_widthnumber_alien_x = int(available_space_x / (2 * alien_width))return number_alien_xdef get_number_rows(ai_settings,ship_height,alien_height):"""计算屏幕可容纳多少行外星人"""available_space_y = (ai_settings.screen_height - (3 * alien_height) - ship_height)number_rows = int(available_space_y / (2 * alien_height))return number_rowsdef create_alien(ai_settings,screen,aliens,alien_number,row_number):"""创建一个外星人并将其加入当前行"""alien = Alien(ai_settings,screen)alien_width = alien.rect.widthalien.x = alien_width + 2 * alien_width * alien_numberalien.rect.x = alien.xalien.rect.y = alien.rect.height + 2 * alien.rect.height * row_numberaliens.add(alien)def create_fleet(ai_settings,screen,ship,aliens):"""创建外星人"""#创建一个外星人,并计算一行可容纳多少外星人#外星人间距为外星人宽度alien = Alien(ai_settings,screen)number_aliens_x = get_number_aliens_x(ai_settings,alien.rect.width)number_rows = get_number_rows(ai_settings,ship.rect.height,alien.rect.height)#创建第一行外星人for row_number in range(number_rows):for alien_number in range(number_aliens_x):create_alien(ai_settings,screen,aliens,alien_number,row_number)def update_aliens(ai_settings,ship,aliens):"""更新外星人群中所有外星人的位置"""aliens.update()#检测外星人和飞船之间的碰撞if pygame.sprite.spritescollideany(ship,aliens):print("Ship hit!!!")def check_fleet_edges(ai_settings,aliens):"""有外星人到达边缘时采取相应的措施"""for alien in aliens.sprites():if alien.check_edges():change_fleet_direction(ai_settings,aliens)breakdef change_fleet_direction(ai_settings,aliens):"""将整群外星人下移,并改变它们的方向"""for alien in aliens.sprites():alien.rect.y += ai_settings.fleet_drop_speedai_settings.fleet_direction *= -1def ship_hit(ai_settings,stats,screen,ship,aliens,bullets):"""相应被外星人撞到的飞船"""if stats.ships_left > 0:#将ships_left 减1stats.ships_left -= 1#清空外星人到列表和子弹列表aliens.empty()bullets.empty()#创建一群外星人,并将飞船放到屏幕底端中央create_fleet(ai_settings,screen,ship,aliens)ship.center_ship()#暂停sleep(0.5)sys.exit(0)else:stats.game_active = Falsepygame.mouse.set_visible(True)def check_aliens_bottom(ai_settings,stats,screen,ship,aliens,bullets):"""检查是否有外星人到达了屏幕底端"""screen_rect = screen.get_rect()for alien in aliens.sprites():if alien.rect.bottom >= screen_rect.bottom:#像飞船被撞到一样进行处理ship_hit(ai_settings,stats,screen,ship,aliens,bullets)breakdef update_aliens(ai_settings,stats,screen,ship,aliens,bullets):"""检查是否有外星人位于屏幕边缘,并更新整群外星人的位置"""check_fleet_edges(ai_settings,aliens)aliens.update()if pygame.sprite.spritecollideany(ship,aliens):ship_hit(ai_settings,stats,screen,ship,aliens,bullets)#检查是否有外星人到达屏幕底端check_aliens_bottom(ai_settings,stats,screen,ship,aliens,bullets)def check_high_score(stats,sb):"""检查是否诞生了新的最高分"""if stats.score > stats.high_score:stats.high_score = stats.scoresb.prep_high_score()

在这里插入图片描述

3.8 显示等级

想要在游戏中显示玩家的等级,需要在GameStats中添加一个表示当前等级的属性。为确保每次开始新游戏时都重置等级,在reset_stats()中初始化它:
game_stats.py

class GameStats():"""跟踪游戏的统计信息"""def __init__(self,ai_settings):"""初始化统计信息"""self.ai_settings = ai_settingsself.reset_stats()#游戏刚开始处于非活动状态self.game_active = False#在任何情况下都不应该重置最高得分self.high_score = 0def reset_stats(self):"""初始化在游戏运行期间可能变化的统计信息"""self.ships_left = self.ai_settings.ship_limitself.score = 0self.level = 1

scoreboard.py

import pygame.fontclass Scoreboard():"""显示得分信息的类"""def __init__(self,ai_settings,screen,stats):"""初始化显示得分涉及的属性"""self.screen  = screenself.screen_rect = screen.get_rect()self.ai_settings = ai_settingsself.stats = stats#显示得分信息时使用的字体设置self.text_color = (30,30,30)self.font = pygame.font.SysFont(None,48)#准备初始得分图像self.prep_score()self.prep_high_score()self.prep_level()def prep_score(self):"""将得分转换为一副渲染的图像"""rounded_score = int(round(self.stats.score, -1))score_str = "{:,}".format(rounded_score)#score_str = str(self.stats.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 - 20self.score_rect.top = 20def 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)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.high_score_image.get_rect()self.high_score_rect.centerx = self.screen_rect.centerxself.high_score_rect.top = self.score_rect.topdef 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.rightself.level_rect.top = self.score_rect.bottom + 10

game_functions.py

import sys
import pygame
from bullet import Bullet
from alien import Alien
from time import sleepdef check_keydown_events(event,ai_settings,screen, ship,bullets):"""响应按键"""if event.key == pygame.K_RIGHT:ship.moving_right = Trueelif event.key == pygame.K_LEFT:ship.moving_left = Trueelif event.key == pygame.K_SPACE:fire_bullet(ai_settings,screen,ship,bullets)elif event.key == pygame.K_q:sys.exit(0)def check_keyup_events(event,ship):"""响应松开"""if event.key == pygame.K_RIGHT:ship.moving_right = Falseif event.key == pygame.K_LEFT:ship.moving_left = Falsedef check_events(ai_settings,screen, stats, sb,play_button,ship,aliens,bullets):"""响应按键和鼠标事件"""for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit(0)  #在这里的exit()中需要传递参数,他么的,竟然这么坑吗?elif event.type == pygame.KEYDOWN:check_keydown_events(event, ai_settings,screen,ship, bullets)elif event.type == pygame.KEYUP:check_keyup_events(event,ship)elif event.type == pygame.MOUSEBUTTONDOWN:mouse_x, mouse_y = pygame.mouse.get_pos()check_play_button(ai_settings,screen,stats,sb,play_button,ship,aliens,bullets,mouse_x,mouse_y)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:#重置游戏设置ai_settings.initialize_dynamic_settings()#隐藏光标pygame.mouse.set_visible(False)#重置游戏统计信息stats.reset_stats()stats.game_active = True#重置记分牌图像sb.prep_score()sb.prep_high_score()sb.prep_level()#清空外星人列表和子弹列表aliens.empty()bullets.empty()#创建一群新的外星人,并让飞船居中create_fleet(ai_settings,screen,ship,aliens)ship.center_ship()def update_screen(ai_settings,screen,stats,sb,ship,bullets,aliens,play_button):"""更新屏幕上的图像,并切换到新屏幕"""#每次循环时都重绘屏幕screen.fill(ai_settings.bg_color)#在飞船和外星人后面重绘所有子弹for bullet in bullets.sprites():bullet.draw_bullet()ship.blitme()aliens.draw(screen)#显示得分sb.show_score()#如果游戏处于非活动状态,就绘制Play按钮if not stats.game_active:play_button.draw_button()#让最近绘制的屏幕可见pygame.display.flip()def update_bullets(ai_settings,screen,stats,sb,ship,aliens,bullets):"""更新子弹的位置,并删除已销失的子弹"""#更新子弹的位置bullets.update()#删除已销失的子弹for bullet in bullets.copy():if bullet.rect.bottom <= 0:bullets.remove(bullet)if len(bullets) != 0:print(len(bullets))#检查是否有子弹击中了外星人#如果这样,就删除相应的子弹和外星人check_bullet_alien_collisions(ai_settings,screen,stats,sb,ship,aliens,bullets)def check_bullet_alien_collisions(ai_settings,screen,stats,sb,ship,aliens,bullets):"""响应子弹和外星人的碰撞"""#删除发生碰撞的子弹和外星人collisions = pygame.sprite.groupcollide(bullets,aliens,True,True)if collisions:for aliens in collisions.values():stats.score += ai_settings.alien_pointssb.prep_score()check_high_score(stats,sb)if len(aliens) == 0:#删除现有的子弹并新建一群外星人#删除现有的子弹,加快游戏节奏,并创建一群新的外星人bullets.empty()ai_settings.increase_speed()stats.level += 1sb.prep_level()create_fleet(ai_settings,screen,ship,aliens)def fire_bullet(ai_settings,screen,ship,bullets):"""如果还没有到达限制,就发射一颗子弹"""#创建新子弹,并将其加入到编组bullets中if len(bullets) < ai_settings.bullets_allowed:new_bullet = Bullet(ai_settings,screen,ship)bullets.add(new_bullet)def get_number_aliens_x(ai_settings,alien_width):"""计算每行可容纳多少外星人"""available_space_x = ai_settings.screen_width - 2 * alien_widthnumber_alien_x = int(available_space_x / (2 * alien_width))return number_alien_xdef get_number_rows(ai_settings,ship_height,alien_height):"""计算屏幕可容纳多少行外星人"""available_space_y = (ai_settings.screen_height - (3 * alien_height) - ship_height)number_rows = int(available_space_y / (2 * alien_height))return number_rowsdef create_alien(ai_settings,screen,aliens,alien_number,row_number):"""创建一个外星人并将其加入当前行"""alien = Alien(ai_settings,screen)alien_width = alien.rect.widthalien.x = alien_width + 2 * alien_width * alien_numberalien.rect.x = alien.xalien.rect.y = alien.rect.height + 2 * alien.rect.height * row_numberaliens.add(alien)def create_fleet(ai_settings,screen,ship,aliens):"""创建外星人"""#创建一个外星人,并计算一行可容纳多少外星人#外星人间距为外星人宽度alien = Alien(ai_settings,screen)number_aliens_x = get_number_aliens_x(ai_settings,alien.rect.width)number_rows = get_number_rows(ai_settings,ship.rect.height,alien.rect.height)#创建第一行外星人for row_number in range(number_rows):for alien_number in range(number_aliens_x):create_alien(ai_settings,screen,aliens,alien_number,row_number)def update_aliens(ai_settings,ship,aliens):"""更新外星人群中所有外星人的位置"""aliens.update()#检测外星人和飞船之间的碰撞if pygame.sprite.spritescollideany(ship,aliens):print("Ship hit!!!")def check_fleet_edges(ai_settings,aliens):"""有外星人到达边缘时采取相应的措施"""for alien in aliens.sprites():if alien.check_edges():change_fleet_direction(ai_settings,aliens)breakdef change_fleet_direction(ai_settings,aliens):"""将整群外星人下移,并改变它们的方向"""for alien in aliens.sprites():alien.rect.y += ai_settings.fleet_drop_speedai_settings.fleet_direction *= -1def ship_hit(ai_settings,stats,screen,ship,aliens,bullets):"""相应被外星人撞到的飞船"""if stats.ships_left > 0:#将ships_left 减1stats.ships_left -= 1#清空外星人到列表和子弹列表aliens.empty()bullets.empty()#创建一群外星人,并将飞船放到屏幕底端中央create_fleet(ai_settings,screen,ship,aliens)ship.center_ship()#暂停sleep(0.5)#sys.exit(0)stats.game_active = Falseelse:stats.game_active = Falsepygame.mouse.set_visible(True)def check_aliens_bottom(ai_settings,stats,screen,ship,aliens,bullets):"""检查是否有外星人到达了屏幕底端"""screen_rect = screen.get_rect()for alien in aliens.sprites():if alien.rect.bottom >= screen_rect.bottom:#像飞船被撞到一样进行处理ship_hit(ai_settings,stats,screen,ship,aliens,bullets)breakdef update_aliens(ai_settings,stats,screen,ship,aliens,bullets):"""检查是否有外星人位于屏幕边缘,并更新整群外星人的位置"""check_fleet_edges(ai_settings,aliens)aliens.update()if pygame.sprite.spritecollideany(ship,aliens):ship_hit(ai_settings,stats,screen,ship,aliens,bullets)#检查是否有外星人到达屏幕底端check_aliens_bottom(ai_settings,stats,screen,ship,aliens,bullets)def check_high_score(stats,sb):"""检查是否诞生了新的最高分"""if stats.score > stats.high_score:stats.high_score = stats.scoresb.prep_high_score()

alien_invasion.py

import sys
import pygame
from settings import Settings
from game_stats import GameStats
from ship import Ship
from alien import Alien
import game_functions as gf
from pygame.sprite import Group
from button import Button  #导入button类
from scoreboard import Scoreboarddef run_game():#初始化游戏并创建一个屏幕对象pygame.init()ai_settings = Settings()screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))pygame.display.set_caption("Alien Invasion")#创建Play按钮,并创建一个button实例play_button = Button(ai_settings,screen,"play") #创建一个外星人alien = Alien(ai_settings,screen)#创建一个用于存储游戏统计信息的实例,并创建记分牌stats = GameStats(ai_settings)sb = Scoreboard(ai_settings,screen,stats)#创建一艘非飞船ship = Ship(ai_settings,screen)#创建一个用于存储子弹的编组bullets = Group()aliens = Group()#创建外星人群gf.create_fleet(ai_settings,screen,ship,aliens)#开始游戏的主循环while True:#sys.pause()#监视键盘和鼠标事件gf.check_events(ai_settings,screen,stats,sb,play_button,ship,aliens,bullets)if stats.game_active:ship.update()gf.update_bullets(ai_settings,screen,stats,sb,ship,aliens,bullets)gf.update_aliens(ai_settings,stats,screen,ship,aliens,bullets)gf.update_screen(ai_settings,screen,stats,sb,ship,bullets,aliens,play_button)run_game()

在这里插入图片描述

4.9 显示余下的飞船数

最后,我们来显示玩家还有多少艘飞船,使用图形的方式,为此,我们需要在屏幕左上角绘制飞船图像来指出还余下多少艘飞船。
ship.py

import pygame
from pygame.sprite import Spriteclass Ship(Sprite):def __init__(self,ai_settings,screen):"""初始化飞船并设置其初始化位置"""super(Ship,self).__init__()self.screen = screenself.ai_settings = ai_settings#加载飞船图像并获取其外接矩形self.image = pygame.image.load('images/ship.bmp')self.rect = self.image.get_rect()self.screen_rect = screen.get_rect()#将每艘新飞船放在屏幕底部中央self.rect.centerx = self.screen_rect.centerxself.rect.bottom = self.screen_rect.bottom#在飞船的属性center中存储小数值self.center = float(self.rect.centerx)#移动标志self.moving_right = Falseself.moving_left = Falseself.moving_up = Falseself.moving_down = Falsedef update(self):"""根据移动标志调整飞船的位置"""#更新飞船的center值,而不是rectif self.moving_right and self.rect.right < self.screen_rect.right:self.center += self.ai_settings.ship_speed_factorelif self.moving_left and self.rect.left > 0:self.center -= self.ai_settings.ship_speed_factorelif self.moving_up and self.rect.up < self.screen_rect.up:self.center += self.ai_settings.ship_speed_factorelif self.moving_down and self.rect.down > 0:self.center -= self.ai_settings.ship_speed_factor#根据self.center更新rect对象self.rect.centerx = self.centerdef blitme(self):"""在指定位置绘制飞船"""self.screen.blit(self.image,self.rect)def center_ship(self):"""让飞船在屏幕上居中"""self.center = self.screen_rect.centerx

scoreboard.py

import pygame.font
from pygame.sprite import Group
from ship import Shipclass Scoreboard():"""显示得分信息的类"""def __init__(self,ai_settings,screen,stats):"""初始化显示得分涉及的属性"""self.screen  = screenself.screen_rect = screen.get_rect()self.ai_settings = ai_settingsself.stats = stats#显示得分信息时使用的字体设置self.text_color = (30,30,30)self.font = pygame.font.SysFont(None,48)#准备初始得分图像self.prep_score()self.prep_high_score()self.prep_level()self.prep_ships()def prep_score(self):"""将得分转换为一副渲染的图像"""rounded_score = int(round(self.stats.score, -1))score_str = "{:,}".format(rounded_score)#score_str = str(self.stats.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 - 20self.score_rect.top = 20def 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_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.high_score_image.get_rect()self.high_score_rect.centerx = self.screen_rect.centerxself.high_score_rect.top = self.score_rect.topdef 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.rightself.level_rect.top = self.score_rect.bottom + 10#该方法创建一个空的编组self.ships,用于存储飞船的实例def prep_ships(self):"""显示还余下多少艘飞船"""self.ships = Group()for ship_number in range(self.stats.ship_left):ship = Ship(self.ai_settings,self.screen)ship.rect.x = 10 + ship_number * ship,rect.widthship.rect.y = 10self.ships.add(ship)

game_functions.py

import sys
import pygame
from bullet import Bullet
from alien import Alien
from time import sleepdef check_keydown_events(event,ai_settings,screen, stats,ship,bullets):"""响应按键"""if event.key == pygame.K_RIGHT:ship.moving_right = Trueelif event.key == pygame.K_LEFT:ship.moving_left = Trueelif event.key == pygame.K_SPACE:fire_bullet(ai_settings,screen,ship,bullets)elif event.key == pygame.K_q:sys.exit(0)elif event.key == pygame.K_p:stats.game_active = Truedef check_keyup_events(event,ship):"""响应松开"""if event.key == pygame.K_RIGHT:ship.moving_right = Falseif event.key == pygame.K_LEFT:ship.moving_left = Falsedef check_events(ai_settings,screen, stats, sb,play_button,ship,aliens,bullets):"""响应按键和鼠标事件"""for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit(0)  #在这里的exit()中需要传递参数,他么的,竟然这么坑吗?elif event.type == pygame.KEYDOWN:check_keydown_events(event, ai_settings,screen,stats,ship, bullets)elif event.type == pygame.KEYUP:check_keyup_events(event,ship)elif event.type == pygame.MOUSEBUTTONDOWN:mouse_x, mouse_y = pygame.mouse.get_pos()check_play_button(ai_settings,screen,stats,sb,play_button,ship,aliens,bullets,mouse_x,mouse_y)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:#重置游戏设置ai_settings.initialize_dynamic_settings()#隐藏光标pygame.mouse.set_visible(False)#重置游戏统计信息stats.reset_stats()stats.game_active = True#重置记分牌图像sb.prep_score()sb.prep_high_score()sb.prep_level()sb.prep_ships()#清空外星人列表和子弹列表aliens.empty()bullets.empty()#创建一群新的外星人,并让飞船居中create_fleet(ai_settings,screen,ship,aliens)ship.center_ship()def update_screen(ai_settings,screen,stats,sb,ship,bullets,aliens,play_button):"""更新屏幕上的图像,并切换到新屏幕"""#每次循环时都重绘屏幕screen.fill(ai_settings.bg_color)#在飞船和外星人后面重绘所有子弹for bullet in bullets.sprites():bullet.draw_bullet()ship.blitme()aliens.draw(screen)#显示得分sb.show_score()#如果游戏处于非活动状态,就绘制Play按钮if not stats.game_active:play_button.draw_button()#让最近绘制的屏幕可见pygame.display.flip()def update_bullets(ai_settings,screen,stats,sb,ship,aliens,bullets):"""更新子弹的位置,并删除已销失的子弹"""#更新子弹的位置bullets.update()#删除已销失的子弹for bullet in bullets.copy():if bullet.rect.bottom <= 0:bullets.remove(bullet)if len(bullets) != 0:print(len(bullets))#检查是否有子弹击中了外星人#如果这样,就删除相应的子弹和外星人check_bullet_alien_collisions(ai_settings,screen,stats,sb,ship,aliens,bullets)def check_bullet_alien_collisions(ai_settings,screen,stats,sb,ship,aliens,bullets):"""响应子弹和外星人的碰撞"""#删除发生碰撞的子弹和外星人collisions = pygame.sprite.groupcollide(bullets,aliens,True,True)if collisions:for aliens in collisions.values():stats.score += ai_settings.alien_pointssb.prep_score()check_high_score(stats,sb)if len(aliens) == 0:#删除现有的子弹并新建一群外星人#删除现有的子弹,加快游戏节奏,并创建一群新的外星人bullets.empty()ai_settings.increase_speed()stats.level += 1sb.prep_level()create_fleet(ai_settings,screen,ship,aliens)def fire_bullet(ai_settings,screen,ship,bullets):"""如果还没有到达限制,就发射一颗子弹"""#创建新子弹,并将其加入到编组bullets中if len(bullets) < ai_settings.bullets_allowed:new_bullet = Bullet(ai_settings,screen,ship)bullets.add(new_bullet)def get_number_aliens_x(ai_settings,alien_width):"""计算每行可容纳多少外星人"""available_space_x = ai_settings.screen_width - 2 * alien_widthnumber_alien_x = int(available_space_x / (2 * alien_width))return number_alien_xdef get_number_rows(ai_settings,ship_height,alien_height):"""计算屏幕可容纳多少行外星人"""available_space_y = (ai_settings.screen_height - (3 * alien_height) - ship_height)number_rows = int(available_space_y / (2 * alien_height))return number_rowsdef create_alien(ai_settings,screen,aliens,alien_number,row_number):"""创建一个外星人并将其加入当前行"""alien = Alien(ai_settings,screen)alien_width = alien.rect.widthalien.x = alien_width + 2 * alien_width * alien_numberalien.rect.x = alien.xalien.rect.y = alien.rect.height + 2 * alien.rect.height * row_numberaliens.add(alien)def create_fleet(ai_settings,screen,ship,aliens):"""创建外星人"""#创建一个外星人,并计算一行可容纳多少外星人#外星人间距为外星人宽度alien = Alien(ai_settings,screen)number_aliens_x = get_number_aliens_x(ai_settings,alien.rect.width)number_rows = get_number_rows(ai_settings,ship.rect.height,alien.rect.height)#创建第一行外星人for row_number in range(number_rows):for alien_number in range(number_aliens_x):create_alien(ai_settings,screen,aliens,alien_number,row_number)def update_aliens(ai_settings,screen,stats,sb,ship,aliens,bullets):"""更新外星人群中所有外星人的位置"""aliens.update()#检测外星人和飞船之间的碰撞if pygame.sprite.spritescollideany(ship,aliens):ship_hit(ai_settings,screen,stats,sb,ship,aliens,bullets)print("Ship hit!!!")check_aliens_bottom(ai_settings,screen,stats,sb, ship,aliens,bullets)def check_fleet_edges(ai_settings,aliens):"""有外星人到达边缘时采取相应的措施"""for alien in aliens.sprites():if alien.check_edges():change_fleet_direction(ai_settings,aliens)breakdef change_fleet_direction(ai_settings,aliens):"""将整群外星人下移,并改变它们的方向"""for alien in aliens.sprites():alien.rect.y += ai_settings.fleet_drop_speedai_settings.fleet_direction *= -1def ship_hit(ai_settings,stats,screen,sb,ship,aliens,bullets):"""相应被外星人撞到的飞船"""if stats.ships_left > 0:#将ships_left 减1stats.ships_left -= 1#更新记分牌sb.prep_ships()#清空外星人到列表和子弹列表aliens.empty()bullets.empty()#创建一群外星人,并将飞船放到屏幕底端中央create_fleet(ai_settings,screen,ship,aliens)ship.center_ship()#暂停sleep(0.5)#sys.exit(0)#stats.game_active = Falseelse:stats.game_active = Falsepygame.mouse.set_visible(True)def check_aliens_bottom(ai_settings,stats,screen,sb,ship,aliens,bullets):"""检查是否有外星人到达了屏幕底端"""screen_rect = screen.get_rect()for alien in aliens.sprites():if alien.rect.bottom >= screen_rect.bottom:#像飞船被撞到一样进行处理ship_hit(ai_settings,stats,screen,sb,ship,aliens,bullets)breakdef update_aliens(ai_settings,stats,screen,sb,ship,aliens,bullets):"""检查是否有外星人位于屏幕边缘,并更新整群外星人的位置"""check_fleet_edges(ai_settings,aliens)aliens.update()if pygame.sprite.spritecollideany(ship,aliens):ship_hit(ai_settings,stats,screen,sb,ship,aliens,bullets)#检查是否有外星人到达屏幕底端check_aliens_bottom(ai_settings,stats,screen,sb,ship,aliens,bullets)def check_high_score(stats,sb):"""检查是否诞生了新的最高分"""if stats.score > stats.high_score:stats.high_score = stats.scoresb.prep_high_score()

alien_invasion.py

import sys
import pygame
from settings import Settings
from game_stats import GameStats
from ship import Ship
from alien import Alien
import game_functions as gf
from pygame.sprite import Group
from button import Button  #导入button类
from scoreboard import Scoreboarddef run_game():#初始化游戏并创建一个屏幕对象pygame.init()ai_settings = Settings()screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))pygame.display.set_caption("Alien Invasion")#创建Play按钮,并创建一个button实例play_button = Button(ai_settings,screen,"play") #创建一个外星人alien = Alien(ai_settings,screen)#创建一个用于存储游戏统计信息的实例,并创建记分牌stats = GameStats(ai_settings)sb = Scoreboard(ai_settings,screen,stats)#创建一艘非飞船ship = Ship(ai_settings,screen)#创建一个用于存储子弹的编组bullets = Group()aliens = Group()#创建外星人群gf.create_fleet(ai_settings,screen,ship,aliens)#开始游戏的主循环while True:#sys.pause()#监视键盘和鼠标事件gf.check_events(ai_settings,screen,stats,sb,play_button,ship,aliens,bullets)if stats.game_active:ship.update()gf.update_bullets(ai_settings,screen,stats,sb,ship,aliens,bullets)gf.update_aliens(ai_settings,stats,screen,sb,ship,aliens,bullets)gf.update_screen(ai_settings,screen,stats,sb,ship,bullets,aliens,play_button)run_game()

在这里插入图片描述

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. 希尔排序--java实现

    希尔排序的java实现 希尔排序是插入排序的一种优化版本,比插入排序更高效。 原理:选定增量h并按照h将元素分为若干组,对分好的每一组都进行插入排序,然后减小增量h的值并重复上述操作,直至h=1。 比如给出乱序数组{66,32,59,13,7,21,256,1},设定h=4;过程如下: (1)按h=…...

    2024/4/24 11:21:55
  2. LeetCode js题解 两数之和I/II/IV、三数之和/最接近的三数之和

    把两数之和和三数之和的题目都刷了一遍,熟悉一下这类题。两数之和 题源:https://leetcode-cn.com/problems/two-sum 题解 通过目标数减去当前数,在哈希表中寻找存在的组合,两次遍历可以完成,当然还可以缩减到一次遍历。 这种类似于用哈希表做登记的思路是比较简单也容易想…...

    2024/4/26 18:31:22
  3. leetcode刷题记录(1)

    1.两数之和题目:给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。初版思路:记录每一个数的值和下标,然后找到对应的差的下标,如…...

    2024/4/24 11:21:54
  4. 一个简单三层神经网络BP算法的公式推导

    一个简单的三层神经网络BP算法的公式推导神经网络表示梯度下降法前向误差传播反向误差传播 神经网络表示 让我们来看一个最简单的神经网络,该神经网络只有三层,分别是输入层,隐藏层和输出层。为了表示方便,我们把线性函数和非线性函数分开,神经网络可以画成如下:其中φ(x…...

    2024/4/20 22:57:05
  5. golang 性能剖析pprof

    golang 性能剖析pprof pprof 简介 pprof 是用于可视化和分析性能分析数据的工具. 功能CPU Profiling:CPU 分析, 按照一定的频率采集所监听的应用程序 CPU(含寄存器)的使用情况, 可确定应用程序在主动消耗 CPU 周期时花费时间的位置. Memory Profiling:内存分析, 在应用程序…...

    2024/4/24 8:20:32
  6. 【C++ 系列笔记】C++ 面向对象进阶

    ContentC++ 面向对象进阶继承 - 基础继承中的对象模型继承中的构造和析构继承中的同名处理不会继承的函数继承 - 进阶多继承虚继承多态 - 基础静态多态和动态多态动态多态原理解析开闭原则多态 - 进阶纯虚函数和抽象类虚析构和纯虚析构 C++ 面向对象进阶 继承 - 基础 class Bas…...

    2024/4/22 14:24:18
  7. JavaWeb开发--简易论坛--4全文搜索

    简易论坛–全文搜索 1、思路 2、使用技术或方法 mybatis,依赖注入,SpringMVC,MVC,thymeleaf,Elasticsearch3、关键代码 3.1、关键类 ElasticsearchTemplate/*** 该类使用了ES建立索引,并对应*/ //shards:分片数,replicas:副本数 @Document(indexName = "discusspost&q…...

    2024/4/25 12:11:25
  8. Loadrunner 负载生成器

    对场景进行设计后,需要对负载生成进行管理和配置,Load Generators是运行脚本的负载引擎,(相当于加压机)主要功能是生成虚拟用户进行负载,在默认情况下使用本地的负载生成器来运行脚本点击添加,然后点击连接但是每生成一个虚拟用户,需要花费负载生成器大约1-3M的内存空间…...

    2024/4/26 10:29:43
  9. 入门 - 07 - Java程序运行机制

    入门 - 07 - Java程序运行机制 在计算机的高级编程类型分为两种: 一、编译型(compile) 需通过编译器(compiler)将源代码编译成机器码,之后才能执行的语言。一般需经过编译(compile)、链接(linker)这两个步骤。编译是把源代码编译成机器码,链接是把各个模块的机器码和依…...

    2024/4/27 8:42:37
  10. python docx 模块替换 word内容

    from docx import Document doc = Document(r’D:\python\Python37\testWord\卢祥和.docx’) ‘’’ paragraph = document.add_paragraph(‘这是个段落11。’) #将一段新文本添加到文档末尾 prior_paragraph = paragraph.insert_paragraph_before(‘这是前面的段落11。’) pa…...

    2024/4/19 18:31:11
  11. (纪中)1397. 寻找星座 (Standard IO)

    时间限制: 1000 ms 空间限制: 131072 KB 具体限制 Goto ProblemSet题目描述 现在你在一张卫星图片中寻找星座,已知该星座在图片中正好出现一次,而且形状一样,方向一样,大小也一样。注意图片中可能有一些与该星座无关的星星。例如图111中的星座出现在图222的卫星图片中(用…...

    2024/4/28 0:24:49
  12. Pandas-03-文件读和存储

    以pandas读.csv文件和存储为.csv文件为例。版权声明:本文为博主原创文章,转载请注明原文出处,禁止白嫖!写作时间:2020-06-06 18:42目录1、pandas.read_csv读取文件2、快速浏览读入的数据3、pandas.DataFrame.to_csv写入文件4、参考资料 pandas非常擅长处理表格型数据,pan…...

    2024/4/27 23:36:25
  13. 直通车优化 提分 关键词 展现位置 相关性 买家体验 优化秘术:提升质量得分,打爆自然流量!

    话不多说直奔主题。 一个店铺想要长久良好的生存下去,那么店铺必须要有足够的流量作来维持,但也并不意味着什么流量都是来者不拒的。 流量可以分为付费和免费这两流量。一个店铺光靠付费流量肯定是不行的,做推广引流的目的,就是去通过付费去获取免费流量,这才是我们的初衷。…...

    2024/4/24 11:21:54
  14. 极大似然估计、最大后验概率估计和贝叶斯估计

    We can interpret the Bayes’ Rule...

    2024/4/24 11:21:50
  15. 手写分布式爬虫框架

    目录分布式爬虫框架 Demo起因弊端目标用最简单的代码实现一个爬虫建立爬虫模型(接口)使用集群,异构需要改动的点分布式后语 分布式爬虫框架 Demo 记录用Java开发一个简单的分布式爬虫框架,从最开始的十几行代码到开发一个支持集群、分布式的爬虫框架。 代码地址:单机版本 …...

    2024/4/26 0:42:51
  16. 《Spring Boot+Vue全站开发指南》第7章笔记:构建RESTFul服务

    构建RESTful服务 本章概要REST简介 JPA实现REST MongoDB实现REST7.1 REST简介 REST(Representational State Transfer)是一种Web软件架构风格,它是风格而不是标准,匹配或兼容这种架构风格的网络服务称为REST服务。REST服务简洁并且有层次,REST常基于HTTP、URI和XML以及HTM…...

    2024/4/24 11:21:49
  17. 立习习学python——第二天

    Python基础(二)赋值常量最基本内置数据类型数字布尔值字符串 赋值 1.链式赋值 x=y=123注意:变量x、y的地址是相同的。运行结果如下:2. 系列解包赋值 a,b,c=1,2,3应用:实现变量互换 c,d=4,6 c,d=d,c而在C语言中,需要另外一个变量进行倒腾。 常量 Python不支持常量,我们只…...

    2024/4/24 11:21:50
  18. LeetCode(top100)任务调度器

    任务调度器 题目描述 给定一个用字符数组表示的 CPU 需要执行的任务列表。其中包含使用大写的 A - Z 字母表示的26 种不同种类的任务。任务可以以任意顺序执行,并且每个任务都可以在 1 个单位时间内执行完。CPU 在任何一个单位时间内都可以执行一个任务,或者在待命状态。 然而…...

    2024/4/27 15:17:31
  19. HTML布局

    HTML 布局 - 使用 元素 div 元素是用于分组 HTML 元素的块级元素。 下面的例子使用五个 div 元素来创建多列布局: 实例666 主要的网页标题菜单 HTML CSS JavaScript内容在这里66666尝试一下 上面的 HTML 代码会产生如下结果:  HTML 布局 - 使用表格 使用 HTML 标签是创建…...

    2024/4/24 11:21:45
  20. 性能测试:Windows系统资源性能常用计数器

    https://blog.csdn.net/qq_26298403/article/details/52474127...

    2024/4/24 11:21:44

最新文章

  1. 256. 最大异或和(可持续化trie数,位运算,模板,* * )

    256. 最大异或和 - AcWing题库 给定一个非负整数序列 a&#xff0c;初始长度为 N。 有 M&#x1d440; 个操作&#xff0c;有以下两种操作类型&#xff1a; A x&#xff1a;添加操作&#xff0c;表示在序列末尾添加一个数 x&#xff0c;序列的长度 N 增大 1。Q l r x&#x…...

    2024/4/28 3:26:53
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. 实现窗口拖拽移动

    import Vue from "vue"; /* * 定义公共js里&#xff0c;在入口文件main.js中import&#xff1b; * 给elementUI的dialog上加上 v-dialogDrag 指令就可以实现弹窗的全屏和拉伸了。 */ // v-dialogDrag: 弹窗拖拽水平方向伸缩 Vue.directive(dialogDrag, { bind(e…...

    2024/4/21 18:20:44
  4. 【图论】知识点集合

    边的类型 neighbors(邻居)&#xff1a;两个顶点有一条共同边 loop&#xff1a;链接自身 link&#xff1a;两个顶点有一条边 parallel edges&#xff1a;两个顶点有两条及以上条边 无向图 必要条件&#xff1a;删掉顶点数一定大于等于剩下的顶点数 设无向图G<V,E>是…...

    2024/4/25 6:59:51
  5. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/4/26 18:09:39
  6. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/4/28 3:28:32
  7. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/4/26 23:05:52
  8. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/4/27 4:00:35
  9. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/4/27 17:58:04
  10. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/4/27 14:22:49
  11. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/4/28 1:28:33
  12. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/4/27 9:01:45
  13. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/4/27 17:59:30
  14. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/4/25 18:39:16
  15. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/4/28 1:34:08
  16. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/4/26 19:03:37
  17. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/4/28 1:22:35
  18. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/4/25 18:39:14
  19. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/4/26 23:04:58
  20. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/4/27 23:24:42
  21. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/4/25 18:39:00
  22. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/4/26 19:46:12
  23. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/4/27 11:43:08
  24. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/4/27 8:32:30
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57