/**
* Copyright 2008 - 2011
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*
* @project loon
* @author cping
* @email:javachenpeng@yahoo.com
* @version 0.1
*/
package loon.action.sprite;
import java.util.ArrayList;
import loon.LSystem;
import loon.core.LRelease;
import loon.core.event.Updateable;
import loon.core.graphics.device.LColor;
import loon.core.graphics.opengl.LTexture;
import loon.core.graphics.opengl.LTextures;
import loon.core.graphics.opengl.TextureUtils;
import loon.utils.CollectionUtils;
public class Animation implements LRelease {
public interface AnimationListener {
public void onComplete(Animation animation);
}
public AnimationListener Listener;
public void setAnimationListener(AnimationListener l) {
this.Listener = l;
}
public AnimationListener getAnimationListener() {
return this.Listener;
}
boolean isRunning;
private ArrayList<AnimationFrame> frames;
int loopCount, loopPlay;
int currentFrameIndex;
long animTime, totalDuration;
int size;
public Animation() {
this(new ArrayList<AnimationFrame>(CollectionUtils.INITIAL_CAPACITY), 0);
}
public Animation(Animation a) {
this.isRunning = a.isRunning;
this.frames = new ArrayList<Animation.AnimationFrame>(a.frames);
this.loopCount = a.loopCount;
this.loopPlay = a.loopPlay;
this.currentFrameIndex = a.currentFrameIndex;
this.animTime = a.animTime;
this.totalDuration = a.totalDuration;
this.size = frames.size();
}
private Animation(ArrayList<AnimationFrame> frames, long totalDuration) {
this.loopCount = -1;
this.frames = frames;
this.size = frames.size();
this.totalDuration = totalDuration;
this.isRunning = true;
start();
}
public static Animation getDefaultAnimation(String fileName) {
return Animation.getDefaultAnimation(LTextures.loadTexture(fileName));
}
public static Animation getDefaultAnimation(final LTexture texture) {
return Animation.getDefaultAnimation(new LTexture[] { texture }, 1,
65535);
}
/**
* 转化指定文件为动画图像
*
* @param fileName
* @param width
* @param height
* @param timer
* @return
*/
public static Animation getDefaultAnimation(String fileName, int width,
int height, int timer) {
return Animation.getDefaultAnimation(
TextureUtils.getSplitTextures(fileName, width, height), -1,
timer);
}
/**
* 转化指定文件为动画图像
*
* @param fileName
* @param width
* @param height
* @param timer
* @param filterColor
* @return
*/
public static Animation getDefaultAnimation(String fileName, int width,
int height, int timer, LColor filterColor) {
return Animation.getDefaultAnimation(
TextureUtils.getSplitTextures(
TextureUtils.filterColor(fileName, filterColor), width,
height), -1, timer);
}
/**
* 转化指定文件为动画图像
*
* @param fileName
* @param maxFrame
* @param width
* @param height
* @param timer
* @return
*/
public static Animation getDefaultAnimation(String fileName, int maxFrame,
int width, int height, int timer) {
return Animation.getDefaultAnimation(
TextureUtils.getSplitTextures(fileName, width, height),
maxFrame, timer);
}
/**
* 转化一组Image为动画图像
*
* @param images
* @param maxFrame
* @param width
* @param height
* @param timer
* @return
*/
public static Animation getDefaultAnimation(LTexture[] images,
int maxFrame, int timer) {
if (images == null) {
return new Animation();
}
Animation animation = new Animation();
if (maxFrame != -1) {
for (int i = 0; i < maxFrame; i++) {
animation.addFrame(images[i], timer);
}
} else {
int size = images.length;
for (int i = 0; i < size; i++) {
animation.addFrame(images[i], timer);
}
}
return animation;
}
/**
* 克隆一个独立动画
*/
@Override
public Object clone() {
return new Animation(frames, totalDuration);
}
/**
* 添加一个动画图像
*
* @param image
* @param timer
*/
public synchronized void addFrame(LTexture image, long timer) {
totalDuration += timer;
frames.add(new AnimationFrame(image, totalDuration));
size++;
}
/**
* 添加一个动画图像
*
* @param fileName
* @param timer
*/
public synchronized void addFrame(String fileName, long timer) {
addFrame(LTextures.loadTexture(fileName), timer);
}
/**
* 开始执行动画
*
*/
public synchronized void start() {
animTime = 0;
if (size > 0) {
currentFrameIndex = 0;
}
}
/**
* 刷新动画为初始状态
*/
public void reset() {
animTime = 0;
currentFrameIndex = 0;
loopPlay = 0;
loopCount = -1;
isRunning = true;
}
/**
* 更新当前动画
*
* @param timer
*/
public synchronized void update(long timer) {
if (loopCount != -1 && loopPlay > loopCount) {
return;
}
if (isRunning) {
if (size > 0) {
animTime += timer;
if (animTime > totalDuration) {
if (Listener != null) {
Listener.onComplete(this);
}
animTime = animTime % totalDuration;
currentFrameIndex = 0;
loopPlay++;
}
for (; animTime > getFrame(currentFrameIndex).endTimer;) {
currentFrameIndex++;
}
}
}
}
/**
* 返回当前动画图象
*
* @return
*/
public LTexture getSpriteImage() {
if (size == 0) {
return null;
} else {
final LTexture texture = getFrame(currentFrameIndex).image;
if (!texture.isLoaded()) {
Updateable update = new Updateable() {
@Override
public void action(Object a) {
texture.loadTexture();
}
};
LSystem.load(update);
}
return texture;
}
}
/**
* 返回当前动画图象
*
* @param index
* @return
*/
public LTexture getSpriteImage(int index) {
if (index < 0 || index >= size) {
return null;
} else {
LTexture texture = getFrame(index).image;
if (!texture.isLoaded()) {
texture.loadTexture();
}
return texture;
}
}
/**
* 返回当前动画面板
*
* @param i
* @return
*/
private AnimationFrame getFrame(int index) {
if (index < 0) {
return frames.get(0);
} else if (index >= size) {
return frames.get(size - 1);
}
return frames.get(index);
}
/**
* 设定停止状态
*
* @param isStop
*/
public void setRunning(boolean runing) {
this.isRunning = runing;
}
/**
* 返回动画状态
*
* @param isStop
*/
public boolean isRunning() {
return this.isRunning;
}
/**
* 返回当前动画索引
*
* @return
*/
public int getCurrentFrameIndex() {
return this.currentFrameIndex;
}
public void setCurrentFrameIndex(int index) {
this.currentFrameIndex = index;
}
public int getTotalFrames() {
return size;
}
public int getLoopCount() {
return loopCount;
}
public void setLoopCount(int loopCount) {
this.loopCount = loopCount;
}
private class AnimationFrame implements LRelease {
LTexture image;
long endTimer;
public AnimationFrame(LTexture image, long endTimer) {
this.image = image;
this.endTimer = endTimer;
}
@Override
public void dispose() {
if (image != null) {
LTexture father = image.getParent();
if (father != null && !father.isClose()) {
father.destroy();
} else if (image != null && !image.isClose()) {
image.destroy();
}
}
}
}
@Override
public void dispose() {
if (frames != null) {
for (AnimationFrame frame : frames) {
if (frame != null) {
frame.dispose();
frame = null;
}
}
frames.clear();
}
this.size = 0;
}
}