pats
pats

Reputation: 1291

Position and rotate animations in Libgdx

I have 20 spites, I want them to be animated when a button is clicked. Two types of animations 1) Position 2) Rotation.

Is there a recommended way to do this? Only way I can think of is recursively call setposition and angle with a delta value on Render method till the desired position and angle are reached.

Upvotes: 0

Views: 714

Answers (2)

Laurence
Laurence

Reputation: 1666

When you have a start state and an end state, and you want to fill in the middle states, this is known as 'tweening (from inbetween). It comes from cartoon animation, but has come to be used more generally.

LibGDX makes use of Universal Tween Engine. You can start your journey to animating anything you want here. But, to give a bit more detail on how it works, here is an example from some of my own stuff. A similar usecase with regards to a sprite, but I have my sprites wrapped in a more generic class, a JJRenderNode. Here is how I make my class open to being tweened.

First you need a TweenAccessor for the class you want to tween.

public class RenderNodeTweenAccessor implements TweenAccessor<JJRenderNode> {


public static final int WIDTH = 1;
public static final int HEIGHT = 2;
public static final int WIDTH_HEIGHT = 3;
public static final int ALPHA = 4;
public static final int ALPHA_WIDTH_HEIGHT=5;

@Override
public int getValues(JJRenderNode target, int tweenType, float[] returnValues) {
    switch (tweenType) {
        case WIDTH:
            returnValues[0] = target.getWidth();
            return 1;
        case HEIGHT:
            returnValues[0] = target.getHeight();
            return 1;
        case WIDTH_HEIGHT:
            returnValues[0] = target.getWidth();
            returnValues[1] = target.getHeight();
            return 2;
        case ALPHA:
            returnValues[0] = target.getColour().a;
            return 1;
        case ALPHA_WIDTH_HEIGHT:
            returnValues[0] = target.getColour().a;
            returnValues[1] = target.getWidth();
            returnValues[2] = target.getHeight();
            return 3;
        default:
            assert false;
            return -1;
    }
}

@Override
public void setValues(JJRenderNode target, int tweenType, float[] newValues) {
    switch (tweenType) {
        case WIDTH:
            target.setWidth(newValues[0]);
            break;
        case HEIGHT:
            target.setHeight(newValues[0]);
            break;
        case WIDTH_HEIGHT:
            target.setWidth(newValues[0]);
            target.setHeight(newValues[1]);
            break;
        case ALPHA:
            target.getColour().a=newValues[0];
            break;
        case ALPHA_WIDTH_HEIGHT:
            target.getColour().a=newValues[0];
            target.setWidth(newValues[1]);
            target.setHeight(newValues[2]);
        default:
            break;
    }
}
}

The constant ints and the 'tweenType' in each of the get and set methods let you tween more than one combination of fields. In this case I have different combinations of width, height and alpha values for my JJRenderNode.

You have to register this TweenAccessor as follows:

Tween.registerAccessor(JJRenderNode.class, new RenderNodeTweenAccessor());

And then you are free to tween your class, for example:

Timeline.createSequence()
                .push(Tween.set(node, RenderNodeTweenAccessor.WIDTH_HEIGHT).target(START_WIDTH, START_WIDTH))
                .push(Tween.to(node, RenderNodeTweenAccessor.WIDTH_HEIGHT, 0.4f).target(PuzzleBlockCore.MAX_RENDER_WIDTH, PuzzleBlockCore.MAX_RENDER_WIDTH))
                .start(JJ.tweenManager);

PS. You also need an instance of a TweenManger, and this needs to be updated with delta for each gameloop. I have a 'singleton' global instance that I use everywhere (JJ.TweenManager).

Upvotes: 1

Lucas B
Lucas B

Reputation: 348

You might as well use spine 2d for animation. It costs, but it is worth it. For $60 I think, you get full libgdx support + bone rigging and animation.

http://esotericsoftware.com/

If you do want to animate with only libgdx however, you can create a list with all your sprite animations frames, loop through, and switch sprite texture to next frame in the animation.

private void render() {
   sprite.set(aninationframes.get(currentFrame)
   currentFrame = currentFrame + 1} 

Though, you may want to add a delay per frame.

If(current time - time > some value) {
   sprite.set(animationframes.get(currrntFrame)
   currentFrame = currentFrame + 1
   time = get current time here
} 

Upvotes: 1

Related Questions