我对Python / PyGame中的定时事件有疑问。 我正在制作一个2D侧滚动平台游戏,目标是触及所有敌人, 在收集完所有敌人之后,我希望相机中心位于“出口区”。
相机在“出口挡板”上居中后,我想要移除周围的挡块并居中 相机重新回到播放器上。所以玩家可以看到周围的块如何 被删除,可以到达“退出区块”。
在所有敌人被收集后,我已经将代码集中在“出口区块”上, 但是然后相机会切换到播放器,然后移除周围的块。 相机在播放器上居中后,将移除这些块。
我在这里缺少关键部位。我试过pygame.time.wait() 在周围的街区被移除后。有帮助吗?请告诉我代码 我提供的还不够。
编辑:我已将主要游戏循环分解为:
level.handle_events(pygame.event.get())
level.update()
level.render(screen)
pygame.display.flip()
问题可能是,主循环处理USEREVENT,之后相机更新并且只有 之后才完成绘图,这就是为什么无法看到周围块的移除?但我仍然不知道如何继续......
相关代码:
玩家的初始:
self.EXITBLOCKCLEAR = pygame.USEREVENT + 1
玩家的碰撞检测:
for e in enemies_group:
if pygame.sprite.collide_rect(self, e)
if len(enemies_group) == 0:
self.exit_block_reveal = True
pygame.time.set_timer(self.EXITBLOCKCLEAR, 3000)
级别更新:
if self.player.exit_block_reveal == False:
self.camera.update(self.player) # camera follows player
else:
self.camera.update(self.exit_block) # camera centered on "exit block"
级别的事件处理:
if event.type == self.player.EXITBLOCKCLEAR:
if self.player.exit_block_reveal == True:
for block in self.disappearing_block_group:
block.kill()
self.disappearing_block_group.remove(block) # remove the surrounding blocks
if len(self.disappearing_block_group) == 0: # when blocks are removed, center camera back to player
self.player.exit_block_reveal = False
最新编辑:让代码生效
我玩了,我让它像我想要的那样工作。这对我来说非常适合。
更新后的代码(这些只是原始代码的变更)
使用此代码,当我收集最后一个敌人时,相机移动到“退出阻止”状态3秒钟,周围的块被移除,再过3秒后,相机会回到播放器。
级别的初始:
self.i = 0
级别的事件处理:
if event.type == self.player.EXITBLOCKCLEAR:
for block in self.disappearing_block_group:
block.kill()
self.disappearing_block_group.remove(block)
if len(self.disappearing_block_group) == 0 and self.i < 1:
self.i += 1
self.player.exit_block_reveal = True
else:
self.player.exit_block_reveal = False
pygame.time.set_timer(self.player.EXITBLOCKCLEAR, 0) # stop calling USEREVENT
答案 0 :(得分:0)
问题是你的块清除代码在关卡事件处理程序中设置,然后重置用于在屏幕实际重绘之前重新定位摄像机的开关。一旦事件处理程序看到exit_block_reveal
是True
,它会清除退出块。列表disappearing_exit_group
被清空,功能继续。清除所有块的循环之后的下一条指令检查是否有任何块 - if len(self.disappearing_block_group) == 0:
。我们知道不会有,因为迭代器刚刚将它们杀死了。触发if
块,在更新程序知道更改之前将exit_block_reveal
设置回False。
简而言之:碰撞检测器将exit_block_reveal
设置为True,但事件处理程序在更新程序看到它之前将其设置回False。
您的解决方案通过向块删除功能添加一个循环来工作,但我认为您可以在没有该附加属性的情况下执行此操作。考虑对事件处理程序进行此修改,在 disappearing_block_group
切换之前执行<{1>}检查,而不是在之后:
exit_block_reveal
在此,我所做的就是将if event.type == self.player.EXITBLOCKCLEAR:
if self.player.exit_block_reveal:
if not self.disappearing_block_group: # disappearing_block_group still has contents at this point, so player.exit_block_reveal won't toggle!
self.player.exit_block_reveal = False
for block in self.disappearing_block_group:
block.kill()
self.disappearing_block_group = list() # ** SEE NOTE **
切换移到exit_block_reveal
真值检查之上。由于该列表仍有内容,disappearing_block_group
在下一个周期之前不会运行。此时,列表已减少(或初始化,如果您按照所示重新分配),并且if not self.disappearing_block_group:
块运行。由于if
中没有元素,disappearing_block_group
块无关,并且运行零迭代。
注意:您也可以一次清除整个列表,而不是删除每个元素。你根本就不需要这样!如果您有兴趣的话,这只是一个选择。
希望这有帮助!