package loon.action.sprite;
import loon.LTexture;
/**
* Entity类的动画播放扩展类,相比单纯使用Sprite类,此类更容易进行具体帧的临时播放和设置参数变更,以及监听.
*/
public class AnimatedEntity extends Entity {
public static interface IAnimationListener {
public void onAnimationStarted(final AnimatedEntity animatedSprite, final int initialLoopCount);
public void onAnimationFrameChanged(final AnimatedEntity animatedSprite, final int oldFrameIndex,
final int newFrameIndex);
public void onAnimationLoopFinished(final AnimatedEntity animatedSprite, final int remainingLoopCount,
final int initialLoopCount);
public void onAnimationFinished(final AnimatedEntity animatedSprite);
}
private static final int FRAMEINDEX_INVALID = -1;
private boolean _animationRunning;
private boolean _animationStartedFired;
private int _currentFrameIndex;
private long _animationProgress;
private int _remainingLoopCount;
private Animation _animation;
private final AnimationData _animationData = new AnimationData();
private IAnimationListener _animationListener;
public AnimatedEntity(final String[] paths, final int maxFrames, final float x, final float y, final float width,
final float height) {
this(Animation.getDefaultAnimation(paths, maxFrames, 0), x, y, width, height);
}
public AnimatedEntity(final LTexture[] texs, final int maxFrames, final float x, final float y, final float width,
final float height) {
this(Animation.getDefaultAnimation(texs, maxFrames, 0), x, y, width, height);
}
public AnimatedEntity(final String path, final int maxFrames, final int frameWidth, final int frameHeight,
final float x, final float y, final float width, final float height) {
this(Animation.getDefaultAnimation(path, maxFrames, frameWidth, frameHeight, 0), x, y, width, height);
}
public AnimatedEntity(final String path, final int frameWidth, final int frameHeight, final float x, final float y,
final float width, final float height) {
this(Animation.getDefaultAnimation(path, frameWidth, frameHeight, 10), x, y, width, height);
}
public AnimatedEntity(final Animation ani, final float x, final float y, final float width, final float height) {
super(ani.getSpriteImage());
this.setLocation(x, y);
this.setSize(width, height);
this._animation = ani;
}
public boolean isAnimationRunning() {
return this._animationRunning;
}
public void setCurrentFrameIndex(int idx) {
_animation.setCurrentFrameIndex(idx);
}
public int getCount() {
return _animation.size;
}
@Override
public void onUpdate(final long elapsedTime) {
if (this._animationRunning) {
final int loopCount = this._animationData.getLoopCount();
final int[] frames = this._animationData.getFrames();
final long animationDuration = this._animationData.getAnimationDuration();
if (!this._animationStartedFired && (this._animationProgress == 0)) {
this._animationStartedFired = true;
if (frames == null) {
this.setCurrentFrameIndex(this._animationData.getFirstFrameIndex());
} else {
this.setCurrentFrameIndex(frames[0]);
}
this._currentFrameIndex = 0;
if (this._animationListener != null) {
this._animationListener.onAnimationStarted(this, loopCount);
this._animationListener.onAnimationFrameChanged(this, AnimatedEntity.FRAMEINDEX_INVALID, 0);
}
}
this._animationProgress += (elapsedTime * 1000);
if (loopCount == AnimationData.LOOP_CONTINUOUS) {
while (this._animationProgress > animationDuration) {
this._animationProgress -= animationDuration;
if (this._animationListener != null) {
this._animationListener.onAnimationLoopFinished(this, this._remainingLoopCount, loopCount);
}
}
} else {
while (this._animationProgress > animationDuration) {
this._animationProgress -= animationDuration;
this._remainingLoopCount--;
if (this._remainingLoopCount < 0) {
break;
} else if (this._animationListener != null) {
this._animationListener.onAnimationLoopFinished(this, this._remainingLoopCount, loopCount);
}
}
}
if ((loopCount == AnimationData.LOOP_CONTINUOUS) || (this._remainingLoopCount >= 0)) {
final int newFrameIndex = this._animationData.calculateCurrentFrameIndex(this._animationProgress);
if (this._currentFrameIndex != newFrameIndex) {
if (frames == null) {
this.setCurrentFrameIndex(this._animationData.getFirstFrameIndex() + newFrameIndex);
} else {
this.setCurrentFrameIndex(frames[newFrameIndex]);
}
if (this._animationListener != null) {
this._animationListener.onAnimationFrameChanged(this, this._currentFrameIndex, newFrameIndex);
}
}
this._currentFrameIndex = newFrameIndex;
} else {
this._animationRunning = false;
if (this._animationListener != null) {
this._animationListener.onAnimationFinished(this);
}
}
setTexture(_animation.getSpriteImage());
}
}
public void stopAnimation() {
this._animationRunning = false;
}
public void stopAnimation(final int index) {
this._animationRunning = false;
this.setCurrentFrameIndex(index);
}
public void animate(final long frameDurationEach) {
this.animate(frameDurationEach, null);
}
public void animate(final long frameDurationEach, final IAnimationListener animationListener) {
this._animationData.set(frameDurationEach, this.getCount());
this.initAnimation(animationListener);
}
public void animate(final long frameDurationEach, final boolean loop) {
this.animate(frameDurationEach, loop, null);
}
public void animate(final long frameDurationEach, final boolean loop, final IAnimationListener animationListener) {
this._animationData.set(frameDurationEach, this.getCount(), loop);
this.initAnimation(animationListener);
}
public void animate(final long frameDurationEach, final int loopCount) {
this.animate(frameDurationEach, loopCount, null);
}
public void animate(final long frameDurationEach, final int loopCount, final IAnimationListener animationListener) {
this._animationData.set(frameDurationEach, this.getCount(), loopCount);
this.initAnimation(animationListener);
}
public void animate(final long[] frameDurations) {
this.animate(frameDurations, (IAnimationListener) null);
}
public void animate(final long[] frameDurations, final IAnimationListener animationListener) {
this._animationData.set(frameDurations);
this.initAnimation(animationListener);
}
public void animate(final long[] frameDurations, final boolean loop) {
this.animate(frameDurations, loop, null);
}
public void animate(final long[] frameDurations, final boolean loop, final IAnimationListener animationListener) {
this._animationData.set(frameDurations, loop);
this.initAnimation(animationListener);
}
public void animate(final long[] frameDurations, final int loopCount) {
this.animate(frameDurations, loopCount, null);
}
public void animate(final long[] frameDurations, final int loopCount, final IAnimationListener animationListener) {
this._animationData.set(frameDurations, loopCount);
this.initAnimation(animationListener);
}
public void animate(final long[] frameDurations, final int firstTileIndex, final int lastTileIndex,
final boolean loop) {
this.animate(frameDurations, firstTileIndex, lastTileIndex, loop, null);
}
public void animate(final long[] frameDurations, final int firstTileIndex, final int lastTileIndex,
final boolean loop, final IAnimationListener animationListener) {
this._animationData.set(frameDurations, firstTileIndex, lastTileIndex, loop);
this.initAnimation(animationListener);
}
public void animate(final long[] frameDurations, final int firstTileIndex, final int lastTileIndex,
final int loopCount) {
this.animate(frameDurations, firstTileIndex, lastTileIndex, loopCount, null);
}
public void animate(final long[] frameDurations, final int firstTileIndex, final int lastTileIndex,
final int loopCount, final IAnimationListener animationListener) {
this._animationData.set(frameDurations, firstTileIndex, lastTileIndex, loopCount);
this.initAnimation(animationListener);
}
public void animate(final long[] frameDurations, final int[] frames) {
this.animate(frameDurations, frames, null);
}
public void animate(final long[] frameDurations, final int[] frames, final IAnimationListener animationListener) {
this._animationData.set(frameDurations, frames);
this.initAnimation(animationListener);
}
public void animate(final long[] frameDurations, final int[] frames, final boolean loop) {
this.animate(frameDurations, frames, loop, null);
}
public void animate(final long[] frameDurations, final int[] frames, final boolean loop,
final IAnimationListener animationListener) {
this._animationData.set(frameDurations, frames, loop);
this.initAnimation(animationListener);
}
public void animate(final long[] frameDurations, final int[] frames, final int loopCount) {
this.animate(frameDurations, frames, loopCount, null);
}
public void animate(final long[] frameDurations, final int[] frames, final int loopCount,
final IAnimationListener animationListener) {
this._animationData.set(frameDurations, frames, loopCount);
this.initAnimation(animationListener);
}
public void animate(final AnimationData animationData) {
this.animate(animationData, null);
}
public void animate(final AnimationData animationData, final IAnimationListener animationListener) {
this._animationData.set(animationData);
this.initAnimation(animationListener);
}
private void initAnimation(final IAnimationListener animationListener) {
this._animationStartedFired = false;
this._animationListener = animationListener;
this._remainingLoopCount = this._animationData.getLoopCount();
this._animationProgress = 0;
this._animationRunning = true;
}
}