杂乱搞乱动画

时间:2013-07-24 03:59:36

标签: python linux animation clutter

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()

看看我的问题的这个例子:

enter image description here

对于那些不喜欢GIF的人来说,这是我用语言描述的问题: 我希望演员从中间向右移动,然后一直向左移动。相反,它只是从中间直线向左移动。

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

3 个答案:

答案 0 :(得分:2)

就像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])

这就是你所看到的。

如果你想连接两个动画,你必须使用completed函数连接到ClutterAnimation的{​​{1}}信号,以便Clutter可以创建一个新动画:

connect_after

我想指出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() 信号处理程序,并恢复缓动状态以避免每次更改actor的状态时创建隐式动画,但我会将其作为练习留给读者。

答案 1 :(得分:1)

请尝试以下代码:

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])
    )

答案 2 :(得分:0)

当你紧接着对着这些行

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