上节我们绘制了play按钮,这节我们来实现开始游戏的功能。
3.1.3 开始游戏
我们需要更新game_function函数,监视与开始按钮相关的鼠标事件:
def check_events(ai_settings,screen,stats,play_button,ship,bullets):
#响应案件和鼠标事件
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.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 = True
我们首先修改了check_events() 的定义,在其中添加了形参stats 和play_button。我们将使用stats 来访问标志game_active,并使用play_button来检查玩家是否单击了Play按钮。
无论玩家单击屏幕的什么地方,Pygame都将检测到一个MOUSEBUTTONDOWN事件,但我们只想让这个游戏在玩家用鼠标单击Play按钮时作出响应。为此,我们使用了pygame.mouse.get_pos() ,它返回一个元组,其中包含玩家单击时鼠标的x和y坐标。我们将这些值传递给函数check_play_button(),而这个函数使用collidepoint() 检查鼠标单击位置是否在Play按钮的rect内。如果是这样的,我们就将game_active设置为True,让游戏就此开始!
在alien_invasion.py 中调用check_events() ,需要传递另外两个实参——stats 和play_button:
#开始游戏主循环
while True:
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,aliens,bullets,play_button)
至此,你应该能够开始这个游戏了。游戏结束时,game_active 应为False ,并重新显示Play按钮。
3.1.4 重置游戏
前面编写的代码只处理了玩家第一次单击Play按钮的情况,而没有处理游戏结束的情况,因为没有重置导致游戏结束的条件。 为在玩家每次单击Play按钮时都重置游戏,需要重置统计信息、删除现有的敌人和子弹、创建一群新的敌人,并让飞船居中,如下所示,我们需要修改game_function模块:
def check_play_button(ai_settings,screen,bullets,aliens,ship,stats,play_button,mouse_x,mouse_y):
# 在玩家单击play按钮时,开始新游戏
if play_button.rect.collidepoint(mouse_x,mouse_y):
# 重置游戏统计信息
stats.reset_stats()
stats.game_active = True
# 清空敌人列表和子弹列表
aliens.empty()
bullets.empty()
# 创建一群新的敌人,并让飞船居中
create_fleet(ai_settings,screen,ship,aliens)
ship.center_ship()
我们更新了check_play_button() 的定义,使其能够访问ai_settings 、stats 、ship 、aliens 和bullets 。为重置在游戏期间发生了变化的设置以及刷新游戏的 视觉元素,它需要这些对象。
首先,我们重置了游戏统计信息,给玩家提供了三艘新飞船。接下来,我们将game_active 设置为True (这样,这个函数的代码执行完毕后,游戏就会开始),清空编组aliens 和bullets,创建一群新的敌人,并将飞船居中。
check_events() 的定义需要修改,调用check_play_button() 的代码亦如此:
def check_events(ai_settings,screen,stats,play_button,ship,bullets):
#响应案件和鼠标事件
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.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,bullets,aliens,ship,stats,play_button,mouse_x,mouse_y)
下面来修改alien_invasion.py中调用check_events() 的代码,以将实参aliens 传递给它:
gf.check_events(ai_settings,screen,stats,play_button,ship,aliens,bullets)
现在,每当玩家单击Play按钮时,这个游戏都将正确地重置,让玩家想玩多少次就玩多少次!
3.1.5 将Play按钮切换到非活动状态
当前,Play按钮存在一个问题,那就是即便Play按钮不可见,玩家单击其原来所在的区域时,游戏依然会作出响应。游戏开始后,如果玩家不小心单击了Play按钮原来所处的区域,游戏将重新开始!
为修复这个问题,可让游戏仅在game_active 为False 时才开始:
def check_play_button(ai_settings,screen,bullets,aliens,ship,stats,play_button,mouse_x,mouse_y):
# 在玩家单击play按钮时,开始新游戏
button_clicked = play_button.rect.collidepoint(mouse_x,mouse_y)
if button_clicked and not stats.game_active:
# 重置游戏统计信息
stats.reset_stats()
stats.game_active = True
# 清空敌人列表和子弹列表
aliens.empty()
bullets.empty()
# 创建一群新的敌人,并让飞船居中
create_fleet(ai_settings,screen,ship,aliens)
ship.center_ship()
标志button_clicked 的值为True 或False,仅当玩家单击了Play按钮且游戏当前处于非活动状态时,游戏才重新开始。为测试这种行为,可开始新游戏,并不断地单击Play按钮原来所在的区域。如果一切都像预期的那样工作,单击Play按钮原来所处的区域应该没有任何影响。
3.1.6 隐藏光标
为让玩家能够开始游戏,我们要让光标可见,但游戏开始后,光标只会添乱。为修复这种问题,我们在游戏处于活动状态时让光标不可见,修改game_function模块:
def check_play_button(ai_settings,screen,bullets,aliens,ship,stats,play_button,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()
通过向set_visible() 传递False ,让Pygame在光标位于游戏窗口内时将其隐藏起来。 游戏结束后,我们将重新显示光标,让玩家能够单击Play按钮来开始新游戏。相关的代码如下:
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
pygame.mouse.set_visible(True)
在ship_hit() 中,我们在游戏进入非活动状态后,立即让光标可见。关注这样的细节让游戏显得更专业,也让玩家能够专注于玩游戏而不是费力搞明白用户界面。
到这里,我们的开始按钮就算是完整的绘制完成了。下节开始实现提高等级的功能~
网友评论