新增动画 移除不相关的库
This commit is contained in:
@@ -2,6 +2,8 @@ abstract class Component extends egret.DisplayObjectContainer {
|
||||
public entity: Entity;
|
||||
private _enabled: boolean = true;
|
||||
public updateInterval: number = 1;
|
||||
/** 允许用户为实体存入信息 */
|
||||
public userData: any;
|
||||
|
||||
public get enabled(){
|
||||
return this.entity ? this.entity.enabled && this._enabled : this._enabled;
|
||||
|
||||
9
source/src/ECS/Components/SpriteAnimation.ts
Normal file
9
source/src/ECS/Components/SpriteAnimation.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
class SpriteAnimation {
|
||||
public readonly sprites: Sprite[];
|
||||
public readonly frameRate: number;
|
||||
|
||||
constructor(sprites: Sprite[], frameRate: number){
|
||||
this.sprites = sprites;
|
||||
this.frameRate = frameRate;
|
||||
}
|
||||
}
|
||||
142
source/src/ECS/Components/SpriteAnimator.ts
Normal file
142
source/src/ECS/Components/SpriteAnimator.ts
Normal file
@@ -0,0 +1,142 @@
|
||||
///<reference path="./SpriteRenderer.ts" />
|
||||
class SpriteAnimator extends SpriteRenderer {
|
||||
/** 在动画完成时触发,包括动画名称; */
|
||||
public onAnimationCompletedEvent: Function;
|
||||
/** 动画播放速度 */
|
||||
public speed = 1;
|
||||
/** 动画的当前状态 */
|
||||
public animationState = State.none;
|
||||
/** 当前动画 */
|
||||
public currentAnimation: SpriteAnimation;
|
||||
/** 当前动画的名称 */
|
||||
public currentAnimationName: string;
|
||||
/** 当前动画的精灵数组中当前帧的索引 */
|
||||
public currentFrame: number;
|
||||
/** 检查当前动画是否正在运行 */
|
||||
public get isRunning(): boolean{
|
||||
return this.animationState == State.running;
|
||||
}
|
||||
|
||||
private _animations: Map<string, SpriteAnimation> = new Map<string, SpriteAnimation>();
|
||||
private _elapsedTime: number = 0;
|
||||
private _loopMode: LoopMode;
|
||||
|
||||
constructor(sprite?: Sprite){
|
||||
super();
|
||||
|
||||
if (sprite) this.setSprite(sprite);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加一个SpriteAnimation
|
||||
* @param name
|
||||
* @param animation
|
||||
*/
|
||||
public addAnimation(name: string, animation: SpriteAnimation): SpriteAnimator{
|
||||
if (!this.sprite && animation.sprites.length > 0)
|
||||
this.setSprite(animation.sprites[0]);
|
||||
this._animations[name] = animation;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 以给定的名称放置动画。如果没有指定循环模式,则默认为循环
|
||||
* @param name
|
||||
* @param loopMode
|
||||
*/
|
||||
public play(name: string, loopMode: LoopMode = null){
|
||||
this.currentAnimation = this._animations[name];
|
||||
this.currentAnimationName = name;
|
||||
this.currentFrame = 0;
|
||||
this.animationState = State.running;
|
||||
|
||||
this.sprite = this.currentAnimation.sprites[0];
|
||||
this._elapsedTime = 0;
|
||||
this._loopMode = loopMode ? loopMode : LoopMode.loop;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查动画是否正在播放(即动画是活动的)。它可能仍然处于暂停状态)
|
||||
* @param name
|
||||
*/
|
||||
public isAnimationActive(name: string): boolean{
|
||||
return this.currentAnimation && this.currentAnimationName == name;
|
||||
}
|
||||
|
||||
/**
|
||||
* 暂停动画
|
||||
*/
|
||||
public pause(){
|
||||
this.animationState = State.paused;
|
||||
}
|
||||
|
||||
/**
|
||||
* 继续动画
|
||||
*/
|
||||
public unPause(){
|
||||
this.animationState = State.running;
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止当前动画并将其设为null
|
||||
*/
|
||||
public stop(){
|
||||
this.currentAnimation = null;
|
||||
this.currentAnimationName = null;
|
||||
this.currentFrame = 0;
|
||||
this.animationState = State.none;
|
||||
}
|
||||
|
||||
public update(){
|
||||
if (this.animationState != State.running || !this.currentAnimation) return;
|
||||
|
||||
let animation = this.currentAnimation;
|
||||
let secondsPerFrame = 1 / (animation.frameRate * this.speed);
|
||||
let iterationDuration = secondsPerFrame * animation.sprites.length;
|
||||
|
||||
this._elapsedTime += Time.deltaTime;
|
||||
let time = Math.abs(this._elapsedTime);
|
||||
|
||||
if (this._loopMode == LoopMode.once && time > iterationDuration ||
|
||||
this._loopMode == LoopMode.pingPongOnce && time > iterationDuration * 2){
|
||||
this.animationState = State.completed;
|
||||
this._elapsedTime = 0;
|
||||
this.currentFrame = 0;
|
||||
this.sprite = animation.sprites[this.currentFrame];
|
||||
return;
|
||||
}
|
||||
|
||||
// 弄清楚我们在哪个坐标系上
|
||||
let i = Math.floor(time / secondsPerFrame);
|
||||
let n = animation.sprites.length;
|
||||
if (n > 2 && (this._loopMode == LoopMode.pingPong || this._loopMode == LoopMode.pingPongOnce)){
|
||||
// pingpong
|
||||
let maxIndex = n - 1;
|
||||
this.currentFrame = maxIndex - Math.abs(maxIndex - i % (maxIndex * 2));
|
||||
}else{
|
||||
this.currentFrame = i % n;
|
||||
}
|
||||
|
||||
this.sprite = animation.sprites[this.currentFrame];
|
||||
}
|
||||
}
|
||||
|
||||
enum LoopMode {
|
||||
/** 在一个循环序列[A][B][C][A][B][C][A][B][C]... */
|
||||
loop,
|
||||
/** [A][B][C]然后暂停,设置时间为0 [A] */
|
||||
once,
|
||||
/** [A][B][C]。当它到达终点时,它会继续播放最后一帧,并且不会停止播放 */
|
||||
clampForever,
|
||||
/** 以一个乒乓循环的方式永远播放这个序列 [A][B][C][B][A][B][C][B]... */
|
||||
pingPong,
|
||||
/** 将顺序向前播放一次,然后返回到开始[A][B][C][B][A],然后暂停并设置时间为0 */
|
||||
pingPongOnce,
|
||||
}
|
||||
|
||||
enum State {
|
||||
none,
|
||||
running,
|
||||
paused,
|
||||
completed,
|
||||
}
|
||||
@@ -15,6 +15,14 @@ class SpriteRenderer extends RenderableComponent {
|
||||
}
|
||||
return this;
|
||||
}
|
||||
/** 应该由这个精灵显示的精灵。当设置时,精灵的原点也被设置为匹配精灵.origin。 */
|
||||
public get sprite(): Sprite{
|
||||
return this._sprite;
|
||||
}
|
||||
/** 应该由这个精灵显示的精灵。当设置时,精灵的原点也被设置为匹配精灵.origin。 */
|
||||
public set sprite(value: Sprite){
|
||||
this.setSprite(value);
|
||||
}
|
||||
|
||||
public setSprite(sprite: Sprite): SpriteRenderer{
|
||||
this.removeChildren();
|
||||
|
||||
Reference in New Issue
Block a user