在本篇文章中,主要学习射击子弹时外星人消失,达到击杀外星人的效果
一、编程思路
1.1击杀
我们需要在碰撞发生后让外星人立即消失,故在更新子弹的位置后检测碰撞。我们创建一个字典,这个字典的每一个键都是一颗子弹,而相应的键值则包含击中的外星人。sprite.groupcollide()将每颗子弹的rect与每个rect比较。每当有子弹和外星人的rect重叠时,判断其被子弹击中,groupcollide()就在返回字典中添加一个键-值对。
game_functions.py
def update_bullets(aliens, bullets):
"""更新子弹的位置,并删除已消失的子弹"""
--snip--
# 检查是否有子弹击中了外星人
# 如果是这样,就删除相应的子弹和外星人
collisions = pygame.sprite.groupcollide(bullets, aliens, True, True)
紧接着在alien_invasion.py的while循环中加入该方法
# 开始游戏主循环
while True:
gf.check_events(ai_settings, screen, ship, bullets)
ship.update()
gf.update_bullets(aliens, bullets)
gf.update_aliens(ai_settings, aliens)
gf.update_screen(ai_settings, screen, ship, aliens, bullets)
此时的运行效果如下:
1.2产生新外星人
要在所有外星人被消灭之后再产生新的一群外星人,我们需要检查aliens编组是否为空,如果为空,就调用empty()删除所有元素,从而删除现有的子弹,再调用creat_fleet(),产生一群新的外星人
def update_bullets(ai_settings, screen, ship, aliens, bullets):
--snip--
# 检查是否有子弹击中了外星人
# 如果是,就删除相应的子弹和外星人
collisions = pygame.sprite.groupcollide(bullets, aliens,True, True)
if len(aliens) == 0:
# 删除现有的子弹并新建一群外星人
bullets.empty()
create_fleet(ai_settings, screen, ship, aliens)
1.3 重构update_bullets()
把处理子弹和外星人碰撞的代码已到一个独立的函数中,避免该函数过长。
def update_bullets(ai_settings, screen, ship, aliens, bullets):
"""更新子弹的位置,删除已消失的子弹"""
#更新子弹位置
bullets.update()
# 删除已经消失的子弹
for bullet in bullets.copy():
if bullet.rect.bottom <= 0:
bullets.remove(bullet)
check_bullet_alien_collisions(ai_settings, screen,ship, aliens, bullets)
1.4 结束游戏
在外星人与飞船碰撞时或者外星人到达屏幕底端就结束游戏。首先我们要检测外星人与飞船是否碰撞,调用方法spritecollideany(),它检查编组中的外星人是否发生碰撞,找到与飞船碰撞的外星人后就停止遍历编组。
# 检测外星人和飞船之间的碰撞
if pygame.sprite.spritecollideany(ship, aliens):
print("Ship hit!!!")
新建一个GameStats.py,通过跟踪游戏的统计信息来记录飞船被撞了多少次,reset_stats()中初始化大部分统计信息,然后在__init__中调用,有外星人撞到飞船时,我们将余下的飞船数减1,创建一群新的外星人,并将飞船重新放置到屏幕底端中央,并暂停0.5秒。
game_stats.py
class GameStates():
"""跟踪游戏的统计信息"""
def __init__(self, ai_settings):
"""初始化统计信息"""
self.ai_settings = ai_settings
self.reset_stats()
#游戏刚启动时处于活动状态
self.game_active = True
def reset_stats(self):
"""初始化在游戏运行期间可能变化的统计信息"""
self.ships_left = self.ai_settings.ship_limit
game_functions.py