【问题标题】:Clutter messing up animations杂乱无章的动画
【发布时间】:2013-07-24 03:59:36
【问题描述】:

Clutter 没有做完整的动画。

这是我当前的代码:

from gi.repository import Clutter, Gtk
import sys

def onClick(actor, event):
    actor.animatev(Clutter.AnimationMode.LINEAR, 1000, ["x"], [280])  # clutter does not seem to be running this line
    actor.animatev(Clutter.AnimationMode.LINEAR, 1000, ["x"], [20])

def main():
    Clutter.init(sys.argv)

    # Colors
    red = Clutter.Color().new(255, 0, 0, 255)
    black = Clutter.Color().new(0, 0, 0, 255)

    # Create Stage
    stage = Clutter.Stage()
    stage.set_title("Basic Usage")
    stage.set_size(400, 200)
    stage.set_color(black)

    # Rectangle Actor
    actor = Clutter.Rectangle()
    actor.set_size(100, 50)
    actor.set_position(150, 100)
    actor.set_color(red)
    actor.set_reactive(True)
    actor.connect("button-press-event", onClick)

    # Add Actor to the Stage
    stage.add_actor(actor)
    stage.connect("destroy", lambda w:  Clutter.main_quit())
    stage.show_all()

    Clutter.main()

if __name__ == '__main__':
    main()

看看我的问题的这个说明:

对于那些不喜欢 gif 的人,这里是我用文字描述的问题: 我希望演员从中间向右移动,然后一直向左移动。相反,它只是从中间直接向左移动。

这是什么原因造成的,我该如何解决?

【问题讨论】:

  • 您介意切换动画语句的顺序并告诉我它的作用吗?我想我知道这个问题的答案。
  • @Stephan 谢谢。切换两条线使其从中间向右移动,而不是从中间向左移动。
  • 好的,我知道答案了,一会儿贴出来
  • ...地狱就是我们应该如何向对方解释我们的问题。 +1 仅用于 gif!

标签: python linux animation clutter


【解决方案1】:

就像 ClutterActor.animate() 的文档所说:

在一个已经被动画化的actor上调用这个函数将会 使当前动画随着新的最终值而改变, 新的宽松模式和新的持续时间 https://developer.gnome.org/clutter/stable/clutter-Implicit-Animations.html#clutter-actor-animate

表示如下代码:

actor.animatev(Clutter.AnimationMode.LINEAR, 1000, ["x"], [280])
actor.animatev(Clutter.AnimationMode.LINEAR, 1000, ["x"], [20])

完全等同于:

actor.animatev(Clutter.AnimationMode.LINEAR, 1000, ["x"], [20])

这就是你所看到的。

如果你想链接两个动画,你必须连接到ClutterAnimationcompleted信号,使用connect_after函数,这样Clutter才能创建一个新动画:

def moveLeft (animation, actor):
    actor.animatev(Clutter.AnimationMode.LINEAR, 1000, ["x"], [20])

actor.animatev(Clutter.AnimationMode.LINEAR, 1000, ["x"], [280]).connect_after('completed', moveLeft)

我想指出 animatev()ClutterAnimation 已被弃用;它们可以通过使用显式 Clutter.KeyframeTransition 或隐式转换来替换,例如:

from gi.repository import Clutter

Clutter.init(None)

stage = Clutter.Stage()
stage.connect('destroy', lambda x: Clutter.main_quit())

actor = Clutter.Actor()
actor.set_background_color(Clutter.Color.get_static(Clutter.StaticColor.RED))
actor.set_reactive(True)
actor.set_size(32, 32)
stage.add_child(actor)
actor.set_position(82, 82)

def moveLeft(actor):
    actor.set_x(20)

def moveRight(actor):

    actor.set_easing_duration(1000)
    actor.set_easing_mode(Clutter.AnimationMode.LINEAR)
    actor.set_x(280)
    actor.connect('transition-stopped::x', lambda a, n, t: moveLeft(actor))

actor.connect('button-press-event', lambda a, e: moveRight(actor))

stage.show()
Clutter.main()

它可以比这更复杂;您还需要记住断开transition-stopped::x 信号处理程序,并恢复缓动状态以避免每次更改演员的状态时创建隐式动画,但我将把它作为练习留给读者。

【讨论】:

    【解决方案2】:

    试试下面的代码:

    def onClick(actor, event):
        animation1 = actor.animatev(Clutter.AnimationMode.LINEAR, 1000, ["x"], [280])
        animation1.connect_after(
            'completed',
            lambda animation: actor.animatev(Clutter.AnimationMode.LINEAR, 1000, ["x"], [20])
        )
    

    【讨论】:

      【解决方案3】:

      当你对一行执行这些操作时

      def onClick(actor, event):
          actor.animatev(Clutter.AnimationMode.LINEAR, 1000, ["x"], [280])
          actor.animatev(Clutter.AnimationMode.LINEAR, 1000, ["x"], [20])
      

      Clutter 无需等待对方完成即可完成这两件事。这意味着在第二个命令接管之前,第一个命令几乎没有时间移动代理。

      这里是一个使用“完成”信号的例子:

      def onClick(actor, event):
          animate(actor)
      
      def animate(actor):
          firstAnimation = actor.animatev(Clutter.AnimationMode.LINEAR, 1000, ["x"], [280]) 
      
          firstAnimation.connect_after("completed", moveLeft)
      
      def moveLeft():
          self.actor.animatev(Clutter.AnimationMode.LINEAR, 1000, ["x"], [20])
      

      Here is the documentation on clutter animations
      Here is the documentation on the "completed" signal
      Here is some working example code

      【讨论】:

      • 当我在两行之间添加它时: while (actor.get_x()
      • @DanielTA 我很怀疑,您需要以合法的方式进行操作,而不是 hack 方式。我最近完成了真正的答案
      • @DanielTA 对不起,我提交了这个错误的答案,这只是一个临时的黑客攻击,请查看更新的答案。
      • 你越来越近了,它向左移动,但立即,它没有动画。它向右移动,然后仅出现在左侧。
      • @DanielTA here 是我想要模仿的东西 也许阅读并尝试调整?我会继续调查的
      猜你喜欢
      • 1970-01-01
      • 2017-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-12
      • 2010-11-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多