ibgdx的ui库可以实现一些动画效果,但是做游戏来说可能有些不足。Universal Tween Engine是一个纯java实现的动画库。

地址:http://code.google.com/p/java-universal-tween-engine/

只要能够用float表示的一切java对象它可以让它动画化,可以使用于Libgdx、Android、Swing等等。

Universal Tween Engine使用一般流程

使用Universal Tween Engine最重要的一个步骤就是实现TweenAccessor接口,这个接口定义了getValues和setValues方法。

然后Engine中注册对应的接口。然后定义一些动画效果并添加到管理器中。最后用update方法更新时间。

具体的可以参考一下Wiki:http://code.google.com/p/java-universal-tween-engine/wiki/GetStarted

在libgdx中实现简单动画

我比较喜欢使用Stage,所以下面的例子都是Stage中的。

首先实现TweenAccessor接口,我没有区分对待,比如给Image写一个,再给Button写个啥的。我直接给Actor写了一个,这样都可以用。

getValues和setValues中我定义了3中操作:只修改X值;只修改Y值;修改X和Y值。


123
public static final int POSITION_X = 1;public static final int POSITION_Y = 2;public static final int POSITION_XY = 3;


这里注意一下getValues的返回值,你修改或者操作了几个值就返回几。

代码如下:


1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
package com.cnblogs.htynkn;import aurelienribon.tweenengine.TweenAccessor;import com.badlogic.gdx.scenes.scene2d.Actor;public class ActorAccessor implements TweenAccessor {public static final int POSITION_X = 1;public static final int POSITION_Y = 2;public static final int POSITION_XY = 3;@Overridepublic int getValues(Actor target, int tweenType, float[] returnValues) {switch (tweenType) {case POSITION_X:returnValues[0] = target.x;return 1;case POSITION_Y:returnValues[0] = target.y;return 1;case POSITION_XY:returnValues[0] = target.x;returnValues[1] = target.y;return 2;default:assert false;return -1;}}@Overridepublic void setValues(Actor target, int tweenType, float[] newValues) {switch (tweenType) {case POSITION_X:target.x = newValues[0];break;case POSITION_Y:target.y = newValues[0];break;case POSITION_XY:target.x = newValues[0];target.y = newValues[1];break;default:assert false;break;}}}


然后来写具体的动画和绘制部分。为了方便演示我编写一个随着点击移动的小图标的例子。

我的图标是news。声明image和stage的绘制和原来一样。

先声明一个动画管理器


1
private TweenManager tweenManager = new TweenManager();


然后将我们的Image注册一下


1
Tween.registerAccessor(Image.class, new ActorAccessor());


同时实现InputProcessor接口以接收触碰事件。

在touchDown方法中添加


123456789
@Overridepublic boolean touchDown(int x, int y, int pointer, int button) {Vector3 vector3 = new Vector3(x, y, 0);stage.getCamera().unproject(vector3);Tween.to(image, ActorAccessor.POSITION_XY, 1.0f).ease(Bounce.OUT).target(vector3.x, vector3.y).start(tweenManager);return false;}


说明一下,因为Stage的坐标和默认的Input的坐标不一致,所以通过unproject转化一下。

Tween.to(image, ActorAccessor.POSITION_XY, 1.0f)代表操作image对象移动。target(vector3.x, vector3.y)代表移动的目标。

ease(Bounce.OUT)声明了缓冲效果,具体的效果可以参考http://robertpenner.com/easing/easing_demo.html

start(tweenManager)启动管理器。

在render方法中添加


1
tweenManager.update(Gdx.graphics.getDeltaTime());


让管理器的时间更新。

完整代码:


123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
package com.cnblogs.htynkn;import aurelienribon.tweenengine.Tween;import aurelienribon.tweenengine.TweenManager;import aurelienribon.tweenengine.equations.Bounce;import com.badlogic.gdx.ApplicationListener;import com.badlogic.gdx.Gdx;import com.badlogic.gdx.InputMultiplexer;import com.badlogic.gdx.InputProcessor;import com.badlogic.gdx.graphics.GL10;import com.badlogic.gdx.graphics.g2d.TextureAtlas;import com.badlogic.gdx.math.Vector3;import com.badlogic.gdx.scenes.scene2d.Stage;import com.badlogic.gdx.scenes.scene2d.ui.Image;public class App implements ApplicationListener, InputProcessor {Stage stage;private TweenManager tweenManager = new TweenManager();Image image;@Overridepublic void create() {stage = new Stage(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(),true);TextureAtlas atlas = new TextureAtlas("packer/test.pack");image = new Image(atlas.findRegion("news"));image.x = 20;image.y = 20;stage.addActor(image);Tween.registerAccessor(Image.class, new ActorAccessor());InputMultiplexer multiplexer = new InputMultiplexer();multiplexer.addProcessor(this);multiplexer.addProcessor(stage);Gdx.input.setInputProcessor(multiplexer);}@Overridepublic void dispose() {}@Overridepublic void render() {tweenManager.update(Gdx.graphics.getDeltaTime());Gdx.gl.glClearColor(1, 1, 1, 1);Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);stage.act(Gdx.graphics.getDeltaTime());stage.draw();}@Overridepublic void resize(int width, int height) {}@Overridepublic void pause() {}@Overridepublic void resume() {}@Overridepublic boolean keyDown(int keycode) {// TODO Auto-generated method stubreturn false;}@Overridepublic boolean keyUp(int keycode) {// TODO Auto-generated method stubreturn false;}@Overridepublic boolean keyTyped(char character) {// TODO Auto-generated method stubreturn false;}@Overridepublic boolean touchDown(int x, int y, int pointer, int button) {Vector3 vector3 = new Vector3(x, y, 0);stage.getCamera().unproject(vector3);Tween.to(image, ActorAccessor.POSITION_XY, 1.0f).ease(Bounce.OUT).target(vector3.x, vector3.y).start(tweenManager);return false;}@Overridepublic boolean touchUp(int x, int y, int pointer, int button) {// TODO Auto-generated method stubreturn false;}@Overridepublic boolean touchDragged(int x, int y, int pointer) {// TODO Auto-generated method stubreturn false;}@Overridepublic boolean touchMoved(int x, int y) {// TODO Auto-generated method stubreturn false;}@Overridepublic boolean scrolled(int amount) {// TODO Auto-generated method stubreturn false;}}


因为是动画效果,这里就不贴出了,文章末尾会有一个小视频的。

使用TimeLine实现更多动画效果

上面只是一个简单的移动效果,但就动画而言这个显然是不够的。如果希望实现一个渐渐显示的效果怎么办?

还是想想TweenAccessor接口,只要float类型的值就行了。所以同样的我们可以实现修改透明程度、大小等等实现更多的效果。

我最终选用了六种效果:


123456
public static final int POS_XY = 1;public static final int CPOS_XY = 2;public static final int SCALE_XY = 3;public static final int ROTATION = 4;public static final int OPACITY = 5;public static final int COLOR = 6;


实现修改X和Y值,修改X和Y值(包括对象自身大小),修改缩放,修改旋转,修改透明,修改颜色。

代码如下:


12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
package com.cnblogs.htynkn;import aurelienribon.tweenengine.TweenAccessor;import com.badlogic.gdx.graphics.Color;import com.badlogic.gdx.scenes.scene2d.Actor;public class ActorAccessor implements TweenAccessor {public static final int POS_XY = 1;public static final int CPOS_XY = 2;public static final int SCALE_XY = 3;public static final int ROTATION = 4;public static final int OPACITY = 5;public static final int TINT = 6;@Overridepublic int getValues(Actor target, int tweenType, float[] returnValues) {switch (tweenType) {case POS_XY:returnValues[0] = target.x;returnValues[1] = target.y;return 2;case CPOS_XY:returnValues[0] = target.x + target.width / 2;returnValues[1] = target.y + target.height / 2;return 2;case SCALE_XY:returnValues[0] = target.scaleX;returnValues[1] = target.scaleY;return 2;case ROTATION:returnValues[0] = target.rotation;return 1;case OPACITY:returnValues[0] = target.color.a;return 1;case TINT:returnValues[0] = target.color.r;returnValues[1] = target.color.g;returnValues[2] = target.color.b;return 3;default:assert false;return -1;}}@Overridepublic void setValues(Actor target, int tweenType, float[] newValues) {switch (tweenType) {case POS_XY:target.x = newValues[0];target.y = newValues[1];break;case CPOS_XY:target.x = newValues[0] - target.width / 2;target.y = newValues[1] - target.height / 2;break;case SCALE_XY:target.scaleX = newValues[0];target.scaleY = newValues[1];break;case ROTATION:target.rotation = newValues[0];break;case OPACITY:Color c = target.color;c.set(c.r, c.g, c.b, newValues[0]);target.color = c;break;case TINT:c = target.color;c.set(newValues[0], newValues[1], newValues[2], c.a);target.color = c;break;default:assert false;}}}


因为Actor中的color是final,所以不能修改,自己改一下源代码吧。

TimeLine是Universal Tween Engine中的一大利器,可以实现平行和顺序动画。

比如


123456
Timeline.createSequence().beginSequence().push(Tween.to(image, ActorAccessor.POS_XY, 1.0f).target(100,100)).push(Tween.to(image, ActorAccessor.POS_XY, 1.0f).target(200,20)).start(tweenManager);


就表示先移动到100,100处在移动到200,20处。

再比如


1234567
Timeline.createParallel().beginParallel().push(Tween.to(image, ActorAccessor.CPOS_XY, 1.0f).target(vector3.x, vector3.y)).push(Tween.to(image, ActorAccessor.ROTATION, 1.0f).target(360)).push(Tween.to(image, ActorAccessor.SCALE_XY, 1.0f).target(1.5f, 1.5f)).end().start(tweenManager);


实现的就是一般移动一般旋转和放大的效果。




更多相关文章

  1. [安卓开发Android][叠层 层叠 卡片效果]RecyclerView与CardView
  2. Android(安卓)RecyclerView 滑动到指定item(position)并加动画
  3. LCD:LCD常用接口原理篇
  4. Android(安卓)-- Property Animation
  5. Android创建旋转箭头-不恢复原位-旋转动画的使用
  6. Android框架保证View更新必须在主线程的解读
  7. Android(安卓)读取扫码枪的内容,可以读取条形码 ,二维码
  8. Android:TextView的垂直滚动效果,和上下滚动效果
  9. Android中的Parcelable序列化对象

随机推荐

  1. android raw 文件下写入数据库
  2. ANDROID上获取MSN邮件列表
  3. android activity以对话框形式显示
  4. android permission设置
  5. Android SDK Android NDK 下载地址
  6. ubuntu 18.04 编译Android坑s
  7. 关于基于jetty在android上开发未能解决的
  8. androidimplementationxorg-server-1.12.
  9. Android中Timer计时器详解
  10. Android单例模式封装HttpURLConnection网