Android:位图的补间动画

7
我的应用程序通过在视图的onDraw()方法中调用以下内容来实现自己的精灵:
  canvas.drawBitmap(sprite.getBitmap(), sprite.getX(), sprite.getY(), null);

该应用是一个物理模拟器,到目前为止这个功能运作得很好。但现在我想通过在某些事件发生时在精灵之间进行图像变形来增强动画效果。
例如- 当发生碰撞时,我想播放爆炸动画。我的想法是用爆炸PNG替换通常的精灵位图,并使用Android“补间动画”使爆炸变大。
但是Android tween animation example 假定您在XML配置中的某个地方静态定义了一个 ImageView
是否有一种方法可以使用补间动画来动画化在onDraw()中绘制的位图?还是我需要将我的精灵转换为使用某种类型的ImageView?如果是后者,请指向一个在Android中适当的精灵动画示例?
谢谢
4个回答

10
我在Java中构建了一个通用的Tween Engine, 您可以使用它来为任何东西(包括精灵)创建动画。它经过优化,适用于Android和游戏开发,因为它不会在运行时分配任何内容,以避免任何垃圾回收。此外,所有Tweens都被池化,因此实际上根本没有垃圾收集!您可以在此处查看完整的演示:适用于Android应用程序,或者在此处查看WebGL HTML页面(需要Chrome)
您只需实现接口即可使所有精灵支持Tween。您甚至无需更改Sprite类,只需创建一个实现>的类 SpriteTweenAccessor,并将其在初始化时注册到引擎中。请参阅 GetStarted wiki页面 ;)
我还正在构建一个可嵌入到任何应用程序中的可视时间轴编辑器。 它将提供类似于Flash作者工具和Expression Blend (Silverlight开发工具)的时间线。
整个引擎都有详细的文档(所有公共方法和类都有详细的Javadoc),而且语法与在Flash世界中使用的Greensock's TweenMax/TweenLite引擎非常相似。请注意,它支持每个Robert Penner缓动方程式。
项目主页: http://code.google.com/p/java-universal-tween-engine/ logo

// Arguments are (1) the target, (2) the type of interpolation, 
// and (3) the duration in seconds. Additional methods specify  
// the target values, and the easing function. 

Tween.to(mySprite, Type.POSITION_XY, 1.0f).target(50, 50).ease(Elastic.INOUT);

// Possibilities are:

Tween.to(...); // interpolates from the current values to the targets
Tween.from(...); // interpolates from the given values to the current ones
Tween.set(...); // apply the target values without animation (useful with a delay)
Tween.call(...); // calls a method (useful with a delay)

// Current options are:

yourTween.delay(0.5f);
yourTween.repeat(2, 0.5f);
yourTween.repeatYoyo(2, 0.5f);
yourTween.pause();
yourTween.resume();
yourTween.setCallback(callback);
yourTween.setCallbackTriggers(flags);
yourTween.setUserData(obj);

// You can of course chain everything:

Tween.to(...).delay(1.0f).repeat(2, 0.5f).start();

// Moreover, slow-motion, fast-motion and reverse play is easy,
// you just need to change the speed of the update:

yourTween.update(delta * speed);

当然,没有提供构建强大序列的方式,任何缓动引擎都不会完整 :)

Timeline.createSequence()
    // First, set all objects to their initial positions
    .push(Tween.set(...))
    .push(Tween.set(...))
    .push(Tween.set(...))

    // Wait 1s
    .pushPause(1.0f)

    // Move the objects around, one after the other
    .push(Tween.to(...))
    .push(Tween.to(...))
    .push(Tween.to(...))

    // Then, move the objects around at the same time
    .beginParallel()
        .push(Tween.to(...))
        .push(Tween.to(...))
        .push(Tween.to(...))
    .end()

    // And repeat the whole sequence 2 times
    // with a 0.5s pause between each iteration
    .repeatYoyo(2, 0.5f)

    // Let's go!
    .start();
我希望你已经被说服了 :) 已经有很多人在游戏中或用于Android UI动画中使用该引擎。

我刚刚更新了一下描述,因为自从我第一次写答案以来,引擎已经取得了巨大的进步 :) - Aurelien Ribon
@AurélienRibon,它是否提供从一个精灵到另一个精灵的动画? - Moha the almighty camel

1

你可以使用补间动画来实现动画效果,而不需要从xml文件中获取ImageView,但它确实需要成为视图层次结构中的一个View。

Canvas中进行的绘制对于视图层次结构是不透明的。我认为你有两个选择:

  1. 在自定义视图上叠加一个ImageView,并使用补间动画来对其进行动画处理。
  2. 使用Canvas绘制例程来实现爆炸动画。

我认为使用Canvas例程以及它们的矩阵变换是有意义的,因为你可能已经在应用程序中有一个动画线程。


1
如果你正在制作一个游戏,你可以使用向量(数学)来更新图像的位置,然后使用getX和getY来绘制它们。你应该迭代并以某个速度在某个方向上更新这个向量。 - Marcos Vasconcelos
@Marcos:我已经在我的Sprite类中实现了一种向量(x/y位置,x/y速度)。我是否忽略了某个标准类? - George Armhold
你认为使用ImageView来进行绝对定位的精灵动画,然后依靠它们进行绘制是有意义的吗?这是我在iPhone上使用核心动画常用的动画类型,而且我很惊讶类似的东西不是Android中推荐的示例。Android似乎鼓励手动定期更新画布。我想知道这是否仅仅因为我选择的示例是物理模拟,而且没有自动建模数十个相互施加引力的粒子的方法。 - George Armhold
我认为不是这样,虽然我在这个领域的经验相对较少。ImageView 应该在视图层次结构中,我认为它通常不用作基于画布的视图的叠加层。 - Matthew
抱歉,我不想评论那个。请查看答案。 - Marcos Vasconcelos

0

你可以在Adobe Flash中绘制和动画化你的爆炸效果,使用swfSheet或类似工具导出精灵图像,然后使用帧动画


0

如果您正在创建游戏,可以使用向量(数学)来更新图像的位置,然后使用getX和getY进行绘制。您应该迭代并以某个方向通过某个速度更新此向量。

这些向量不是本地的(游戏API有)。

您需要循环迭代并更新位置,然后重新绘制。

对于游戏而言,使用诸如ImageView之类的组件来制作动画并不是一个好主意。它们需要系统在一段时间内反复计算所有布局。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接