Animation Class.

Background

An animation consists of multiple frames which are shown in a sequence at set intervals. An animation of a running man can be achieved by taking pictures of him while running and playing those images back sequentially in a loop. The following “sprite sheet” image shows a complete cycle of a man running. Each box contains a frame of animation. When these frames are shown sequentially over a period of time, they appear as an animated image. 0.033 seconds per frame. An animation is a very simple state machine. The running man has 30 states as per the sprite sheet. The numbered frames represent the states a running man goes through, only one at a time. The current state is determined by the amount of time since the animation began. If less than 0.033 seconds have elapsed, we are in State 1, so the first sprite is drawn. If we are between 0.033 and 0.067 seconds, then we are in State 2, and so on. If the animation is looping, it returns to the first frame after all frames have been shown.

The Animation class

Animation (code) class can be used to easily manage an animation. It is constructed with a list of images and the frame interval time. During playback, its getKeyFrame method takes an elapsed time parameter and returns the appropriate image for that time. Animation<TextureRegion> myAnimation = new Animation<TextureRegion>(/*...*/). Note that it would usually be inadvisable to use the Sprite class to represent frames of an animation, because the Sprite class contains positional data that would not carry from frame to frame.

TextureAtlas example

TextureAtlas (code) class is typically used for combining many separate TextureRegions into a smaller set of Textures to reduce expensive draw calls. (details here). running_0.png, running_1.png, running_2.png, etc. TexturePacker will automatically use these numbers as frame numbers (so long as the packing parameter useIndexes is left true). After the TextureAtlas is loaded, a complete array of frames can be acquired at once and passed into the Animation constructor:

  1. public Animation<TextureRegion> runningAnimation;//...runningAnimation = new Animation<TextureRegion>(0.033f, atlas.findRegions("running"), PlayMode.LOOP);

Sprite sheet example

The following code snippet will create an Animation using the animation_sheet.png sprite-sheet and renders the animation to the screen.

  1. public class Animator implements ApplicationListener { // Constant rows and columns of the sprite sheet private static final int FRAME_COLS = 6, FRAME_ROWS = 5; // Objects used Animation<TextureRegion> walkAnimation; // Must declare frame type (TextureRegion) Texture walkSheet; SpriteBatch spriteBatch; // A variable for tracking elapsed time for the animation float stateTime; @Override public void create() { // Load the sprite sheet as a Texture walkSheet = new Texture(Gdx.files.internal("animation_sheet.png")); // Use the split utility method to create a 2D array of TextureRegions. This is // possible because this sprite sheet contains frames of equal size and they are // all aligned. TextureRegion[][] tmp = TextureRegion.split(walkSheet, walkSheet.getWidth() / FRAME_COLS, walkSheet.getHeight() / FRAME_ROWS); // Place the regions into a 1D array in the correct order, starting from the top // left, going across first. The Animation constructor requires a 1D array. TextureRegion[] walkFrames = new TextureRegion[FRAME_COLS * FRAME_ROWS]; int index = 0; for (int i = 0; i < FRAME_ROWS; i++) { for (int j = 0; j < FRAME_COLS; j++) { walkFrames[index++] = tmp[i][j]; } } // Initialize the Animation with the frame interval and array of frames walkAnimation = new Animation<TextureRegion>(0.025f, walkFrames); // Instantiate a SpriteBatch for drawing and reset the elapsed animation // time to 0 spriteBatch = new SpriteBatch(); stateTime = 0f; } @Override public void render() { Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); // Clear screen stateTime += Gdx.graphics.getDeltaTime(); // Accumulate elapsed animation time // Get current frame of animation for the current stateTime TextureRegion currentFrame = walkAnimation.getKeyFrame(stateTime, true); spriteBatch.begin(); spriteBatch.draw(currentFrame, 50, 50); // Draw current frame at (50, 50) spriteBatch.end(); } @Override public void dispose() { // SpriteBatches and Textures must always be disposed spriteBatch.dispose(); walkSheet.dispose(); }}

Creating an animation is extremely simple by using the following constructor.

Best practices

  • -

    Assets

    here.