【问题标题】:Kivy wait for animation to finish before continuingKivy 等待动画完成后再继续
【发布时间】:2016-05-01 14:37:41
【问题描述】:

在允许启动它的代码继续之前,我如何才能等待 kivy 动画完成?例如,以下方法更新小部件位置:

def update_actor_widget(self, actor):
    final = self._get_screen_pos(actor.location)
    a = Animation(x=final[0], y=final[1], duration=0.5)
    a.start(actor.widget)

我不希望它在 actor 实际上是它所属的位置之前返回(因此可能允许其他动画开始)。使用 time.sleep() 只是完全挂起应用程序。使用Animation.on_complete 确实会在动画完成时安排一些事情发生,但不会阻止调用动画的函数的执行。

【问题讨论】:

  • 尝试使用时钟对象来安排动画。 kivy.org/docs/api-kivy.clock.html?highlight=clock
  • 谢谢。一般来说,它并不能真正回答我的问题,但它可以解决我遇到的问题。如果您将您的评论改写为答案,我很乐意接受。
  • 我自己不确定我是否完全理解你的问题,只是把它放在这里以防万一它可能有帮助,这不是一个真正的答案。如果您设法使用 kivy Clock 对象解决了您的问题,请将其发布为答案:)。
  • 好吧,事实证明我并没有真正解决我的问题。我已经构建了类似此处所述的顺序动画stackoverflow.com/questions/27623010/…,但在动画完成之前我仍然无法禁用其余代码。我试图创建一个跟踪动画状态的布尔值(在 on_start 中设置 True 并在 on_complete 中设置 False 并在它为 True 时禁用输入),但由于某些奇怪的原因,即使动画明显运行,它也会保持 False .
  • 如果你不想在动画之后运行一些代码,你可以安排它,因为你知道动画需要多长时间。

标签: python animation kivy


【解决方案1】:

感谢大家的cmets,我终于让它工作了。这有点棘手,所以如果其他人想做类似的事情,我就是这样做的(在主游戏小部件类中):

def __init__(self):
    ...
    # Initializing stuff...
    ...
    self.anim_queue = []
    self.block_keyboard = False

def create_movement_animation(self, widget):
    self.anim_queue.append((widget, Animation(x=widget.expected_x, y=widget.expected_y))
    # Adding widget-animation tuple

def block(self):
    self.block_keyboard = True

def run_animation(self):
    if len(self.anim_queue)>0:
        w, a = self.anim_queue.pop(0)
        a.bind(on_start=lambda x,y: self.block(),
            on_complete=lambda x,y: self.run_animation())
        a.start(w)
    else:
        self.block_keyboard=False

def _on_key_down(self, keyboard, keycode, text, modifiers):
    if self.block_keyboard:
        return
    for actor in self.map.actors:
        actor.make_turn()
        if actor.moved:
            self.create_movement_animation(actor.widget)
    self.run_animation()

它的工作原理如下:_on_key_down 调用游戏逻辑代码来计算所有小部件的预期位置。所有需要移动的小部件以及预期的动画都放在self.anim_queue 中。 self.run_animation 不断通过 on_complete 调用自己,一路上将阻塞标志设置为 True,直到 self.anim_queue 用尽。此时它将其设置为 False 并退出,允许处理下一个按钮,从而开始下一回合。

我已经射击了我的腿几次,所以:首先,on_* 参数的参数在绑定期间进行评估,因此必须将它们包装在 lambda 中以防止所有动画同时触发。其次,您需要创建actor_moved() 检查,否则会有空动画将小部件从它们的位置移动到完全相同的位置,实际上冻结游戏 num-widgets*duration 秒。

【讨论】:

    猜你喜欢
    • 2015-10-03
    • 2013-11-25
    • 1970-01-01
    • 2013-04-25
    • 2019-11-01
    • 2021-05-06
    • 2021-05-21
    • 2014-02-03
    相关资源
    最近更新 更多