LibGDX Tutorial 3B: Simple Animation

Back in Tutorial 3 I created a simple animation using a Timer and setting the frame manually from a TextureAtlas.  This is not the ideal way to perform animation using LibGDX and was done to illustrate how to use a TextureAtlas, not how to perform animation.  Instead the better way to perform animations is using the Animation class.  Here is an example using the same spritesheet from tutorial 3, remember you need to add it to the Android project assets folder.

package com.gamefromscratch;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.g2d.Animation;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;

public class AnimationDemo implements ApplicationListener {
    private SpriteBatch batch;
    private TextureAtlas textureAtlas;
    private Animation animation;
    private float elapsedTime = 0;
    
    @Override
    public void create() {        
        batch = new SpriteBatch();
        textureAtlas = new TextureAtlas(Gdx.files.internal("data/spritesheet.atlas"));
        animation = new Animation(1/15f, textureAtlas.getRegions());
    }

    @Override
    public void dispose() {
        batch.dispose();
        textureAtlas.dispose();
    }

    @Override
    public void render() {        
        Gdx.gl.glClearColor(0, 0, 0, 1);
        Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
        
        batch.begin();
        //sprite.draw(batch);
        elapsedTime += Gdx.graphics.getDeltaTime();
        batch.draw(animation.getKeyFrame(elapsedTime, true), 0, 0);
        batch.end();
    }

    @Override
    public void resize(int width, int height) {
    }

    @Override
    public void pause() {
    }

    @Override
    public void resume() {
    }
}

When you run it, you should see:

Animation

The key here is the Animation, created here:

animation = new Animation(1/15f, textureAtlas.getRegions());

When creating an animation you pass in the amount of time per frame ( 15 frames per second in this case ) and an array of TextureRegions.  These represent the individual frames of animation within the TextureAtlas.  In this particular example we are simply using all of the frames available within the Atlas as a single animation.  The next key change is:

elapsedTime += Gdx.graphics.getDeltaTime();

batch.draw(animation.getKeyFrame(elapsedTime, true), 0, 0);

Here we are simply drawing the current frame from the animation to the screen.  We pass in the amount of time that has elapsed so the animation knows where it is in the sequence.  The true parameter is telling it to loop the animation.

Of course, you can have multiple animations from a single texture Atlas.  Consider the spritesheet we are currently working with.  If you take a look at the .atlas file, you will see each individual frame is named:

image

Looking at the spritesheet, you will see the animations are organized like such:

spritesheet

What we want to do is treat this as two sepeate animations.  Frames 1 through 10 represent an upward roll, while 11-20 are a downward roll.  Let’s take a look at how we do that:

public void create() {        
    batch = new SpriteBatch();
    textureAtlas = new TextureAtlas(Gdx.files.internal("data/spritesheet.atlas"));
    
    TextureRegion[] rotateUpFrames = new TextureRegion[10];
    
    // Rotate Up Animation
    // Create an array of TextureRegions
    rotateUpFrames[0] = (textureAtlas.findRegion("0001"));
    rotateUpFrames[1] = (textureAtlas.findRegion("0002"));
    rotateUpFrames[2] = (textureAtlas.findRegion("0003"));
    rotateUpFrames[3] = (textureAtlas.findRegion("0004"));
    rotateUpFrames[4] = (textureAtlas.findRegion("0005"));
    rotateUpFrames[5] = (textureAtlas.findRegion("0006"));
    rotateUpFrames[6] = (textureAtlas.findRegion("0007"));
    rotateUpFrames[7] = (textureAtlas.findRegion("0008"));
    rotateUpFrames[8] = (textureAtlas.findRegion("0009"));
    rotateUpFrames[9] = (textureAtlas.findRegion("0010"));

    rotateUpAnimation = new Animation(0.1f,rotateUpFrames);
    
    // Rotate Down Animation
    // Or you can just pass in all of the regions to the Animation constructor
    rotateDownAnimation = new Animation(0.1f,
            (textureAtlas.findRegion("0011")),
            (textureAtlas.findRegion("0012")),
            (textureAtlas.findRegion("0013")),
            (textureAtlas.findRegion("0014")),
            (textureAtlas.findRegion("0015")),
            (textureAtlas.findRegion("0016")),
            (textureAtlas.findRegion("0017")),
            (textureAtlas.findRegion("0018")),
            (textureAtlas.findRegion("0019")),
            (textureAtlas.findRegion("0020")));

    Gdx.input.setInputProcessor(this);
}

As you can see, it’s easy to create multiple animations from a single TextureAtlas.  Keep in mind, when creating a TextureAtlas using TexturePacker, it was the filename that you passed in that created the region names.  So what you would generally do is name your separate animations accordingly, such as WalkLeft, WalkRight, etc. 


Previous PartTable Of ContentsNext Part
Scroll to Top