Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to finish animation with libgdx

Tags:

libgdx

I am trying to implement a simple animation with libGDX and I am currently stuck on one thing. Lets say I have a bunch of sprites which take some time to finish. For example, around 30 sprites like this link: https://github.com/libgdx/libgdx/wiki/2D-Animation

However, before the animation completes some key is pressed. For smooth animation I want the 30 frames to be completed before I start the next set of animation, to prevent an abrupt stop.

So my question is how do I achieve it this in libGDX? My current idea is to extend the Animation class, which would keep track of how frames I have and how many have been rendered and then display the rest. Or use the isAnimationFinished(float stateTime) function (though I haven't had luck using that).

The examples I have seen like superjumper have very few animations and don't really change that much.

Also, is there a way to hold the list of sprites from a TextureAtlas.createSprites method and use those with the Animation class? If not, whats the purpose of providing this function?

Thanks

like image 804
ssarangi Avatar asked Feb 19 '23 10:02

ssarangi


2 Answers

You can use

animation.isAnimationFinished(stateTime);

To see if your animation is finished.

For the sprites : personnaly I use TextureRegion from a TextureAtlas and I store them in an array for my animation

like image 177
JulienBe Avatar answered Mar 20 '23 10:03

JulienBe


I create a class AnimatedImage that extends Image to automate spriting in Image. My code will be like this:

public class AnimatedImage extends Image{
    private Array<Array<Sprite>> spriteCollection;
    private TextureRegionDrawable drawableSprite;
    private Animation _animation;
    private boolean isLooping;
    private float stateTime;
    private float currentTime;


    public AnimatedImage(Array<Array<Sprite>> _sprites, float animTime, boolean _looping){
//      set the first sprite as the initial drawable
        super(_sprites.first().first());
        spriteCollection = _sprites;

//      set first collection of sprite to be the animation
        stateTime = animTime;
        currentTime = 0;
        _animation = new Animation(stateTime, spriteCollection.first());

//      set if the anmation needs looping
        isLooping = _looping;
        drawableSprite = new TextureRegionDrawable(_animation.getKeyFrame(currentTime));
        this.setDrawable(drawableSprite);
    }

    public void update(float delta){
        currentTime += delta;
        TextureRegion currentSprite = _animation.getKeyFrame(currentTime, isLooping);
        drawableSprite.setRegion(currentSprite);
    }

    public void changeToSequence(int seq){
//      reset current animation time
        resetTime();
        _animation = new Animation(stateTime, spriteCollection.get(seq));
    }

    public void changeToSequence(float newseqTime, int seq){
        _animation = new Animation(newseqTime, spriteCollection.get(seq));
    }

    public void setRepeated(boolean _repeat){
        isLooping = _repeat;
    }

    public boolean isAnimationFinished(){
        return _animation.isAnimationFinished(currentTime);
    }

    public void resetTime(){
            currentTime = 0;
    }


}

changetosequence method will make new Animation that will be used to update the current TextureRegionDrawable at the update method. resetTime will reset the total time for the animation when you call changeToSequence. You could add the event listener to call changeToSequence method.

Here is the example:

private AnimatedImage _img;

then I add the InputListener like this:

_img.addListener(new InputListener(){
            @Override
            public boolean touchDown(InputEvent event, float x, float y, int pointer, int button){
                _img.changeToSequence(1);
                return true;

            }
        });

Hope it helps.

like image 31
Arie Avatar answered Mar 20 '23 10:03

Arie