来源:《Python编程:从入门到实践》
在更新每个外星人的位置后立即检测外星人和飞船之间的碰撞
game_functions.py
def update_aliens(ai_settings, ship, aliens):
"""
检查是否有外星人位于屏幕边缘,并更新整群外星人的位置
"""
check_fleet_edges(ai_settings, aliens)
aliens.update()
# 检测外星人和飞船之间的碰撞
if pygame.sprite.spritecollideany(ship, aliens):
print("Ship hit!!!")
方法spritecollideany()接受两个实参:一个精灵和一个编组
如果没有发生碰撞,spritecollideany()返回None,因此if代码块不会执行
alien_invasion.py
def update_aliens(ai_settings, ship, aliens):
"""
检查是否有外星人位于屏幕边缘,并更新整群外星人的位置
"""
check_fleet_edges(ai_settings, aliens)
aliens.update()
# 检测外星人和飞船之间的碰撞
if pygame.sprite.spritecollideany(ship, aliens):
print("Ship hit!!!")
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
ships_left
,它在游戏运行期间将不断变化一开始玩家拥有的飞船数存储在settings.py的ship_limit中
:settings.py
# 飞船的设置
self.ship_speed_factor = 1.5
self.ship_limit = 3
创建一个GameStats实例
alien_invasion.py
--snip--
from game_stats import GameStats
from ship import Ship
--snip--
def run_game():
--snip--
pygame.display.set_caption("Alien Invasion")
# 创建一个用于存储游戏统计信息的实例
stats = GameStats(ai_settings)
--snip--
# 开始游戏的主循环
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)
--snip--
game_functions.py
import sys
from time import sleep
--snip--
def ship_hit(ai_settings, stats, screen, ship, aliens, bullets):
"""响应被外星人撞到的飞船"""
# 将ship_left减去1
stats.ships_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):
--snip--
# 检测外星人和飞船之间的碰撞
if pygame.sprite.spritecollideany(ship, aliens):
ship_hit(ai_settings, stats, screen, ship, aliens, bullets)
从模块time导入函数sleep(),以便使用它来暂停游戏
ship_hit()在飞船外星人相撞时做出响应
在Ship类中添加方法center_ship()
函数sleep()执行完毕后,将接着执行函数update_screen(),将新的外星人群绘制到屏幕
ship.py
def center_ship(self):
"""让飞船在屏幕上居中"""
self.center = self.screen_rect.centerx
注意:我们根本没有创建多艘飞船,在整个游戏运行期间,都只创建了一个飞船实例,并在该飞船被撞到时将其居中
如果有外星人到达屏幕底端,将像有外星人撞到飞船那样做出响应
新函数check_aliens_bottom()
game_functions.py
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)
break
def update_aliens(ai_settings, stats, screen, ship, aliens, bullets):
--snip--
# 检查是否有外星人到达屏幕底端
check_aliens_bottom(ai_settings, stats, screen, ship, aliens, bullets)
如果有外星人到达屏幕底端,就调用ship_hit()
game_stats.py
def __init__(self, ai_settings):
--snip--
# 游戏刚启动时处于活动状态
self.game_active = True
在玩家的飞船用完后将game_active设置为False
:game_functions.py
def ship_hit(ai_settings, stats, screen, ship, aliens, bullets):
"""响应被外星人撞到的飞船"""
if stats.ships_left > 0:
# 将ship_left减去1
stats.ships_left -= 1
--snip--
# 暂停一会儿
sleep(0.5)
else:
stats.game_active = False
alien_invasion.py
# 开始游戏的主循环
while True:
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, ship, aliens, bullets)