Coroutine 类型从IEnumerable为Iterator

This commit is contained in:
yhh
2020-09-01 11:51:03 +08:00
parent 8db028db1c
commit 34a8d48df9
26 changed files with 3835 additions and 3057 deletions

View File

@@ -0,0 +1,106 @@
///<reference path="RenderableComponent.ts"/>
module es {
/**
* 可用于创建简单网格的基本类
*/
export class Mesh extends RenderableComponent {
public displayObject: egret.Mesh = new egret.Mesh();
public get bounds(){
if (this._areBoundsDirty){
this._bounds.calculateBounds(Vector2.add(this.entity.transform.position, this._topLeftVertPosition), Vector2.zero,
Vector2.zero, this.entity.transform.scale, this.entity.transform.rotation, this._width, this._height);
this._areBoundsDirty = false;
}
return this._bounds;
}
public _primitiveCount: number = 0;
public _topLeftVertPosition: Vector2;
public _width: number = 0;
public _height: number = 0;
public _triangles: number[] = [];
public _verts: VertexPositionColorTexture[] = [];
/**
* 重新计算边界和可选地设置uv。设置uv以最适合的方式映射纹理。
* @param recalculateUVs
*/
public recalculateBounds(recalculateUVs: boolean){
this._topLeftVertPosition = new Vector2(Number.MAX_VALUE, Number.MAX_VALUE);
let max = new Vector2(Number.MIN_VALUE, Number.MIN_VALUE);
for (let i = 0; i < this._verts.length; i ++){
this._topLeftVertPosition.x = Math.min(this._topLeftVertPosition.x, this._verts[i].position.x);
this._topLeftVertPosition.y = Math.min(this._topLeftVertPosition.y, this._verts[i].position.y);
max.x = Math.max(max.x, this._verts[i].position.x);
max.y = Math.max(max.y, this._verts[i].position.y);
}
this._width = max.x - this._topLeftVertPosition.x;
this._height = max.y - this._topLeftVertPosition.y;
// 如果需要处理uv
if (recalculateUVs){
for (let i = 0; i < this._verts.length; i ++){
this._verts[i].textureCoordinate.x = (this._verts[i].position.x - this._topLeftVertPosition.x) / this._width;
this._verts[i].textureCoordinate.y = (this._verts[i].position.y - this._topLeftVertPosition.y) / this._height;
}
}
return this;
}
/**
* 设置纹理。传入null来取消纹理设置。
* @param texture
*/
public setTexture(texture: egret.Texture): Mesh{
this.displayObject.texture = texture;
return this;
}
/**
* 设置vert位置。如果position数组与vert数组大小不匹配则将重新创建vert数组。
* @param positions
*/
public setVertPositions(positions: Vector2[]){
if (this._verts == undefined || this._verts.length != positions.length){
this._verts = new Array(positions.length);
this._verts.fill(new VertexPositionColorTexture(), 0, positions.length);
}
for (let i = 0; i < this._verts.length; i ++){
this._verts[i].position = positions[i];
}
return this;
}
/**
* 设置渲染的三角形索引
* @param triangles
*/
public setTriangles(triangles: number[]){
if (triangles.length % 3 != 0){
console.error("三角形必须是3的倍数");
return;
}
this._primitiveCount = triangles.length / 3;
this._triangles = triangles;
return this;
}
public render(camera: es.Camera) {
let renderNode = this.displayObject.$renderNode as egret.sys.MeshNode;
renderNode.imageWidth = this._width;
renderNode.imageHeight = this._height;
renderNode.vertices = this._triangles;
}
}
export class VertexPositionColorTexture {
public position: Vector2;
public textureCoordinate: Vector2;
}
}

View File

@@ -1,231 +1,231 @@
///<reference path="./PooledComponent.ts" />
module es {
/**
*
*/
export abstract class RenderableComponent extends Component implements IRenderable {
/**
* egret显示对象
*/
public displayObject: egret.DisplayObject = new egret.DisplayObject();
public hollowShape: egret.Shape = new egret.Shape();
public pixelShape: egret.Shape = new egret.Shape();
/**
*
*/
public color: number = 0x000000;
protected _areBoundsDirty = true;
/**
* renderableComponent的宽度
* bounds属性则需要实现这个
*/
public get width() {
return this.bounds.width;
}
/**
* renderableComponent的高度
* bounds属性则需要实现这个
*/
public get height() {
return this.bounds.height;
}
public debugRenderEnabled: boolean = true;
protected _localOffset: Vector2 = Vector2.zero;
/**
*
*/
public get localOffset(): Vector2 {
return this._localOffset;
}
/**
*
* @param value
*/
public set localOffset(value: Vector2) {
this.setLocalOffset(value);
}
protected _renderLayer: number = 0;
/**
*
*/
public get renderLayer(): number {
return this._renderLayer;
}
public set renderLayer(value: number) {
this.setRenderLayer(value);
}
protected _bounds: Rectangle = new Rectangle();
/**
* AABB,
*/
public get bounds(): Rectangle {
if (this._areBoundsDirty) {
this._bounds.calculateBounds(this.entity.transform.position, this._localOffset, Vector2.zero,
this.entity.transform.scale, this.entity.transform.rotation, this.width, this.height);
this._areBoundsDirty = false;
}
return this._bounds;
}
private _isVisible: boolean;
/**
* onBecameVisible/onBecameInvisible方法
*/
public get isVisible() {
return this._isVisible;
}
/**
* onBecameVisible/onBecameInvisible方法
* @param value
*/
public set isVisible(value: boolean) {
if (this._isVisible != value) {
this._isVisible = value;
if (this._isVisible)
this.onBecameVisible();
else
this.onBecameInvisible();
}
}
public onEntityTransformChanged(comp: transform.Component) {
this._areBoundsDirty = true;
}
/**
* 使
* @param camera
*/
public abstract render(camera: Camera);
public debugRender(camera: Camera) {
if (!this.debugRenderEnabled)
return;
if (!this.hollowShape.parent)
this.debugDisplayObject.addChild(this.hollowShape);
if (!this.pixelShape.parent)
this.debugDisplayObject.addChild(this.pixelShape);
if (!this.entity.getComponent(Collider)){
this.hollowShape.graphics.clear();
this.hollowShape.graphics.beginFill(Colors.renderableBounds, 0);
this.hollowShape.graphics.lineStyle(1, Colors.renderableBounds);
this.hollowShape.graphics.drawRect(this.bounds.x - camera.bounds.x, this.bounds.y - camera.bounds.y, this.bounds.width, this.bounds.height);
this.hollowShape.graphics.endFill();
}
let pixelPos = Vector2.add(this.entity.transform.position, this._localOffset).subtract(camera.bounds.location);
this.pixelShape.graphics.clear();
this.pixelShape.graphics.beginFill(Colors.renderableCenter, 0);
this.pixelShape.graphics.lineStyle(4, Colors.renderableCenter);
this.pixelShape.graphics.moveTo(pixelPos.x, pixelPos.y);
this.pixelShape.graphics.lineTo(pixelPos.x, pixelPos.y);
this.pixelShape.graphics.endFill();
}
/**
* renderableComponent的边界与camera.bounds相交 true
* isVisible标志的状态开关
* 使
* @param camera
*/
public isVisibleFromCamera(camera: Camera): boolean {
if (!camera)
return false;
this.isVisible = camera.bounds.intersects(this.bounds);
return this.isVisible;
}
/**
*
* @param renderLayer
*/
public setRenderLayer(renderLayer: number): RenderableComponent {
if (renderLayer != this._renderLayer) {
let oldRenderLayer = this._renderLayer;
this._renderLayer = renderLayer;
// 如果该组件拥有一个实体那么是由ComponentList管理需要通知它改变了渲染层
if (this.entity && this.entity.scene)
this.entity.scene.renderableComponents.updateRenderableRenderLayer(this, oldRenderLayer, this._renderLayer);
}
return this;
}
/**
*
* @param color
*/
public setColor(color: number): RenderableComponent {
this.color = color;
return this;
}
/**
*
* @param offset
*/
public setLocalOffset(offset: Vector2): RenderableComponent {
if (this._localOffset != offset) {
this._localOffset = offset;
}
return this;
}
/**
*
*/
public sync(camera: Camera) {
if (this.displayObject.x != this.bounds.x - camera.bounds.y) this.displayObject.x = this.bounds.x - camera.bounds.y;
if (this.displayObject.y != this.bounds.y - camera.bounds.y) this.displayObject.y = this.bounds.y - camera.bounds.y;
if (this.displayObject.scaleX != this.entity.scale.x) this.displayObject.scaleX = this.entity.scale.x;
if (this.displayObject.scaleY != this.entity.scale.y) this.displayObject.scaleY = this.entity.scale.y;
if (this.displayObject.rotation != this.entity.rotationDegrees) this.displayObject.rotation = this.entity.rotationDegrees;
}
public compareTo(other: RenderableComponent){
return other.renderLayer - this.renderLayer;
}
public toString() {
return `[RenderableComponent] renderLayer: ${this.renderLayer}`;
}
/**
* renderableComponent进入相机框架时调用
* isVisibleFromCamera进行剔除检查
*/
protected onBecameVisible() {
this.displayObject.visible = this.isVisible;
this.debugDisplayObject.visible = this.isVisible;
}
/**
* renderableComponent离开相机框架时调用
* isVisibleFromCamera进行剔除检查
*/
protected onBecameInvisible() {
this.displayObject.visible = this.isVisible;
this.debugDisplayObject.visible = this.isVisible;
}
}
///<reference path="../PooledComponent.ts" />
module es {
/**
*
*/
export abstract class RenderableComponent extends Component implements IRenderable {
/**
* egret显示对象
*/
public displayObject: egret.DisplayObject = new egret.DisplayObject();
public hollowShape: egret.Shape = new egret.Shape();
public pixelShape: egret.Shape = new egret.Shape();
/**
*
*/
public color: number = 0x000000;
protected _areBoundsDirty = true;
/**
* renderableComponent的宽度
* bounds属性则需要实现这个
*/
public get width() {
return this.bounds.width;
}
/**
* renderableComponent的高度
* bounds属性则需要实现这个
*/
public get height() {
return this.bounds.height;
}
public debugRenderEnabled: boolean = true;
protected _localOffset: Vector2 = Vector2.zero;
/**
*
*/
public get localOffset(): Vector2 {
return this._localOffset;
}
/**
*
* @param value
*/
public set localOffset(value: Vector2) {
this.setLocalOffset(value);
}
protected _renderLayer: number = 0;
/**
*
*/
public get renderLayer(): number {
return this._renderLayer;
}
public set renderLayer(value: number) {
this.setRenderLayer(value);
}
protected _bounds: Rectangle = new Rectangle();
/**
* AABB,
*/
public get bounds(): Rectangle {
if (this._areBoundsDirty) {
this._bounds.calculateBounds(this.entity.transform.position, this._localOffset, Vector2.zero,
this.entity.transform.scale, this.entity.transform.rotation, this.width, this.height);
this._areBoundsDirty = false;
}
return this._bounds;
}
private _isVisible: boolean;
/**
* onBecameVisible/onBecameInvisible方法
*/
public get isVisible() {
return this._isVisible;
}
/**
* onBecameVisible/onBecameInvisible方法
* @param value
*/
public set isVisible(value: boolean) {
if (this._isVisible != value) {
this._isVisible = value;
if (this._isVisible)
this.onBecameVisible();
else
this.onBecameInvisible();
}
}
public onEntityTransformChanged(comp: transform.Component) {
this._areBoundsDirty = true;
}
/**
* 使
* @param camera
*/
public abstract render(camera: Camera);
public debugRender(camera: Camera) {
if (!this.debugRenderEnabled)
return;
if (!this.hollowShape.parent)
this.debugDisplayObject.addChild(this.hollowShape);
if (!this.pixelShape.parent)
this.debugDisplayObject.addChild(this.pixelShape);
if (!this.entity.getComponent(Collider)){
this.hollowShape.graphics.clear();
this.hollowShape.graphics.beginFill(Colors.renderableBounds, 0);
this.hollowShape.graphics.lineStyle(1, Colors.renderableBounds);
this.hollowShape.graphics.drawRect(this.bounds.x - camera.bounds.x, this.bounds.y - camera.bounds.y, this.bounds.width, this.bounds.height);
this.hollowShape.graphics.endFill();
}
let pixelPos = Vector2.add(this.entity.transform.position, this._localOffset).subtract(camera.bounds.location);
this.pixelShape.graphics.clear();
this.pixelShape.graphics.beginFill(Colors.renderableCenter, 0);
this.pixelShape.graphics.lineStyle(4, Colors.renderableCenter);
this.pixelShape.graphics.moveTo(pixelPos.x, pixelPos.y);
this.pixelShape.graphics.lineTo(pixelPos.x, pixelPos.y);
this.pixelShape.graphics.endFill();
}
/**
* renderableComponent的边界与camera.bounds相交 true
* isVisible标志的状态开关
* 使
* @param camera
*/
public isVisibleFromCamera(camera: Camera): boolean {
if (!camera)
return false;
this.isVisible = camera.bounds.intersects(this.bounds);
return this.isVisible;
}
/**
*
* @param renderLayer
*/
public setRenderLayer(renderLayer: number): RenderableComponent {
if (renderLayer != this._renderLayer) {
let oldRenderLayer = this._renderLayer;
this._renderLayer = renderLayer;
// 如果该组件拥有一个实体那么是由ComponentList管理需要通知它改变了渲染层
if (this.entity && this.entity.scene)
this.entity.scene.renderableComponents.updateRenderableRenderLayer(this, oldRenderLayer, this._renderLayer);
}
return this;
}
/**
*
* @param color
*/
public setColor(color: number): RenderableComponent {
this.color = color;
return this;
}
/**
*
* @param offset
*/
public setLocalOffset(offset: Vector2): RenderableComponent {
if (this._localOffset != offset) {
this._localOffset = offset;
}
return this;
}
/**
*
*/
public sync(camera: Camera) {
if (this.displayObject.x != this.bounds.x - camera.bounds.y) this.displayObject.x = this.bounds.x - camera.bounds.y;
if (this.displayObject.y != this.bounds.y - camera.bounds.y) this.displayObject.y = this.bounds.y - camera.bounds.y;
if (this.displayObject.scaleX != this.entity.scale.x) this.displayObject.scaleX = this.entity.scale.x;
if (this.displayObject.scaleY != this.entity.scale.y) this.displayObject.scaleY = this.entity.scale.y;
if (this.displayObject.rotation != this.entity.rotationDegrees) this.displayObject.rotation = this.entity.rotationDegrees;
}
public compareTo(other: RenderableComponent){
return other.renderLayer - this.renderLayer;
}
public toString() {
return `[RenderableComponent] renderLayer: ${this.renderLayer}`;
}
/**
* renderableComponent进入相机框架时调用
* isVisibleFromCamera进行剔除检查
*/
protected onBecameVisible() {
this.displayObject.visible = this.isVisible;
this.debugDisplayObject.visible = this.isVisible;
}
/**
* renderableComponent离开相机框架时调用
* isVisibleFromCamera进行剔除检查
*/
protected onBecameInvisible() {
this.displayObject.visible = this.isVisible;
this.debugDisplayObject.visible = this.isVisible;
}
}
}

View File

@@ -1,62 +1,62 @@
module es {
import RenderTexture = egret.RenderTexture;
import Bitmap = egret.Bitmap;
import SpriteSheet = egret.SpriteSheet;
export class Sprite {
public texture2D: egret.Texture;
public readonly sourceRect: Rectangle;
public readonly center: Vector2;
public origin: Vector2;
public readonly uvs: Rectangle = new Rectangle();
constructor(texture: egret.Texture,
sourceRect: Rectangle = new Rectangle(0, 0, texture.textureWidth, texture.textureHeight),
origin: Vector2 = sourceRect.getHalfSize()) {
this.texture2D = texture;
this.sourceRect = sourceRect;
this.center = new Vector2(sourceRect.width * 0.5, sourceRect.height * 0.5);
this.origin = origin;
let inverseTexW = 1 / texture.textureWidth;
let inverseTexH = 1 / texture.textureHeight;
this.uvs.x = sourceRect.x * inverseTexW;
this.uvs.y = sourceRect.y * inverseTexH;
this.uvs.width = sourceRect.width * inverseTexW;
this.uvs.height = sourceRect.height * inverseTexH;
}
/**
* /
* @param texture
* @param cellWidth
* @param cellHeight
* @param cellOffset 0
* @param maxCellsToInclude
*/
public static spritesFromAtlas(texture: egret.Texture, cellWidth: number, cellHeight: number,
cellOffset: number = 0, maxCellsToInclude: number = Number.MAX_VALUE){
let sprites: Sprite[] = [];
let cols = texture.textureWidth / cellWidth;
let rows = texture.textureHeight / cellHeight;
let i = 0;
let spriteSheet = new SpriteSheet(texture);
for (let y = 0; y < rows; y ++){
for (let x = 0; x < cols; x ++) {
if (i++ < cellOffset) continue;
let texture = spriteSheet.getTexture(`${y}_${x}`);
if (!texture)
texture = spriteSheet.createTexture(`${y}_${x}`, x * cellWidth, y * cellHeight, cellWidth, cellHeight);
sprites.push(new Sprite(texture));
if (sprites.length == maxCellsToInclude) return sprites;
}
}
return sprites;
}
}
}
module es {
import RenderTexture = egret.RenderTexture;
import Bitmap = egret.Bitmap;
import SpriteSheet = egret.SpriteSheet;
export class Sprite {
public texture2D: egret.Texture;
public readonly sourceRect: Rectangle;
public readonly center: Vector2;
public origin: Vector2;
public readonly uvs: Rectangle = new Rectangle();
constructor(texture: egret.Texture,
sourceRect: Rectangle = new Rectangle(0, 0, texture.textureWidth, texture.textureHeight),
origin: Vector2 = sourceRect.getHalfSize()) {
this.texture2D = texture;
this.sourceRect = sourceRect;
this.center = new Vector2(sourceRect.width * 0.5, sourceRect.height * 0.5);
this.origin = origin;
let inverseTexW = 1 / texture.textureWidth;
let inverseTexH = 1 / texture.textureHeight;
this.uvs.x = sourceRect.x * inverseTexW;
this.uvs.y = sourceRect.y * inverseTexH;
this.uvs.width = sourceRect.width * inverseTexW;
this.uvs.height = sourceRect.height * inverseTexH;
}
/**
* /
* @param texture
* @param cellWidth
* @param cellHeight
* @param cellOffset 0
* @param maxCellsToInclude
*/
public static spritesFromAtlas(texture: egret.Texture, cellWidth: number, cellHeight: number,
cellOffset: number = 0, maxCellsToInclude: number = Number.MAX_VALUE){
let sprites: Sprite[] = [];
let cols = texture.textureWidth / cellWidth;
let rows = texture.textureHeight / cellHeight;
let i = 0;
let spriteSheet = new SpriteSheet(texture);
for (let y = 0; y < rows; y ++){
for (let x = 0; x < cols; x ++) {
if (i++ < cellOffset) continue;
let texture = spriteSheet.getTexture(`${y}_${x}`);
if (!texture)
texture = spriteSheet.createTexture(`${y}_${x}`, x * cellWidth, y * cellHeight, cellWidth, cellHeight);
sprites.push(new Sprite(texture));
if (sprites.length == maxCellsToInclude) return sprites;
}
}
return sprites;
}
}
}

View File

@@ -1,11 +1,11 @@
module es {
export class SpriteAnimation {
public readonly sprites: Sprite[];
public readonly frameRate: number;
constructor(sprites: Sprite[], frameRate: number = 10) {
this.sprites = sprites;
this.frameRate = frameRate;
}
}
}
module es {
export class SpriteAnimation {
public readonly sprites: Sprite[];
public readonly frameRate: number;
constructor(sprites: Sprite[], frameRate: number = 10) {
this.sprites = sprites;
this.frameRate = frameRate;
}
}
}

View File

@@ -1,163 +1,163 @@
///<reference path="./SpriteRenderer.ts" />
module es {
export 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,
}
export enum State {
none,
running,
paused,
completed,
}
export class SpriteAnimator extends SpriteRenderer {
/**
*
*/
public onAnimationCompletedEvent: (string) => {};
/**
*
*/
public speed = 1;
/**
*
*/
public animationState = State.none;
/**
*
*/
public currentAnimation: SpriteAnimation;
/**
*
*/
public currentAnimationName: string;
/**
*
*/
public currentFrame: number;
public _elapsedTime: number = 0;
public _loopMode: LoopMode;
constructor(sprite?: Sprite) {
super(sprite);
}
/**
*
*/
public get isRunning(): boolean {
return this.animationState == State.running;
}
private _animations: Map<string, SpriteAnimation> = new Map<string, SpriteAnimation>();
/** 提供对可用动画列表的访问 */
public get animations() {
return this._animations;
}
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);
// Once和PingPongOnce完成后重置为Time = 0
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.displayObject as egret.Bitmap).texture = animation.sprites[this.currentFrame].texture2D;
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.displayObject as egret.Bitmap).texture = animation.sprites[this.currentFrame].texture2D;
}
/**
* 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.displayObject as egret.Bitmap).texture = this.currentAnimation.sprites[0].texture2D;
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;
}
}
}
///<reference path="./SpriteRenderer.ts" />
module es {
export 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,
}
export enum State {
none,
running,
paused,
completed,
}
export class SpriteAnimator extends SpriteRenderer {
/**
*
*/
public onAnimationCompletedEvent: (string) => {};
/**
*
*/
public speed = 1;
/**
*
*/
public animationState = State.none;
/**
*
*/
public currentAnimation: SpriteAnimation;
/**
*
*/
public currentAnimationName: string;
/**
*
*/
public currentFrame: number;
public _elapsedTime: number = 0;
public _loopMode: LoopMode;
constructor(sprite?: Sprite) {
super(sprite);
}
/**
*
*/
public get isRunning(): boolean {
return this.animationState == State.running;
}
private _animations: Map<string, SpriteAnimation> = new Map<string, SpriteAnimation>();
/** 提供对可用动画列表的访问 */
public get animations() {
return this._animations;
}
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);
// Once和PingPongOnce完成后重置为Time = 0
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.displayObject as egret.Bitmap).texture = animation.sprites[this.currentFrame].texture2D;
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.displayObject as egret.Bitmap).texture = animation.sprites[this.currentFrame].texture2D;
}
/**
* 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.displayObject as egret.Bitmap).texture = this.currentAnimation.sprites[0].texture2D;
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;
}
}
}

View File

@@ -1,131 +1,131 @@
module es {
import Bitmap = egret.Bitmap;
export class SpriteRenderer extends RenderableComponent {
constructor(sprite: Sprite | egret.Texture = null) {
super();
if (sprite instanceof Sprite)
this.setSprite(sprite);
else if (sprite instanceof egret.Texture)
this.setSprite(new Sprite(sprite));
}
public get bounds() {
if (this._areBoundsDirty) {
if (this._sprite) {
this._bounds.calculateBounds(this.entity.transform.position, this._localOffset, this._origin,
this.entity.transform.scale, this.entity.transform.rotation, this._sprite.sourceRect.width,
this._sprite.sourceRect.height);
this._areBoundsDirty = false;
}
}
return this._bounds;
}
/**
*
* x/y 0-1
*/
public get originNormalized(): Vector2 {
return new Vector2(this._origin.x / this.width * this.entity.transform.scale.x,
this._origin.y / this.height * this.entity.transform.scale.y);
}
/**
*
* x/y 0-1
* @param value
*/
public set originNormalized(value: Vector2) {
this.setOrigin(new Vector2(value.x * this.width / this.entity.transform.scale.x,
value.y * this.height / this.entity.transform.scale.y));
}
protected _origin: Vector2;
/**
*
*/
public get origin(): Vector2 {
return this._origin;
}
/**
*
* @param value
*/
public set origin(value: Vector2) {
this.setOrigin(value);
}
protected _sprite: Sprite;
/**
*
* origin
*/
public get sprite(): Sprite {
return this._sprite;
}
/**
*
* origin
* @param value
*/
public set sprite(value: Sprite) {
this.setSprite(value);
}
/**
* sprite.origin
* @param sprite
*/
public setSprite(sprite: Sprite): SpriteRenderer {
this._sprite = sprite;
if (this._sprite) {
this._origin = this._sprite.origin;
this.displayObject.anchorOffsetX = this._origin.x;
this.displayObject.anchorOffsetY = this._origin.y;
}
this.displayObject = new Bitmap(sprite.texture2D);
return this;
}
/**
*
* @param origin
*/
public setOrigin(origin: Vector2): SpriteRenderer {
if (this._origin != origin) {
this._origin = origin;
this.displayObject.anchorOffsetX = this._origin.x;
this.displayObject.anchorOffsetY = this._origin.y;
this._areBoundsDirty = true;
}
return this;
}
/**
*
* x/y 0-1
* @param value
*/
public setOriginNormalized(value: Vector2): SpriteRenderer {
this.setOrigin(new Vector2(value.x * this.width / this.entity.transform.scale.x,
value.y * this.height / this.entity.transform.scale.y));
return this;
}
public render(camera: Camera) {
this.sync(camera);
if (this.displayObject.x != this.bounds.x - camera.bounds.x) this.displayObject.x = this.bounds.x - camera.bounds.x;
if (this.displayObject.y != this.bounds.y - camera.bounds.y) this.displayObject.y = this.bounds.y - camera.bounds.y;
}
}
}
module es {
import Bitmap = egret.Bitmap;
export class SpriteRenderer extends RenderableComponent {
constructor(sprite: Sprite | egret.Texture = null) {
super();
if (sprite instanceof Sprite)
this.setSprite(sprite);
else if (sprite instanceof egret.Texture)
this.setSprite(new Sprite(sprite));
}
public get bounds() {
if (this._areBoundsDirty) {
if (this._sprite) {
this._bounds.calculateBounds(this.entity.transform.position, this._localOffset, this._origin,
this.entity.transform.scale, this.entity.transform.rotation, this._sprite.sourceRect.width,
this._sprite.sourceRect.height);
this._areBoundsDirty = false;
}
}
return this._bounds;
}
/**
*
* x/y 0-1
*/
public get originNormalized(): Vector2 {
return new Vector2(this._origin.x / this.width * this.entity.transform.scale.x,
this._origin.y / this.height * this.entity.transform.scale.y);
}
/**
*
* x/y 0-1
* @param value
*/
public set originNormalized(value: Vector2) {
this.setOrigin(new Vector2(value.x * this.width / this.entity.transform.scale.x,
value.y * this.height / this.entity.transform.scale.y));
}
protected _origin: Vector2;
/**
*
*/
public get origin(): Vector2 {
return this._origin;
}
/**
*
* @param value
*/
public set origin(value: Vector2) {
this.setOrigin(value);
}
protected _sprite: Sprite;
/**
*
* origin
*/
public get sprite(): Sprite {
return this._sprite;
}
/**
*
* origin
* @param value
*/
public set sprite(value: Sprite) {
this.setSprite(value);
}
/**
* sprite.origin
* @param sprite
*/
public setSprite(sprite: Sprite): SpriteRenderer {
this._sprite = sprite;
if (this._sprite) {
this._origin = this._sprite.origin;
this.displayObject.anchorOffsetX = this._origin.x;
this.displayObject.anchorOffsetY = this._origin.y;
}
this.displayObject = new Bitmap(sprite.texture2D);
return this;
}
/**
*
* @param origin
*/
public setOrigin(origin: Vector2): SpriteRenderer {
if (this._origin != origin) {
this._origin = origin;
this.displayObject.anchorOffsetX = this._origin.x;
this.displayObject.anchorOffsetY = this._origin.y;
this._areBoundsDirty = true;
}
return this;
}
/**
*
* x/y 0-1
* @param value
*/
public setOriginNormalized(value: Vector2): SpriteRenderer {
this.setOrigin(new Vector2(value.x * this.width / this.entity.transform.scale.x,
value.y * this.height / this.entity.transform.scale.y));
return this;
}
public render(camera: Camera) {
this.sync(camera);
if (this.displayObject.x != this.bounds.x - camera.bounds.x) this.displayObject.x = this.bounds.x - camera.bounds.x;
if (this.displayObject.y != this.bounds.y - camera.bounds.y) this.displayObject.y = this.bounds.y - camera.bounds.y;
}
}
}

View File

@@ -1,148 +1,148 @@
///<reference path="./SpriteRenderer.ts" />
module es {
import Bitmap = egret.Bitmap;
import RenderTexture = egret.RenderTexture;
/**
*
*/
export class TiledSpriteRenderer extends SpriteRenderer {
public get bounds(): Rectangle {
if (this._areBoundsDirty){
if (this._sprite){
this._bounds.calculateBounds(this.entity.transform.position, this._localOffset, this._origin,
this.entity.transform.scale, this.entity.transform.rotation, this.width, this.height);
this._areBoundsDirty = false;
}
}
return this._bounds;
}
/**
* x值
*/
public get scrollX() {
return this._sourceRect.x;
}
/**
* x值
* @param value
*/
public set scrollX(value: number) {
this._sourceRect.x = value;
}
/**
* y值
*/
public get scrollY() {
return this._sourceRect.y;
}
/**
* y值
* @param value
*/
public set scrollY(value: number) {
this._sourceRect.y = value;
}
/**
*
*/
public get textureScale(): Vector2 {
return this._textureScale;
}
/**
*
* @param value
*/
public set textureScale(value: Vector2) {
this._textureScale = value;
// 重新计算我们的inverseTextureScale和源矩形大小
this._inverseTexScale = new Vector2(1 / this._textureScale.x, 1 / this._textureScale.y);
this._sourceRect.width = Math.floor(this._sprite.sourceRect.width * this._inverseTexScale.x);
this._sourceRect.height = Math.floor(this._sprite.sourceRect.height * this._inverseTexScale.y);
}
/**
* TiledSprite可以有一个独立于其纹理的宽度
*/
public get width(): number{
return this._sourceRect.width;
}
public set width(value: number) {
this._areBoundsDirty = true;
this._sourceRect.width = value;
}
public get height(): number {
return this._sourceRect.height;
}
public set height(value: number) {
this._areBoundsDirty = true;
this._sourceRect.height = value;
}
public get gapXY(): Vector2{
return new Vector2(this._gapX, this._gapY);
}
public set gapXY(value: Vector2){
this._gapX = value.x;
this._gapY = value.y;
let renderTexture = new RenderTexture();
let newRectangle = this.sprite.sourceRect;
newRectangle.x = 0;
newRectangle.y = 0;
newRectangle.width += this._gapX;
newRectangle.height += this._gapY;
renderTexture.drawToTexture(this.displayObject, newRectangle);
if (!this.displayObject){
this.displayObject = new Bitmap(renderTexture);
}else{
(this.displayObject as Bitmap).texture = renderTexture;
}
}
protected _sourceRect: Rectangle;
protected _textureScale = Vector2.one;
protected _inverseTexScale = Vector2.one;
private _gapX = 0;
private _gapY = 0;
constructor(sprite: Sprite) {
super(sprite);
this._sourceRect = sprite.sourceRect;
let bitmap = this.displayObject as Bitmap;
bitmap.$fillMode = egret.BitmapFillMode.REPEAT;
}
/**
*
* @param value
*/
public setGapXY(value: Vector2): TiledSpriteRenderer {
this.gapXY = value;
return this;
}
public render(camera: es.Camera) {
super.render(camera);
let bitmap = this.displayObject as Bitmap;
bitmap.width = this.width;
bitmap.height = this.height;
bitmap.scrollRect = this._sourceRect;
}
}
}
///<reference path="./SpriteRenderer.ts" />
module es {
import Bitmap = egret.Bitmap;
import RenderTexture = egret.RenderTexture;
/**
*
*/
export class TiledSpriteRenderer extends SpriteRenderer {
public get bounds(): Rectangle {
if (this._areBoundsDirty){
if (this._sprite){
this._bounds.calculateBounds(this.entity.transform.position, this._localOffset, this._origin,
this.entity.transform.scale, this.entity.transform.rotation, this.width, this.height);
this._areBoundsDirty = false;
}
}
return this._bounds;
}
/**
* x值
*/
public get scrollX() {
return this._sourceRect.x;
}
/**
* x值
* @param value
*/
public set scrollX(value: number) {
this._sourceRect.x = value;
}
/**
* y值
*/
public get scrollY() {
return this._sourceRect.y;
}
/**
* y值
* @param value
*/
public set scrollY(value: number) {
this._sourceRect.y = value;
}
/**
*
*/
public get textureScale(): Vector2 {
return this._textureScale;
}
/**
*
* @param value
*/
public set textureScale(value: Vector2) {
this._textureScale = value;
// 重新计算我们的inverseTextureScale和源矩形大小
this._inverseTexScale = new Vector2(1 / this._textureScale.x, 1 / this._textureScale.y);
this._sourceRect.width = Math.floor(this._sprite.sourceRect.width * this._inverseTexScale.x);
this._sourceRect.height = Math.floor(this._sprite.sourceRect.height * this._inverseTexScale.y);
}
/**
* TiledSprite可以有一个独立于其纹理的宽度
*/
public get width(): number{
return this._sourceRect.width;
}
public set width(value: number) {
this._areBoundsDirty = true;
this._sourceRect.width = value;
}
public get height(): number {
return this._sourceRect.height;
}
public set height(value: number) {
this._areBoundsDirty = true;
this._sourceRect.height = value;
}
public get gapXY(): Vector2{
return new Vector2(this._gapX, this._gapY);
}
public set gapXY(value: Vector2){
this._gapX = value.x;
this._gapY = value.y;
let renderTexture = new RenderTexture();
let newRectangle = this.sprite.sourceRect;
newRectangle.x = 0;
newRectangle.y = 0;
newRectangle.width += this._gapX;
newRectangle.height += this._gapY;
renderTexture.drawToTexture(this.displayObject, newRectangle);
if (!this.displayObject){
this.displayObject = new Bitmap(renderTexture);
}else{
(this.displayObject as Bitmap).texture = renderTexture;
}
}
protected _sourceRect: Rectangle;
protected _textureScale = Vector2.one;
protected _inverseTexScale = Vector2.one;
private _gapX = 0;
private _gapY = 0;
constructor(sprite: Sprite) {
super(sprite);
this._sourceRect = sprite.sourceRect;
let bitmap = this.displayObject as Bitmap;
bitmap.$fillMode = egret.BitmapFillMode.REPEAT;
}
/**
*
* @param value
*/
public setGapXY(value: Vector2): TiledSpriteRenderer {
this.gapXY = value;
return this;
}
public render(camera: es.Camera) {
super.render(camera);
let bitmap = this.displayObject as Bitmap;
bitmap.width = this.width;
bitmap.height = this.height;
bitmap.scrollRect = this._sourceRect;
}
}
}

View File

@@ -133,7 +133,7 @@ module es {
* 返回null将使协程在下一帧中被执行。
* @param enumerator
*/
public static startCoroutine(enumerator: IEnumerator){
public static startCoroutine(enumerator: Iterator<any>){
return this._instance._coroutineManager.startCoroutine(enumerator);
}

View File

@@ -3,7 +3,7 @@ module es {
* CoroutineManager使用的内部类用于隐藏协同程序所需的数据
*/
export class CoroutineImpl implements ICoroutine, IPoolable {
public enumerator: IEnumerator;
public enumerator: Iterator<any>;
/**
* 每当产生延迟时它就被添加到跟踪延迟的waitTimer中
*/
@@ -34,12 +34,6 @@ module es {
}
}
export interface IEnumerator {
current: any;
moveNext(): boolean;
reset();
}
/**
* 基本CoroutineManager。协同程序可以做以下事情:
* - return null(在下一帧继续执行)
@@ -60,7 +54,7 @@ module es {
* 将i枚举器添加到CoroutineManager。协程在每一帧调用更新之前被执行。
* @param enumerator
*/
public startCoroutine(enumerator: IEnumerator) {
public startCoroutine(enumerator: Iterator<any>) {
// 查找或创建CoroutineImpl
let coroutine = Pool.obtain<CoroutineImpl>(CoroutineImpl);
coroutine.prepareForuse();
@@ -126,30 +120,30 @@ module es {
* @param coroutine
*/
public tickCoroutine(coroutine: CoroutineImpl){
let current = coroutine.enumerator.next();
// 这个协同程序已经完成了
if (!coroutine.enumerator.moveNext() || coroutine.isDone){
if (!current.value || current.done){
Pool.free<CoroutineImpl>(coroutine);
return false;
}
if (coroutine.enumerator.current == null){
// 再运行下一帧
if (!current.value){
return true;
}
if (coroutine.enumerator.current instanceof WaitForSeconds){
coroutine.waitTimer = (coroutine.enumerator.current as WaitForSeconds).waitTime;
if (current.value instanceof WaitForSeconds){
coroutine.waitTimer = (current.value as WaitForSeconds).waitTime;
return true;
}
if (coroutine.enumerator.current instanceof Number){
if (current.value instanceof Number){
console.warn("协同程序检查返回一个Number类型请不要在生产环境使用");
coroutine.waitTimer = Number(coroutine.enumerator.current);
coroutine.waitTimer = Number(current);
return true;
}
if (coroutine.enumerator.current instanceof CoroutineImpl){
coroutine.waitForCoroutine = coroutine.enumerator.current as CoroutineImpl;
if (current.value instanceof CoroutineImpl){
coroutine.waitForCoroutine = current.value as CoroutineImpl;
return true;
}else {
return true;