2d Animation in Libgdx

In this post we will cover how to make a 2d Animation for a sprite.

Firstly we will need different sprites which would constitute the animation. Lets take for example we have 3 images Animation1.png, Animation2.png and Animation3.png.

First we would use TexturePacker discussed in the post Game Development in Android using Libgdx Part I to pack the textures in a single texture atlas. Then we would load the atlas using the following code

TextureAtlas textureAtlas;

String TexturePath="Textures/";
String textureFile = TexturePath+"pack" ;
textureAtlas= new TextureAtlas(Gdx.files.internal(textureFile), Gdx.files.internal(textureDir));

We will make a different TextureWrapper than the one in previous tutorials. Basically the draw function would be different so that it can also handle rotation of the sprite.

TextureWrapper

public class TextureWrapper{
      public TextureRegion textureRegion;
      public Vector2 Position;
      int width;
      int height;
      float scaleX;
      float scaleY;
      int originX;
      int originY;
      public TextureWrapper(TextureAtlas atlas,String regionName,Vector2 pos){
            //For above textures reigon names would be name of png like Animation1,Animation2 etc
            texture =atlasgetRegion(regionName).         
            Position=pos;
            width=texture.getRegionWidth()/2;
            height=texture.getRegionHeight()/2;
           //Origin is the pivot for rotation. width/2 and height/2 set image's center as pivot for rotation
            originX=width/2;
            originY=height/2;
            scaleX=1;
            scaleY=1;
      } 

      public void Draw(SpriteBatch sp){
                   sp.Draw(textureRegion,
                                      Position.x-width/2,   //To position it in center horizontally
                                      Position.y-height/2,  //To position it in center vertically
                                      originX,
                                       originY,  
                                       width,    //width of texture
                                       height,    //height of texture
                                       scaleX,   //Negative value will flip the texture horizontally
                                       scaleY   //Negative value will flip the texture vertically
                                       Rotation //Rotation angle in degrees
                                       );
      } 

}

So above method for drawing can be used to rotate ,scale ,flip the texture.

Basically, each frame can have two properties – first is the texture which should be drawn and second the length of time it should be drawn. So we will make a simple class to hold this information.

public class AnimationProperty{
       public int Frame;
       public float TimeLimit;
       public AnimationProperty(int f,float t){
                 Frame=f;
                 TimeLimit=t;
       }
}

And now the animation class.

public class Animation{
         public TextureWrapper[] textures;
         public Vector2 Position;
         public AnimationProperty[] animationProperty;
         int currentFrame;
         int animationCycles;
         float ticker;
         float timeLimit;
         Boolean paused;
         public Animation(int numberOfTextures,Vector2 pos){
               textures=new TextureWrapper[numberOfTextures];
               Position=pos;
         }

         public void AddFrame(TextureAtlas atlas,String regionName,int index){
               textures[index]=new TextureWrapper(atlas,regionName,Position);
         }
         public void Set(int frame){ 
               currentFrame=(currentFrame+1)%animationProperty.length;
               timeLimit=animationProperty[currentFrame].TimeLimit;
               ticker=0;
         }
         public void SetAnimationProperty(AnimationProperty[] anim){
               animationProperty=anim;
               Set(0);

         }
         public void Update(float dt){
              if(!paused){
                   ticker+=dt;
                   if(ticker>timeLimit){
                       ticker-=timeLimit;
                       currentFrame=(currentFrame+1)%animationProperty.length;
                       timeLimit=animationProperty[currentFrame].TimeLimit;
                       if(currentFrame==0)
                            animationCycles++;
                   }

              }
         }
         public  void Draw(SpriteBatch sp){
              int texFrame=animationProperty[currentFrame].Frame;
              textures[texFrame].Draw(sp);
         } 
}

In the above class we hold textures in one array and their properties in another. In update we increment time and check if time limit for the frame has crossed or not. If it is crossed then we load the next frame. If current frame crosses the last frame then it goes back to the first and we increase the cycle count. So if you want to run the animation once then check if the cycle count is equal to 1 to halt the animation.

Mostly for one particular set of textures their animation is similar so we make global array of animation property and pass that reference to all the animations we instantiate.

//Texture constants
static int ANIMATION1_TEXTURE=0;
static int ANIMATION2_TEXTURE=1;
static int ANIMATION3_TEXTURE=2;

//Animation Property constants
static int ANIMATION_FRAME_1=ANIMATION1_TEXTURE;
static int ANIMATION_FRAME_2=ANIMATION2_TEXTURE;
static int ANIMATION_FRAME_3=ANIMATION3_TEXTURE;
static int ANIMATION_FRAME_4=ANIMATION2_TEXTURE;
static float ANIMATION_FRAME_TIME_1=0.5f;
static float ANIMATION_FRAME_TIME_2=0.2f;
static float ANIMATION_FRAME_TIME_3=0.2f;
static float ANIMATION_FRAME_TIME_4=0.2f;

//Animation Property
AnimationProperty[] globalProperty1=new AnimationProperty[4];
globalPoperty1[0]=new AnimationProperty(ANIMATION_FRAME_1,ANIMATION_FRAME_TIME_1);
globalPoperty1[1]=new AnimationProperty(ANIMATION_FRAME_2,ANIMATION_FRAME_TIME_2);
globalPoperty1[2]=new AnimationProperty(ANIMATION_FRAME_3,ANIMATION_FRAME_TIME_3);
globalPoperty1[3]=new AnimationProperty(ANIMATION_FRAME_4,ANIMATION_FRAME_TIME_4);

//Initialize Animation
Animation testAnimation=new Animation(3,new Vector2(10,10));
testAnimation.AddFrame(atlas,"Animation1",ANIMATION1_TEXTURE);
testAnimation.AddFrame(atlas,"Animation2",ANIMATION2_TEXTURE);
testAnimation.AddFrame(atlas,"Animation3",ANIMATION3_TEXTURE);
testAnimation.SetAnimationProperty(globalProperty1);

In this way we can initialize the animation. The above example will the draw Animation1.png for 0.5 seconds, then Animation2.png for 0.2 seconds, then Animation3.png for 0.2 seconds and then Animation2.png again for 0.2 seconds. This cycle of textures would repeat with time.

Hopefully this will give you a direction into how to animate a 2d sprite.

Let us know any of your doubts/suggestions; please put them in the comments section and we would try to answer them.

Thank you for the patience.

Tagged with: , , , ,
Posted in Tutorials
2 comments on “2d Animation in Libgdx
  1. Baqir Talpur says:

    Looks like i have found a treasure on Libgdx finally, was looking for a start for learning libgdx and here it is. Hopefully as soon as i complete all of these articles here, i will have more to read. can you please write on Level design, and tile and actor collisions?

    • Rahul Srivastava says:

      Glad to know you find it useful. Well we use box collision so we never had to handle tile collisions ourselves, just let box handle the physics part

2 Pings/Trackbacks for "2d Animation in Libgdx"
  1. [...] creating the animation in game then you have to loop through the three images shown below. We did a post earlier regarding 2d animation so you can have a look at that if needed. Explosion [...]

  2. [...] creating the animation in game then you have to loop through the three images shown below. We did a post earlier regarding 2d animation so you can have a look at that if needed. Explosion [...]

Try our games



Error: Twitter did not respond. Please wait a few minutes and refresh this page.