[Bug] Confusing playMode replacement in 2D animation getKeyFrame Method
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 25.4k
- Forks
- 6.5k
- Avg merge
- 1d 16h
- Merged PRs (30d)
- 5
Description
In 'com.badlogic.gdx.graphics.g2d.Animation'
there is a method called getKeyFrame with an additional looping param, I think the parameter looping can override the Animation playMode temporarily when it get its keyFrames, the current code are following:
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;
if (looping && (playMode == PlayMode.NORMAL || playMode == PlayMode.REVERSED)) {
if (playMode == PlayMode.NORMAL)
playMode = PlayMode.LOOP;
else
playMode = PlayMode.LOOP_REVERSED;
} else if (!looping && !(playMode == PlayMode.NORMAL || playMode == PlayMode.REVERSED)) {
if (playMode == PlayMode.LOOP_REVERSED)
playMode = PlayMode.REVERSED;
else
playMode = PlayMode.LOOP;
}
T frame = getKeyFrame(stateTime);
playMode = oldPlayMode;
return frame;
}
In Addition, the current PlayMode enum has six values where the code is
public enum PlayMode {
NORMAL, REVERSED, LOOP, LOOP_REVERSED, LOOP_PINGPONG, LOOP_RANDOM,
}
In the first if part, it says when looping=true and playMode is NORMAL or REVERSED, the playMode is changed to corresponding loop mode LOOP AND LOOP_REVERSED.
Next, in the second else if part, when looping=false and playMode is LOOP_REVERSED, the playMode will be replaced to PlayMode.REVERSED, which also makes sense, but it turns the other three loop PlayMode into LOOP, which confuses me.
In my Opinion, all the 4 loop modes shall keep the Animation playing forever. the other 2 non-loop modes will stop the Animation and offer the last frame. But when you are in LOOP_PINGPONG or LOOP_RANDOM mode, and you want a non-loop output, I'm not quite sure what kind of output you are looking for, may be no changes shall be made? throw an Exception seems unfriendly. But a replacement from LOOP to NARMAL shall be made which is consistant with the first part.
So perhaps the second part can be written like this:
else if (!looping && !(playMode == PlayMode.NORMAL || playMode == PlayMode.REVERSED)) {
if (playMode == PlayMode.LOOP_REVERSED)
playMode = PlayMode.REVERSED;
else if (playMode == PlayMode.LOOP) // replace the LOOP mode by NORMAL
playMode = PlayMode.NORMAL;
// ignore LOOP_PINGPONG and LOOP_RANDOM mode even if you want non-loop output
}
Moreover, there are three tests for getKeyFrame(float stateTime, boolean looping), but all of them require looping=true, so the second part might has never been tested.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with com.badlogic.gdx.graphics.g2d.Animation.getKeyFrame(float stateTime, boolean looping) and the three existing tests for that overload. Reproduce the behavior for each PlayMode, especially the looping=false cases, then establish the intended semantics before changing the method. Done means the behavior is documented by tests covering the relevant PlayMode combinations.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- game-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100