2.6 结束游戏
如果玩家根本不会输,游戏还有什么趣味和挑战性可言?如果玩家没能在足够短的时间内将整群敌人都消灭干净,且有敌人撞到了飞船,飞船将被摧毁。与此同时,我们还限制了可供玩家使用的飞船数,而有敌人抵达屏幕底端时,飞船也将被摧毁。玩家用光了飞船后,游戏便结束。
2.6.1 检测飞船与敌人的碰撞
在更新每个敌人的位置后立即检测外星人和飞船之间的碰撞:
def update_aliens(ai_settings,aliens):
#检查是否有敌人到屏幕边缘,更新所有敌人位置
check_fleet_edges(ai_settings,aliens)
aliens.update()
#检测外星人与飞船之间的碰撞
if pygame.sprite.spritecollideany(ship,aliens):
print("Ship hit!!!")
然后需要将ship传递给update_aliens():
while True:
gf.check_events(ai_settings,screen,ship,bullets)
ship.update()
gf.update_bullets(ai_settings,screen,ship,aliens,bullets)
gf.update_aliens(ai_settings,ship,aliens)
gf.update_screen(ai_settings,screen,ship,aliens,bullets)
2.6.2 响应外星人与飞船碰撞
现在需要确定敌人与飞船发生碰撞时,该做些什么。我们不销毁ship 实例并创建一个新的ship 实例,而是通过跟踪游戏的统计信息来记录飞船被撞了多少次(跟踪统计信息
还有助于记分)。
下面来编写一个用于跟踪游戏统计信息的新类——GameStats ,并将其保存为文件game_stats.py:
class GameStats():
# 跟踪游戏的统计信息
def __init__(self,ai_settings):
# 初始化统计信息
self.ai_settings = ai_settings
self.reset_stats()
def reset_stats(self):
# 初始化在游戏运行期间可能变化的统计信息
self.ships_left = self.ai_settings.ship_limit
修改一下setting中飞船的限制数:
#飞船设置
self.ship_speed_factor = 1.5
self.ship_limit = 3
我们还需对alien_invasion.py做些修改,以创建一个GameStats 实例:
import pygame
from pygame.sprite import Group
from setting import Settings
from game_stats import GameStats
from ship import Ship
from alien import Alien
import game_functions as gf
def rungame():
#初始化游戏并创建一个屏幕对象
pygame.init()
#实例化设置对象
ai_settings = Settings()
screen = pygame.display.set_mode((ai_settings.screen_width,ai_settings.screen_height))
pygame.display.set_caption("Alien Invasion")
#创建一个用于存储游戏统计信息的实例
stats = GameStats(ai_settings)
#创建一只飞船
ship = Ship(ai_settings,screen)
#创建一个用于存储子弹的编组
bullets = Group()
#创建一个用于存储敌人的编组
aliens = Group()
# #创建一个外星人
# alien = Alien(ai_settings,screen)
# 创建一群敌人
gf.create_fleet(ai_settings,screen,ship,aliens)
#开始游戏主循环
while True:
gf.check_events(ai_settings,screen,ship,bullets)
ship.update()
gf.update_bullets(ai_settings,screen,ship,aliens,bullets)
gf.update_aliens(ai_settings,stats,screen,ship,aliens,bullets)
gf.update_aliens(ai_settings,ship,aliens)
gf.update_screen(ai_settings,screen,ship,aliens,bullets)
rungame()
有敌人撞到飞船时,我们将余下的飞船数减1,创建一群新的敌人,并将飞船重新放置到屏幕底端中央(我们还将让游戏暂停一段时间,让玩家在新敌人群出现前注意到发生了碰撞,并将重新创建敌人群)。
下面将实现这些功能的大部分代码放到函数ship_hit() 中:
def ship_hit(ai_settings,stats,screen,ship,aliens,bullets):
# 响应被外星人撞到的飞船
# 将ships_left减1
stats.ship_left -= 1
# 清空敌人列表和子弹列表
aliens.empty()
bullets.empty()
# 创建一群新的敌人,并将飞船放到屏幕底端中央
create_fleet(ai_settings,screen,ship,aliens)
ship.center_ship()
# 暂停
sleep(0.5)
def 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)
下面我们添加center_ship()方法到ship.py。
def center_ship(self):
# 让飞船在屏幕上居中
self.center = self.screen_rect.centerx
2.6.3 有敌人到达屏幕底端
如果有敌人到达屏幕底端,我们将像有敌人撞到飞船那样作出响应。添加一个执行这项任务的新函数,并将其命名为update_aliens() :
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)
2.6.4 游戏结束
现在这个游戏看起来更完整了,但它永远都不会结束,只是ships_left 不断变成更小的负数。下面在GameStats 中添加一个作为标志的属性game_active ,以便在玩家的飞船用完后结束游戏:
def __init__(self,ai_settings):
# 初始化统计信息
self.ai_settings = ai_settings
self.reset_stats()
# 游戏刚启动时处于活动状态
现在在ship_hit() 中添加代码,在玩家的飞船都用完后将game_active 设置为False :
def ship_hit(ai_settings,stats,screen,ship,aliens,bullets):
# 响应被外星人撞到的飞船
# 将ships_left减1
if stats.ships_left > 0:
stats.ship_left -= 1
# 清空敌人列表和子弹列表
aliens.empty()
bullets.empty()
# 创建一群新的敌人,并将飞船放到屏幕底端中央
create_fleet(ai_settings,screen,ship,aliens)
ship.center_ship()
# 暂停
sleep(0.5)
else:
stats.game_active = False
先到这里啦~
网友评论