python pygame - 以set_timer事件为中心的相机

时间:2013-11-12 10:58:03

标签: python scroll pygame

我对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

1 个答案:

答案 0 :(得分:0)

问题是你的块清除代码在关卡事件处理程序中设置,然后重置用于在屏幕实际重绘之前重新定位摄像机的开关。一旦事件处理程序看到exit_block_revealTrue,它会清除退出块。列表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块无关,并且运行零迭代。

注意:您也可以一次清除整个列表,而不是删除每个元素。你根本就不需要这样!如果您有兴趣的话,这只是一个选择。

希望这有帮助!