Using an Animation instance is a common way to create an animated sprite in libGDX. To optimize rendering we apply Textures instead of Sprites. Rotating a Sprite is trivial (with setOrigin and rotate()). Now how can we rotate a Texture Animation?
Let’s take a look at the plane game example. The animation is created from a set of PNG assets:
Texture frame1 = new Texture("plane1.png"); frame1.setFilter(TextureFilter.Linear, TextureFilter.Linear); Texture frame2 = new Texture("plane2.png"); Texture frame3 = new Texture("plane3.png"); plane = new Animation(0.05f, new TextureRegion(frame1), new TextureRegion(frame2), new TextureRegion(frame3), new TextureRegion(frame2)); plane.setPlayMode(PlayMode.LOOP); |
It would be nice if we could adjust the plane’s pitch a little to its vertical movement. SpriteBatch offers some draw() methods with a signature to rotate the plane animation. They take a bunch of paramaters that fortunately can easily be calculated. The vertical velocity is available as the y component of the velocity vector (a Vector2 object). Here is the original animation rendering code in the drawWorld() method that is called from the game’s render() method:
batch.draw(plane.getKeyFrame(planeStateTime), planePosition.x, planePosition.y); |
To add a pitch, declare the fields keyFrame and rotation, then replace the rendering code with this (note that the shape is at 270° when not rotated):
keyFrame = plane.getKeyFrame(planeStateTime); rotation = 270; if (planeVelocity.y > 30) rotation = 280; if (planeVelocity.y < -30) rotation = 260; batch.draw(keyFrame, planePosition.x, planePosition.y, keyFrame.getRegionWidth() / 2.0f, keyFrame.getRegionHeight() / 2.0f, keyFrame.getRegionWidth(), keyFrame.getRegionHeight(), 1f, 1f, rotation, false); |
So now the plane will move in a slightly more natural looking way.
However, the plane appears to be somewhat stretched in the y direction and shrunken in the x direction. The eighth and the ninth parameter of the draw() method represent scaling in both directions. Since both are set to one we wouldn’t expect the observed behaviour (at least I wouldn’t). Though the rationale behind this remains a bit of a mystery to me, I solved it as follows:
batch.draw(keyFrame, planePosition.x, planePosition.y, keyFrame .getRegionWidth() / 2.0f, keyFrame.getRegionHeight() / 2.0f, keyFrame.getRegionWidth(), keyFrame.getRegionHeight(), keyFrame.getRegionHeight() / (float) keyFrame.getRegionWidth(), 2 - (keyFrame.getRegionHeight() / (float) keyFrame .getRegionWidth()), rotation, false); |