How to do animation with TexturePacker files

I am trying to use the TextureAtlas loader.

The “AtlasData.json” looks like this:

{"frames": [

{
	"filename": "Char/walk/down/1.png",
	"frame": {"x":142,"y":0,"w":15,"h":14},
	"rotated": true,
	"trimmed": true,
	"spriteSourceSize": {"x":1,"y":1,"w":15,"h":14},
	"sourceSize": {"w":16,"h":16},
	"pivot": {"x":0.5,"y":0.5}
},
{
	"filename": "Char/walk/down/2.png",
	"frame": {"x":84,"y":0,"w":15,"h":15},
	"rotated": false,
	"trimmed": true,
	"spriteSourceSize": {"x":1,"y":1,"w":15,"h":15},
	"sourceSize": {"w":17,"h":16},
	"pivot": {"x":0.5,"y":0.5}
},
etc.

As you can see, there are rotated frames, because this is how it was packed.

I use the SpriteSheetAnimation class to do the animation.

var atlas = game.Content.Load<TextureAtlas>("AtlasData");
TextureRegion2D[] walkDown = {
    atlas.GetRegion("Char/walk/down/1"),
    atlas.GetRegion("Char/walk/down/2"),
    atlas.GetRegion("Char/walk/down/3"),
    atlas.GetRegion("Char/walk/down/4")
};
spriteSheetAnimation = new SpriteSheetAnimation("walkDown", walkDown);
sprite = new Sprite(spriteSheetAnimation.CurrentFrame) { Position = new Vector2(200, 200) };

I also contemplated building the animation with the SpriteSheetAnimationFactory class, and using AnimatedSprite, but it requires me to use the SpriteSheetAnimationData class, and it’s not clear how I can integrate that with the atlas, as it asks for frame indices, but I would like to refer to my frames with strings (it is basically the only reason for me to use a texture packer). Can I do that?

Then I update the SpriteSheetAnimation and Draw it:

// in Update method
spriteSheetAnimation.Update((float)gameTime.ElapsedGameTime.TotalSeconds);
// in Draw method
sprite.TextureRegion = spriteSheetAnimation.CurrentFrame;
spriteBatch.Draw(sprite);

I get this animation:

As you can see, the rotated sprite is problematic. Since the image is packed tightly there are also a few pixels from the next sprite (and the bottom is cut out), because the width and height parameters are getting mixed up.

Why rotate the asset when you can rotate the sprite in game?

I don’t rotate it, the texture packer does, so it can pack the images more optimally I guess. The intended animation would be without rotation.
I realized if I edit the “allowRotation” key to “false” in the .tps file it will not rotate the image.
So, I think that’s what I should do because MonoGame.Extended doesn’t support it right?

I’m not sure, but the image is square so I’m confused why it needs to be rotated at all. If you need the final image to be rotated you should do it with sprites in game via SpriteBatch which allows for arbitrary rotation.

Why would it be more optimal ? Rotations are not the most expensive things, especially with things like x90°, whereas storage can be especially if you are targetting mobiles platforms.
A rotation is better than storing each possible rotation of each animation to me.

…what?

Guys, you are totally missing the point.
The TexturePacker is a software that packs the sprites into one atlas. It can rotate the sprites to make the texture atlas smaller. It’s NOT ME who rotated it, and it was not even the goal.

BUT, I found a way, to turn it off (the rotation feature in TexturePacker), because apparently it is not supported (see the original post) in MonoGame.Extended. It’s ok, I didn’t need it anyway.

Currently I use the AnimatedSprite class:

var atlas = contentManager.Load<TextureAtlas>("AtlasData");
var animationFactory = new SpriteSheetAnimationFactory(atlas);
animationFactory.Add("idleDown", new SpriteSheetAnimationData(new[] { 0 }));
animationFactory.Add("walkDown", new SpriteSheetAnimationData(new[] { 0, 1, 2, 3 }));
animationFactory.Add("idleLeft", new SpriteSheetAnimationData(new[] { 4 }));
animationFactory.Add("walkLeft", new SpriteSheetAnimationData(new[] { 4, 5, 6, 7 }));
animationFactory.Add("idleRight", new SpriteSheetAnimationData(new[] { 8 }));
animationFactory.Add("walkRight", new SpriteSheetAnimationData(new[] { 8, 9, 10, 11 }));
animationFactory.Add("idleUp", new SpriteSheetAnimationData(new[] { 12 }));
animationFactory.Add("walkUp", new SpriteSheetAnimationData(new[] { 12, 13, 14, 15 }));
animatedSprite = new AnimatedSprite(animationFactory) { Position = this.Position };

Which is not as good as I wanted, because I need to specify the indices of the frames instead of referring to them with their names.

Although it was not part of the original question, I met a new problem: how can I check currently which animation is playing? There is a member called

private SpriteSheetAnimation _currentAnimation;

in AnimatedSprite, but I can’t access that.

Yep, that’s right. We don’t currently support sprite rotation in texture the texture atlas.

Yes, you’re right. There doesn’t appear to be a way to do this currently. I guess there’d be no harm in making _currentAnimation public.