add TextureAtlasAnimator
This commit is contained in:
parent
bb516baa2f
commit
aff54c9c1d
33
src/com/blarg/gdx/graphics/atlas/AnimationSequence.java
Normal file
33
src/com/blarg/gdx/graphics/atlas/AnimationSequence.java
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
package com.blarg.gdx.graphics.atlas;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.graphics.Pixmap;
|
||||||
|
import com.badlogic.gdx.utils.Disposable;
|
||||||
|
|
||||||
|
class AnimationSequence implements Disposable {
|
||||||
|
public TextureAtlas atlas;
|
||||||
|
public int animatingIndex;
|
||||||
|
public int start;
|
||||||
|
public int stop;
|
||||||
|
public int current;
|
||||||
|
public float delay;
|
||||||
|
public float currentFrameTime;
|
||||||
|
public boolean isAnimating;
|
||||||
|
public boolean loop;
|
||||||
|
public Pixmap originalAnimatingTile;
|
||||||
|
public Pixmap[] frames;
|
||||||
|
|
||||||
|
public int getNumFrames() {
|
||||||
|
return stop - start + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAnimationFinished() {
|
||||||
|
return (isAnimating && !loop && current == stop);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose() {
|
||||||
|
originalAnimatingTile.dispose();
|
||||||
|
for (int i = 0; i < frames.length; ++i)
|
||||||
|
frames[i].dispose();
|
||||||
|
}
|
||||||
|
}
|
149
src/com/blarg/gdx/graphics/atlas/TextureAtlasAnimator.java
Normal file
149
src/com/blarg/gdx/graphics/atlas/TextureAtlasAnimator.java
Normal file
|
@ -0,0 +1,149 @@
|
||||||
|
package com.blarg.gdx.graphics.atlas;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.graphics.Pixmap;
|
||||||
|
import com.badlogic.gdx.graphics.TextureData;
|
||||||
|
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||||
|
import com.badlogic.gdx.utils.Disposable;
|
||||||
|
import com.badlogic.gdx.utils.ObjectMap;
|
||||||
|
import com.blarg.gdx.graphics.GraphicsHelpers;
|
||||||
|
|
||||||
|
public class TextureAtlasAnimator implements Disposable {
|
||||||
|
ObjectMap<String, AnimationSequence> animations;
|
||||||
|
|
||||||
|
public TextureAtlasAnimator() {
|
||||||
|
animations = new ObjectMap<String, AnimationSequence>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addSequence(String name, TextureAtlas atlas, int tileToBeAnimated, int start, int stop, float delay, boolean loop) {
|
||||||
|
if (animations.containsKey(name))
|
||||||
|
throw new UnsupportedOperationException("Duplicate animation sequence name.");
|
||||||
|
if (atlas.texture.getTextureData().getType() != TextureData.TextureDataType.Pixmap)
|
||||||
|
throw new UnsupportedOperationException("This only works with Textures backed by Pixmap texture data.");
|
||||||
|
|
||||||
|
AnimationSequence sequence = new AnimationSequence();
|
||||||
|
sequence.atlas = atlas;
|
||||||
|
sequence.animatingIndex = tileToBeAnimated;
|
||||||
|
sequence.start = start;
|
||||||
|
sequence.stop = stop;
|
||||||
|
sequence.delay = delay;
|
||||||
|
sequence.isAnimating = true;
|
||||||
|
sequence.loop = loop;
|
||||||
|
sequence.frames = new Pixmap[sequence.getNumFrames()];
|
||||||
|
sequence.current = sequence.start;
|
||||||
|
sequence.currentFrameTime = 0.0f;
|
||||||
|
|
||||||
|
// build up some CPU-side cache's of image data from the original TextureAtlas texture. we grab the image data
|
||||||
|
// for the tile we're placing animation frames to so we can restore the original texture when/if needed. and we
|
||||||
|
// grab each of the tiles that appear in the animation sequence so we can quickly upload it to the texture when
|
||||||
|
// we're at that frame
|
||||||
|
|
||||||
|
// grab the TextureAtlas texture's image data
|
||||||
|
TextureData textureData = atlas.texture.getTextureData();
|
||||||
|
if (!textureData.isPrepared())
|
||||||
|
textureData.prepare();
|
||||||
|
Pixmap textureImage = textureData.consumePixmap();
|
||||||
|
|
||||||
|
// copy the image data for the destination animation tile region
|
||||||
|
TextureRegion tileRegion = atlas.get(tileToBeAnimated);
|
||||||
|
sequence.originalAnimatingTile = new Pixmap(tileRegion.getRegionWidth(), tileRegion.getRegionHeight(), textureData.getFormat());
|
||||||
|
sequence.originalAnimatingTile.drawPixmap(
|
||||||
|
textureImage, 0, 0,
|
||||||
|
tileRegion.getRegionX(), tileRegion.getRegionY(), tileRegion.getRegionWidth(), tileRegion.getRegionHeight()
|
||||||
|
);
|
||||||
|
|
||||||
|
// copy image data for each of the animation sequence tiles (from "start" to and including "stop")
|
||||||
|
for (int i = 0; i < sequence.getNumFrames(); ++i) {
|
||||||
|
TextureRegion tile = atlas.get(i + sequence.start);
|
||||||
|
sequence.frames[i] = new Pixmap(tileRegion.getRegionWidth(), tileRegion.getRegionHeight(), textureData.getFormat());
|
||||||
|
sequence.frames[i].drawPixmap(
|
||||||
|
textureImage, 0, 0,
|
||||||
|
tile.getRegionX(), tile.getRegionY(), tile.getRegionWidth(), tile.getRegionHeight()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// all good!
|
||||||
|
animations.put(name, sequence);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetSequence(String name) {
|
||||||
|
AnimationSequence sequence = animations.get(name);
|
||||||
|
if (sequence == null)
|
||||||
|
throw new RuntimeException("No sequence with that name.");
|
||||||
|
|
||||||
|
sequence.isAnimating = true;
|
||||||
|
sequence.current = sequence.start;
|
||||||
|
sequence.currentFrameTime = 0.0f;
|
||||||
|
|
||||||
|
updateTextureWithCurrentTileFrame(sequence);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stopSequence(String name, boolean restoreOriginalTile) {
|
||||||
|
AnimationSequence sequence = animations.get(name);
|
||||||
|
if (sequence == null)
|
||||||
|
throw new RuntimeException("No sequence with that name.");
|
||||||
|
|
||||||
|
sequence.isAnimating = false;
|
||||||
|
sequence.current = sequence.stop;
|
||||||
|
sequence.currentFrameTime = 0.0f;
|
||||||
|
|
||||||
|
if (restoreOriginalTile)
|
||||||
|
restoreTextureWithOriginalTile(sequence);
|
||||||
|
else
|
||||||
|
updateTextureWithCurrentTileFrame(sequence);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void enableSequence(String name, boolean enable) {
|
||||||
|
AnimationSequence sequence = animations.get(name);
|
||||||
|
if (sequence == null)
|
||||||
|
throw new RuntimeException("No sequence with that name.");
|
||||||
|
|
||||||
|
sequence.isAnimating = enable;
|
||||||
|
sequence.currentFrameTime = 0.0f;
|
||||||
|
|
||||||
|
updateTextureWithCurrentTileFrame(sequence);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onUpdate(float delta) {
|
||||||
|
for (ObjectMap.Entry<String, AnimationSequence> i : animations.entries()) {
|
||||||
|
AnimationSequence sequence = i.value;
|
||||||
|
if (!sequence.isAnimationFinished() && sequence.isAnimating) {
|
||||||
|
sequence.currentFrameTime += delta;
|
||||||
|
if (sequence.currentFrameTime >= sequence.delay) {
|
||||||
|
// move to the next frame
|
||||||
|
sequence.currentFrameTime = 0.0f;
|
||||||
|
++sequence.current;
|
||||||
|
if (sequence.current > sequence.stop)
|
||||||
|
sequence.current = sequence.start;
|
||||||
|
|
||||||
|
updateTextureWithCurrentTileFrame(sequence);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onResume() {
|
||||||
|
for (ObjectMap.Entry<String, AnimationSequence> i : animations.entries())
|
||||||
|
updateTextureWithCurrentTileFrame(i.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateTextureWithCurrentTileFrame(AnimationSequence sequence) {
|
||||||
|
int frameIndex = sequence.current - sequence.start;
|
||||||
|
Pixmap frameImage = sequence.frames[frameIndex];
|
||||||
|
TextureRegion tile = sequence.atlas.get(sequence.animatingIndex);
|
||||||
|
GraphicsHelpers.drawToTexture(sequence.atlas.texture, frameImage, tile.getRegionX(), tile.getRegionY());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void restoreTextureWithOriginalTile(AnimationSequence sequence) {
|
||||||
|
TextureRegion tile = sequence.atlas.get(sequence.animatingIndex);
|
||||||
|
GraphicsHelpers.drawToTexture(sequence.atlas.texture, sequence.originalAnimatingTile, tile.getRegionX(), tile.getRegionY());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose() {
|
||||||
|
for (ObjectMap.Entry<String, AnimationSequence> i : animations.entries()) {
|
||||||
|
restoreTextureWithOriginalTile(i.value);
|
||||||
|
i.value.dispose();
|
||||||
|
}
|
||||||
|
animations.clear();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue