Skip to content

Commit

Permalink
Generic 2D Animation (#4448)
Browse files Browse the repository at this point in the history
  • Loading branch information
cypherdare authored and Tom-Ski committed Dec 3, 2016
1 parent b449f84 commit 2e76082
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 58 deletions.
1 change: 1 addition & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
- Lwjgl3Window now has a maximize() method, and windows can be started maximized using the window or app configuration's setMaximized() method.
- NinePatch can now be drawn rotated or scaled.
- NinepatchDrawable is now a TransformDrawable.
- API Change: g2d.Animation is now generic so it can support Drawables, PolygonRegions, NinePatches, etc. To fix existing code, specify the TextureRegion type in animation declarations (and instantiations in Java 6), i.e. Animation<TextureRegion> myAnimation = new Animation<TextureRegion>(...);

[1.9.4]
- Moved snapping from ProgressBar to Slider to prevent snapping when setting the value programmatically.
Expand Down
81 changes: 39 additions & 42 deletions gdx/src/com/badlogic/gdx/graphics/g2d/Animation.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,16 @@
import com.badlogic.gdx.utils.Array;

/** <p>
* An Animation stores a list of {@link TextureRegion}s representing an animated sequence, e.g. for running or jumping. Each
* region of an Animation is called a key frame, multiple key frames make up the animation.
* </p>
* An Animation stores a list of objects representing an animated sequence, e.g. for running or jumping. Each
* object in the Animation is called a key frame, and multiple key frames make up the animation.
* <p>
* The animation's type is the class representing a frame of animation. For example, a typical 2D animation could be made
* up of {@link com.badlogic.gdx.graphics.g2d.TextureRegion TextureRegions} and would be specified as:
* <p><code>Animation&lt;TextureRegion&gt; myAnimation = new Animation&lt;TextureRegion&gt;(...);</code>
*
* @author mzechner */
public class Animation {

public class Animation<T> {
/** Defines possible playback modes for an {@link Animation}. */
public enum PlayMode {
NORMAL,
Expand All @@ -36,8 +39,9 @@ public enum PlayMode {
LOOP_PINGPONG,
LOOP_RANDOM,
}

final TextureRegion[] keyFrames;

/** Length must not be modified without updating {@link #animationDuration}. See {@link #setKeyFrames(T[])}. */
T[] keyFrames;
private float frameDuration;
private float animationDuration;
private int lastFrameNumber;
Expand All @@ -48,54 +52,42 @@ public enum PlayMode {
/** Constructor, storing the frame duration and key frames.
*
* @param frameDuration the time between frames in seconds.
* @param keyFrames the {@link TextureRegion}s representing the frames. */
public Animation (float frameDuration, Array<? extends TextureRegion> keyFrames) {
* @param keyFrames the objects representing the frames. */
public Animation (float frameDuration, Array<? extends T> keyFrames) {
this.frameDuration = frameDuration;
this.animationDuration = keyFrames.size * frameDuration;
this.keyFrames = new TextureRegion[keyFrames.size];
T[] frames = (T[]) new Object[keyFrames.size];
for (int i = 0, n = keyFrames.size; i < n; i++) {
this.keyFrames[i] = keyFrames.get(i);
frames[i] = keyFrames.get(i);
}

this.playMode = PlayMode.NORMAL;
setKeyFrames(frames);
}

/** Constructor, storing the frame duration, key frames and play type.
/** Constructor, storing the frame duration and key frames.
*
* @param frameDuration the time between frames in seconds.
* @param keyFrames the {@link TextureRegion}s representing the frames.
* @param playMode the animation playback mode. */
public Animation (float frameDuration, Array<? extends TextureRegion> keyFrames, PlayMode playMode) {

this.frameDuration = frameDuration;
this.animationDuration = keyFrames.size * frameDuration;
this.keyFrames = new TextureRegion[keyFrames.size];
for (int i = 0, n = keyFrames.size; i < n; i++) {
this.keyFrames[i] = keyFrames.get(i);
}

this.playMode = playMode;
* @param keyFrames the objects representing the frames. */
public Animation (float frameDuration, Array<? extends T> keyFrames, PlayMode playMode) {
this(frameDuration, keyFrames);
setPlayMode(playMode);
}

/** Constructor, storing the frame duration and key frames.
*
* @param frameDuration the time between frames in seconds.
* @param keyFrames the {@link TextureRegion}s representing the frames. */
public Animation (float frameDuration, TextureRegion... keyFrames) {
* @param keyFrames the objects representing the frames. */
public Animation (float frameDuration, T... keyFrames) {
this.frameDuration = frameDuration;
this.animationDuration = keyFrames.length * frameDuration;
this.keyFrames = keyFrames;
this.playMode = PlayMode.NORMAL;
setKeyFrames(keyFrames);
}

/** Returns a {@link TextureRegion} based on the so called state time. This is the amount of seconds an object has spent in the
/** Returns a frame based on the so called state time. This is the amount of seconds an object has spent in the
* state this Animation instance represents, e.g. running, jumping and so on. The mode specifies whether the animation is
* looping or not.
*
* @param stateTime the time spent in the state represented by this animation.
* @param looping whether the animation is looping or not.
* @return the TextureRegion representing the frame of animation for the given state time. */
public TextureRegion getKeyFrame (float stateTime, boolean looping) {
* @return the frame of animation for the given state time. */
public T getKeyFrame (float stateTime, boolean looping) {
// we set the play mode by overriding the previous mode based on looping
// parameter value
PlayMode oldPlayMode = playMode;
Expand All @@ -111,18 +103,18 @@ public TextureRegion getKeyFrame (float stateTime, boolean looping) {
playMode = PlayMode.LOOP;
}

TextureRegion frame = getKeyFrame(stateTime);
T frame = getKeyFrame(stateTime);
playMode = oldPlayMode;
return frame;
}

/** Returns a {@link TextureRegion} based on the so called state time. This is the amount of seconds an object has spent in the
/** Returns a frame based on the so called state time. This is the amount of seconds an object has spent in the
* state this Animation instance represents, e.g. running, jumping and so on using the mode specified by
* {@link #setPlayMode(PlayMode)} method.
*
* @param stateTime
* @return the TextureRegion representing the frame of animation for the given state time. */
public TextureRegion getKeyFrame (float stateTime) {
* @return the frame of animation for the given state time. */
public T getKeyFrame (float stateTime) {
int frameNumber = getKeyFrameIndex(stateTime);
return keyFrames[frameNumber];
}
Expand Down Expand Up @@ -168,11 +160,16 @@ public int getKeyFrameIndex (float stateTime) {
return frameNumber;
}

/** Returns the keyFrames[] array where all the TextureRegions of the animation are stored.
* @return keyFrames[] field */
public TextureRegion[] getKeyFrames () {
/** Returns the keyframes[] array where all the frames of the animation are stored.
* @return The keyframes[] field. */
public T[] getKeyFrames () {
return keyFrames;
}

protected void setKeyFrames (T... keyFrames) {
this.keyFrames = keyFrames;
this.animationDuration = keyFrames.length * frameDuration;
}

/** Returns the animation play mode. */
public PlayMode getPlayMode () {
Expand Down
8 changes: 4 additions & 4 deletions tests/gdx-tests/src/com/badlogic/gdx/tests/AnimationTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ public void update (float deltaTime) {
}
}

Animation leftWalk;
Animation rightWalk;
Animation<TextureRegion> leftWalk;
Animation<TextureRegion> rightWalk;
Caveman[] cavemen;
Texture texture;
SpriteBatch batch;
Expand All @@ -65,8 +65,8 @@ public void create () {
frame.flip(true, false);
rightWalkFrames[i] = frame;
}
leftWalk = new Animation(0.25f, leftWalkFrames);
rightWalk = new Animation(0.25f, rightWalkFrames);
leftWalk = new Animation<TextureRegion>(0.25f, leftWalkFrames);
rightWalk = new Animation<TextureRegion>(0.25f, rightWalkFrames);

cavemen = new Caveman[100];
for (int i = 0; i < 100; i++) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,16 @@
import com.badlogic.gdx.tests.utils.GdxTest;

public class SimpleAnimationTest extends GdxTest {
private Animation currentWalk;
private Animation<TextureRegion> currentWalk;
private float currentFrameTime;
private Vector2 position;

private Texture texture;

private Animation downWalk;
private Animation leftWalk;
private Animation rightWalk;
private Animation upWalk;
private Animation<TextureRegion> downWalk;
private Animation<TextureRegion> leftWalk;
private Animation<TextureRegion> rightWalk;
private Animation<TextureRegion> upWalk;

private SpriteBatch spriteBatch;

Expand All @@ -50,10 +50,10 @@ public void create () {
TextureRegion[] leftWalkReg = regions[1];
TextureRegion[] rightWalkReg = regions[2];
TextureRegion[] upWalkReg = regions[3];
downWalk = new Animation(ANIMATION_SPEED, downWalkReg);
leftWalk = new Animation(ANIMATION_SPEED, leftWalkReg);
rightWalk = new Animation(ANIMATION_SPEED, rightWalkReg);
upWalk = new Animation(ANIMATION_SPEED, upWalkReg);
downWalk = new Animation<TextureRegion>(ANIMATION_SPEED, downWalkReg);
leftWalk = new Animation<TextureRegion>(ANIMATION_SPEED, leftWalkReg);
rightWalk = new Animation<TextureRegion>(ANIMATION_SPEED, rightWalkReg);
upWalk = new Animation<TextureRegion>(ANIMATION_SPEED, upWalkReg);

currentWalk = leftWalk;
currentFrameTime = 0.0f;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,9 @@ enum State {
private OrthogonalTiledMapRenderer renderer;
private OrthographicCamera camera;
private Texture koalaTexture;
private Animation stand;
private Animation walk;
private Animation jump;
private Animation<TextureRegion> stand;
private Animation<TextureRegion> walk;
private Animation<TextureRegion> jump;
private Koala koala;
private Pool<Rectangle> rectPool = new Pool<Rectangle>() {
@Override
Expand Down

1 comment on commit 2e76082

@Mur4ik
Copy link

@Mur4ik Mur4ik commented on 2e76082 Dec 12, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, see #4476
And that usecase should be added to tests.

Please sign in to comment.