Animation

Hi,
I have a sprite sheet already but no atlas file - can you create an atlas file from a sprite sheet?

Just wondering what is the simplest way of implementing walking animation when player presses a key.

Thanks

Why would you need atlas file? Just load the sprite sheet, cut it into sprites and store it in a list. Then when you want to draw the sprites chose an index (change it every (let’s say) 150 ms) and there you go…

Just going to use a spritesheet unpacker then feed these into texturepacker to create an atlas file, failing that
I could just type the atlas file up myself…

You mean, load sprite sheet and use the split method? Or manually cut the sprites up and store in a List?

Something like:


	playerTextures = new Texture(textureFile);
	
	TextureRegion[][] tmp = TextureRegion.split(playerTextures, playerTextures.getWidth()/FRAMECOLS, playerTextures.getHeight()/FRAMEROWS);              


Yup… ;D Something like that

You’re using LibGDX? It’s very simple even without using an Atlas file. I usually just pack my textures into a larger texture by myself and then do something like this (taken almost straight from the LibGDX Github Wiki):

public static Animation generate(Texture sheet, int rows, int cols) {
		TextureRegion[][] tmp = TextureRegion.split(sheet, sheet.getWidth() / cols, sheet.getHeight() / rows);
		TextureRegion[] frames = new TextureRegion[cols * rows];
		int index = 0;
		for(int y = 0; y < rows; y++) {
			for(int x = 0; x < cols; x++) {
				frames[index++] = tmp[y][x];
			}
		}

		return new Animation(0.1f, frames);
	}

Where rows and cols specifies the number of rows and columns of textures in your “spritesheet”. Then you can get the current frame of the animation like this:


private Animation anim;
private float animTime;
public TextureRegion currentFrame;

public void tick() {
		animTime += Gdx.graphics.getDeltaTime();
		currentFrame = anim.getKeyFrame(animTime, looping);
}

Then simply just draw the currentFrame as usual with your SpriteBatch!

Thanks for that,

Exactly what I was doing without having the atlas :slight_smile:

What is best way to update the frame when user presses a key - I’ve been doing this:


	currentFrame = walkAnimation.getKeyFrame(TIMER, true);
		if(TIMER > AMOUNTFRAMES) TIMER= 0.0f;
		else
			TIMER+=0.1f;

Thanks

Do you mean you want to have an idle animation, and then when the user hits a key you want to switch to a moving animation? I would do something like this:


    //AnimationManager
	static Map<String, Animation> animations = new HashMap<String, Animation>();

    public static void initialize(){
		animations.put("player-left", anim1);
		animations.add("player-right", anim2);
                animations.add("player-idle", anim3);
		//etc...
	}
	
	public static Animation getAnimation(String animKey) {
		if(!animations.contains(animKey)) { //can't remember if the map contains function is actually called 'contains'. 
			return null;
		}
		
		return animations.get(animKey);
	}
	
	//Player
	
	private float animTime;
	private Animation currentAnim;
	
	//Tick or Update, whichever you prefer to call it
	public void tick() {
		animTime += Gdx.graphics.getDeltaTime();
		
		if(Gdx.input.isKeyPressed(Keys.A)) {
			currentAnim = AnimationHandler.getAnimation("player-left");
		} else {
         currentAnim = AnimationHandler.getAnimation("player-idle");
      }
	}
	
	//Draw or render or whatever
	public void draw(SpriteBatch batch) {
		batch.draw(currentAnim.getKeyFrame(animTime, true);
	}
	
	

Hi,

Thanks for that. What I was meaning is, when player presses right key for instance, the player moves right and walk animation is done :slight_smile:

Right, that’s what I was showing you:


      if(Gdx.input.isKeyPressed(Keys.A)) {
         currentAnim = AnimationHandler.getAnimation("player-left");
      } else {
         currentAnim = AnimationHandler.getAnimation("player-idle");
      }

This says, “when the A (left) key is pressed, set the current animation to the walk animation. When the key is no longer pressed, set the animation to the idle animation”. Do you mean you actually want to cycle through the entire animation before setting the idle animation? For instance:

Press ‘D’ - Set animation to walk animation
Let go of ‘D’ - Walk animation cycles through the remaining frames, and THEN switches to idle animation

Hi,

No, when you click key to move left, just do walk animation for left.

Yes, what you had done previously looks like what I’m looking for. I’m taking it the Animation objects are made up from
the texture regions, like so:


 playerTextures = new Texture(textureFile);
 TextureRegion[][] tmp = TextureRegion.split(playerTextures, playerTextures.getWidth()/FRAMECOLS,   playerTextures.getHeight()/FRAMEROWS);              
        walkFrames = new TextureRegion[FRAMECOLS * FRAMEROWS];
		
        int index = 0;
        for (int i = 0; i < FRAMEROWS; i++) {
            for (int j = 0; j < FRAMECOLS; j++) {
                walkFrames[index++] = tmp[i][j];
            }
        }
        walkAnimation = new Animation(TIMER, walkFrames); 

Thanks

So your problem is solved then? I would find a good way to store those different animations, I use a map just because it’s the easiest solution I know of.