The libgdx ui library can achieve some animation effects, but it may be insufficient for games. The Universal Tween Engine is a java-only animation library.
Address: http://code.google.com/p/java-universal-tween-engine/
All java objects that can be expressed with float can be animated and can be used in Libgdx, Android, Swing, and so on.
General process for using the Universal Tween Engine
The most important step to use the Universal Tween Engine is to implement the TweenAccessor interface, which defines the getValues and setValues methods.
Then, register the corresponding interface in the Engine. Then define some animation effects and add them to the manager. Finally, update the time using the update method.
Specific can refer to Wiki: http://code.google.com/p/java-universal-tween-engine/wiki/GetStarted
Implement simple animation in libgdx
I prefer to use Stage, so the following examples are all in Stage.
First, implement the TweenAccessor interface. I didn't treat it differently. For example, write an Image or a Button. I wrote one directly to the Actor, which can be used in this way.
In getValues and setValues, I have defined the actions in 3: Modify only the X value, modify only the Y value, and modify the X and Y values.
public static final int POSITION_X = 1;public static final int POSITION_Y = 2;public static final int POSITION_XY = 3;
Here, pay attention to the getValues return value. If you modify or operate on a few values, the return value will be several.
The Code is as follows:
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;}}}
Then write the specific animation and drawing part. To facilitate the demonstration, I wrote an example of moving a small icon with the click.
My icon is. Declare that the image and stage are drawn in the same way as the original one.
Declare an animation manager first
private TweenManager tweenManager = new TweenManager();
Then register our Image
Tween.registerAccessor(Image.class, new ActorAccessor());
At the same time, the InputProcessor interface is implemented to receive touch events.
Add in the touchDown Method
@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;}
Note: Because the Stage coordinates are inconsistent with the default Input coordinates, you can convert them through unproject.
Tween. to (image, ActorAccessor. POSITION_XY, 1.0f) indicates the operation on moving an image object. Target (vector3.x, vector3.y) indicates the moving target.
Explain (Bounce. OUT) declares the buffer effect, the specific effect can refer to the http://robertpenner.com/easing/easing_demo.html
Start (tweenManager) start the manager.
Add
tweenManager.update(Gdx.graphics.getDeltaTime());
Update the Time of the manager.
Complete code:
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;}}
Because it is an animated effect, we will not post it here. There will be a small video at the end of the article.
Use TimeLine for more animation Effects
The above is just a simple moving effect, but it is obviously not enough for animation. What if I want to achieve a gradual display effect?
Think about the TweenAccessor interface, as long as the value of the float type is enough. So we can achieve more results by changing the transparency, size, and so on.
I finally selected six effects:
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;
Modify the X and Y values, modify the X and Y values (including the object size), modify the scaling, modify the rotation, modify the transparency, and modify the color.
The Code is as follows:
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;}}}
Because the color in Actor is final, you cannot modify it. Change the source code.
TimeLine is a in the Universal Tween Engine, which can be used for parallel and sequential animation.
For example
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);
It indicates that the data is first moved to 100,100 and then to and 20.
For example
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);
It achieves general moving, General rotation, and amplification.
Effect: