[LibGDX] Trouble with animations

Hi,

I am creating a very simple game where the player moves left and right, avoiding falling objects while collecting gems to increase their score. This is all fine and dandy and easily done, since it is similar to the “simple game” on the LibGDX wiki.

However I am using this little dude called jim, you can fine him here: http://opengameart.org/content/jim

So basically what I am doing is splitting them all up using Gimp, then recreate it using TexturePacker so I can use the TextureAtlas functions.

I am creating the TextureAtlas then using the following code to insert them into the array and size then:

		spriteSheet = new TextureAtlas(
				Gdx.files.internal("data/img/jimAnim.atlas.txt"));
		jimSprites = new Array<Sprite>();
		jimSprites = spriteSheet.createSprites();
		for (int i = 0; i < jimSprites.size; i++) {
			jimSprites.get(i).setSize(32, 90);
		}

I then use this code to render my frames:

stateTime += Gdx.graphics.getDeltaTime();
				if (Gdx.input.isKeyPressed(Keys.D)) {
					while (stateTime > ANIM_DURATION) {
						stateTime -= ANIM_DURATION;
						currentFrame = (currentFrame == jimSprites.size -1) ? 0
								: ++currentFrame;
					}
				}

Now the problems I am having:

Expected -
In order to save space I just want to have 1 spritesheet, then flip it if needed. So if the player presses A to move left it flips and remains flipped.

Outcome -
Whenever I press A it flips back and forth on each animation end

Code used -

				if (Gdx.input.isKeyPressed(Keys.A)) {
					jimSprites.get(currentFrame).flip(true, false);
					while (stateTime > ANIM_DURATION) {
						stateTime -= ANIM_DURATION;
						currentFrame = (currentFrame == jimSprites.size -1) ? 0
								: ++currentFrame;
					}
				}

Expected -
When the player is not pressing either A or D, the character uses the correct sprite. I want to ignore his idle state within the array when animating and then fetch it when nothing is pressed.

Outcome -
The sprite is included in the spritesheet and therefore gets animated as if its part of the walking animation

What I have tried -
Various fail code to try and start the animation from a different array index, removing it from the spritesheet and instead draw it like a normal sprite whenever nothing is pressed and only draw the animations when a key is pressed. Is this efficient?

Thanks for any help!

Right off the bat, I know from experience that you should not be using while loops in libgdx on the main thread as this stops everything else from occurring.

How would you go about it yourself?

I have the animation working at least, well some of it. Even if the implementation is piss poor.

OK here is what I have now, it’s different and ineffiecient due to me loading loads of individual files rather than a single texture with multiple sprites but a learning process :D. Animation is new to me since my last attempt at a game never had it (Pong).

This is how I am creating my sprites and inserting them into the array, stupid question but is there a way I can do this via loop? I know how to do for loops and add values to an array but adding objects I am not sure, it seems the use of arrays is something I struggle with despite how many times I read tutorials on them lol:

		// Create our assets
		rock = new Texture(Gdx.files.internal("data/img/rock.png"));
		gems = new Texture(Gdx.files.internal("data/img/gems.png"));
		jim0 = new Sprite(new Texture(Gdx.files.internal("data/img/jim0.png")));
		jim1 = new Sprite(new Texture(Gdx.files.internal("data/img/jim1.png")));
		jim2 = new Sprite(new Texture(Gdx.files.internal("data/img/jim2.png")));
		jim3 = new Sprite(new Texture(Gdx.files.internal("data/img/jim3.png")));
		jim4 = new Sprite(new Texture(Gdx.files.internal("data/img/jim4.png")));
		jim5 = new Sprite(new Texture(Gdx.files.internal("data/img/jim5.png")));
		jim6 = new Sprite(new Texture(Gdx.files.internal("data/img/jim6.png")));

		// Create animations
		sprites = new Sprite[]{jim0, jim1, jim2, jim3, jim4, jim5, jim6};		
		walkFrames = new Animation(ANIM_DURATION, sprites);
		stateTime = 0;

This here is my render method, which atm just infinitely animates but will add input to handle it:

stateTime += Gdx.graphics.getDeltaTime();
		currentFrame = walkFrames.getKeyFrame(stateTime, true);
		// TODO Remove and fix later, testing code
		
		batch.setProjectionMatrix(cam.combined);
		batch.begin();
		batch.draw(currentFrame, 400, 50);
		
		batch.end();

No while loops locking up the thread as the above user has said.

Definitely. isKeyPressed() is already input polling so the while loops are redundant. To fix the problem of having jim1, jim2, etc. just use a texture atlas (it will also make things a lot faster if you’re doing a lot of texture binding).

I have the animation fully working with the current setup, I split everything up into an MVC pattern. Which seems to be working. The only problem I have is flipping the sprites when the character changes direction, the closest I can get it is about 90% working.

What happens is the animation goes frame 1-6 flipped, then restarts from 1 but the flip resets so it flips back to normal the back to mirrored again.

Deleted all that code for now though, just happy to actually have a non floaty sprite!

I will work on better methods down the line and adjust accordingly, this is only my second attempt at a game and last time I used Pong and that was heavily reliant on box2d, which for this game will not be used so I can learn basic collisions for non full physics engine games.