diff --git a/.gitignore b/.gitignore index 8e249491..11c72867 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ /source/node_modules /demo/bin-debug /demo/bin-release +/.idea +/.vscode +/demo_wxgame diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 7b7a8605..00000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - // 使用 IntelliSense 了解相关属性。 - // 悬停以查看现有属性的描述。 - // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "type": "pwa-chrome", - "request": "launch", - "name": "Launch Chrome against localhost", - "url": "http://localhost:8080", - "webRoot": "${workspaceFolder}" - } - ] -} \ No newline at end of file diff --git a/README.md b/README.md index 84a9434b..7ad9c452 100644 --- a/README.md +++ b/README.md @@ -3,26 +3,11 @@ [![Language grade: JavaScript](https://img.shields.io/lgtm/grade/javascript/g/esengine/egret-framework.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/esengine/egret-framework/context:javascript) -``` -[![Language grade: JavaScript](https://img.shields.io/lgtm/grade/javascript/g/esengine/egret-framework.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/esengine/egret-framework/context:javascript) -``` +这是一套用于egret的游戏框架,里面包含ECS框架用于管理场景实体,一些常用2D碰撞检测及A*寻路。如果您还需要包含其他的AI系统可以查看作者其他库(行为树、简易FSM、实用AI)。 -这是一套用于egret的游戏框架,里面包含ECS框架用于管理场景实体,MVC框架用于管理ui界面(fairygui),一些常用2D碰撞检测及A*寻路。如果您还需要包含其他的AI系统可以查看作者其他库(行为树、简易FSM、实用AI)。 - -## 当前版本功能 +## 版本计划功能 - [x] 简易ECS框架 -- [x] A*寻路(AStar) -- [x] 常用碰撞检测 -- [x] 数学库 - - [x] 简易矩阵类 - - [x] 简易2d 向量类 - - [x] 掩码实用类 -- [x] BreadthFirst 寻路算法 -- [x] Dijkstra 寻路算法 -- [x] 事件处理器 - -- [x] ECS - [x] 组件列表 - [x] 碰撞组件 - [x] 移动组件 @@ -38,9 +23,37 @@ - [x] 系统列表 - [x] 被动系统 - [x] 协调系统 -- [ ] 数学库 - - [ ] 贝塞尔曲线 - - [ ] 快速随机数类 +- [x] A*寻路(AStar) +- [x] 常用碰撞检测 +- [x] 数学库 + - [x] 简易矩阵类 + - [x] 简易2d 向量类 + - [x] 掩码实用类 + - [x] 贝塞尔曲线 + - [x] 快速随机数类 +- [x] BreadthFirst 寻路算法 +- [x] Dijkstra 寻路算法 +- [x] 事件处理器 + +## 关于egret用ecs框架(typescript/javascript) +ecs 是功能强大的实体组件系统。typescript与其他语言不同,因此我对ecs的设计尽可能的支持typescript特性。虽然ecs拥有标准实体组件系统,但在细节上有很大不同。创建标准ecs通常处于原始速度、缓存位置和其他性能原因。使用typescript,我们没有struct,因为没有必要匹配标准实体组件系统的设计方式,因为我们对内存布局没有那种控制。 + +ecs更灵活,可以更好的集中、组织、排序和过滤游戏中的对象。ecs让您拥有轻量级实体和组件,这些组件可以由系统批量处理。 +例如,您在制作一个射手,您可能会有几十到几百个子弹,这些作为轻量级实体由系统批量处理。 + +所以ecs在设计当中拥有四种重要类型:世界(Scene),过滤器(Matcher),系统(System)和实体(Entity) + +## 世界(Scene) +Scene是ecs包含系统和实体最外面的容器。 + +## 实体(Entity) +实体只由系统处理。 + +## 组件(Component) +组件应该只包含数据而没有逻辑代码。对数据进行逻辑是系统的工作。 + +## 系统(System) +ecs中的系统会不断的更新实体。系统使用过滤器选择某些实体,然后仅更新那些选择的实体。 ## 作者其他库(egret) diff --git a/_config.yml b/_config.yml new file mode 100644 index 00000000..c7418817 --- /dev/null +++ b/_config.yml @@ -0,0 +1 @@ +theme: jekyll-theme-slate \ No newline at end of file diff --git a/demo/.idea/.gitignore b/demo/.idea/.gitignore new file mode 100644 index 00000000..e7e9d11d --- /dev/null +++ b/demo/.idea/.gitignore @@ -0,0 +1,2 @@ +# Default ignored files +/workspace.xml diff --git a/demo/.idea/demo.iml b/demo/.idea/demo.iml new file mode 100644 index 00000000..c956989b --- /dev/null +++ b/demo/.idea/demo.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/demo/.idea/misc.xml b/demo/.idea/misc.xml new file mode 100644 index 00000000..28a804d8 --- /dev/null +++ b/demo/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/demo/.idea/modules.xml b/demo/.idea/modules.xml new file mode 100644 index 00000000..c95e899e --- /dev/null +++ b/demo/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/demo/.idea/vcs.xml b/demo/.idea/vcs.xml new file mode 100644 index 00000000..6c0b8635 --- /dev/null +++ b/demo/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/demo/libs/framework/framework.d.ts b/demo/libs/framework/framework.d.ts index a8d146ad..f8cf463e 100644 --- a/demo/libs/framework/framework.d.ts +++ b/demo/libs/framework/framework.d.ts @@ -1,1058 +1,1848 @@ declare interface Array { - findIndex(predicate: Function): number; - any(predicate: Function): boolean; - firstOrDefault(predicate: Function): T; - find(predicate: Function): T; - where(predicate: Function): Array; - count(predicate: Function): number; - findAll(predicate: Function): Array; - contains(value: any): boolean; - removeAll(predicate: Function): void; - remove(element: any): boolean; - removeAt(index: any): void; - removeRange(index: any, count: any): void; + findIndex(predicate: (c: T) => boolean): number; + any(predicate: (c: T) => boolean): boolean; + firstOrDefault(predicate: (c: T) => boolean): T; + find(predicate: (c: T) => boolean): T; + where(predicate: (c: T) => boolean): Array; + count(predicate: (c: T) => boolean): number; + findAll(predicate: (c: T) => boolean): Array; + contains(value: T): boolean; + removeAll(predicate: (c: T) => boolean): void; + remove(element: T): boolean; + removeAt(index: number): void; + removeRange(index: number, count: number): void; select(selector: Function): Array; orderBy(keySelector: Function, comparer: Function): Array; orderByDescending(keySelector: Function, comparer: Function): Array; groupBy(keySelector: Function): Array; - sum(selector: any): any; -} -declare class PriorityQueueNode { - priority: number; - insertionIndex: number; - queueIndex: number; -} -declare class AStarPathfinder { - static search(graph: IAstarGraph, start: T, goal: T): T[]; - private static hasKey; - private static getKey; - static recontructPath(cameFrom: Map, start: T, goal: T): T[]; -} -declare class AStarNode extends PriorityQueueNode { - data: T; - constructor(data: T); -} -declare class AstarGridGraph implements IAstarGraph { - dirs: Vector2[]; - walls: Vector2[]; - weightedNodes: Vector2[]; - defaultWeight: number; - weightedNodeWeight: number; - private _width; - private _height; - private _neighbors; - constructor(width: number, height: number); - isNodeInBounds(node: Vector2): boolean; - isNodePassable(node: Vector2): boolean; - search(start: Vector2, goal: Vector2): Vector2[]; - getNeighbors(node: Vector2): Vector2[]; - cost(from: Vector2, to: Vector2): number; - heuristic(node: Vector2, goal: Vector2): number; -} -interface IAstarGraph { - getNeighbors(node: T): Array; - cost(from: T, to: T): number; - heuristic(node: T, goal: T): any; -} -declare class PriorityQueue { - private _numNodes; - private _nodes; - private _numNodesEverEnqueued; - constructor(maxNodes: number); - clear(): void; - readonly count: number; - contains(node: T): boolean; - enqueue(node: T, priority: number): void; - dequeue(): T; - remove(node: T): void; - isValidQueue(): boolean; - private onNodeUpdated; - private cascadeDown; - private cascadeUp; - private swap; - private hasHigherPriority; -} -declare class BreadthFirstPathfinder { - static search(graph: IUnweightedGraph, start: T, goal: T): T[]; - private static hasKey; -} -interface IUnweightedGraph { - getNeighbors(node: T): T[]; -} -declare class UnweightedGraph implements IUnweightedGraph { - edges: Map; - addEdgesForNode(node: T, edges: T[]): this; - getNeighbors(node: T): T[]; -} -declare class Vector2 { - x: number; - y: number; - private static readonly unitYVector; - private static readonly unitXVector; - private static readonly unitVector2; - private static readonly zeroVector2; - static readonly zero: Vector2; - static readonly one: Vector2; - static readonly unitX: Vector2; - static readonly unitY: Vector2; - constructor(x?: number, y?: number); - static add(value1: Vector2, value2: Vector2): Vector2; - static divide(value1: Vector2, value2: Vector2): Vector2; - static multiply(value1: Vector2, value2: Vector2): Vector2; - static subtract(value1: Vector2, value2: Vector2): Vector2; - normalize(): void; - length(): number; - round(): Vector2; - static normalize(value: Vector2): Vector2; - static dot(value1: Vector2, value2: Vector2): number; - static distanceSquared(value1: Vector2, value2: Vector2): number; - static clamp(value1: Vector2, min: Vector2, max: Vector2): Vector2; - static lerp(value1: Vector2, value2: Vector2, amount: number): Vector2; - static transform(position: Vector2, matrix: Matrix2D): Vector2; - static distance(value1: Vector2, value2: Vector2): number; - static negate(value: Vector2): Vector2; -} -declare class UnweightedGridGraph implements IUnweightedGraph { - private static readonly CARDINAL_DIRS; - private static readonly COMPASS_DIRS; - walls: Vector2[]; - private _width; - private _hegiht; - private _dirs; - private _neighbors; - constructor(width: number, height: number, allowDiagonalSearch?: boolean); - isNodeInBounds(node: Vector2): boolean; - isNodePassable(node: Vector2): boolean; - getNeighbors(node: Vector2): Vector2[]; - search(start: Vector2, goal: Vector2): Vector2[]; -} -interface IWeightedGraph { - getNeighbors(node: T): T[]; - cost(from: T, to: T): number; -} -declare class WeightedGridGraph implements IWeightedGraph { - static readonly CARDINAL_DIRS: Vector2[]; - private static readonly COMPASS_DIRS; - walls: Vector2[]; - weightedNodes: Vector2[]; - defaultWeight: number; - weightedNodeWeight: number; - private _width; - private _height; - private _dirs; - private _neighbors; - constructor(width: number, height: number, allowDiagonalSearch?: boolean); - isNodeInBounds(node: Vector2): boolean; - isNodePassable(node: Vector2): boolean; - search(start: Vector2, goal: Vector2): Vector2[]; - getNeighbors(node: Vector2): Vector2[]; - cost(from: Vector2, to: Vector2): number; -} -declare class WeightedNode extends PriorityQueueNode { - data: T; - constructor(data: T); -} -declare class WeightedPathfinder { - static search(graph: IWeightedGraph, start: T, goal: T): T[]; - private static hasKey; - private static getKey; - static recontructPath(cameFrom: Map, start: T, goal: T): T[]; -} -declare class DebugDefaults { - static verletParticle: number; - static verletConstraintEdge: number; -} -declare abstract class Component extends egret.DisplayObjectContainer { - entity: Entity; - private _enabled; - updateInterval: number; - userData: any; - enabled: boolean; - setEnabled(isEnabled: boolean): this; - initialize(): void; - onAddedToEntity(): void; - onRemovedFromEntity(): void; - onEnabled(): void; - onDisabled(): void; - update(): void; - debugRender(): void; - onEntityTransformChanged(comp: TransformComponent): void; - registerComponent(): void; - deregisterComponent(): void; -} -declare class Entity extends egret.DisplayObjectContainer { - private static _idGenerator; - name: string; - readonly id: number; - scene: Scene; - readonly components: ComponentList; - private _updateOrder; - private _enabled; - _isDestoryed: boolean; - private _tag; - componentBits: BitSet; - readonly isDestoryed: boolean; - position: Vector2; - scale: Vector2; - rotation: number; - enabled: boolean; - setEnabled(isEnabled: boolean): this; - tag: number; - readonly stage: egret.Stage; - constructor(name: string); - updateOrder: number; - roundPosition(): void; - setUpdateOrder(updateOrder: number): this; - setTag(tag: number): Entity; - attachToScene(newScene: Scene): void; - detachFromScene(): void; - addComponent(component: T): T; - hasComponent(type: any): boolean; - getOrCreateComponent(type: T): T; - getComponent(type: any): T; - getComponents(typeName: string | any, componentList?: any): any; - private onEntityTransformChanged; - removeComponentForType(type: any): boolean; - removeComponent(component: Component): void; - removeAllComponents(): void; - update(): void; - onAddedToScene(): void; - onRemovedFromScene(): void; - destroy(): void; -} -declare enum TransformComponent { - rotation = 0, - scale = 1, - position = 2 -} -declare class Scene extends egret.DisplayObjectContainer { - camera: Camera; - readonly entities: EntityList; - readonly renderableComponents: RenderableComponentList; - readonly content: ContentManager; - enablePostProcessing: boolean; - private _renderers; - private _postProcessors; - private _didSceneBegin; - readonly entityProcessors: EntityProcessorList; - constructor(); - createEntity(name: string): Entity; - addEntity(entity: Entity): Entity; - destroyAllEntities(): void; - findEntity(name: string): Entity; - addEntityProcessor(processor: EntitySystem): EntitySystem; - removeEntityProcessor(processor: EntitySystem): void; - getEntityProcessor(): T; - addRenderer(renderer: T): T; - getRenderer(type: any): T; - removeRenderer(renderer: Renderer): void; - begin(): void; - end(): void; - protected onStart(): Promise; - protected onActive(): void; - protected onDeactive(): void; - protected unload(): void; - update(): void; - postRender(): void; - render(): void; - addPostProcessor(postProcessor: T): T; -} -declare class SceneManager { - private static _scene; - private static _nextScene; - static sceneTransition: SceneTransition; - static stage: egret.Stage; - constructor(stage: egret.Stage); - static scene: Scene; - static initialize(stage: egret.Stage): void; - static update(): void; - static render(): void; - static startSceneTransition(sceneTransition: T): T; -} -declare class Camera extends Component { - private _zoom; - private _origin; - private _minimumZoom; - private _maximumZoom; - private _position; - followLerp: number; - deadzone: Rectangle; - focusOffset: Vector2; - mapLockEnabled: boolean; - mapSize: Vector2; - targetEntity: Entity; - private _worldSpaceDeadZone; - private _desiredPositionDelta; - private _targetCollider; - cameraStyle: CameraStyle; - zoom: number; - minimumZoom: number; - maximumZoom: number; - origin: Vector2; - position: Vector2; - x: number; - y: number; - constructor(); - onSceneSizeChanged(newWidth: number, newHeight: number): void; - setMinimumZoom(minZoom: number): Camera; - setMaximumZoom(maxZoom: number): Camera; - setZoom(zoom: number): Camera; - setRotation(rotation: number): Camera; - setPosition(position: Vector2): this; - follow(targetEntity: Entity, cameraStyle?: CameraStyle): void; - update(): void; - private clampToMapSize; - private updateFollow; -} -declare enum CameraStyle { - lockOn = 0, - cameraWindow = 1 -} -declare class ComponentPool { - private _cache; - private _type; - constructor(typeClass: any); - obtain(): T; - free(component: T): void; -} -declare abstract class PooledComponent extends Component { - abstract reset(): any; -} -declare abstract class RenderableComponent extends PooledComponent implements IRenderable { - private _isVisible; - protected _areBoundsDirty: boolean; - protected _bounds: Rectangle; - protected _localOffset: Vector2; - color: number; - readonly width: number; - readonly height: number; - isVisible: boolean; - readonly bounds: Rectangle; - protected getWidth(): number; - protected getHeight(): number; - protected onBecameVisible(): void; - protected onBecameInvisible(): void; - abstract render(camera: Camera): any; - isVisibleFromCamera(camera: Camera): boolean; -} -declare class Mesh extends RenderableComponent { - private _mesh; - constructor(); - setTexture(texture: egret.Texture): Mesh; - onAddedToEntity(): void; - onRemovedFromEntity(): void; - render(camera: Camera): void; - reset(): void; -} -declare class SpriteRenderer extends RenderableComponent { - private _sprite; - protected bitmap: egret.Bitmap; - sprite: Sprite; - setSprite(sprite: Sprite): SpriteRenderer; - setColor(color: number): SpriteRenderer; - isVisibleFromCamera(camera: Camera): boolean; - render(camera: Camera): void; - onRemovedFromEntity(): void; - reset(): void; -} -declare class TiledSpriteRenderer extends SpriteRenderer { - protected sourceRect: Rectangle; - protected leftTexture: egret.Bitmap; - protected rightTexture: egret.Bitmap; - scrollX: number; - scrollY: number; - constructor(sprite: Sprite); - render(camera: Camera): void; -} -declare class ScrollingSpriteRenderer extends TiledSpriteRenderer { - scrollSpeedX: number; - scroolSpeedY: number; - private _scrollX; - private _scrollY; - update(): void; -} -declare class Sprite { - texture2D: egret.Texture; - readonly sourceRect: Rectangle; - readonly center: Vector2; - origin: Vector2; - readonly uvs: Rectangle; - constructor(texture: egret.Texture, sourceRect?: Rectangle, origin?: Vector2); -} -declare class SpriteAnimation { - readonly sprites: Sprite[]; - readonly frameRate: number; - constructor(sprites: Sprite[], frameRate: number); -} -declare class SpriteAnimator extends SpriteRenderer { - onAnimationCompletedEvent: Function; - speed: number; - animationState: State; - currentAnimation: SpriteAnimation; - currentAnimationName: string; - currentFrame: number; - readonly isRunning: boolean; - private _animations; - private _elapsedTime; - private _loopMode; - constructor(sprite?: Sprite); - addAnimation(name: string, animation: SpriteAnimation): SpriteAnimator; - play(name: string, loopMode?: LoopMode): void; - isAnimationActive(name: string): boolean; - pause(): void; - unPause(): void; - stop(): void; - update(): void; -} -declare enum LoopMode { - loop = 0, - once = 1, - clampForever = 2, - pingPong = 3, - pingPongOnce = 4 -} -declare enum State { - none = 0, - running = 1, - paused = 2, - completed = 3 -} -interface ITriggerListener { - onTriggerEnter(other: Collider, local: Collider): any; - onTriggerExit(other: Collider, local: Collider): any; -} -declare class Mover extends Component { - private _triggerHelper; - onAddedToEntity(): void; - calculateMovement(motion: Vector2): { - collisionResult: CollisionResult; - motion: Vector2; - }; - applyMovement(motion: Vector2): void; - move(motion: Vector2): CollisionResult; -} -declare abstract class Collider extends Component { - shape: Shape; - physicsLayer: number; - isTrigger: boolean; - registeredPhysicsBounds: Rectangle; - shouldColliderScaleAndRotateWithTransform: boolean; - collidesWithLayers: number; - _localOffsetLength: number; - protected _isParentEntityAddedToScene: any; - protected _colliderRequiresAutoSizing: any; - protected _localOffset: Vector2; - protected _isColliderRegistered: any; - readonly bounds: Rectangle; - localOffset: Vector2; - setLocalOffset(offset: Vector2): void; - registerColliderWithPhysicsSystem(): void; - unregisterColliderWithPhysicsSystem(): void; - overlaps(other: Collider): any; - collidesWith(collider: Collider, motion: Vector2): CollisionResult; - onAddedToEntity(): void; - onRemovedFromEntity(): void; - onEnabled(): void; - onDisabled(): void; - onEntityTransformChanged(comp: TransformComponent): void; -} -declare class BoxCollider extends Collider { - width: number; - setWidth(width: number): BoxCollider; - height: number; - setHeight(height: number): void; - constructor(); - setSize(width: number, height: number): this; -} -declare class EntitySystem { - private _scene; - private _entities; - private _matcher; - readonly matcher: Matcher; - scene: Scene; - constructor(matcher?: Matcher); - initialize(): void; - onChanged(entity: Entity): void; - add(entity: Entity): void; - onAdded(entity: Entity): void; - remove(entity: Entity): void; - onRemoved(entity: Entity): void; - update(): void; - lateUpdate(): void; - protected begin(): void; - protected process(entities: Entity[]): void; - protected lateProcess(entities: Entity[]): void; - protected end(): void; -} -declare abstract class EntityProcessingSystem extends EntitySystem { - constructor(matcher: Matcher); - abstract processEntity(entity: Entity): any; - lateProcessEntity(entity: Entity): void; - protected process(entities: Entity[]): void; - protected lateProcess(entities: Entity[]): void; -} -declare abstract class PassiveSystem extends EntitySystem { - onChanged(entity: Entity): void; - protected process(entities: Entity[]): void; -} -declare abstract class ProcessingSystem extends EntitySystem { - onChanged(entity: Entity): void; - protected process(entities: Entity[]): void; - abstract processSystem(): any; -} -declare class BitSet { - private static LONG_MASK; - private _bits; - constructor(nbits?: number); - and(bs: BitSet): void; - andNot(bs: BitSet): void; - cardinality(): number; - clear(pos?: number): void; - private ensure; - get(pos: number): boolean; - intersects(set: BitSet): boolean; - isEmpty(): boolean; - nextSetBit(from: number): number; - set(pos: number, value?: boolean): void; -} -declare class ComponentList { - private _entity; - private _components; - private _componentsToAdd; - private _componentsToRemove; - private _tempBufferList; - constructor(entity: Entity); - readonly count: number; - readonly buffer: Component[]; - add(component: Component): void; - remove(component: Component): void; - removeAllComponents(): void; - deregisterAllComponents(): void; - registerAllComponents(): void; - updateLists(): void; - onEntityTransformChanged(comp: TransformComponent): void; - private handleRemove; - getComponent(type: any, onlyReturnInitializedComponents: boolean): T; - getComponents(typeName: string | any, components?: any): any; - update(): void; -} -declare class ComponentTypeManager { - private static _componentTypesMask; - static add(type: any): void; - static getIndexFor(type: any): number; -} -declare class EntityList { - scene: Scene; - private _entitiesToRemove; - private _entitiesToAdded; - private _tempEntityList; - private _entities; - private _entityDict; - private _unsortedTags; - constructor(scene: Scene); - readonly count: number; - readonly buffer: Entity[]; - add(entity: Entity): void; - remove(entity: Entity): void; - findEntity(name: string): Entity; - getTagList(tag: number): Entity[]; - addToTagList(entity: Entity): void; - removeFromTagList(entity: Entity): void; - update(): void; - removeAllEntities(): void; - updateLists(): void; -} -declare class EntityProcessorList { - private _processors; - add(processor: EntitySystem): void; - remove(processor: EntitySystem): void; - onComponentAdded(entity: Entity): void; - onComponentRemoved(entity: Entity): void; - onEntityAdded(entity: Entity): void; - onEntityRemoved(entity: Entity): void; - protected notifyEntityChanged(entity: Entity): void; - protected removeFromProcessors(entity: Entity): void; - begin(): void; - update(): void; - lateUpdate(): void; - end(): void; - getProcessor(): T; -} -declare class Matcher { - protected allSet: BitSet; - protected exclusionSet: BitSet; - protected oneSet: BitSet; - static empty(): Matcher; - getAllSet(): BitSet; - getExclusionSet(): BitSet; - getOneSet(): BitSet; - IsIntersted(e: Entity): boolean; - all(...types: any[]): Matcher; - exclude(...types: any[]): this; - one(...types: any[]): this; -} -declare class RenderableComponentList { - private _components; - readonly count: number; - readonly buffer: IRenderable[]; - add(component: IRenderable): void; - remove(component: IRenderable): void; - updateList(): void; -} -declare class Time { - static unscaledDeltaTime: any; - static deltaTime: number; - static timeScale: number; - static frameCount: number; - private static _lastTime; - static update(currentTime: number): void; -} -declare class GraphicsCapabilities { - supportsTextureFilterAnisotropic: boolean; - supportsNonPowerOfTwo: boolean; - supportsDepth24: boolean; - supportsPackedDepthStencil: boolean; - supportsDepthNonLinear: boolean; - supportsTextureMaxLevel: boolean; - supportsS3tc: boolean; - supportsDxt1: boolean; - supportsPvrtc: boolean; - supportsAtitc: boolean; - supportsFramebufferObjectARB: boolean; - initialize(device: GraphicsDevice): void; - private platformInitialize; -} -declare class GraphicsDevice { - private viewport; - graphicsCapabilities: GraphicsCapabilities; - constructor(); -} -declare class Viewport { - private _x; - private _y; - private _width; - private _height; - private _minDepth; - private _maxDepth; - readonly aspectRatio: number; - bounds: Rectangle; - constructor(x: number, y: number, width: number, height: number); -} -declare class GaussianBlurEffect extends egret.CustomFilter { - private static blur_frag; - constructor(); -} -declare class PolygonLightEffect extends egret.CustomFilter { - private static vertSrc; - private static fragmentSrc; - constructor(); -} -declare class PostProcessor { - enable: boolean; - effect: egret.Filter; - scene: Scene; - shape: egret.Shape; - static default_vert: string; - constructor(effect?: egret.Filter); - onAddedToScene(scene: Scene): void; - process(): void; - onSceneBackBufferSizeChanged(newWidth: number, newHeight: number): void; - protected drawFullscreenQuad(): void; - unload(): void; -} -declare class GaussianBlurPostProcessor extends PostProcessor { - onAddedToScene(scene: Scene): void; -} -declare abstract class Renderer { - camera: Camera; - onAddedToScene(scene: Scene): void; - protected beginRender(cam: Camera): void; - abstract render(scene: Scene): any; - unload(): void; - protected renderAfterStateCheck(renderable: IRenderable, cam: Camera): void; -} -declare class DefaultRenderer extends Renderer { - render(scene: Scene): void; -} -interface IRenderable { - bounds: Rectangle; - enabled: boolean; - isVisible: boolean; - isVisibleFromCamera(camera: Camera): any; - render(camera: Camera): any; -} -declare class ScreenSpaceRenderer extends Renderer { - render(scene: Scene): void; -} -declare class PolyLight extends RenderableComponent { - power: number; - protected _radius: number; - private _lightEffect; - private _indices; - radius: number; - constructor(radius: number, color: number, power: number); - private computeTriangleIndices; - setRadius(radius: number): void; - render(camera: Camera): void; - reset(): void; -} -declare abstract class SceneTransition { - private _hasPreviousSceneRender; - loadsNewScene: boolean; - isNewSceneLoaded: boolean; - protected sceneLoadAction: Function; - onScreenObscured: Function; - onTransitionCompleted: Function; - readonly hasPreviousSceneRender: boolean; - constructor(sceneLoadAction: Function); - preRender(): void; - render(): void; - onBeginTransition(): Promise; - protected transitionComplete(): void; - protected loadNextScene(): Promise; - tickEffectProgressProperty(filter: egret.CustomFilter, duration: number, easeType: Function, reverseDirection?: boolean): Promise<{}>; -} -declare class FadeTransition extends SceneTransition { - fadeToColor: number; - fadeOutDuration: number; - fadeEaseType: Function; - delayBeforeFadeInDuration: number; - private _mask; - private _alpha; - constructor(sceneLoadAction: Function); - onBeginTransition(): Promise; - render(): void; -} -declare class WindTransition extends SceneTransition { - private _mask; - private _windEffect; - duration: number; - windSegments: number; - size: number; - easeType: (t: number) => number; - constructor(sceneLoadAction: Function); - onBeginTransition(): Promise; -} -declare class Flags { - static isFlagSet(self: number, flag: number): boolean; - static isUnshiftedFlagSet(self: number, flag: number): boolean; - static setFlagExclusive(self: number, flag: number): number; - static setFlag(self: number, flag: number): number; - static unsetFlag(self: number, flag: number): number; - static invertFlags(self: number): number; -} -declare class MathHelper { - static readonly Epsilon: number; - static readonly Rad2Deg: number; - static readonly Deg2Rad: number; - static toDegrees(radians: number): number; - static toRadians(degrees: number): number; - static map(value: number, leftMin: number, leftMax: number, rightMin: number, rightMax: number): number; - static lerp(value1: number, value2: number, amount: number): number; - static clamp(value: number, min: number, max: number): number; - static pointOnCirlce(circleCenter: Vector2, radius: number, angleInDegrees: number): Vector2; - static isEven(value: number): boolean; -} -declare class Matrix2D { - m11: number; - m12: number; - m21: number; - m22: number; - m31: number; - m32: number; - private static _identity; - static readonly identity: Matrix2D; - constructor(m11?: number, m12?: number, m21?: number, m22?: number, m31?: number, m32?: number); - translation: Vector2; - rotation: number; - rotationDegrees: number; - scale: Vector2; - static add(matrix1: Matrix2D, matrix2: Matrix2D): Matrix2D; - static divide(matrix1: Matrix2D, matrix2: Matrix2D): Matrix2D; - static multiply(matrix1: Matrix2D, matrix2: Matrix2D): Matrix2D; - static multiplyTranslation(matrix: Matrix2D, x: number, y: number): Matrix2D; - determinant(): number; - static invert(matrix: Matrix2D, result?: Matrix2D): Matrix2D; - static createTranslation(xPosition: number, yPosition: number): Matrix2D; - static createTranslationVector(position: Vector2): Matrix2D; - static createRotation(radians: number, result?: Matrix2D): Matrix2D; - static createScale(xScale: number, yScale: number, result?: Matrix2D): Matrix2D; - toEgretMatrix(): egret.Matrix; -} -declare class Rectangle extends egret.Rectangle { - readonly max: Vector2; - readonly center: Vector2; - location: Vector2; - size: Vector2; - intersects(value: egret.Rectangle): boolean; - containsInVec(value: Vector2): boolean; - containsRect(value: Rectangle): boolean; - getHalfSize(): Vector2; - static fromMinMax(minX: number, minY: number, maxX: number, maxY: number): Rectangle; - getClosestPointOnRectangleBorderToPoint(point: Vector2): { - res: Vector2; - edgeNormal: Vector2; - }; - getClosestPointOnBoundsToOrigin(): Vector2; - static rectEncompassingPoints(points: Vector2[]): Rectangle; -} -declare class Vector3 { - x: number; - y: number; - z: number; - constructor(x: number, y: number, z: number); -} -declare class ColliderTriggerHelper { - private _entity; - private _activeTriggerIntersections; - private _previousTriggerIntersections; - private _tempTriggerList; - constructor(entity: Entity); - update(): void; - private checkForExitedColliders; - private notifyTriggerListeners; -} -declare enum PointSectors { - center = 0, - top = 1, - bottom = 2, - topLeft = 9, - topRight = 5, - left = 8, - right = 4, - bottomLeft = 10, - bottomRight = 6 -} -declare class Collisions { - static isLineToLine(a1: Vector2, a2: Vector2, b1: Vector2, b2: Vector2): boolean; - static lineToLineIntersection(a1: Vector2, a2: Vector2, b1: Vector2, b2: Vector2): Vector2; - static closestPointOnLine(lineA: Vector2, lineB: Vector2, closestTo: Vector2): Vector2; - static isCircleToCircle(circleCenter1: Vector2, circleRadius1: number, circleCenter2: Vector2, circleRadius2: number): boolean; - static isCircleToLine(circleCenter: Vector2, radius: number, lineFrom: Vector2, lineTo: Vector2): boolean; - static isCircleToPoint(circleCenter: Vector2, radius: number, point: Vector2): boolean; - static isRectToCircle(rect: Rectangle, cPosition: Vector2, cRadius: number): boolean; - static isRectToLine(rect: Rectangle, lineFrom: Vector2, lineTo: Vector2): boolean; - static isRectToPoint(rX: number, rY: number, rW: number, rH: number, point: Vector2): boolean; - static getSector(rX: number, rY: number, rW: number, rH: number, point: Vector2): PointSectors; -} -declare class Physics { - private static _spatialHash; - static spatialHashCellSize: number; - static readonly allLayers: number; - static reset(): void; - static clear(): void; - static overlapCircleAll(center: Vector2, randius: number, results: any[], layerMask?: number): number; - static boxcastBroadphase(rect: Rectangle, layerMask?: number): { - colliders: Collider[]; - rect: Rectangle; - }; - static boxcastBroadphaseExcludingSelf(collider: Collider, rect: Rectangle, layerMask?: number): { - tempHashSet: Collider[]; + sum(selector: Function): number; +} +declare module es { + class PriorityQueueNode { + priority: number; + insertionIndex: number; + queueIndex: number; + } +} +declare module es { + class AStarPathfinder { + static search(graph: IAstarGraph, start: T, goal: T): T[]; + static recontructPath(cameFrom: Map, start: T, goal: T): T[]; + private static hasKey; + private static getKey; + } + class AStarNode extends PriorityQueueNode { + data: T; + constructor(data: T); + } +} +declare module es { + class AstarGridGraph implements IAstarGraph { + dirs: Vector2[]; + walls: Vector2[]; + weightedNodes: Vector2[]; + defaultWeight: number; + weightedNodeWeight: number; + private _width; + private _height; + private _neighbors; + constructor(width: number, height: number); + isNodeInBounds(node: Vector2): boolean; + isNodePassable(node: Vector2): boolean; + search(start: Vector2, goal: Vector2): Vector2[]; + getNeighbors(node: Vector2): Vector2[]; + cost(from: Vector2, to: Vector2): number; + heuristic(node: Vector2, goal: Vector2): number; + } +} +declare module es { + interface IAstarGraph { + getNeighbors(node: T): Array; + cost(from: T, to: T): number; + heuristic(node: T, goal: T): any; + } +} +declare module es { + class PriorityQueue { + private _numNodes; + private _nodes; + private _numNodesEverEnqueued; + constructor(maxNodes: number); + readonly count: number; + readonly maxSize: number; + clear(): void; + contains(node: T): boolean; + enqueue(node: T, priority: number): void; + dequeue(): T; + remove(node: T): void; + isValidQueue(): boolean; + private onNodeUpdated; + private cascadeDown; + private cascadeUp; + private swap; + private hasHigherPriority; + } +} +declare module es { + class BreadthFirstPathfinder { + static search(graph: IUnweightedGraph, start: T, goal: T): T[]; + private static hasKey; + } +} +declare module es { + interface IUnweightedGraph { + getNeighbors(node: T): T[]; + } +} +declare module es { + class UnweightedGraph implements IUnweightedGraph { + edges: Map; + addEdgesForNode(node: T, edges: T[]): this; + getNeighbors(node: T): T[]; + } +} +declare module es { + class Vector2 { + private static readonly unitYVector; + private static readonly unitXVector; + private static readonly unitVector2; + private static readonly zeroVector2; + x: number; + y: number; + constructor(x?: number, y?: number); + static readonly zero: Vector2; + static readonly one: Vector2; + static readonly unitX: Vector2; + static readonly unitY: Vector2; + static add(value1: Vector2, value2: Vector2): Vector2; + static divide(value1: Vector2, value2: Vector2): Vector2; + static multiply(value1: Vector2, value2: Vector2): Vector2; + static subtract(value1: Vector2, value2: Vector2): Vector2; + static normalize(value: Vector2): Vector2; + static dot(value1: Vector2, value2: Vector2): number; + static distanceSquared(value1: Vector2, value2: Vector2): number; + static clamp(value1: Vector2, min: Vector2, max: Vector2): Vector2; + static lerp(value1: Vector2, value2: Vector2, amount: number): Vector2; + static transform(position: Vector2, matrix: Matrix2D): Vector2; + static distance(value1: Vector2, value2: Vector2): number; + static negate(value: Vector2): Vector2; + add(value: Vector2): Vector2; + divide(value: Vector2): Vector2; + multiply(value: Vector2): Vector2; + subtract(value: Vector2): this; + normalize(): this; + length(): number; + lengthSquared(): number; + round(): Vector2; + equals(other: Vector2): boolean; + } +} +declare module es { + class UnweightedGridGraph implements IUnweightedGraph { + private static readonly CARDINAL_DIRS; + private static readonly COMPASS_DIRS; + walls: Vector2[]; + private _width; + private _hegiht; + private _dirs; + private _neighbors; + constructor(width: number, height: number, allowDiagonalSearch?: boolean); + isNodeInBounds(node: Vector2): boolean; + isNodePassable(node: Vector2): boolean; + getNeighbors(node: Vector2): Vector2[]; + search(start: Vector2, goal: Vector2): Vector2[]; + } +} +declare module es { + interface IWeightedGraph { + getNeighbors(node: T): T[]; + cost(from: T, to: T): number; + } +} +declare module es { + class WeightedGridGraph implements IWeightedGraph { + static readonly CARDINAL_DIRS: Vector2[]; + private static readonly COMPASS_DIRS; + walls: Vector2[]; + weightedNodes: Vector2[]; + defaultWeight: number; + weightedNodeWeight: number; + private _width; + private _height; + private _dirs; + private _neighbors; + constructor(width: number, height: number, allowDiagonalSearch?: boolean); + isNodeInBounds(node: Vector2): boolean; + isNodePassable(node: Vector2): boolean; + search(start: Vector2, goal: Vector2): Vector2[]; + getNeighbors(node: Vector2): Vector2[]; + cost(from: Vector2, to: Vector2): number; + } +} +declare module es { + class WeightedNode extends PriorityQueueNode { + data: T; + constructor(data: T); + } + class WeightedPathfinder { + static search(graph: IWeightedGraph, start: T, goal: T): T[]; + static recontructPath(cameFrom: Map, start: T, goal: T): T[]; + private static hasKey; + private static getKey; + } +} +declare module es { + class Debug { + private static _debugDrawItems; + static drawHollowRect(rectanle: Rectangle, color: number, duration?: number): void; + static render(): void; + } +} +declare module es { + class DebugDefaults { + static verletParticle: number; + static verletConstraintEdge: number; + } +} +declare module es { + enum DebugDrawType { + line = 0, + hollowRectangle = 1, + pixel = 2, + text = 3 + } + class DebugDrawItem { + rectangle: Rectangle; + color: number; + duration: number; + drawType: DebugDrawType; + text: string; + start: Vector2; + end: Vector2; + x: number; + y: number; + size: number; + constructor(rectangle: Rectangle, color: number, duration: number); + draw(shape: egret.Shape): boolean; + } +} +declare module es { + abstract class Component extends egret.HashObject { + entity: Entity; + updateInterval: number; + readonly transform: Transform; + private _enabled; + enabled: boolean; + private _updateOrder; + updateOrder: number; + initialize(): void; + onAddedToEntity(): void; + onRemovedFromEntity(): void; + onEntityTransformChanged(comp: transform.Component): void; + debugRender(): void; + onEnabled(): void; + onDisabled(): void; + update(): void; + setEnabled(isEnabled: boolean): this; + setUpdateOrder(updateOrder: number): this; + clone(): Component; + } +} +declare module es { + class Core extends egret.DisplayObjectContainer { + static emitter: Emitter; + static graphicsDevice: GraphicsDevice; + static content: ContentManager; + static _instance: Core; + _nextScene: Scene; + _sceneTransition: SceneTransition; + _globalManagers: GlobalManager[]; + constructor(); + static readonly Instance: Core; + _scene: Scene; + static scene: Scene; + static startSceneTransition(sceneTransition: T): T; + static registerGlobalManager(manager: es.GlobalManager): void; + static unregisterGlobalManager(manager: es.GlobalManager): void; + static getGlobalManager(type: any): T; + onOrientationChanged(): void; + draw(): Promise; + startDebugUpdate(): void; + endDebugUpdate(): void; + onSceneChanged(): void; + protected onGraphicsDeviceReset(): void; + protected initialize(): void; + protected update(): Promise; + private onAddToStage; + } +} +declare module es { + enum CoreEvents { + GraphicsDeviceReset = 0, + SceneChanged = 1, + OrientationChanged = 2 + } +} +declare module es { + class Entity { + static _idGenerator: number; + scene: Scene; + name: string; + readonly id: number; + readonly transform: Transform; + readonly components: ComponentList; + updateInterval: number; + componentBits: BitSet; + constructor(name: string); + _isDestroyed: boolean; + readonly isDestroyed: boolean; + private _tag; + tag: number; + private _enabled; + enabled: boolean; + private _updateOrder; + updateOrder: number; + parent: Transform; + readonly childCount: number; + position: Vector2; + localPosition: Vector2; + rotation: number; + rotationDegrees: number; + localRotation: number; + localRotationDegrees: number; + scale: Vector2; + localScale: Vector2; + readonly worldInverseTransform: Matrix2D; + readonly localToWorldTransform: Matrix2D; + readonly worldToLocalTransform: Matrix2D; + onTransformChanged(comp: transform.Component): void; + setTag(tag: number): Entity; + setEnabled(isEnabled: boolean): this; + setUpdateOrder(updateOrder: number): this; + destroy(): void; + detachFromScene(): void; + attachToScene(newScene: Scene): void; + clone(position?: Vector2): Entity; + onAddedToScene(): void; + onRemovedFromScene(): void; + update(): void; + addComponent(component: T): T; + getComponent(type: any): T; + hasComponent(type: any): boolean; + getOrCreateComponent(type: T): T; + getComponents(typeName: string | any, componentList?: any): any; + removeComponent(component: Component): void; + removeComponentForType(type: any): boolean; + removeAllComponents(): void; + compareTo(other: Entity): number; + toString(): string; + protected copyFrom(entity: Entity): void; + } +} +declare module es { + class Scene extends egret.DisplayObjectContainer { + camera: Camera; + readonly content: ContentManager; + enablePostProcessing: boolean; + readonly entities: EntityList; + readonly renderableComponents: RenderableComponentList; + readonly entityProcessors: EntityProcessorList; + _renderers: Renderer[]; + readonly _postProcessors: PostProcessor[]; + _didSceneBegin: any; + constructor(); + static createWithDefaultRenderer(): Scene; + initialize(): void; + onStart(): Promise; + unload(): void; + onActive(): void; + onDeactive(): void; + begin(): Promise; + end(): void; + update(): void; + render(): void; + postRender(): void; + addRenderer(renderer: T): T; + getRenderer(type: any): T; + removeRenderer(renderer: Renderer): void; + addPostProcessor(postProcessor: T): T; + getPostProcessor(type: any): T; + removePostProcessor(postProcessor: PostProcessor): void; + createEntity(name: string): Entity; + addEntity(entity: Entity): Entity; + destroyAllEntities(): void; + findEntity(name: string): Entity; + findEntitiesWithTag(tag: number): Entity[]; + entitiesOfType(type: any): T[]; + findComponentOfType(type: any): T; + findComponentsOfType(type: any): T[]; + addEntityProcessor(processor: EntitySystem): EntitySystem; + removeEntityProcessor(processor: EntitySystem): void; + getEntityProcessor(): T; + } +} +declare module transform { + enum Component { + position = 0, + scale = 1, + rotation = 2 + } +} +declare module es { + import HashObject = egret.HashObject; + enum DirtyType { + clean = 0, + positionDirty = 1, + scaleDirty = 2, + rotationDirty = 3 + } + class Transform extends HashObject { + readonly entity: Entity; + hierarchyDirty: DirtyType; + _localDirty: boolean; + _localPositionDirty: boolean; + _localScaleDirty: boolean; + _localRotationDirty: boolean; + _positionDirty: boolean; + _worldToLocalDirty: boolean; + _worldInverseDirty: boolean; + _localTransform: Matrix2D; + _worldTransform: Matrix2D; + _rotationMatrix: Matrix2D; + _translationMatrix: Matrix2D; + _scaleMatrix: Matrix2D; + _children: Transform[]; + constructor(entity: Entity); + readonly childCount: number; + rotationDegrees: number; + localRotationDegrees: number; + readonly localToWorldTransform: Matrix2D; + _parent: Transform; + parent: Transform; + _worldToLocalTransform: Matrix2D; + readonly worldToLocalTransform: Matrix2D; + _worldInverseTransform: Matrix2D; + readonly worldInverseTransform: Matrix2D; + _position: Vector2; + position: Vector2; + _scale: Vector2; + scale: Vector2; + _rotation: number; + rotation: number; + _localPosition: Vector2; + localPosition: Vector2; + _localScale: Vector2; + localScale: Vector2; + _localRotation: number; + localRotation: number; + getChild(index: number): Transform; + setParent(parent: Transform): Transform; + setPosition(x: number, y: number): Transform; + setLocalPosition(localPosition: Vector2): Transform; + setRotation(radians: number): Transform; + setRotationDegrees(degrees: number): Transform; + lookAt(pos: Vector2): void; + setLocalRotation(radians: number): this; + setLocalRotationDegrees(degrees: number): Transform; + setScale(scale: Vector2): Transform; + setLocalScale(scale: Vector2): Transform; + roundPosition(): void; + updateTransform(): void; + setDirty(dirtyFlagType: DirtyType): void; + copyFrom(transform: Transform): void; + toString(): string; + equals(other: Transform): boolean; + } +} +declare module es { + enum CameraStyle { + lockOn = 0, + cameraWindow = 1 + } + class CameraInset { + left: number; + right: number; + top: number; + bottom: number; + } + class Camera extends Component { + _inset: CameraInset; + _areMatrixedDirty: boolean; + _areBoundsDirty: boolean; + _isProjectionMatrixDirty: boolean; + followLerp: number; + deadzone: Rectangle; + focusOffset: Vector2; + mapLockEnabled: boolean; + mapSize: Vector2; + _targetEntity: Entity; + _targetCollider: Collider; + _desiredPositionDelta: Vector2; + _cameraStyle: CameraStyle; + _worldSpaceDeadZone: Rectangle; + constructor(targetEntity?: Entity, cameraStyle?: CameraStyle); + position: Vector2; + rotation: number; + _zoom: any; + zoom: number; + _minimumZoom: number; + minimumZoom: number; + _maximumZoom: number; + maximumZoom: number; + _bounds: Rectangle; + readonly bounds: Rectangle; + _transformMatrix: Matrix2D; + readonly transformMatrix: Matrix2D; + _inverseTransformMatrix: Matrix2D; + readonly inverseTransformMatrix: Matrix2D; + _origin: Vector2; + origin: Vector2; + onSceneSizeChanged(newWidth: number, newHeight: number): void; + setInset(left: number, right: number, top: number, bottom: number): Camera; + setPosition(position: Vector2): this; + setRotation(rotation: number): Camera; + setZoom(zoom: number): Camera; + setMinimumZoom(minZoom: number): Camera; + setMaximumZoom(maxZoom: number): Camera; + onEntityTransformChanged(comp: transform.Component): void; + zoomIn(deltaZoom: number): void; + zoomOut(deltaZoom: number): void; + worldToScreenPoint(worldPosition: Vector2): Vector2; + screenToWorldPoint(screenPosition: Vector2): Vector2; + mouseToWorldPoint(): Vector2; + onAddedToEntity(): void; + update(): void; + clampToMapSize(position: Vector2): Vector2; + updateFollow(): void; + follow(targetEntity: Entity, cameraStyle?: CameraStyle): void; + setCenteredDeadzone(width: number, height: number): void; + protected updateMatrixes(): void; + } +} +declare module es { + class ComponentPool { + private _cache; + private _type; + constructor(typeClass: any); + obtain(): T; + free(component: T): void; + } +} +declare module es { + class IUpdatableComparer { + compare(a: Component, b: Component): number; + } +} +declare module es { + abstract class PooledComponent extends Component { + abstract reset(): any; + } +} +declare module es { + abstract class RenderableComponent extends Component implements IRenderable { + displayObject: egret.DisplayObject; + color: number; + protected _areBoundsDirty: boolean; + readonly width: number; + readonly height: number; + protected _localOffset: Vector2; + localOffset: Vector2; + protected _renderLayer: number; + renderLayer: number; + protected _bounds: Rectangle; + readonly bounds: Rectangle; + private _isVisible; + isVisible: boolean; + onEntityTransformChanged(comp: transform.Component): void; + abstract render(camera: Camera): any; + isVisibleFromCamera(camera: Camera): boolean; + setRenderLayer(renderLayer: number): RenderableComponent; + setColor(color: number): RenderableComponent; + setLocalOffset(offset: Vector2): RenderableComponent; + sync(camera: Camera): void; + toString(): string; + protected onBecameVisible(): void; + protected onBecameInvisible(): void; + } +} +declare module es { + class Mesh extends RenderableComponent { + private _mesh; + constructor(); + setTexture(texture: egret.Texture): Mesh; + reset(): void; + render(camera: es.Camera): void; + } +} +declare module es { + class SpriteRenderer extends RenderableComponent { + constructor(sprite?: Sprite | egret.Texture); + readonly bounds: Rectangle; + originNormalized: Vector2; + protected _origin: Vector2; + origin: Vector2; + protected _sprite: Sprite; + sprite: Sprite; + setSprite(sprite: Sprite): SpriteRenderer; + setOrigin(origin: Vector2): SpriteRenderer; + setOriginNormalized(value: Vector2): SpriteRenderer; + render(camera: Camera): void; + } +} +declare module es { + class TiledSpriteRenderer extends SpriteRenderer { + readonly bounds: Rectangle; + scrollX: number; + scrollY: number; + textureScale: Vector2; + width: number; + height: number; + protected _sourceRect: Rectangle; + protected _textureScale: Vector2; + protected _inverseTexScale: Vector2; + constructor(sprite: Sprite); + render(camera: es.Camera): void; + } +} +declare module es { + class ScrollingSpriteRenderer extends TiledSpriteRenderer { + scrollSpeedX: number; + scroolSpeedY: number; + textureScale: Vector2; + private _scrollX; + private _scrollY; + constructor(sprite: Sprite); + update(): void; + } +} +declare module es { + class Sprite { + texture2D: egret.Texture; + readonly sourceRect: Rectangle; + readonly center: Vector2; + origin: Vector2; + readonly uvs: Rectangle; + constructor(texture: egret.Texture, sourceRect?: Rectangle, origin?: Vector2); + } +} +declare module es { + class SpriteAnimation { + readonly sprites: Sprite[]; + readonly frameRate: number; + constructor(sprites: Sprite[], frameRate: number); + } +} +declare module es { + enum LoopMode { + loop = 0, + once = 1, + clampForever = 2, + pingPong = 3, + pingPongOnce = 4 + } + enum State { + none = 0, + running = 1, + paused = 2, + completed = 3 + } + class SpriteAnimator extends SpriteRenderer { + onAnimationCompletedEvent: (string: any) => {}; + speed: number; + animationState: State; + currentAnimation: SpriteAnimation; + currentAnimationName: string; + currentFrame: number; + _elapsedTime: number; + _loopMode: LoopMode; + constructor(sprite?: Sprite); + readonly isRunning: boolean; + private _animations; + readonly animations: Map; + update(): void; + addAnimation(name: string, animation: SpriteAnimation): SpriteAnimator; + play(name: string, loopMode?: LoopMode): void; + isAnimationActive(name: string): boolean; + pause(): void; + unPause(): void; + stop(): void; + } +} +declare module es { + interface ITriggerListener { + onTriggerEnter(other: Collider, local: Collider): any; + onTriggerExit(other: Collider, local: Collider): any; + } +} +declare module es { + class Mover extends Component { + private _triggerHelper; + onAddedToEntity(): void; + calculateMovement(motion: Vector2, collisionResult: CollisionResult): boolean; + applyMovement(motion: Vector2): void; + move(motion: Vector2, collisionResult: CollisionResult): boolean; + } +} +declare module es { + class ProjectileMover extends Component { + private _tempTriggerList; + private _collider; + onAddedToEntity(): void; + move(motion: Vector2): boolean; + private notifyTriggerListeners; + } +} +declare module es { + abstract class Collider extends Component { + shape: Shape; + isTrigger: boolean; + physicsLayer: number; + collidesWithLayers: number; + shouldColliderScaleAndRotateWithTransform: boolean; + registeredPhysicsBounds: Rectangle; + _localOffsetLength: number; + _isPositionDirty: boolean; + _isRotationDirty: boolean; + protected _colliderRequiresAutoSizing: any; + protected _isParentEntityAddedToScene: any; + protected _isColliderRegistered: any; + readonly absolutePosition: Vector2; + readonly rotation: number; + readonly bounds: Rectangle; + protected _localOffset: Vector2; + localOffset: Vector2; + setLocalOffset(offset: Vector2): Collider; + setShouldColliderScaleAndRotateWithTransform(shouldColliderScaleAndRotationWithTransform: boolean): Collider; + onAddedToEntity(): void; + onRemovedFromEntity(): void; + onEntityTransformChanged(comp: transform.Component): void; + onEnabled(): void; + onDisabled(): void; + registerColliderWithPhysicsSystem(): void; + unregisterColliderWithPhysicsSystem(): void; + overlaps(other: Collider): boolean; + collidesWith(collider: Collider, motion: Vector2, result: CollisionResult): boolean; + clone(): Component; + } +} +declare module es { + class BoxCollider extends Collider { + constructor(); + width: number; + height: number; + setSize(width: number, height: number): this; + setWidth(width: number): BoxCollider; + setHeight(height: number): void; + toString(): string; + } +} +declare module es { + class CircleCollider extends Collider { + constructor(radius?: number); + radius: number; + setRadius(radius: number): CircleCollider; + toString(): string; + } +} +declare module es { + class PolygonCollider extends Collider { + constructor(points: Vector2[]); + } +} +declare module es { + class EntitySystem { + private _entities; + constructor(matcher?: Matcher); + private _scene; + scene: Scene; + private _matcher; + readonly matcher: Matcher; + initialize(): void; + onChanged(entity: Entity): void; + add(entity: Entity): void; + onAdded(entity: Entity): void; + remove(entity: Entity): void; + onRemoved(entity: Entity): void; + update(): void; + lateUpdate(): void; + protected begin(): void; + protected process(entities: Entity[]): void; + protected lateProcess(entities: Entity[]): void; + protected end(): void; + } +} +declare module es { + abstract class EntityProcessingSystem extends EntitySystem { + constructor(matcher: Matcher); + abstract processEntity(entity: Entity): any; + lateProcessEntity(entity: Entity): void; + protected process(entities: Entity[]): void; + protected lateProcess(entities: Entity[]): void; + } +} +declare module es { + abstract class PassiveSystem extends EntitySystem { + onChanged(entity: Entity): void; + protected process(entities: Entity[]): void; + } +} +declare module es { + abstract class ProcessingSystem extends EntitySystem { + onChanged(entity: Entity): void; + abstract processSystem(): any; + protected process(entities: Entity[]): void; + } +} +declare module es { + class BitSet { + private static LONG_MASK; + private _bits; + constructor(nbits?: number); + and(bs: BitSet): void; + andNot(bs: BitSet): void; + cardinality(): number; + clear(pos?: number): void; + get(pos: number): boolean; + intersects(set: BitSet): boolean; + isEmpty(): boolean; + nextSetBit(from: number): number; + set(pos: number, value?: boolean): void; + private ensure; + } +} +declare module es { + class ComponentList { + static compareUpdatableOrder: IUpdatableComparer; + _entity: Entity; + _components: Component[]; + _componentsToAdd: Component[]; + _componentsToRemove: Component[]; + _tempBufferList: Component[]; + _isComponentListUnsorted: boolean; + constructor(entity: Entity); + readonly count: number; + readonly buffer: Component[]; + markEntityListUnsorted(): void; + add(component: Component): void; + remove(component: Component): void; + removeAllComponents(): void; + deregisterAllComponents(): void; + registerAllComponents(): void; + updateLists(): void; + handleRemove(component: Component): void; + getComponent(type: any, onlyReturnInitializedComponents: boolean): T; + getComponents(typeName: string | any, components?: any): any; + update(): void; + onEntityTransformChanged(comp: transform.Component): void; + onEntityEnabled(): void; + onEntityDisabled(): void; + } +} +declare module es { + class ComponentTypeManager { + private static _componentTypesMask; + static add(type: any): void; + static getIndexFor(type: any): number; + } +} +declare module es { + class EntityList { + scene: Scene; + _entities: Entity[]; + _entitiesToAdded: Entity[]; + _entitiesToRemove: Entity[]; + _isEntityListUnsorted: boolean; + _entityDict: Map; + _unsortedTags: number[]; + _tempEntityList: Entity[]; + constructor(scene: Scene); + readonly count: number; + readonly buffer: Entity[]; + markEntityListUnsorted(): void; + markTagUnsorted(tag: number): void; + add(entity: Entity): void; + remove(entity: Entity): void; + removeAllEntities(): void; + contains(entity: Entity): boolean; + getTagList(tag: number): Entity[]; + addToTagList(entity: Entity): void; + removeFromTagList(entity: Entity): void; + update(): void; + updateLists(): void; + findEntity(name: string): Entity; + entitiesWithTag(tag: number): Entity[]; + entitiesOfType(type: any): T[]; + findComponentOfType(type: any): T; + findComponentsOfType(type: any): T[]; + } +} +declare module es { + class EntityProcessorList { + private _processors; + add(processor: EntitySystem): void; + remove(processor: EntitySystem): void; + onComponentAdded(entity: Entity): void; + onComponentRemoved(entity: Entity): void; + onEntityAdded(entity: Entity): void; + onEntityRemoved(entity: Entity): void; + begin(): void; + update(): void; + lateUpdate(): void; + end(): void; + getProcessor(): T; + protected notifyEntityChanged(entity: Entity): void; + protected removeFromProcessors(entity: Entity): void; + } +} +declare module es { + class Matcher { + protected allSet: BitSet; + protected exclusionSet: BitSet; + protected oneSet: BitSet; + static empty(): Matcher; + getAllSet(): BitSet; + getExclusionSet(): BitSet; + getOneSet(): BitSet; + IsIntersted(e: Entity): boolean; + all(...types: any[]): Matcher; + exclude(...types: any[]): this; + one(...types: any[]): this; + } +} +declare class ObjectUtils { + static clone(p: any, c?: T): T; +} +declare module es { + interface IRenderable { bounds: Rectangle; - }; - static addCollider(collider: Collider): void; - static removeCollider(collider: Collider): void; - static updateCollider(collider: Collider): void; + enabled: boolean; + renderLayer: number; + isVisible: boolean; + isVisibleFromCamera(camera: Camera): any; + render(camera: Camera): any; + } + class RenderableComparer { + compare(self: IRenderable, other: IRenderable): number; + } } -declare abstract class Shape { - bounds: Rectangle; - position: Vector2; - center: Vector2; - abstract recalculateBounds(collider: Collider): any; - abstract pointCollidesWithShape(point: Vector2): CollisionResult; - abstract overlaps(other: Shape): any; - abstract collidesWithShape(other: Shape): CollisionResult; +declare module es { + class RenderableComponentList { + static compareUpdatableOrder: RenderableComparer; + _components: IRenderable[]; + _componentsByRenderLayer: Map; + _unsortedRenderLayers: number[]; + _componentsNeedSort: boolean; + readonly count: number; + readonly buffer: IRenderable[]; + add(component: IRenderable): void; + remove(component: IRenderable): void; + updateRenderableRenderLayer(component: IRenderable, oldRenderLayer: number, newRenderLayer: number): void; + setRenderLayerNeedsComponentSort(renderLayer: number): void; + setNeedsComponentSort(): void; + addToRenderLayerList(component: IRenderable, renderLayer: number): void; + componentsWithRenderLayer(renderLayer: number): IRenderable[]; + updateList(): void; + } } -declare class Polygon extends Shape { - points: Vector2[]; - isUnrotated: boolean; - private _polygonCenter; - private _areEdgeNormalsDirty; - protected _originalPoints: Vector2[]; - _edgeNormals: Vector2[]; - readonly edgeNormals: Vector2[]; - isBox: boolean; - constructor(points: Vector2[], isBox?: boolean); - private buildEdgeNormals; - setPoints(points: Vector2[]): void; - collidesWithShape(other: Shape): any; - recalculateCenterAndEdgeNormals(): void; - overlaps(other: Shape): any; - static findPolygonCenter(points: Vector2[]): Vector2; - static getClosestPointOnPolygonToPoint(points: Vector2[], point: Vector2): { - closestPoint: any; - distanceSquared: any; - edgeNormal: any; - }; - pointCollidesWithShape(point: Vector2): CollisionResult; - containsPoint(point: Vector2): boolean; - static buildSymmertricalPolygon(vertCount: number, radius: number): any[]; - recalculateBounds(collider: Collider): void; +declare class StringUtils { + private static specialSigns; + static matchChineseWord(str: string): string[]; + static lTrim(target: string): string; + static rTrim(target: string): string; + static trim(target: string): string; + static isWhiteSpace(str: string): boolean; + static replaceMatch(mainStr: string, targetStr: string, replaceStr: string, caseMark?: boolean): string; + static htmlSpecialChars(str: string, reversion?: boolean): string; + static zfill(str: string, width?: number): string; + static reverse(str: string): string; + static cutOff(str: string, start: number, len: number, order?: boolean): string; + static strReplace(str: string, rStr: string[]): string; } -declare class Box extends Polygon { - width: number; - height: number; - constructor(width: number, height: number); - private static buildBox; - overlaps(other: Shape): any; - collidesWithShape(other: Shape): any; - updateBox(width: number, height: number): void; - containsPoint(point: Vector2): boolean; +declare module es { + class TextureUtils { + static sharedCanvas: HTMLCanvasElement; + static sharedContext: CanvasRenderingContext2D; + static convertImageToCanvas(texture: egret.Texture, rect?: egret.Rectangle): HTMLCanvasElement; + static toDataURL(type: string, texture: egret.Texture, rect?: egret.Rectangle, encoderOptions?: any): string; + static eliFoTevas(type: string, texture: egret.Texture, filePath: string, rect?: egret.Rectangle, encoderOptions?: any): void; + static getPixel32(texture: egret.Texture, x: number, y: number): number[]; + static getPixels(texture: egret.Texture, x: number, y: number, width?: number, height?: number): number[]; + } } -declare class Circle extends Shape { - radius: number; - private _originalRadius; - constructor(radius: number); - pointCollidesWithShape(point: Vector2): CollisionResult; - collidesWithShape(other: Shape): CollisionResult; - recalculateBounds(collider: Collider): void; - overlaps(other: Shape): any; +declare module es { + class Time { + static unscaledDeltaTime: any; + static deltaTime: number; + static timeScale: number; + static frameCount: number; + static _timeSinceSceneLoad: any; + private static _lastTime; + static update(currentTime: number): void; + static sceneChanged(): void; + static checkEvery(interval: number): boolean; + } } -declare class CollisionResult { - collider: Collider; - minimumTranslationVector: Vector2; - normal: Vector2; - point: Vector2; - invertResult(): void; +declare class TimeUtils { + static monthId(d?: Date): number; + static dateId(t?: Date): number; + static weekId(d?: Date, first?: boolean): number; + static diffDay(a: Date, b: Date, fixOne?: boolean): number; + static getFirstDayOfWeek(d?: Date): Date; + static getFirstOfDay(d?: Date): Date; + static getNextFirstOfDay(d?: Date): Date; + static formatDate(date: Date): string; + static formatDateTime(date: Date): string; + static parseDate(s: string): Date; + static secondToTime(time?: number, partition?: string, showHour?: boolean): string; + static timeToMillisecond(time: string, partition?: string): string; } -declare class ShapeCollisions { - static polygonToPolygon(first: Polygon, second: Polygon): CollisionResult; - static intervalDistance(minA: number, maxA: number, minB: number, maxB: any): number; - static getInterval(axis: Vector2, polygon: Polygon, min: number, max: number): { +declare module es { + class GraphicsCapabilities extends egret.Capabilities { + initialize(device: GraphicsDevice): void; + private platformInitialize; + } +} +declare module es { + class GraphicsDevice { + graphicsCapabilities: GraphicsCapabilities; + constructor(); + private _viewport; + readonly viewport: Viewport; + private setup; + } +} +declare module es { + class Viewport { + private _x; + private _y; + private _minDepth; + private _maxDepth; + constructor(x: number, y: number, width: number, height: number); + private _width; + width: number; + private _height; + height: number; + readonly aspectRatio: number; + bounds: Rectangle; + } +} +declare module es { + class GaussianBlurEffect extends egret.CustomFilter { + private static blur_frag; + constructor(); + } +} +declare module es { + class PolygonLightEffect extends egret.CustomFilter { + private static vertSrc; + private static fragmentSrc; + constructor(); + } +} +declare module es { + class PostProcessor { + static default_vert: string; + enabled: boolean; + effect: egret.Filter; + scene: Scene; + shape: egret.Shape; + constructor(effect?: egret.Filter); + onAddedToScene(scene: Scene): void; + process(): void; + onSceneBackBufferSizeChanged(newWidth: number, newHeight: number): void; + unload(): void; + protected drawFullscreenQuad(): void; + } +} +declare module es { + class GaussianBlurPostProcessor extends PostProcessor { + onAddedToScene(scene: Scene): void; + } +} +declare module es { + abstract class Renderer { + camera: Camera; + readonly renderOrder: number; + protected constructor(renderOrder: number, camera?: Camera); + onAddedToScene(scene: Scene): void; + unload(): void; + abstract render(scene: Scene): any; + onSceneBackBufferSizeChanged(newWidth: number, newHeight: number): void; + compareTo(other: Renderer): number; + protected beginRender(cam: Camera): void; + protected renderAfterStateCheck(renderable: IRenderable, cam: Camera): void; + } +} +declare module es { + class DefaultRenderer extends Renderer { + constructor(); + render(scene: Scene): void; + } +} +declare module es { + class ScreenSpaceRenderer extends Renderer { + render(scene: Scene): void; + } +} +declare module es { + class PolyLight extends RenderableComponent { + power: number; + private _lightEffect; + private _indices; + constructor(radius: number, color: number, power: number); + protected _radius: number; + radius: number; + setRadius(radius: number): void; + render(camera: Camera): void; + reset(): void; + private computeTriangleIndices; + } +} +declare module es { + abstract class SceneTransition { + loadsNewScene: boolean; + isNewSceneLoaded: boolean; + onScreenObscured: Function; + onTransitionCompleted: Function; + protected sceneLoadAction: Function; + constructor(sceneLoadAction: Function); + private _hasPreviousSceneRender; + readonly hasPreviousSceneRender: boolean; + preRender(): void; + render(): void; + onBeginTransition(): Promise; + tickEffectProgressProperty(filter: egret.CustomFilter, duration: number, easeType: Function, reverseDirection?: boolean): Promise; + protected transitionComplete(): void; + protected loadNextScene(): Promise; + } +} +declare module es { + class FadeTransition extends SceneTransition { + fadeToColor: number; + fadeOutDuration: number; + fadeEaseType: Function; + delayBeforeFadeInDuration: number; + private _mask; + private _alpha; + constructor(sceneLoadAction: Function); + onBeginTransition(): Promise; + render(): void; + } +} +declare module es { + class WindTransition extends SceneTransition { + duration: number; + easeType: (t: number) => number; + private _mask; + private _windEffect; + constructor(sceneLoadAction: Function); + windSegments: number; + size: number; + onBeginTransition(): Promise; + } +} +declare module es { + class Bezier { + static getPoint(p0: Vector2, p1: Vector2, p2: Vector2, t: number): Vector2; + static getFirstDerivative(p0: Vector2, p1: Vector2, p2: Vector2, t: number): Vector2; + static getFirstDerivativeThree(start: Vector2, firstControlPoint: Vector2, secondControlPoint: Vector2, end: Vector2, t: number): Vector2; + static getPointThree(start: Vector2, firstControlPoint: Vector2, secondControlPoint: Vector2, end: Vector2, t: number): Vector2; + static getOptimizedDrawingPoints(start: Vector2, firstCtrlPoint: Vector2, secondCtrlPoint: Vector2, end: Vector2, distanceTolerance?: number): Vector2[]; + private static recursiveGetOptimizedDrawingPoints; + } +} +declare module es { + class Flags { + static isFlagSet(self: number, flag: number): boolean; + static isUnshiftedFlagSet(self: number, flag: number): boolean; + static setFlagExclusive(self: number, flag: number): number; + static setFlag(self: number, flag: number): number; + static unsetFlag(self: number, flag: number): number; + static invertFlags(self: number): number; + } +} +declare module es { + class MathHelper { + static readonly Epsilon: number; + static readonly Rad2Deg: number; + static readonly Deg2Rad: number; + static toDegrees(radians: number): number; + static toRadians(degrees: number): number; + static map(value: number, leftMin: number, leftMax: number, rightMin: number, rightMax: number): number; + static lerp(value1: number, value2: number, amount: number): number; + static clamp(value: number, min: number, max: number): number; + static pointOnCirlce(circleCenter: Vector2, radius: number, angleInDegrees: number): Vector2; + static isEven(value: number): boolean; + static clamp01(value: number): number; + static angleBetweenVectors(from: Vector2, to: Vector2): number; + } +} +declare module es { + var matrixPool: any[]; + class Matrix2D extends egret.Matrix { + m11: number; + m12: number; + m21: number; + m22: number; + m31: number; + m32: number; + static create(): Matrix2D; + identity(): Matrix2D; + translate(dx: number, dy: number): Matrix2D; + scale(sx: number, sy: number): Matrix2D; + rotate(angle: number): Matrix2D; + invert(): Matrix2D; + add(matrix: Matrix2D): Matrix2D; + substract(matrix: Matrix2D): Matrix2D; + divide(matrix: Matrix2D): Matrix2D; + multiply(matrix: Matrix2D): Matrix2D; + determinant(): number; + release(matrix: Matrix2D): void; + } +} +declare module es { + class Rectangle extends egret.Rectangle { + _tempMat: Matrix2D; + _transformMat: Matrix2D; + readonly max: Vector2; + readonly center: Vector2; + location: Vector2; + size: Vector2; + static fromMinMax(minX: number, minY: number, maxX: number, maxY: number): Rectangle; + static rectEncompassingPoints(points: Vector2[]): Rectangle; + intersects(value: egret.Rectangle): boolean; + rayIntersects(ray: Ray2D): number; + containsRect(value: Rectangle): boolean; + contains(x: number, y: number): boolean; + getHalfSize(): Vector2; + getClosestPointOnRectangleBorderToPoint(point: Vector2, edgeNormal: Vector2): Vector2; + getClosestPointOnBoundsToOrigin(): Vector2; + calculateBounds(parentPosition: Vector2, position: Vector2, origin: Vector2, scale: Vector2, rotation: number, width: number, height: number): void; + } +} +declare module es { + class Vector3 { + x: number; + y: number; + z: number; + constructor(x: number, y: number, z: number); + } +} +declare module es { + class ColliderTriggerHelper { + private _entity; + private _activeTriggerIntersections; + private _previousTriggerIntersections; + private _tempTriggerList; + constructor(entity: Entity); + update(): void; + private checkForExitedColliders; + private notifyTriggerListeners; + } +} +declare module es { + enum PointSectors { + center = 0, + top = 1, + bottom = 2, + topLeft = 9, + topRight = 5, + left = 8, + right = 4, + bottomLeft = 10, + bottomRight = 6 + } + class Collisions { + static isLineToLine(a1: Vector2, a2: Vector2, b1: Vector2, b2: Vector2): boolean; + static lineToLineIntersection(a1: Vector2, a2: Vector2, b1: Vector2, b2: Vector2): Vector2; + static closestPointOnLine(lineA: Vector2, lineB: Vector2, closestTo: Vector2): Vector2; + static isCircleToCircle(circleCenter1: Vector2, circleRadius1: number, circleCenter2: Vector2, circleRadius2: number): boolean; + static isCircleToLine(circleCenter: Vector2, radius: number, lineFrom: Vector2, lineTo: Vector2): boolean; + static isCircleToPoint(circleCenter: Vector2, radius: number, point: Vector2): boolean; + static isRectToCircle(rect: egret.Rectangle, cPosition: Vector2, cRadius: number): boolean; + static isRectToLine(rect: Rectangle, lineFrom: Vector2, lineTo: Vector2): boolean; + static isRectToPoint(rX: number, rY: number, rW: number, rH: number, point: Vector2): boolean; + static getSector(rX: number, rY: number, rW: number, rH: number, point: Vector2): PointSectors; + } +} +declare module es { + class Physics { + static spatialHashCellSize: number; + static readonly allLayers: number; + private static _spatialHash; + static raycastsHitTriggers: boolean; + static raycastsStartInColliders: boolean; + static reset(): void; + static clear(): void; + static overlapCircleAll(center: Vector2, randius: number, results: any[], layerMask?: number): number; + static boxcastBroadphase(rect: Rectangle, layerMask?: number): Collider[]; + static boxcastBroadphaseExcludingSelf(collider: Collider, rect: Rectangle, layerMask?: number): Collider[]; + static addCollider(collider: Collider): void; + static removeCollider(collider: Collider): void; + static updateCollider(collider: Collider): void; + static debugDraw(secondsToDisplay: any): void; + } +} +declare module es { + class Ray2D { + start: Vector2; + end: Vector2; + direction: Vector2; + constructor(position: Vector2, end: Vector2); + } +} +declare module es { + class RaycastHit { + collider: Collider; + fraction: number; + distance: number; + point: Vector2; + normal: Vector2; + centroid: Vector2; + constructor(collider: Collider, fraction: number, distance: number, point: Vector2, normal: Vector2); + setValues(collider: Collider, fraction: number, distance: number, point: Vector2): void; + setValuesNonCollider(fraction: number, distance: number, point: Vector2, normal: Vector2): void; + reset(): void; + toString(): string; + } +} +declare module es { + abstract class Shape { + position: Vector2; + center: Vector2; + bounds: Rectangle; + abstract recalculateBounds(collider: Collider): any; + abstract overlaps(other: Shape): boolean; + abstract collidesWithShape(other: Shape, collisionResult: CollisionResult): boolean; + abstract collidesWithLine(start: Vector2, end: Vector2, hit: RaycastHit): boolean; + abstract containsPoint(point: Vector2): any; + abstract pointCollidesWithShape(point: Vector2, result: CollisionResult): boolean; + clone(): Shape; + } +} +declare module es { + class Polygon extends Shape { + points: Vector2[]; + _areEdgeNormalsDirty: boolean; + _originalPoints: Vector2[]; + _polygonCenter: Vector2; + isBox: boolean; + isUnrotated: boolean; + constructor(points: Vector2[], isBox?: boolean); + _edgeNormals: Vector2[]; + readonly edgeNormals: Vector2[]; + setPoints(points: Vector2[]): void; + recalculateCenterAndEdgeNormals(): void; + buildEdgeNormals(): void; + static buildSymmetricalPolygon(vertCount: number, radius: number): any[]; + static recenterPolygonVerts(points: Vector2[]): void; + static findPolygonCenter(points: Vector2[]): Vector2; + static getFarthestPointInDirection(points: Vector2[], direction: Vector2): Vector2; + static getClosestPointOnPolygonToPoint(points: Vector2[], point: Vector2, distanceSquared: number, edgeNormal: Vector2): Vector2; + static rotatePolygonVerts(radians: number, originalPoints: Vector2[], rotatedPoints: any): void; + recalculateBounds(collider: Collider): void; + overlaps(other: Shape): any; + collidesWithShape(other: Shape, result: CollisionResult): boolean; + collidesWithLine(start: es.Vector2, end: es.Vector2, hit: es.RaycastHit): boolean; + containsPoint(point: Vector2): boolean; + pointCollidesWithShape(point: Vector2, result: CollisionResult): boolean; + } +} +declare module es { + class Box extends Polygon { + width: number; + height: number; + constructor(width: number, height: number); + private static buildBox; + updateBox(width: number, height: number): void; + overlaps(other: Shape): any; + collidesWithShape(other: Shape, result: CollisionResult): boolean; + containsPoint(point: Vector2): boolean; + pointCollidesWithShape(point: es.Vector2, result: es.CollisionResult): boolean; + } +} +declare module es { + class Circle extends Shape { + radius: number; + _originalRadius: number; + constructor(radius: number); + recalculateBounds(collider: es.Collider): void; + overlaps(other: Shape): any; + collidesWithShape(other: Shape, result: CollisionResult): boolean; + collidesWithLine(start: es.Vector2, end: es.Vector2, hit: es.RaycastHit): boolean; + containsPoint(point: es.Vector2): boolean; + pointCollidesWithShape(point: Vector2, result: CollisionResult): boolean; + } +} +declare module es { + class CollisionResult { + collider: Collider; + normal: Vector2; + minimumTranslationVector: Vector2; + point: Vector2; + removeHorizontal(deltaMovement: Vector2): void; + invertResult(): this; + toString(): string; + } +} +declare module es { + class RealtimeCollisions { + static intersectMovingCircleToBox(s: Circle, b: Box, movement: Vector2): number; + } +} +declare module es { + class ShapeCollisions { + static polygonToPolygon(first: Polygon, second: Polygon, result: CollisionResult): boolean; + static intervalDistance(minA: number, maxA: number, minB: number, maxB: any): number; + static getInterval(axis: Vector2, polygon: Polygon, min: number, max: number): { + min: number; + max: number; + }; + static circleToPolygon(circle: Circle, polygon: Polygon, result: CollisionResult): boolean; + static circleToBox(circle: Circle, box: Box, result: CollisionResult): boolean; + static pointToCircle(point: Vector2, circle: Circle, result: CollisionResult): boolean; + static pointToBox(point: Vector2, box: Box, result: CollisionResult): boolean; + static closestPointOnLine(lineA: Vector2, lineB: Vector2, closestTo: Vector2): Vector2; + static pointToPoly(point: Vector2, poly: Polygon, result: CollisionResult): boolean; + static circleToCircle(first: Circle, second: Circle, result: CollisionResult): boolean; + static boxToBox(first: Box, second: Box, result: CollisionResult): boolean; + private static minkowskiDifference; + static lineToPoly(start: Vector2, end: Vector2, polygon: Polygon, hit: RaycastHit): boolean; + static lineToLine(a1: Vector2, a2: Vector2, b1: Vector2, b2: Vector2, intersection: Vector2): boolean; + static lineToCircle(start: Vector2, end: Vector2, s: Circle, hit: RaycastHit): boolean; + static boxToBoxCast(first: Box, second: Box, movement: Vector2, hit: RaycastHit): boolean; + } +} +declare module es { + class SpatialHash { + gridBounds: Rectangle; + _raycastParser: RaycastResultParser; + _cellSize: number; + _inverseCellSize: number; + _overlapTestCircle: Circle; + _cellDict: NumberDictionary; + _tempHashSet: Collider[]; + constructor(cellSize?: number); + register(collider: Collider): void; + remove(collider: Collider): void; + removeWithBruteForce(obj: Collider): void; + clear(): void; + debugDraw(secondsToDisplay: number, textScale?: number): void; + aabbBroadphase(bounds: Rectangle, excludeCollider: Collider, layerMask: number): Collider[]; + overlapCircle(circleCenter: Vector2, radius: number, results: Collider[], layerMask: any): number; + private cellCoords; + private cellAtPosition; + private debugDrawCellDetails; + } + class NumberDictionary { + _store: Map; + add(x: number, y: number, list: Collider[]): void; + remove(obj: Collider): void; + tryGetValue(x: number, y: number): Collider[]; + clear(): void; + private getKey; + } + class RaycastResultParser { + hitCounter: number; + static compareRaycastHits: (a: RaycastHit, b: RaycastHit) => number; + _hits: RaycastHit[]; + _tempHit: RaycastHit; + _checkedColliders: Collider[]; + _cellHits: RaycastHit[]; + _ray: Ray2D; + _layerMask: number; + start(ray: Ray2D, hits: RaycastHit[], layerMask: number): void; + checkRayIntersection(cellX: number, cellY: number, cell: Collider[]): boolean; + reset(): void; + } +} +declare class ArrayUtils { + static bubbleSort(ary: number[]): void; + static insertionSort(ary: number[]): void; + static binarySearch(ary: number[], value: number): number; + static findElementIndex(ary: any[], num: any): any; + static getMaxElementIndex(ary: number[]): number; + static getMinElementIndex(ary: number[]): number; + static getUniqueAry(ary: number[]): number[]; + static getDifferAry(aryA: number[], aryB: number[]): number[]; + static swap(array: any[], index1: number, index2: number): void; + static clearList(ary: any[]): void; + static cloneList(ary: any[]): any[]; + static equals(ary1: number[], ary2: number[]): Boolean; + static insert(ary: any[], index: number, value: any): any; +} +declare class Base64Utils { + private static _keyNum; + private static _keyStr; + private static _keyAll; + static encode: (input: any) => string; + static decode(input: any, isNotStr?: boolean): string; + private static _utf8_encode; + private static _utf8_decode; + private static getConfKey; +} +declare module es { + class ContentManager { + protected loadedAssets: Map; + loadRes(name: string, local?: boolean): Promise; + dispose(): void; + } +} +declare module es { + class DrawUtils { + static drawLine(shape: egret.Shape, start: Vector2, end: Vector2, color: number, thickness?: number): void; + static drawLineAngle(shape: egret.Shape, start: Vector2, radians: number, length: number, color: number, thickness?: number): void; + static drawHollowRect(shape: egret.Shape, rect: Rectangle, color: number, thickness?: number): void; + static drawHollowRectR(shape: egret.Shape, x: number, y: number, width: number, height: number, color: number, thickness?: number): void; + static drawPixel(shape: egret.Shape, position: Vector2, color: number, size?: number): void; + static getColorMatrix(color: number): egret.ColorMatrixFilter; + } +} +declare module es { + class FuncPack { + func: Function; + context: any; + constructor(func: Function, context: any); + } + class Emitter { + private _messageTable; + constructor(); + addObserver(eventType: T, handler: Function, context: any): void; + removeObserver(eventType: T, handler: Function): void; + emit(eventType: T, data?: any): void; + } +} +declare module es { + class GlobalManager { + _enabled: boolean; + enabled: boolean; + setEnabled(isEnabled: boolean): void; + onEnabled(): void; + onDisabled(): void; + update(): void; + } +} +declare module es { + class TouchState { + x: number; + y: number; + touchPoint: number; + touchDown: boolean; + readonly position: Vector2; + reset(): void; + } + class Input { + private static _init; + private static _previousTouchState; + private static _resolutionOffset; + private static _touchIndex; + private static _gameTouchs; + static readonly gameTouchs: TouchState[]; + private static _resolutionScale; + static readonly resolutionScale: Vector2; + private static _totalTouchCount; + static readonly totalTouchCount: number; + static readonly touchPosition: Vector2; + static maxSupportedTouch: number; + static readonly touchPositionDelta: Vector2; + static initialize(): void; + static scaledPosition(position: Vector2): Vector2; + private static initTouchCache; + private static touchBegin; + private static touchMove; + private static touchEnd; + private static setpreviousTouchState; + } +} +declare class KeyboardUtils { + static TYPE_KEY_DOWN: number; + static TYPE_KEY_UP: number; + static A: string; + static B: string; + static C: string; + static D: string; + static E: string; + static F: string; + static G: string; + static H: string; + static I: string; + static J: string; + static K: string; + static L: string; + static M: string; + static N: string; + static O: string; + static P: string; + static Q: string; + static R: string; + static S: string; + static T: string; + static U: string; + static V: string; + static W: string; + static X: string; + static Y: string; + static Z: string; + static ESC: string; + static F1: string; + static F2: string; + static F3: string; + static F4: string; + static F5: string; + static F6: string; + static F7: string; + static F8: string; + static F9: string; + static F10: string; + static F11: string; + static F12: string; + static NUM_1: string; + static NUM_2: string; + static NUM_3: string; + static NUM_4: string; + static NUM_5: string; + static NUM_6: string; + static NUM_7: string; + static NUM_8: string; + static NUM_9: string; + static NUM_0: string; + static TAB: string; + static CTRL: string; + static ALT: string; + static SHIFT: string; + static CAPS_LOCK: string; + static ENTER: string; + static SPACE: string; + static BACK_SPACE: string; + static INSERT: string; + static DELETE: string; + static HOME: string; + static END: string; + static PAGE_UP: string; + static PAGE_DOWN: string; + static LEFT: string; + static RIGHT: string; + static UP: string; + static DOWN: string; + static PAUSE_BREAK: string; + static NUM_LOCK: string; + static SCROLL_LOCK: string; + static WINDOWS: string; + private static keyDownDict; + private static keyUpDict; + static init(): void; + static registerKey(key: string, fun: Function, thisObj: any, type?: number, ...args: any[]): void; + static unregisterKey(key: string, type?: number): void; + static destroy(): void; + private static onKeyDonwHander; + private static onKeyUpHander; + private static keyCodeToString; +} +declare module es { + class ListPool { + private static readonly _objectQueue; + static warmCache(cacheCount: number): void; + static trimCache(cacheCount: any): void; + static clearCache(): void; + static obtain(): T[]; + static free(obj: Array): void; + } +} +declare const THREAD_ID: string; +declare const nextTick: (fn: any) => void; +declare class LockUtils { + private _keyX; + private _keyY; + private setItem; + private getItem; + private removeItem; + constructor(key: any); + lock(): Promise<{}>; +} +declare module es { + class Pair { + first: T; + second: T; + constructor(first: T, second: T); + clear(): void; + equals(other: Pair): boolean; + } +} +declare class RandomUtils { + static randrange(start: number, stop: number, step?: number): number; + static randint(a: number, b: number): number; + static randnum(a: number, b: number): number; + static shuffle(array: any[]): any[]; + static choice(sequence: any): any; + static sample(sequence: any[], num: number): any[]; + static random(): number; + static boolean(chance?: number): boolean; + private static _randomCompare; +} +declare module es { + class RectangleExt { + static union(first: Rectangle, point: Vector2): Rectangle; + } +} +declare module es { + class Triangulator { + triangleIndices: number[]; + private _triPrev; + private _triNext; + static testPointTriangle(point: Vector2, a: Vector2, b: Vector2, c: Vector2): boolean; + triangulate(points: Vector2[], arePointsCCW?: boolean): void; + private initialize; + } +} +declare module es { + class Vector2Ext { + static isTriangleCCW(a: Vector2, center: Vector2, c: Vector2): boolean; + static cross(u: Vector2, v: Vector2): number; + static perpendicular(first: Vector2, second: Vector2): Vector2; + static normalize(vec: Vector2): Vector2; + static transformA(sourceArray: Vector2[], sourceIndex: number, matrix: Matrix2D, destinationArray: Vector2[], destinationIndex: number, length: number): void; + static transformR(position: Vector2, matrix: Matrix2D): Vector2; + static transform(sourceArray: Vector2[], matrix: Matrix2D, destinationArray: Vector2[]): void; + static round(vec: Vector2): Vector2; + } +} +declare class WebGLUtils { + static getContext(): CanvasRenderingContext2D; +} +declare module es { + class Layout { + clientArea: Rectangle; + safeArea: Rectangle; + constructor(); + place(size: Vector2, horizontalMargin: number, verticalMargine: number, alignment: Alignment): Rectangle; + } + enum Alignment { + none = 0, + left = 1, + right = 2, + horizontalCenter = 4, + top = 8, + bottom = 16, + verticalCenter = 32, + topLeft = 9, + topRight = 10, + topCenter = 12, + bottomLeft = 17, + bottomRight = 18, + bottomCenter = 20, + centerLeft = 33, + centerRight = 34, + center = 36 + } +} +declare namespace stopwatch { + class Stopwatch { + private readonly getSystemTime; + private _startSystemTime; + private _stopSystemTime; + private _stopDuration; + private _pendingSliceStartStopwatchTime; + private _completeSlices; + constructor(getSystemTime?: GetTimeFunc); + getState(): State; + isIdle(): boolean; + isRunning(): boolean; + isStopped(): boolean; + slice(): Slice; + getCompletedSlices(): Slice[]; + getCompletedAndPendingSlices(): Slice[]; + getPendingSlice(): Slice; + getTime(): number; + reset(): void; + start(forceReset?: boolean): void; + stop(recordPendingSlice?: boolean): number; + private calculatePendingSlice; + private caculateStopwatchTime; + private getSystemTimeOfCurrentStopwatchTime; + private recordPendingSlice; + } + type GetTimeFunc = () => number; + enum State { + IDLE = "IDLE", + RUNNING = "RUNNING", + STOPPED = "STOPPED" + } + function setDefaultSystemTimeGetter(systemTimeGetter?: GetTimeFunc): void; + interface Slice { + readonly startTime: number; + readonly endTime: number; + readonly duration: number; + } +} +declare module es { + class TimeRuler { + static readonly maxBars: number; + static readonly maxSamples: number; + static readonly maxNestCall: number; + static readonly barHeight: number; + static readonly maxSampleFrames: number; + static readonly logSnapDuration: number; + static readonly barPadding: number; + static readonly autoAdjustDelay: number; + private static _instance; + targetSampleFrames: number; + width: number; + enabled: true; + showLog: boolean; + private _frameKey; + private _logKey; + private _logs; + private sampleFrames; + private _position; + private _prevLog; + private _curLog; + private frameCount; + private markers; + private stopwacth; + private _markerNameToIdMap; + private _updateCount; + private _frameAdjust; + constructor(); + static readonly Instance: TimeRuler; + startFrame(): void; + beginMark(markerName: string, color: number, barIndex?: number): void; + endMark(markerName: string, barIndex?: number): void; + getAverageTime(barIndex: number, markerName: string): number; + resetLog(): void; + render(position?: Vector2, width?: number): void; + private onGraphicsDeviceReset; + } + class FrameLog { + bars: MarkerCollection[]; + constructor(); + } + class MarkerCollection { + markers: Marker[]; + markCount: number; + markerNests: number[]; + nestCount: number; + constructor(); + } + class Marker { + markerId: number; + beginTime: number; + endTime: number; + color: number; + } + class MarkerInfo { + name: string; + logs: MarkerLog[]; + constructor(name: any); + } + class MarkerLog { + snapMin: number; + snapMax: number; + snapAvg: number; min: number; max: number; - }; - static circleToPolygon(circle: Circle, polygon: Polygon): CollisionResult; - static circleToBox(circle: Circle, box: Box): CollisionResult; - static pointToCircle(point: Vector2, circle: Circle): CollisionResult; - static closestPointOnLine(lineA: Vector2, lineB: Vector2, closestTo: Vector2): Vector2; - static pointToPoly(point: Vector2, poly: Polygon): CollisionResult; - static circleToCircle(first: Circle, second: Circle): CollisionResult; - static boxToBox(first: Box, second: Box): CollisionResult; - private static minkowskiDifference; -} -declare class SpatialHash { - gridBounds: Rectangle; - private _raycastParser; - private _cellSize; - private _inverseCellSize; - private _overlapTestCircle; - private _tempHashSet; - private _cellDict; - constructor(cellSize?: number); - remove(collider: Collider): void; - register(collider: Collider): void; - clear(): void; - overlapCircle(circleCenter: Vector2, radius: number, results: Collider[], layerMask: any): number; - aabbBroadphase(bounds: Rectangle, excludeCollider: Collider, layerMask: number): { - tempHashSet: Collider[]; - bounds: Rectangle; - }; - private cellAtPosition; - private cellCoords; -} -declare class RaycastResultParser { -} -declare class NumberDictionary { - private _store; - private getKey; - private intToUint; - add(x: number, y: number, list: Collider[]): void; - remove(obj: Collider): void; - tryGetValue(x: number, y: number): Collider[]; - clear(): void; -} -declare class fui { -} -declare class ContentManager { - protected loadedAssets: Map; - loadRes(name: string, local?: boolean): Promise; - dispose(): void; -} -declare class Emitter { - private _messageTable; - constructor(); - addObserver(eventType: T, handler: Function): void; - removeObserver(eventType: T, handler: Function): void; - emit(eventType: T, data: any): void; -} -declare class GlobalManager { - static globalManagers: GlobalManager[]; - private _enabled; - enabled: boolean; - setEnabled(isEnabled: boolean): void; - onEnabled(): void; - onDisabled(): void; - update(): void; - static registerGlobalManager(manager: GlobalManager): void; - static unregisterGlobalManager(manager: GlobalManager): void; - static getGlobalManager(type: any): T; -} -declare class TouchState { - x: number; - y: number; - touchPoint: number; - touchDown: boolean; - readonly position: Vector2; - reset(): void; -} -declare class Input { - private static _init; - private static _stage; - private static _previousTouchState; - private static _gameTouchs; - private static _resolutionOffset; - private static _resolutionScale; - private static _touchIndex; - private static _totalTouchCount; - static readonly touchPosition: Vector2; - static maxSupportedTouch: number; - static readonly resolutionScale: Vector2; - static readonly totalTouchCount: number; - static readonly gameTouchs: TouchState[]; - static readonly touchPositionDelta: Vector2; - static initialize(stage: egret.Stage): void; - private static initTouchCache; - private static touchBegin; - private static touchMove; - private static touchEnd; - private static setpreviousTouchState; - static scaledPosition(position: Vector2): Vector2; -} -declare class ListPool { - private static readonly _objectQueue; - static warmCache(cacheCount: number): void; - static trimCache(cacheCount: any): void; - static clearCache(): void; - static obtain(): Array; - static free(obj: Array): void; -} -declare class Pair { - first: T; - second: T; - constructor(first: T, second: T); - clear(): void; - equals(other: Pair): boolean; -} -declare class RectangleExt { - static union(first: Rectangle, point: Vector2): Rectangle; - static unionR(value1: Rectangle, value2: Rectangle): Rectangle; -} -declare class Triangulator { - triangleIndices: number[]; - private _triPrev; - private _triNext; - triangulate(points: Vector2[], arePointsCCW?: boolean): void; - private initialize; - static testPointTriangle(point: Vector2, a: Vector2, b: Vector2, c: Vector2): boolean; -} -declare class Vector2Ext { - static isTriangleCCW(a: Vector2, center: Vector2, c: Vector2): boolean; - static cross(u: Vector2, v: Vector2): number; - static perpendicular(first: Vector2, second: Vector2): Vector2; - static normalize(vec: Vector2): Vector2; - static transformA(sourceArray: Vector2[], sourceIndex: number, matrix: Matrix2D, destinationArray: Vector2[], destinationIndex: number, length: number): void; - static transformR(position: Vector2, matrix: Matrix2D): Vector2; - static transform(sourceArray: Vector2[], matrix: Matrix2D, destinationArray: Vector2[]): void; - static round(vec: Vector2): Vector2; + avg: number; + samples: number; + color: number; + initialized: boolean; + } } diff --git a/demo/libs/framework/framework.js b/demo/libs/framework/framework.js index fb3d7c1e..a1ee37aa 100644 --- a/demo/libs/framework/framework.js +++ b/demo/libs/framework/framework.js @@ -111,6 +111,10 @@ Array.prototype.findAll = function (predicate) { Array.prototype.contains = function (value) { function contains(array, value) { for (var i = 0, len = array.length; i < len; i++) { + if (array[i] instanceof egret.HashObject && value instanceof egret.HashObject) { + if (array[i].hashCode == value.hashCode) + return true; + } if (array[i] == value) { return true; } @@ -214,7 +218,9 @@ Array.prototype.groupBy = function (keySelector) { var keys_1 = []; return array.reduce(function (groups, element, index) { var key = JSON.stringify(keySelector.call(arguments[1], element, index, array)); - var index2 = keys_1.findIndex(function (x) { return x === key; }); + var index2 = keys_1.findIndex(function (x) { + return x === key; + }); if (index2 < 0) { index2 = keys_1.push(key) - 1; } @@ -230,7 +236,9 @@ Array.prototype.groupBy = function (keySelector) { var keys = []; var _loop_1 = function (i, len) { var key = JSON.stringify(keySelector.call(arguments_1[1], array[i], i, array)); - var index = keys.findIndex(function (x) { return x === key; }); + var index = keys.findIndex(function (x) { + return x === key; + }); if (index < 0) { index = keys.push(key) - 1; } @@ -273,2961 +281,4635 @@ Array.prototype.sum = function (selector) { } return sum(this, selector); }; -var PriorityQueueNode = (function () { - function PriorityQueueNode() { - this.priority = 0; - this.insertionIndex = 0; - this.queueIndex = 0; - } - return PriorityQueueNode; -}()); -var AStarPathfinder = (function () { - function AStarPathfinder() { - } - AStarPathfinder.search = function (graph, start, goal) { - var _this = this; - var foundPath = false; - var cameFrom = new Map(); - cameFrom.set(start, start); - var costSoFar = new Map(); - var frontier = new PriorityQueue(1000); - frontier.enqueue(new AStarNode(start), 0); - costSoFar.set(start, 0); - var _loop_2 = function () { - var current = frontier.dequeue(); - if (JSON.stringify(current.data) == JSON.stringify(goal)) { - foundPath = true; - return "break"; - } - graph.getNeighbors(current.data).forEach(function (next) { - var newCost = costSoFar.get(current.data) + graph.cost(current.data, next); - if (!_this.hasKey(costSoFar, next) || newCost < costSoFar.get(next)) { - costSoFar.set(next, newCost); - var priority = newCost + graph.heuristic(next, goal); - frontier.enqueue(new AStarNode(next), priority); - cameFrom.set(next, current.data); +var es; +(function (es) { + var PriorityQueueNode = (function () { + function PriorityQueueNode() { + this.priority = 0; + this.insertionIndex = 0; + this.queueIndex = 0; + } + return PriorityQueueNode; + }()); + es.PriorityQueueNode = PriorityQueueNode; +})(es || (es = {})); +var es; +(function (es) { + var AStarPathfinder = (function () { + function AStarPathfinder() { + } + AStarPathfinder.search = function (graph, start, goal) { + var _this = this; + var foundPath = false; + var cameFrom = new Map(); + cameFrom.set(start, start); + var costSoFar = new Map(); + var frontier = new es.PriorityQueue(1000); + frontier.enqueue(new AStarNode(start), 0); + costSoFar.set(start, 0); + var _loop_2 = function () { + var current = frontier.dequeue(); + if (JSON.stringify(current.data) == JSON.stringify(goal)) { + foundPath = true; + return "break"; } - }); + graph.getNeighbors(current.data).forEach(function (next) { + var newCost = costSoFar.get(current.data) + graph.cost(current.data, next); + if (!_this.hasKey(costSoFar, next) || newCost < costSoFar.get(next)) { + costSoFar.set(next, newCost); + var priority = newCost + graph.heuristic(next, goal); + frontier.enqueue(new AStarNode(next), priority); + cameFrom.set(next, current.data); + } + }); + }; + while (frontier.count > 0) { + var state_1 = _loop_2(); + if (state_1 === "break") + break; + } + return foundPath ? this.recontructPath(cameFrom, start, goal) : null; }; - while (frontier.count > 0) { - var state_1 = _loop_2(); - if (state_1 === "break") - break; + AStarPathfinder.recontructPath = function (cameFrom, start, goal) { + var path = []; + var current = goal; + path.push(goal); + while (current != start) { + current = this.getKey(cameFrom, current); + path.push(current); + } + path.reverse(); + return path; + }; + AStarPathfinder.hasKey = function (map, compareKey) { + var iterator = map.keys(); + var r; + while (r = iterator.next(), !r.done) { + if (JSON.stringify(r.value) == JSON.stringify(compareKey)) + return true; + } + return false; + }; + AStarPathfinder.getKey = function (map, compareKey) { + var iterator = map.keys(); + var valueIterator = map.values(); + var r; + var v; + while (r = iterator.next(), v = valueIterator.next(), !r.done) { + if (JSON.stringify(r.value) == JSON.stringify(compareKey)) + return v.value; + } + return null; + }; + return AStarPathfinder; + }()); + es.AStarPathfinder = AStarPathfinder; + var AStarNode = (function (_super) { + __extends(AStarNode, _super); + function AStarNode(data) { + var _this = _super.call(this) || this; + _this.data = data; + return _this; } - return foundPath ? this.recontructPath(cameFrom, start, goal) : null; - }; - AStarPathfinder.hasKey = function (map, compareKey) { - var iterator = map.keys(); - var r; - while (r = iterator.next(), !r.done) { - if (JSON.stringify(r.value) == JSON.stringify(compareKey)) - return true; + return AStarNode; + }(es.PriorityQueueNode)); + es.AStarNode = AStarNode; +})(es || (es = {})); +var es; +(function (es) { + var AstarGridGraph = (function () { + function AstarGridGraph(width, height) { + this.dirs = [ + new es.Vector2(1, 0), + new es.Vector2(0, -1), + new es.Vector2(-1, 0), + new es.Vector2(0, 1) + ]; + this.walls = []; + this.weightedNodes = []; + this.defaultWeight = 1; + this.weightedNodeWeight = 5; + this._neighbors = new Array(4); + this._width = width; + this._height = height; } - return false; - }; - AStarPathfinder.getKey = function (map, compareKey) { - var iterator = map.keys(); - var valueIterator = map.values(); - var r; - var v; - while (r = iterator.next(), v = valueIterator.next(), !r.done) { - if (JSON.stringify(r.value) == JSON.stringify(compareKey)) - return v.value; + AstarGridGraph.prototype.isNodeInBounds = function (node) { + return 0 <= node.x && node.x < this._width && 0 <= node.y && node.y < this._height; + }; + AstarGridGraph.prototype.isNodePassable = function (node) { + return !this.walls.firstOrDefault(function (wall) { return JSON.stringify(wall) == JSON.stringify(node); }); + }; + AstarGridGraph.prototype.search = function (start, goal) { + return es.AStarPathfinder.search(this, start, goal); + }; + AstarGridGraph.prototype.getNeighbors = function (node) { + var _this = this; + this._neighbors.length = 0; + this.dirs.forEach(function (dir) { + var next = new es.Vector2(node.x + dir.x, node.y + dir.y); + if (_this.isNodeInBounds(next) && _this.isNodePassable(next)) + _this._neighbors.push(next); + }); + return this._neighbors; + }; + AstarGridGraph.prototype.cost = function (from, to) { + return this.weightedNodes.find(function (p) { return JSON.stringify(p) == JSON.stringify(to); }) ? this.weightedNodeWeight : this.defaultWeight; + }; + AstarGridGraph.prototype.heuristic = function (node, goal) { + return Math.abs(node.x - goal.x) + Math.abs(node.y - goal.y); + }; + return AstarGridGraph; + }()); + es.AstarGridGraph = AstarGridGraph; +})(es || (es = {})); +var es; +(function (es) { + var PriorityQueue = (function () { + function PriorityQueue(maxNodes) { + this._numNodes = 0; + this._nodes = new Array(maxNodes + 1); + this._numNodesEverEnqueued = 0; } - return null; - }; - AStarPathfinder.recontructPath = function (cameFrom, start, goal) { - var path = []; - var current = goal; - path.push(goal); - while (current != start) { - current = this.getKey(cameFrom, current); - path.push(current); - } - path.reverse(); - return path; - }; - return AStarPathfinder; -}()); -var AStarNode = (function (_super) { - __extends(AStarNode, _super); - function AStarNode(data) { - var _this = _super.call(this) || this; - _this.data = data; - return _this; - } - return AStarNode; -}(PriorityQueueNode)); -var AstarGridGraph = (function () { - function AstarGridGraph(width, height) { - this.dirs = [ - new Vector2(1, 0), - new Vector2(0, -1), - new Vector2(-1, 0), - new Vector2(0, 1) - ]; - this.walls = []; - this.weightedNodes = []; - this.defaultWeight = 1; - this.weightedNodeWeight = 5; - this._neighbors = new Array(4); - this._width = width; - this._height = height; - } - AstarGridGraph.prototype.isNodeInBounds = function (node) { - return 0 <= node.x && node.x < this._width && 0 <= node.y && node.y < this._height; - }; - AstarGridGraph.prototype.isNodePassable = function (node) { - return !this.walls.firstOrDefault(function (wall) { return JSON.stringify(wall) == JSON.stringify(node); }); - }; - AstarGridGraph.prototype.search = function (start, goal) { - return AStarPathfinder.search(this, start, goal); - }; - AstarGridGraph.prototype.getNeighbors = function (node) { - var _this = this; - this._neighbors.length = 0; - this.dirs.forEach(function (dir) { - var next = new Vector2(node.x + dir.x, node.y + dir.y); - if (_this.isNodeInBounds(next) && _this.isNodePassable(next)) - _this._neighbors.push(next); + Object.defineProperty(PriorityQueue.prototype, "count", { + get: function () { + return this._numNodes; + }, + enumerable: true, + configurable: true }); - return this._neighbors; - }; - AstarGridGraph.prototype.cost = function (from, to) { - return this.weightedNodes.find(function (p) { return JSON.stringify(p) == JSON.stringify(to); }) ? this.weightedNodeWeight : this.defaultWeight; - }; - AstarGridGraph.prototype.heuristic = function (node, goal) { - return Math.abs(node.x - goal.x) + Math.abs(node.y - goal.y); - }; - return AstarGridGraph; -}()); -var PriorityQueue = (function () { - function PriorityQueue(maxNodes) { - this._numNodes = 0; - this._nodes = new Array(maxNodes + 1); - this._numNodesEverEnqueued = 0; - } - PriorityQueue.prototype.clear = function () { - this._nodes.splice(1, this._numNodes); - this._numNodes = 0; - }; - Object.defineProperty(PriorityQueue.prototype, "count", { - get: function () { - return this._numNodes; - }, - enumerable: true, - configurable: true - }); - PriorityQueue.prototype.contains = function (node) { - return (this._nodes[node.queueIndex] == node); - }; - PriorityQueue.prototype.enqueue = function (node, priority) { - node.priority = priority; - this._numNodes++; - this._nodes[this._numNodes] = node; - node.queueIndex = this._numNodes; - node.insertionIndex = this._numNodesEverEnqueued++; - this.cascadeUp(this._nodes[this._numNodes]); - }; - PriorityQueue.prototype.dequeue = function () { - var returnMe = this._nodes[1]; - this.remove(returnMe); - return returnMe; - }; - PriorityQueue.prototype.remove = function (node) { - if (node.queueIndex == this._numNodes) { - this._nodes[this._numNodes] = null; + Object.defineProperty(PriorityQueue.prototype, "maxSize", { + get: function () { + return this._nodes.length - 1; + }, + enumerable: true, + configurable: true + }); + PriorityQueue.prototype.clear = function () { + this._nodes.splice(1, this._numNodes); + this._numNodes = 0; + }; + PriorityQueue.prototype.contains = function (node) { + if (!node) { + console.error("node cannot be null"); + return false; + } + if (node.queueIndex < 0 || node.queueIndex >= this._nodes.length) { + console.error("node.QueueIndex has been corrupted. Did you change it manually? Or add this node to another queue?"); + return false; + } + return (this._nodes[node.queueIndex] == node); + }; + PriorityQueue.prototype.enqueue = function (node, priority) { + node.priority = priority; + this._numNodes++; + this._nodes[this._numNodes] = node; + node.queueIndex = this._numNodes; + node.insertionIndex = this._numNodesEverEnqueued++; + this.cascadeUp(this._nodes[this._numNodes]); + }; + PriorityQueue.prototype.dequeue = function () { + var returnMe = this._nodes[1]; + this.remove(returnMe); + return returnMe; + }; + PriorityQueue.prototype.remove = function (node) { + if (node.queueIndex == this._numNodes) { + this._nodes[this._numNodes] = null; + this._numNodes--; + return; + } + var formerLastNode = this._nodes[this._numNodes]; + this.swap(node, formerLastNode); + delete this._nodes[this._numNodes]; this._numNodes--; - return; - } - var formerLastNode = this._nodes[this._numNodes]; - this.swap(node, formerLastNode); - delete this._nodes[this._numNodes]; - this._numNodes--; - this.onNodeUpdated(formerLastNode); - }; - PriorityQueue.prototype.isValidQueue = function () { - for (var i = 1; i < this._nodes.length; i++) { - if (this._nodes[i]) { - var childLeftIndex = 2 * i; - if (childLeftIndex < this._nodes.length && this._nodes[childLeftIndex] && - this.hasHigherPriority(this._nodes[childLeftIndex], this._nodes[i])) - return false; + this.onNodeUpdated(formerLastNode); + }; + PriorityQueue.prototype.isValidQueue = function () { + for (var i = 1; i < this._nodes.length; i++) { + if (this._nodes[i]) { + var childLeftIndex = 2 * i; + if (childLeftIndex < this._nodes.length && this._nodes[childLeftIndex] && + this.hasHigherPriority(this._nodes[childLeftIndex], this._nodes[i])) + return false; + var childRightIndex = childLeftIndex + 1; + if (childRightIndex < this._nodes.length && this._nodes[childRightIndex] && + this.hasHigherPriority(this._nodes[childRightIndex], this._nodes[i])) + return false; + } + } + return true; + }; + PriorityQueue.prototype.onNodeUpdated = function (node) { + var parentIndex = Math.floor(node.queueIndex / 2); + var parentNode = this._nodes[parentIndex]; + if (parentIndex > 0 && this.hasHigherPriority(node, parentNode)) { + this.cascadeUp(node); + } + else { + this.cascadeDown(node); + } + }; + PriorityQueue.prototype.cascadeDown = function (node) { + var newParent; + var finalQueueIndex = node.queueIndex; + while (true) { + newParent = node; + var childLeftIndex = 2 * finalQueueIndex; + if (childLeftIndex > this._numNodes) { + node.queueIndex = finalQueueIndex; + this._nodes[finalQueueIndex] = node; + break; + } + var childLeft = this._nodes[childLeftIndex]; + if (this.hasHigherPriority(childLeft, newParent)) { + newParent = childLeft; + } var childRightIndex = childLeftIndex + 1; - if (childRightIndex < this._nodes.length && this._nodes[childRightIndex] && - this.hasHigherPriority(this._nodes[childRightIndex], this._nodes[i])) - return false; - } - } - return true; - }; - PriorityQueue.prototype.onNodeUpdated = function (node) { - var parentIndex = Math.floor(node.queueIndex / 2); - var parentNode = this._nodes[parentIndex]; - if (parentIndex > 0 && this.hasHigherPriority(node, parentNode)) { - this.cascadeUp(node); - } - else { - this.cascadeDown(node); - } - }; - PriorityQueue.prototype.cascadeDown = function (node) { - var newParent; - var finalQueueIndex = node.queueIndex; - while (true) { - newParent = node; - var childLeftIndex = 2 * finalQueueIndex; - if (childLeftIndex > this._numNodes) { - node.queueIndex = finalQueueIndex; - this._nodes[finalQueueIndex] = node; - break; - } - var childLeft = this._nodes[childLeftIndex]; - if (this.hasHigherPriority(childLeft, newParent)) { - newParent = childLeft; - } - var childRightIndex = childLeftIndex + 1; - if (childRightIndex <= this._numNodes) { - var childRight = this._nodes[childRightIndex]; - if (this.hasHigherPriority(childRight, newParent)) { - newParent = childRight; + if (childRightIndex <= this._numNodes) { + var childRight = this._nodes[childRightIndex]; + if (this.hasHigherPriority(childRight, newParent)) { + newParent = childRight; + } + } + if (newParent != node) { + this._nodes[finalQueueIndex] = newParent; + var temp = newParent.queueIndex; + newParent.queueIndex = finalQueueIndex; + finalQueueIndex = temp; + } + else { + node.queueIndex = finalQueueIndex; + this._nodes[finalQueueIndex] = node; + break; } } - if (newParent != node) { - this._nodes[finalQueueIndex] = newParent; - var temp = newParent.queueIndex; - newParent.queueIndex = finalQueueIndex; - finalQueueIndex = temp; - } - else { - node.queueIndex = finalQueueIndex; - this._nodes[finalQueueIndex] = node; - break; - } - } - }; - PriorityQueue.prototype.cascadeUp = function (node) { - var parent = Math.floor(node.queueIndex / 2); - while (parent >= 1) { - var parentNode = this._nodes[parent]; - if (this.hasHigherPriority(parentNode, node)) - break; - this.swap(node, parentNode); - parent = Math.floor(node.queueIndex / 2); - } - }; - PriorityQueue.prototype.swap = function (node1, node2) { - this._nodes[node1.queueIndex] = node2; - this._nodes[node2.queueIndex] = node1; - var temp = node1.queueIndex; - node1.queueIndex = node2.queueIndex; - node2.queueIndex = temp; - }; - PriorityQueue.prototype.hasHigherPriority = function (higher, lower) { - return (higher.priority < lower.priority || - (higher.priority == lower.priority && higher.insertionIndex < lower.insertionIndex)); - }; - return PriorityQueue; -}()); -var BreadthFirstPathfinder = (function () { - function BreadthFirstPathfinder() { - } - BreadthFirstPathfinder.search = function (graph, start, goal) { - var _this = this; - var foundPath = false; - var frontier = []; - frontier.unshift(start); - var cameFrom = new Map(); - cameFrom.set(start, start); - var _loop_3 = function () { - var current = frontier.shift(); - if (JSON.stringify(current) == JSON.stringify(goal)) { - foundPath = true; - return "break"; - } - graph.getNeighbors(current).forEach(function (next) { - if (!_this.hasKey(cameFrom, next)) { - frontier.unshift(next); - cameFrom.set(next, current); - } - }); }; - while (frontier.length > 0) { - var state_2 = _loop_3(); - if (state_2 === "break") - break; - } - return foundPath ? AStarPathfinder.recontructPath(cameFrom, start, goal) : null; - }; - BreadthFirstPathfinder.hasKey = function (map, compareKey) { - var iterator = map.keys(); - var r; - while (r = iterator.next(), !r.done) { - if (JSON.stringify(r.value) == JSON.stringify(compareKey)) - return true; - } - return false; - }; - return BreadthFirstPathfinder; -}()); -var UnweightedGraph = (function () { - function UnweightedGraph() { - this.edges = new Map(); - } - UnweightedGraph.prototype.addEdgesForNode = function (node, edges) { - this.edges.set(node, edges); - return this; - }; - UnweightedGraph.prototype.getNeighbors = function (node) { - return this.edges.get(node); - }; - return UnweightedGraph; -}()); -var Vector2 = (function () { - function Vector2(x, y) { - this.x = 0; - this.y = 0; - this.x = x ? x : 0; - this.y = y ? y : this.x; - } - Object.defineProperty(Vector2, "zero", { - get: function () { - return Vector2.zeroVector2; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Vector2, "one", { - get: function () { - return Vector2.unitVector2; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Vector2, "unitX", { - get: function () { - return Vector2.unitXVector; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Vector2, "unitY", { - get: function () { - return Vector2.unitYVector; - }, - enumerable: true, - configurable: true - }); - Vector2.add = function (value1, value2) { - var result = new Vector2(0, 0); - result.x = value1.x + value2.x; - result.y = value1.y + value2.y; - return result; - }; - Vector2.divide = function (value1, value2) { - var result = new Vector2(0, 0); - result.x = value1.x / value2.x; - result.y = value1.y / value2.y; - return result; - }; - Vector2.multiply = function (value1, value2) { - var result = new Vector2(0, 0); - result.x = value1.x * value2.x; - result.y = value1.y * value2.y; - return result; - }; - Vector2.subtract = function (value1, value2) { - var result = new Vector2(0, 0); - result.x = value1.x - value2.x; - result.y = value1.y - value2.y; - return result; - }; - Vector2.prototype.normalize = function () { - var val = 1 / Math.sqrt((this.x * this.x) + (this.y * this.y)); - this.x *= val; - this.y *= val; - }; - Vector2.prototype.length = function () { - return Math.sqrt((this.x * this.x) + (this.y * this.y)); - }; - Vector2.prototype.round = function () { - return new Vector2(Math.round(this.x), Math.round(this.y)); - }; - Vector2.normalize = function (value) { - var val = 1 / Math.sqrt((value.x * value.x) + (value.y * value.y)); - value.x *= val; - value.y *= val; - return value; - }; - Vector2.dot = function (value1, value2) { - return (value1.x * value2.x) + (value1.y * value2.y); - }; - Vector2.distanceSquared = function (value1, value2) { - var v1 = value1.x - value2.x, v2 = value1.y - value2.y; - return (v1 * v1) + (v2 * v2); - }; - Vector2.clamp = function (value1, min, max) { - return new Vector2(MathHelper.clamp(value1.x, min.x, max.x), MathHelper.clamp(value1.y, min.y, max.y)); - }; - Vector2.lerp = function (value1, value2, amount) { - return new Vector2(MathHelper.lerp(value1.x, value2.x, amount), MathHelper.lerp(value1.y, value2.y, amount)); - }; - Vector2.transform = function (position, matrix) { - return new Vector2((position.x * matrix.m11) + (position.y * matrix.m21), (position.x * matrix.m12) + (position.y * matrix.m22)); - }; - Vector2.distance = function (value1, value2) { - var v1 = value1.x - value2.x, v2 = value1.y - value2.y; - return Math.sqrt((v1 * v1) + (v2 * v2)); - }; - Vector2.negate = function (value) { - var result = new Vector2(); - result.x = -value.x; - result.y = -value.y; - return result; - }; - Vector2.unitYVector = new Vector2(0, 1); - Vector2.unitXVector = new Vector2(1, 0); - Vector2.unitVector2 = new Vector2(1, 1); - Vector2.zeroVector2 = new Vector2(0, 0); - return Vector2; -}()); -var UnweightedGridGraph = (function () { - function UnweightedGridGraph(width, height, allowDiagonalSearch) { - if (allowDiagonalSearch === void 0) { allowDiagonalSearch = false; } - this.walls = []; - this._neighbors = new Array(4); - this._width = width; - this._hegiht = height; - this._dirs = allowDiagonalSearch ? UnweightedGridGraph.COMPASS_DIRS : UnweightedGridGraph.CARDINAL_DIRS; - } - UnweightedGridGraph.prototype.isNodeInBounds = function (node) { - return 0 <= node.x && node.x < this._width && 0 <= node.y && node.y < this._hegiht; - }; - UnweightedGridGraph.prototype.isNodePassable = function (node) { - return !this.walls.firstOrDefault(function (wall) { return JSON.stringify(wall) == JSON.stringify(node); }); - }; - UnweightedGridGraph.prototype.getNeighbors = function (node) { - var _this = this; - this._neighbors.length = 0; - this._dirs.forEach(function (dir) { - var next = new Vector2(node.x + dir.x, node.y + dir.y); - if (_this.isNodeInBounds(next) && _this.isNodePassable(next)) - _this._neighbors.push(next); - }); - return this._neighbors; - }; - UnweightedGridGraph.prototype.search = function (start, goal) { - return BreadthFirstPathfinder.search(this, start, goal); - }; - UnweightedGridGraph.CARDINAL_DIRS = [ - new Vector2(1, 0), - new Vector2(0, -1), - new Vector2(-1, 0), - new Vector2(0, -1) - ]; - UnweightedGridGraph.COMPASS_DIRS = [ - new Vector2(1, 0), - new Vector2(1, -1), - new Vector2(0, -1), - new Vector2(-1, -1), - new Vector2(-1, 0), - new Vector2(-1, 1), - new Vector2(0, 1), - new Vector2(1, 1), - ]; - return UnweightedGridGraph; -}()); -var WeightedGridGraph = (function () { - function WeightedGridGraph(width, height, allowDiagonalSearch) { - if (allowDiagonalSearch === void 0) { allowDiagonalSearch = false; } - this.walls = []; - this.weightedNodes = []; - this.defaultWeight = 1; - this.weightedNodeWeight = 5; - this._neighbors = new Array(4); - this._width = width; - this._height = height; - this._dirs = allowDiagonalSearch ? WeightedGridGraph.COMPASS_DIRS : WeightedGridGraph.CARDINAL_DIRS; - } - WeightedGridGraph.prototype.isNodeInBounds = function (node) { - return 0 <= node.x && node.x < this._width && 0 <= node.y && node.y < this._height; - }; - WeightedGridGraph.prototype.isNodePassable = function (node) { - return !this.walls.firstOrDefault(function (wall) { return JSON.stringify(wall) == JSON.stringify(node); }); - }; - WeightedGridGraph.prototype.search = function (start, goal) { - return WeightedPathfinder.search(this, start, goal); - }; - WeightedGridGraph.prototype.getNeighbors = function (node) { - var _this = this; - this._neighbors.length = 0; - this._dirs.forEach(function (dir) { - var next = new Vector2(node.x + dir.x, node.y + dir.y); - if (_this.isNodeInBounds(next) && _this.isNodePassable(next)) - _this._neighbors.push(next); - }); - return this._neighbors; - }; - WeightedGridGraph.prototype.cost = function (from, to) { - return this.weightedNodes.find(function (t) { return JSON.stringify(t) == JSON.stringify(to); }) ? this.weightedNodeWeight : this.defaultWeight; - }; - WeightedGridGraph.CARDINAL_DIRS = [ - new Vector2(1, 0), - new Vector2(0, -1), - new Vector2(-1, 0), - new Vector2(0, 1) - ]; - WeightedGridGraph.COMPASS_DIRS = [ - new Vector2(1, 0), - new Vector2(1, -1), - new Vector2(0, -1), - new Vector2(-1, -1), - new Vector2(-1, 0), - new Vector2(-1, 1), - new Vector2(0, 1), - new Vector2(1, 1), - ]; - return WeightedGridGraph; -}()); -var WeightedNode = (function (_super) { - __extends(WeightedNode, _super); - function WeightedNode(data) { - var _this = _super.call(this) || this; - _this.data = data; - return _this; - } - return WeightedNode; -}(PriorityQueueNode)); -var WeightedPathfinder = (function () { - function WeightedPathfinder() { - } - WeightedPathfinder.search = function (graph, start, goal) { - var _this = this; - var foundPath = false; - var cameFrom = new Map(); - cameFrom.set(start, start); - var costSoFar = new Map(); - var frontier = new PriorityQueue(1000); - frontier.enqueue(new WeightedNode(start), 0); - costSoFar.set(start, 0); - var _loop_4 = function () { - var current = frontier.dequeue(); - if (JSON.stringify(current.data) == JSON.stringify(goal)) { - foundPath = true; - return "break"; + PriorityQueue.prototype.cascadeUp = function (node) { + var parent = Math.floor(node.queueIndex / 2); + while (parent >= 1) { + var parentNode = this._nodes[parent]; + if (this.hasHigherPriority(parentNode, node)) + break; + this.swap(node, parentNode); + parent = Math.floor(node.queueIndex / 2); } - graph.getNeighbors(current.data).forEach(function (next) { - var newCost = costSoFar.get(current.data) + graph.cost(current.data, next); - if (!_this.hasKey(costSoFar, next) || newCost < costSoFar.get(next)) { - costSoFar.set(next, newCost); - var priprity = newCost; - frontier.enqueue(new WeightedNode(next), priprity); - cameFrom.set(next, current.data); - } - }); }; - while (frontier.count > 0) { - var state_3 = _loop_4(); - if (state_3 === "break") - break; + PriorityQueue.prototype.swap = function (node1, node2) { + this._nodes[node1.queueIndex] = node2; + this._nodes[node2.queueIndex] = node1; + var temp = node1.queueIndex; + node1.queueIndex = node2.queueIndex; + node2.queueIndex = temp; + }; + PriorityQueue.prototype.hasHigherPriority = function (higher, lower) { + return (higher.priority < lower.priority || + (higher.priority == lower.priority && higher.insertionIndex < lower.insertionIndex)); + }; + return PriorityQueue; + }()); + es.PriorityQueue = PriorityQueue; +})(es || (es = {})); +var es; +(function (es) { + var BreadthFirstPathfinder = (function () { + function BreadthFirstPathfinder() { } - return foundPath ? this.recontructPath(cameFrom, start, goal) : null; - }; - WeightedPathfinder.hasKey = function (map, compareKey) { - var iterator = map.keys(); - var r; - while (r = iterator.next(), !r.done) { - if (JSON.stringify(r.value) == JSON.stringify(compareKey)) - return true; - } - return false; - }; - WeightedPathfinder.getKey = function (map, compareKey) { - var iterator = map.keys(); - var valueIterator = map.values(); - var r; - var v; - while (r = iterator.next(), v = valueIterator.next(), !r.done) { - if (JSON.stringify(r.value) == JSON.stringify(compareKey)) - return v.value; - } - return null; - }; - WeightedPathfinder.recontructPath = function (cameFrom, start, goal) { - var path = []; - var current = goal; - path.push(goal); - while (current != start) { - current = this.getKey(cameFrom, current); - path.push(current); - } - path.reverse(); - return path; - }; - return WeightedPathfinder; -}()); -var DebugDefaults = (function () { - function DebugDefaults() { - } - DebugDefaults.verletParticle = 0xDC345E; - DebugDefaults.verletConstraintEdge = 0x433E36; - return DebugDefaults; -}()); -var Component = (function (_super) { - __extends(Component, _super); - function Component() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this._enabled = true; - _this.updateInterval = 1; - return _this; - } - Object.defineProperty(Component.prototype, "enabled", { - get: function () { - return this.entity ? this.entity.enabled && this._enabled : this._enabled; - }, - set: function (value) { - this.setEnabled(value); - }, - enumerable: true, - configurable: true - }); - Component.prototype.setEnabled = function (isEnabled) { - if (this._enabled != isEnabled) { - this._enabled = isEnabled; - if (this._enabled) { - this.onEnabled(); + BreadthFirstPathfinder.search = function (graph, start, goal) { + var _this = this; + var foundPath = false; + var frontier = []; + frontier.unshift(start); + var cameFrom = new Map(); + cameFrom.set(start, start); + var _loop_3 = function () { + var current = frontier.shift(); + if (JSON.stringify(current) == JSON.stringify(goal)) { + foundPath = true; + return "break"; + } + graph.getNeighbors(current).forEach(function (next) { + if (!_this.hasKey(cameFrom, next)) { + frontier.unshift(next); + cameFrom.set(next, current); + } + }); + }; + while (frontier.length > 0) { + var state_2 = _loop_3(); + if (state_2 === "break") + break; } - else { - this.onDisabled(); + return foundPath ? es.AStarPathfinder.recontructPath(cameFrom, start, goal) : null; + }; + BreadthFirstPathfinder.hasKey = function (map, compareKey) { + var iterator = map.keys(); + var r; + while (r = iterator.next(), !r.done) { + if (JSON.stringify(r.value) == JSON.stringify(compareKey)) + return true; } + return false; + }; + return BreadthFirstPathfinder; + }()); + es.BreadthFirstPathfinder = BreadthFirstPathfinder; +})(es || (es = {})); +var es; +(function (es) { + var UnweightedGraph = (function () { + function UnweightedGraph() { + this.edges = new Map(); } - return this; - }; - Component.prototype.initialize = function () { - }; - Component.prototype.onAddedToEntity = function () { - }; - Component.prototype.onRemovedFromEntity = function () { - }; - Component.prototype.onEnabled = function () { - }; - Component.prototype.onDisabled = function () { - }; - Component.prototype.update = function () { - }; - Component.prototype.debugRender = function () { - }; - Component.prototype.onEntityTransformChanged = function (comp) { - }; - Component.prototype.registerComponent = function () { - this.entity.componentBits.set(ComponentTypeManager.getIndexFor(this), false); - this.entity.scene.entityProcessors.onComponentAdded(this.entity); - }; - Component.prototype.deregisterComponent = function () { - this.entity.componentBits.set(ComponentTypeManager.getIndexFor(this)); - this.entity.scene.entityProcessors.onComponentRemoved(this.entity); - }; - return Component; -}(egret.DisplayObjectContainer)); -var Entity = (function (_super) { - __extends(Entity, _super); - function Entity(name) { - var _this = _super.call(this) || this; - _this._updateOrder = 0; - _this._enabled = true; - _this._tag = 0; - _this.name = name; - _this.components = new ComponentList(_this); - _this.id = Entity._idGenerator++; - _this.componentBits = new BitSet(); - return _this; - } - Object.defineProperty(Entity.prototype, "isDestoryed", { - get: function () { - return this._isDestoryed; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Entity.prototype, "position", { - get: function () { - return new Vector2(this.x, this.y); - }, - set: function (value) { - this.$setX(value.x); - this.$setY(value.y); - this.onEntityTransformChanged(TransformComponent.position); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Entity.prototype, "scale", { - get: function () { - return new Vector2(this.scaleX, this.scaleY); - }, - set: function (value) { - this.$setScaleX(value.x); - this.$setScaleY(value.y); - this.onEntityTransformChanged(TransformComponent.scale); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Entity.prototype, "rotation", { - set: function (value) { - this.$setRotation(value); - this.onEntityTransformChanged(TransformComponent.rotation); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Entity.prototype, "enabled", { - get: function () { - return this._enabled; - }, - set: function (value) { - this.setEnabled(value); - }, - enumerable: true, - configurable: true - }); - Entity.prototype.setEnabled = function (isEnabled) { - if (this._enabled != isEnabled) { - this._enabled = isEnabled; + UnweightedGraph.prototype.addEdgesForNode = function (node, edges) { + this.edges.set(node, edges); + return this; + }; + UnweightedGraph.prototype.getNeighbors = function (node) { + return this.edges.get(node); + }; + return UnweightedGraph; + }()); + es.UnweightedGraph = UnweightedGraph; +})(es || (es = {})); +var es; +(function (es) { + var Vector2 = (function () { + function Vector2(x, y) { + this.x = 0; + this.y = 0; + this.x = x ? x : 0; + this.y = y != undefined ? y : this.x; } - return this; - }; - Object.defineProperty(Entity.prototype, "tag", { - get: function () { - return this._tag; - }, - set: function (value) { - this.setTag(value); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Entity.prototype, "stage", { - get: function () { - if (!this.scene) - return null; - return this.scene.stage; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Entity.prototype, "updateOrder", { - get: function () { - return this._updateOrder; - }, - set: function (value) { - this.setUpdateOrder(value); - }, - enumerable: true, - configurable: true - }); - Entity.prototype.roundPosition = function () { - this.position = Vector2Ext.round(this.position); - }; - Entity.prototype.setUpdateOrder = function (updateOrder) { - if (this._updateOrder != updateOrder) { - this._updateOrder = updateOrder; - if (this.scene) { + Object.defineProperty(Vector2, "zero", { + get: function () { + return Vector2.zeroVector2; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Vector2, "one", { + get: function () { + return Vector2.unitVector2; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Vector2, "unitX", { + get: function () { + return Vector2.unitXVector; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Vector2, "unitY", { + get: function () { + return Vector2.unitYVector; + }, + enumerable: true, + configurable: true + }); + Vector2.add = function (value1, value2) { + var result = new Vector2(0, 0); + result.x = value1.x + value2.x; + result.y = value1.y + value2.y; + return result; + }; + Vector2.divide = function (value1, value2) { + var result = new Vector2(0, 0); + result.x = value1.x / value2.x; + result.y = value1.y / value2.y; + return result; + }; + Vector2.multiply = function (value1, value2) { + var result = new Vector2(0, 0); + result.x = value1.x * value2.x; + result.y = value1.y * value2.y; + return result; + }; + Vector2.subtract = function (value1, value2) { + var result = new Vector2(0, 0); + result.x = value1.x - value2.x; + result.y = value1.y - value2.y; + return result; + }; + Vector2.normalize = function (value) { + var val = 1 / Math.sqrt((value.x * value.x) + (value.y * value.y)); + value.x *= val; + value.y *= val; + return value; + }; + Vector2.dot = function (value1, value2) { + return (value1.x * value2.x) + (value1.y * value2.y); + }; + Vector2.distanceSquared = function (value1, value2) { + var v1 = value1.x - value2.x, v2 = value1.y - value2.y; + return (v1 * v1) + (v2 * v2); + }; + Vector2.clamp = function (value1, min, max) { + return new Vector2(es.MathHelper.clamp(value1.x, min.x, max.x), es.MathHelper.clamp(value1.y, min.y, max.y)); + }; + Vector2.lerp = function (value1, value2, amount) { + return new Vector2(es.MathHelper.lerp(value1.x, value2.x, amount), es.MathHelper.lerp(value1.y, value2.y, amount)); + }; + Vector2.transform = function (position, matrix) { + return new Vector2((position.x * matrix.m11) + (position.y * matrix.m21) + matrix.m31, (position.x * matrix.m12) + (position.y * matrix.m22) + matrix.m32); + }; + Vector2.distance = function (value1, value2) { + var v1 = value1.x - value2.x, v2 = value1.y - value2.y; + return Math.sqrt((v1 * v1) + (v2 * v2)); + }; + Vector2.negate = function (value) { + var result = new Vector2(); + result.x = -value.x; + result.y = -value.y; + return result; + }; + Vector2.prototype.add = function (value) { + this.x += value.x; + this.y += value.y; + return this; + }; + Vector2.prototype.divide = function (value) { + this.x /= value.x; + this.y /= value.y; + return this; + }; + Vector2.prototype.multiply = function (value) { + this.x *= value.x; + this.y *= value.y; + return this; + }; + Vector2.prototype.subtract = function (value) { + this.x -= value.x; + this.y -= value.y; + return this; + }; + Vector2.prototype.normalize = function () { + var val = 1 / Math.sqrt((this.x * this.x) + (this.y * this.y)); + this.x *= val; + this.y *= val; + return this; + }; + Vector2.prototype.length = function () { + return Math.sqrt((this.x * this.x) + (this.y * this.y)); + }; + Vector2.prototype.lengthSquared = function () { + return (this.x * this.x) + (this.y * this.y); + }; + Vector2.prototype.round = function () { + return new Vector2(Math.round(this.x), Math.round(this.y)); + }; + Vector2.prototype.equals = function (other) { + return other.x == this.x && other.y == this.y; + }; + Vector2.unitYVector = new Vector2(0, 1); + Vector2.unitXVector = new Vector2(1, 0); + Vector2.unitVector2 = new Vector2(1, 1); + Vector2.zeroVector2 = new Vector2(0, 0); + return Vector2; + }()); + es.Vector2 = Vector2; +})(es || (es = {})); +var es; +(function (es) { + var UnweightedGridGraph = (function () { + function UnweightedGridGraph(width, height, allowDiagonalSearch) { + if (allowDiagonalSearch === void 0) { allowDiagonalSearch = false; } + this.walls = []; + this._neighbors = new Array(4); + this._width = width; + this._hegiht = height; + this._dirs = allowDiagonalSearch ? UnweightedGridGraph.COMPASS_DIRS : UnweightedGridGraph.CARDINAL_DIRS; + } + UnweightedGridGraph.prototype.isNodeInBounds = function (node) { + return 0 <= node.x && node.x < this._width && 0 <= node.y && node.y < this._hegiht; + }; + UnweightedGridGraph.prototype.isNodePassable = function (node) { + return !this.walls.firstOrDefault(function (wall) { return JSON.stringify(wall) == JSON.stringify(node); }); + }; + UnweightedGridGraph.prototype.getNeighbors = function (node) { + var _this = this; + this._neighbors.length = 0; + this._dirs.forEach(function (dir) { + var next = new es.Vector2(node.x + dir.x, node.y + dir.y); + if (_this.isNodeInBounds(next) && _this.isNodePassable(next)) + _this._neighbors.push(next); + }); + return this._neighbors; + }; + UnweightedGridGraph.prototype.search = function (start, goal) { + return es.BreadthFirstPathfinder.search(this, start, goal); + }; + UnweightedGridGraph.CARDINAL_DIRS = [ + new es.Vector2(1, 0), + new es.Vector2(0, -1), + new es.Vector2(-1, 0), + new es.Vector2(0, -1) + ]; + UnweightedGridGraph.COMPASS_DIRS = [ + new es.Vector2(1, 0), + new es.Vector2(1, -1), + new es.Vector2(0, -1), + new es.Vector2(-1, -1), + new es.Vector2(-1, 0), + new es.Vector2(-1, 1), + new es.Vector2(0, 1), + new es.Vector2(1, 1), + ]; + return UnweightedGridGraph; + }()); + es.UnweightedGridGraph = UnweightedGridGraph; +})(es || (es = {})); +var es; +(function (es) { + var WeightedGridGraph = (function () { + function WeightedGridGraph(width, height, allowDiagonalSearch) { + if (allowDiagonalSearch === void 0) { allowDiagonalSearch = false; } + this.walls = []; + this.weightedNodes = []; + this.defaultWeight = 1; + this.weightedNodeWeight = 5; + this._neighbors = new Array(4); + this._width = width; + this._height = height; + this._dirs = allowDiagonalSearch ? WeightedGridGraph.COMPASS_DIRS : WeightedGridGraph.CARDINAL_DIRS; + } + WeightedGridGraph.prototype.isNodeInBounds = function (node) { + return 0 <= node.x && node.x < this._width && 0 <= node.y && node.y < this._height; + }; + WeightedGridGraph.prototype.isNodePassable = function (node) { + return !this.walls.firstOrDefault(function (wall) { return JSON.stringify(wall) == JSON.stringify(node); }); + }; + WeightedGridGraph.prototype.search = function (start, goal) { + return es.WeightedPathfinder.search(this, start, goal); + }; + WeightedGridGraph.prototype.getNeighbors = function (node) { + var _this = this; + this._neighbors.length = 0; + this._dirs.forEach(function (dir) { + var next = new es.Vector2(node.x + dir.x, node.y + dir.y); + if (_this.isNodeInBounds(next) && _this.isNodePassable(next)) + _this._neighbors.push(next); + }); + return this._neighbors; + }; + WeightedGridGraph.prototype.cost = function (from, to) { + return this.weightedNodes.find(function (t) { return JSON.stringify(t) == JSON.stringify(to); }) ? this.weightedNodeWeight : this.defaultWeight; + }; + WeightedGridGraph.CARDINAL_DIRS = [ + new es.Vector2(1, 0), + new es.Vector2(0, -1), + new es.Vector2(-1, 0), + new es.Vector2(0, 1) + ]; + WeightedGridGraph.COMPASS_DIRS = [ + new es.Vector2(1, 0), + new es.Vector2(1, -1), + new es.Vector2(0, -1), + new es.Vector2(-1, -1), + new es.Vector2(-1, 0), + new es.Vector2(-1, 1), + new es.Vector2(0, 1), + new es.Vector2(1, 1), + ]; + return WeightedGridGraph; + }()); + es.WeightedGridGraph = WeightedGridGraph; +})(es || (es = {})); +var es; +(function (es) { + var WeightedNode = (function (_super) { + __extends(WeightedNode, _super); + function WeightedNode(data) { + var _this = _super.call(this) || this; + _this.data = data; + return _this; + } + return WeightedNode; + }(es.PriorityQueueNode)); + es.WeightedNode = WeightedNode; + var WeightedPathfinder = (function () { + function WeightedPathfinder() { + } + WeightedPathfinder.search = function (graph, start, goal) { + var _this = this; + var foundPath = false; + var cameFrom = new Map(); + cameFrom.set(start, start); + var costSoFar = new Map(); + var frontier = new es.PriorityQueue(1000); + frontier.enqueue(new WeightedNode(start), 0); + costSoFar.set(start, 0); + var _loop_4 = function () { + var current = frontier.dequeue(); + if (JSON.stringify(current.data) == JSON.stringify(goal)) { + foundPath = true; + return "break"; + } + graph.getNeighbors(current.data).forEach(function (next) { + var newCost = costSoFar.get(current.data) + graph.cost(current.data, next); + if (!_this.hasKey(costSoFar, next) || newCost < costSoFar.get(next)) { + costSoFar.set(next, newCost); + var priprity = newCost; + frontier.enqueue(new WeightedNode(next), priprity); + cameFrom.set(next, current.data); + } + }); + }; + while (frontier.count > 0) { + var state_3 = _loop_4(); + if (state_3 === "break") + break; + } + return foundPath ? this.recontructPath(cameFrom, start, goal) : null; + }; + WeightedPathfinder.recontructPath = function (cameFrom, start, goal) { + var path = []; + var current = goal; + path.push(goal); + while (current != start) { + current = this.getKey(cameFrom, current); + path.push(current); + } + path.reverse(); + return path; + }; + WeightedPathfinder.hasKey = function (map, compareKey) { + var iterator = map.keys(); + var r; + while (r = iterator.next(), !r.done) { + if (JSON.stringify(r.value) == JSON.stringify(compareKey)) + return true; + } + return false; + }; + WeightedPathfinder.getKey = function (map, compareKey) { + var iterator = map.keys(); + var valueIterator = map.values(); + var r; + var v; + while (r = iterator.next(), v = valueIterator.next(), !r.done) { + if (JSON.stringify(r.value) == JSON.stringify(compareKey)) + return v.value; + } + return null; + }; + return WeightedPathfinder; + }()); + es.WeightedPathfinder = WeightedPathfinder; +})(es || (es = {})); +var es; +(function (es) { + var Debug = (function () { + function Debug() { + } + Debug.drawHollowRect = function (rectanle, color, duration) { + if (duration === void 0) { duration = 0; } + this._debugDrawItems.push(new es.DebugDrawItem(rectanle, color, duration)); + }; + Debug.render = function () { + if (this._debugDrawItems.length > 0) { + var debugShape = new egret.Shape(); + if (es.Core.scene) { + es.Core.scene.addChild(debugShape); + } + for (var i = this._debugDrawItems.length - 1; i >= 0; i--) { + var item = this._debugDrawItems[i]; + if (item.draw(debugShape)) + this._debugDrawItems.removeAt(i); + } + } + }; + Debug._debugDrawItems = []; + return Debug; + }()); + es.Debug = Debug; +})(es || (es = {})); +var es; +(function (es) { + var DebugDefaults = (function () { + function DebugDefaults() { + } + DebugDefaults.verletParticle = 0xDC345E; + DebugDefaults.verletConstraintEdge = 0x433E36; + return DebugDefaults; + }()); + es.DebugDefaults = DebugDefaults; +})(es || (es = {})); +var es; +(function (es) { + var DebugDrawType; + (function (DebugDrawType) { + DebugDrawType[DebugDrawType["line"] = 0] = "line"; + DebugDrawType[DebugDrawType["hollowRectangle"] = 1] = "hollowRectangle"; + DebugDrawType[DebugDrawType["pixel"] = 2] = "pixel"; + DebugDrawType[DebugDrawType["text"] = 3] = "text"; + })(DebugDrawType = es.DebugDrawType || (es.DebugDrawType = {})); + var DebugDrawItem = (function () { + function DebugDrawItem(rectangle, color, duration) { + this.rectangle = rectangle; + this.color = color; + this.duration = duration; + this.drawType = DebugDrawType.hollowRectangle; + } + DebugDrawItem.prototype.draw = function (shape) { + switch (this.drawType) { + case DebugDrawType.line: + es.DrawUtils.drawLine(shape, this.start, this.end, this.color); + break; + case DebugDrawType.hollowRectangle: + es.DrawUtils.drawHollowRect(shape, this.rectangle, this.color); + break; + case DebugDrawType.pixel: + es.DrawUtils.drawPixel(shape, new es.Vector2(this.x, this.y), this.color, this.size); + break; + case DebugDrawType.text: + break; + } + this.duration -= es.Time.deltaTime; + return this.duration < 0; + }; + return DebugDrawItem; + }()); + es.DebugDrawItem = DebugDrawItem; +})(es || (es = {})); +var es; +(function (es) { + var Component = (function (_super) { + __extends(Component, _super); + function Component() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.updateInterval = 1; + _this._enabled = true; + _this._updateOrder = 0; + return _this; + } + Object.defineProperty(Component.prototype, "transform", { + get: function () { + return this.entity.transform; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Component.prototype, "enabled", { + get: function () { + return this.entity ? this.entity.enabled && this._enabled : this._enabled; + }, + set: function (value) { + this.setEnabled(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Component.prototype, "updateOrder", { + get: function () { + return this._updateOrder; + }, + set: function (value) { + this.setUpdateOrder(value); + }, + enumerable: true, + configurable: true + }); + Component.prototype.initialize = function () { + }; + Component.prototype.onAddedToEntity = function () { + }; + Component.prototype.onRemovedFromEntity = function () { + }; + Component.prototype.onEntityTransformChanged = function (comp) { + }; + Component.prototype.debugRender = function () { + }; + Component.prototype.onEnabled = function () { + }; + Component.prototype.onDisabled = function () { + }; + Component.prototype.update = function () { + }; + Component.prototype.setEnabled = function (isEnabled) { + if (this._enabled != isEnabled) { + this._enabled = isEnabled; + if (this._enabled) { + this.onEnabled(); + } + else { + this.onDisabled(); + } } return this; - } - }; - Entity.prototype.setTag = function (tag) { - if (this._tag != tag) { - if (this.scene) { - this.scene.entities.removeFromTagList(this); - } - this._tag = tag; - if (this.scene) { - this.scene.entities.addToTagList(this); + }; + Component.prototype.setUpdateOrder = function (updateOrder) { + if (this._updateOrder != updateOrder) { + this._updateOrder = updateOrder; } + return this; + }; + Component.prototype.clone = function () { + var component = ObjectUtils.clone(this); + component.entity = null; + return component; + }; + return Component; + }(egret.HashObject)); + es.Component = Component; +})(es || (es = {})); +var es; +(function (es) { + var Core = (function (_super) { + __extends(Core, _super); + function Core() { + var _this = _super.call(this) || this; + _this._globalManagers = []; + Core._instance = _this; + Core.emitter = new es.Emitter(); + Core.content = new es.ContentManager(); + _this.addEventListener(egret.Event.ADDED_TO_STAGE, _this.onAddToStage, _this); + return _this; } - return this; - }; - Entity.prototype.attachToScene = function (newScene) { - this.scene = newScene; - newScene.entities.add(this); - this.components.registerAllComponents(); - for (var i = 0; i < this.numChildren; i++) { - this.getChildAt(i).entity.attachToScene(newScene); - } - }; - Entity.prototype.detachFromScene = function () { - this.scene.entities.remove(this); - this.components.deregisterAllComponents(); - for (var i = 0; i < this.numChildren; i++) - this.getChildAt(i).entity.detachFromScene(); - }; - Entity.prototype.addComponent = function (component) { - component.entity = this; - this.components.add(component); - this.addChild(component); - component.initialize(); - return component; - }; - Entity.prototype.hasComponent = function (type) { - return this.components.getComponent(type, false) != null; - }; - Entity.prototype.getOrCreateComponent = function (type) { - var comp = this.components.getComponent(type, true); - if (!comp) { - comp = this.addComponent(type); - } - return comp; - }; - Entity.prototype.getComponent = function (type) { - return this.components.getComponent(type, false); - }; - Entity.prototype.getComponents = function (typeName, componentList) { - return this.components.getComponents(typeName, componentList); - }; - Entity.prototype.onEntityTransformChanged = function (comp) { - this.components.onEntityTransformChanged(comp); - }; - Entity.prototype.removeComponentForType = function (type) { - var comp = this.getComponent(type); - if (comp) { - this.removeComponent(comp); - return true; - } - return false; - }; - Entity.prototype.removeComponent = function (component) { - this.components.remove(component); - }; - Entity.prototype.removeAllComponents = function () { - for (var i = 0; i < this.components.count; i++) { - this.removeComponent(this.components.buffer[i]); - } - }; - Entity.prototype.update = function () { - this.components.update(); - }; - Entity.prototype.onAddedToScene = function () { - }; - Entity.prototype.onRemovedFromScene = function () { - if (this._isDestoryed) - this.components.removeAllComponents(); - }; - Entity.prototype.destroy = function () { - this._isDestoryed = true; - this.scene.entities.remove(this); - this.removeChildren(); - for (var i = this.numChildren - 1; i >= 0; i--) { - var child = this.getChildAt(i); - child.entity.destroy(); - } - }; - return Entity; -}(egret.DisplayObjectContainer)); -var TransformComponent; -(function (TransformComponent) { - TransformComponent[TransformComponent["rotation"] = 0] = "rotation"; - TransformComponent[TransformComponent["scale"] = 1] = "scale"; - TransformComponent[TransformComponent["position"] = 2] = "position"; -})(TransformComponent || (TransformComponent = {})); -var Scene = (function (_super) { - __extends(Scene, _super); - function Scene() { - var _this = _super.call(this) || this; - _this.enablePostProcessing = true; - _this._renderers = []; - _this._postProcessors = []; - _this.entityProcessors = new EntityProcessorList(); - _this.renderableComponents = new RenderableComponentList(); - _this.entities = new EntityList(_this); - _this.content = new ContentManager(); - _this.width = SceneManager.stage.stageWidth; - _this.height = SceneManager.stage.stageHeight; - _this.addEventListener(egret.Event.ACTIVATE, _this.onActive, _this); - _this.addEventListener(egret.Event.DEACTIVATE, _this.onDeactive, _this); - return _this; - } - Scene.prototype.createEntity = function (name) { - var entity = new Entity(name); - entity.position = new Vector2(0, 0); - return this.addEntity(entity); - }; - Scene.prototype.addEntity = function (entity) { - this.entities.add(entity); - entity.scene = this; - this.addChild(entity); - for (var i = 0; i < entity.numChildren; i++) - this.addEntity(entity.getChildAt(i).entity); - return entity; - }; - Scene.prototype.destroyAllEntities = function () { - for (var i = 0; i < this.entities.count; i++) { - this.entities.buffer[i].destroy(); - } - }; - Scene.prototype.findEntity = function (name) { - return this.entities.findEntity(name); - }; - Scene.prototype.addEntityProcessor = function (processor) { - processor.scene = this; - this.entityProcessors.add(processor); - return processor; - }; - Scene.prototype.removeEntityProcessor = function (processor) { - this.entityProcessors.remove(processor); - }; - Scene.prototype.getEntityProcessor = function () { - return this.entityProcessors.getProcessor(); - }; - Scene.prototype.addRenderer = function (renderer) { - this._renderers.push(renderer); - this._renderers.sort(); - renderer.onAddedToScene(this); - return renderer; - }; - Scene.prototype.getRenderer = function (type) { - for (var i = 0; i < this._renderers.length; i++) { - if (this._renderers[i] instanceof type) - return this._renderers[i]; - } - return null; - }; - Scene.prototype.removeRenderer = function (renderer) { - this._renderers.remove(renderer); - renderer.unload(); - }; - Scene.prototype.begin = function () { - if (SceneManager.sceneTransition) { - SceneManager.stage.addChildAt(this, SceneManager.stage.numChildren - 1); - } - else { - SceneManager.stage.addChild(this); - } - if (this._renderers.length == 0) { - this.addRenderer(new DefaultRenderer()); - console.warn("场景开始时没有渲染器 自动添加DefaultRenderer以保证能够正常渲染"); - } - this.camera = this.createEntity("camera").getOrCreateComponent(new Camera()); - Physics.reset(); - if (this.entityProcessors) - this.entityProcessors.begin(); - this.camera.onSceneSizeChanged(this.stage.stageWidth, this.stage.stageHeight); - this._didSceneBegin = true; - this.onStart(); - }; - Scene.prototype.end = function () { - this._didSceneBegin = false; - this.removeEventListener(egret.Event.DEACTIVATE, this.onDeactive, this); - this.removeEventListener(egret.Event.ACTIVATE, this.onActive, this); - for (var i = 0; i < this._renderers.length; i++) { - this._renderers[i].unload(); - } - for (var i = 0; i < this._postProcessors.length; i++) { - this._postProcessors[i].unload(); - } - this.entities.removeAllEntities(); - this.removeChildren(); - Physics.clear(); - this.camera = null; - this.content.dispose(); - if (this.entityProcessors) - this.entityProcessors.end(); - this.unload(); - if (this.parent) - this.parent.removeChild(this); - }; - Scene.prototype.onStart = function () { - return __awaiter(this, void 0, void 0, function () { - return __generator(this, function (_a) { - return [2]; - }); + Object.defineProperty(Core, "Instance", { + get: function () { + return this._instance; + }, + enumerable: true, + configurable: true }); - }; - Scene.prototype.onActive = function () { - }; - Scene.prototype.onDeactive = function () { - }; - Scene.prototype.unload = function () { }; - Scene.prototype.update = function () { - this.entities.updateLists(); - if (this.entityProcessors) - this.entityProcessors.update(); - this.entities.update(); - if (this.entityProcessors) - this.entityProcessors.lateUpdate(); - this.renderableComponents.updateList(); - }; - Scene.prototype.postRender = function () { - var enabledCounter = 0; - if (this.enablePostProcessing) { - for (var i = 0; i < this._postProcessors.length; i++) { - if (this._postProcessors[i].enable) { - var isEven = MathHelper.isEven(enabledCounter); - enabledCounter++; - this._postProcessors[i].process(); - } - } - } - }; - Scene.prototype.render = function () { - for (var i = 0; i < this._renderers.length; i++) { - this._renderers[i].render(this); - } - }; - Scene.prototype.addPostProcessor = function (postProcessor) { - this._postProcessors.push(postProcessor); - this._postProcessors.sort(); - postProcessor.onAddedToScene(this); - if (this._didSceneBegin) { - postProcessor.onSceneBackBufferSizeChanged(this.stage.stageWidth, this.stage.stageHeight); - } - return postProcessor; - }; - return Scene; -}(egret.DisplayObjectContainer)); -var SceneManager = (function () { - function SceneManager(stage) { - stage.addEventListener(egret.Event.ENTER_FRAME, SceneManager.update, this); - SceneManager.stage = stage; - SceneManager.initialize(stage); - } - Object.defineProperty(SceneManager, "scene", { - get: function () { - return this._scene; - }, - set: function (value) { - if (!value) - throw new Error("场景不能为空"); - if (this._scene == null) { - this._scene = value; - this._scene.begin(); - } - else { - this._nextScene = value; - } - }, - enumerable: true, - configurable: true - }); - SceneManager.initialize = function (stage) { - Input.initialize(stage); - }; - SceneManager.update = function () { - Time.update(egret.getTimer()); - if (SceneManager._scene) { - for (var i = GlobalManager.globalManagers.length - 1; i >= 0; i--) { - if (GlobalManager.globalManagers[i].enabled) - GlobalManager.globalManagers[i].update(); - } - if (!SceneManager.sceneTransition || - (SceneManager.sceneTransition && (!SceneManager.sceneTransition.loadsNewScene || SceneManager.sceneTransition.isNewSceneLoaded))) { - SceneManager._scene.update(); - } - if (SceneManager._nextScene) { - SceneManager._scene.end(); - for (var i = 0; i < SceneManager._scene.entities.buffer.length; i++) { - var entity = SceneManager._scene.entities.buffer[i]; - entity.destroy(); - } - SceneManager._scene = SceneManager._nextScene; - SceneManager._nextScene = null; - SceneManager._scene.begin(); - } - } - SceneManager.render(); - }; - SceneManager.render = function () { - if (this.sceneTransition) { - this.sceneTransition.preRender(); - if (this._scene && !this.sceneTransition.hasPreviousSceneRender) { - this._scene.render(); - this._scene.postRender(); - this.sceneTransition.onBeginTransition(); - } - else if (this.sceneTransition) { - if (this._scene && this.sceneTransition.isNewSceneLoaded) { - this._scene.render(); - this._scene.postRender(); - } - this.sceneTransition.render(); - } - } - else if (this._scene) { - this._scene.render(); - this._scene.postRender(); - } - }; - SceneManager.startSceneTransition = function (sceneTransition) { - if (this.sceneTransition) { - console.warn("在前一个场景完成之前,不能开始一个新的场景转换。"); - return; - } - this.sceneTransition = sceneTransition; - return sceneTransition; - }; - return SceneManager; -}()); -var Camera = (function (_super) { - __extends(Camera, _super); - function Camera() { - var _this = _super.call(this) || this; - _this._origin = Vector2.zero; - _this._minimumZoom = 0.3; - _this._maximumZoom = 3; - _this._position = Vector2.zero; - _this.followLerp = 0.1; - _this.deadzone = new Rectangle(); - _this.focusOffset = new Vector2(); - _this.mapLockEnabled = false; - _this.mapSize = new Vector2(); - _this._worldSpaceDeadZone = new Rectangle(); - _this._desiredPositionDelta = new Vector2(); - _this.cameraStyle = CameraStyle.lockOn; - _this.width = SceneManager.stage.stageWidth; - _this.height = SceneManager.stage.stageHeight; - _this.setZoom(0); - return _this; - } - Object.defineProperty(Camera.prototype, "zoom", { - get: function () { - if (this._zoom == 0) - return 1; - if (this._zoom < 1) - return MathHelper.map(this._zoom, this._minimumZoom, 1, -1, 0); - return MathHelper.map(this._zoom, 1, this._maximumZoom, 0, 1); - }, - set: function (value) { - this.setZoom(value); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Camera.prototype, "minimumZoom", { - get: function () { - return this._minimumZoom; - }, - set: function (value) { - this.setMinimumZoom(value); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Camera.prototype, "maximumZoom", { - get: function () { - return this._maximumZoom; - }, - set: function (value) { - this.setMaximumZoom(value); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Camera.prototype, "origin", { - get: function () { - return this._origin; - }, - set: function (value) { - if (this._origin != value) { - this._origin = value; - } - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Camera.prototype, "position", { - get: function () { - return this._position; - }, - set: function (value) { - this._position = value; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Camera.prototype, "x", { - get: function () { - return this._position.x; - }, - set: function (value) { - this._position.x = value; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Camera.prototype, "y", { - get: function () { - return this._position.y; - }, - set: function (value) { - this._position.y = value; - }, - enumerable: true, - configurable: true - }); - Camera.prototype.onSceneSizeChanged = function (newWidth, newHeight) { - var oldOrigin = this._origin; - this.origin = new Vector2(newWidth / 2, newHeight / 2); - this.entity.position = Vector2.add(this.entity.position, Vector2.subtract(this._origin, oldOrigin)); - }; - Camera.prototype.setMinimumZoom = function (minZoom) { - if (this._zoom < minZoom) - this._zoom = this.minimumZoom; - this._minimumZoom = minZoom; - return this; - }; - Camera.prototype.setMaximumZoom = function (maxZoom) { - if (this._zoom > maxZoom) - this._zoom = maxZoom; - this._maximumZoom = maxZoom; - return this; - }; - Camera.prototype.setZoom = function (zoom) { - var newZoom = MathHelper.clamp(zoom, -1, 1); - if (newZoom == 0) { - this._zoom = 1; - } - else if (newZoom < 0) { - this._zoom = MathHelper.map(newZoom, -1, 0, this._minimumZoom, 1); - } - else { - this._zoom = MathHelper.map(newZoom, 0, 1, 1, this._maximumZoom); - } - SceneManager.scene.scaleX = this._zoom; - SceneManager.scene.scaleY = this._zoom; - return this; - }; - Camera.prototype.setRotation = function (rotation) { - SceneManager.scene.rotation = rotation; - return this; - }; - Camera.prototype.setPosition = function (position) { - this.entity.position = position; - return this; - }; - Camera.prototype.follow = function (targetEntity, cameraStyle) { - if (cameraStyle === void 0) { cameraStyle = CameraStyle.cameraWindow; } - this.targetEntity = targetEntity; - this.cameraStyle = cameraStyle; - var cameraBounds = new Rectangle(0, 0, SceneManager.stage.stageWidth, SceneManager.stage.stageHeight); - switch (this.cameraStyle) { - case CameraStyle.cameraWindow: - var w = cameraBounds.width / 6; - var h = cameraBounds.height / 3; - this.deadzone = new Rectangle((cameraBounds.width - w) / 2, (cameraBounds.height - h) / 2, w, h); - break; - case CameraStyle.lockOn: - this.deadzone = new Rectangle(cameraBounds.width / 2, cameraBounds.height / 2, 10, 10); - break; - } - }; - Camera.prototype.update = function () { - var cameraBounds = new Rectangle(0, 0, SceneManager.stage.stageWidth, SceneManager.stage.stageHeight); - var halfScreen = Vector2.multiply(new Vector2(cameraBounds.width, cameraBounds.height), new Vector2(0.5)); - this._worldSpaceDeadZone.x = this.position.x - halfScreen.x + this.deadzone.x + this.focusOffset.x; - this._worldSpaceDeadZone.y = this.position.y - halfScreen.y + this.deadzone.y + this.focusOffset.y; - this._worldSpaceDeadZone.width = this.deadzone.width; - this._worldSpaceDeadZone.height = this.deadzone.height; - if (this.targetEntity) - this.updateFollow(); - this.position = Vector2.lerp(this.position, Vector2.add(this.position, this._desiredPositionDelta), this.followLerp); - this.entity.roundPosition(); - if (this.mapLockEnabled) { - this.position = this.clampToMapSize(this.position); - this.entity.roundPosition(); - } - }; - Camera.prototype.clampToMapSize = function (position) { - var cameraBounds = new Rectangle(0, 0, SceneManager.stage.stageWidth, SceneManager.stage.stageHeight); - var halfScreen = Vector2.multiply(new Vector2(cameraBounds.width, cameraBounds.height), new Vector2(0.5)); - var cameraMax = new Vector2(this.mapSize.x - halfScreen.x, this.mapSize.y - halfScreen.y); - return Vector2.clamp(position, halfScreen, cameraMax); - }; - Camera.prototype.updateFollow = function () { - this._desiredPositionDelta.x = this._desiredPositionDelta.y = 0; - if (this.cameraStyle == CameraStyle.lockOn) { - var targetX = this.targetEntity.position.x; - var targetY = this.targetEntity.position.y; - if (this._worldSpaceDeadZone.x > targetX) - this._desiredPositionDelta.x = targetX - this._worldSpaceDeadZone.x; - else if (this._worldSpaceDeadZone.x < targetX) - this._desiredPositionDelta.x = targetX - this._worldSpaceDeadZone.x; - if (this._worldSpaceDeadZone.y < targetY) - this._desiredPositionDelta.y = targetY - this._worldSpaceDeadZone.y; - else if (this._worldSpaceDeadZone.y > targetY) - this._desiredPositionDelta.y = targetY - this._worldSpaceDeadZone.y; - } - else { - if (!this._targetCollider) { - this._targetCollider = this.targetEntity.getComponent(Collider); - if (!this._targetCollider) + Object.defineProperty(Core, "scene", { + get: function () { + if (!this._instance) + return null; + return this._instance._scene; + }, + set: function (value) { + if (!value) { + console.error("场景不能为空"); return; + } + if (this._instance._scene == null) { + this._instance._scene = value; + this._instance.addChild(value); + this._instance._scene.begin(); + Core.Instance.onSceneChanged(); + } + else { + this._instance._nextScene = value; + } + }, + enumerable: true, + configurable: true + }); + Core.startSceneTransition = function (sceneTransition) { + if (this._instance._sceneTransition) { + console.warn("在前一个场景完成之前,不能开始一个新的场景转换。"); + return; } - var targetBounds = this.targetEntity.getComponent(Collider).bounds; - if (!this._worldSpaceDeadZone.containsRect(targetBounds)) { - if (this._worldSpaceDeadZone.left > targetBounds.left) - this._desiredPositionDelta.x = targetBounds.left - this._worldSpaceDeadZone.left; - else if (this._worldSpaceDeadZone.right < targetBounds.right) - this._desiredPositionDelta.x = targetBounds.right - this._worldSpaceDeadZone.right; - if (this._worldSpaceDeadZone.bottom < targetBounds.bottom) - this._desiredPositionDelta.y = targetBounds.bottom - this._worldSpaceDeadZone.bottom; - else if (this._worldSpaceDeadZone.top > targetBounds.top) - this._desiredPositionDelta.y = targetBounds.top - this._worldSpaceDeadZone.top; + this._instance._sceneTransition = sceneTransition; + return sceneTransition; + }; + Core.registerGlobalManager = function (manager) { + this._instance._globalManagers.push(manager); + manager.enabled = true; + }; + Core.unregisterGlobalManager = function (manager) { + this._instance._globalManagers.remove(manager); + manager.enabled = false; + }; + Core.getGlobalManager = function (type) { + for (var i = 0; i < this._instance._globalManagers.length; i++) { + if (this._instance._globalManagers[i] instanceof type) + return this._instance._globalManagers[i]; } - } - }; - return Camera; -}(Component)); -var CameraStyle; -(function (CameraStyle) { - CameraStyle[CameraStyle["lockOn"] = 0] = "lockOn"; - CameraStyle[CameraStyle["cameraWindow"] = 1] = "cameraWindow"; -})(CameraStyle || (CameraStyle = {})); -var ComponentPool = (function () { - function ComponentPool(typeClass) { - this._type = typeClass; - this._cache = []; - } - ComponentPool.prototype.obtain = function () { - try { - return this._cache.length > 0 ? this._cache.shift() : new this._type(); - } - catch (err) { - throw new Error(this._type + err); - } - }; - ComponentPool.prototype.free = function (component) { - component.reset(); - this._cache.push(component); - }; - return ComponentPool; -}()); -var PooledComponent = (function (_super) { - __extends(PooledComponent, _super); - function PooledComponent() { - return _super !== null && _super.apply(this, arguments) || this; - } - return PooledComponent; -}(Component)); -var RenderableComponent = (function (_super) { - __extends(RenderableComponent, _super); - function RenderableComponent() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this._areBoundsDirty = true; - _this._bounds = new Rectangle(); - _this._localOffset = Vector2.zero; - _this.color = 0x000000; - return _this; - } - Object.defineProperty(RenderableComponent.prototype, "width", { - get: function () { - return this.getWidth(); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(RenderableComponent.prototype, "height", { - get: function () { - return this.getHeight(); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(RenderableComponent.prototype, "isVisible", { - get: function () { - return this._isVisible; - }, - set: function (value) { - this._isVisible = value; - if (this._isVisible) - this.onBecameVisible(); - else - this.onBecameInvisible(); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(RenderableComponent.prototype, "bounds", { - get: function () { - return new Rectangle(this.getBounds().x, this.getBounds().y, this.getBounds().width, this.getBounds().height); - }, - enumerable: true, - configurable: true - }); - RenderableComponent.prototype.getWidth = function () { - return this.bounds.width; - }; - RenderableComponent.prototype.getHeight = function () { - return this.bounds.height; - }; - RenderableComponent.prototype.onBecameVisible = function () { }; - RenderableComponent.prototype.onBecameInvisible = function () { }; - RenderableComponent.prototype.isVisibleFromCamera = function (camera) { - this.isVisible = camera.getBounds().intersects(this.getBounds()); - return this.isVisible; - }; - return RenderableComponent; -}(PooledComponent)); -var Mesh = (function (_super) { - __extends(Mesh, _super); - function Mesh() { - var _this = _super.call(this) || this; - _this._mesh = new egret.Mesh(); - return _this; - } - Mesh.prototype.setTexture = function (texture) { - this._mesh.texture = texture; - return this; - }; - Mesh.prototype.onAddedToEntity = function () { - this.addChild(this._mesh); - }; - Mesh.prototype.onRemovedFromEntity = function () { - this.removeChild(this._mesh); - }; - Mesh.prototype.render = function (camera) { - this.x = this.entity.position.x - camera.position.x + camera.origin.x; - this.y = this.entity.position.y - camera.position.y + camera.origin.y; - }; - Mesh.prototype.reset = function () { - }; - return Mesh; -}(RenderableComponent)); -var SpriteRenderer = (function (_super) { - __extends(SpriteRenderer, _super); - function SpriteRenderer() { - return _super !== null && _super.apply(this, arguments) || this; - } - Object.defineProperty(SpriteRenderer.prototype, "sprite", { - get: function () { - return this._sprite; - }, - set: function (value) { - this.setSprite(value); - }, - enumerable: true, - configurable: true - }); - SpriteRenderer.prototype.setSprite = function (sprite) { - this.removeChildren(); - this._sprite = sprite; - if (this._sprite) { - this.anchorOffsetX = this._sprite.origin.x / this._sprite.sourceRect.width; - this.anchorOffsetY = this._sprite.origin.y / this._sprite.sourceRect.height; - } - this.bitmap = new egret.Bitmap(sprite.texture2D); - this.addChild(this.bitmap); - return this; - }; - SpriteRenderer.prototype.setColor = function (color) { - var colorMatrix = [ - 1, 0, 0, 0, 0, - 0, 1, 0, 0, 0, - 0, 0, 1, 0, 0, - 0, 0, 0, 1, 0 - ]; - colorMatrix[0] = Math.floor(color / 256 / 256) / 255; - colorMatrix[6] = Math.floor(color / 256 % 256) / 255; - colorMatrix[12] = color % 256 / 255; - var colorFilter = new egret.ColorMatrixFilter(colorMatrix); - this.filters = [colorFilter]; - return this; - }; - SpriteRenderer.prototype.isVisibleFromCamera = function (camera) { - this.isVisible = new Rectangle(0, 0, this.stage.stageWidth, this.stage.stageHeight).intersects(this.bounds); - this.visible = this.isVisible; - return this.isVisible; - }; - SpriteRenderer.prototype.render = function (camera) { - this.x = -camera.position.x + camera.origin.x; - this.y = -camera.position.y + camera.origin.y; - }; - SpriteRenderer.prototype.onRemovedFromEntity = function () { - if (this.parent) - this.parent.removeChild(this); - }; - SpriteRenderer.prototype.reset = function () { - }; - return SpriteRenderer; -}(RenderableComponent)); -var TiledSpriteRenderer = (function (_super) { - __extends(TiledSpriteRenderer, _super); - function TiledSpriteRenderer(sprite) { - var _this = _super.call(this) || this; - _this.leftTexture = new egret.Bitmap(); - _this.rightTexture = new egret.Bitmap(); - _this.leftTexture.texture = sprite.texture2D; - _this.rightTexture.texture = sprite.texture2D; - _this.setSprite(sprite); - _this.sourceRect = sprite.sourceRect; - return _this; - } - Object.defineProperty(TiledSpriteRenderer.prototype, "scrollX", { - get: function () { - return this.sourceRect.x; - }, - set: function (value) { - this.sourceRect.x = value; - if (this.sourceRect.x < -this.sourceRect.width) - this.sourceRect.x = this.sourceRect.width; - else if (this.sourceRect.x > this.sourceRect.width) - this.sourceRect.x = -this.sourceRect.width; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(TiledSpriteRenderer.prototype, "scrollY", { - get: function () { - return this.sourceRect.y; - }, - set: function (value) { - this.sourceRect.y = value; - if (this.sourceRect.y < -this.sourceRect.height) - this.sourceRect.y = this.sourceRect.height; - else if (this.sourceRect.y > this.sourceRect.height) - this.sourceRect.y = -this.sourceRect.height; - }, - enumerable: true, - configurable: true - }); - TiledSpriteRenderer.prototype.render = function (camera) { - if (!this.sprite) - return; - _super.prototype.render.call(this, camera); - var renderTexture = new egret.RenderTexture(); - var cacheBitmap = new egret.DisplayObjectContainer(); - cacheBitmap.removeChildren(); - cacheBitmap.addChild(this.leftTexture); - cacheBitmap.addChild(this.rightTexture); - this.leftTexture.x = this.sourceRect.x; - this.rightTexture.x = this.sourceRect.x + this.sourceRect.width; - this.leftTexture.y = this.sourceRect.y; - this.rightTexture.y = this.sourceRect.y; - cacheBitmap.cacheAsBitmap = true; - renderTexture.drawToTexture(cacheBitmap, new egret.Rectangle(0, 0, this.sourceRect.width, this.sourceRect.height)); - this.bitmap.texture = renderTexture; - }; - return TiledSpriteRenderer; -}(SpriteRenderer)); -var ScrollingSpriteRenderer = (function (_super) { - __extends(ScrollingSpriteRenderer, _super); - function ScrollingSpriteRenderer() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this.scrollSpeedX = 15; - _this.scroolSpeedY = 0; - _this._scrollX = 0; - _this._scrollY = 0; - return _this; - } - ScrollingSpriteRenderer.prototype.update = function () { - this.scrollX += this.scrollSpeedX * Time.deltaTime; - this.scrollY += this.scroolSpeedY * Time.deltaTime; - this.sourceRect.x = this._scrollX; - this.sourceRect.y = this._scrollY; - }; - return ScrollingSpriteRenderer; -}(TiledSpriteRenderer)); -var Sprite = (function () { - function Sprite(texture, sourceRect, origin) { - if (sourceRect === void 0) { sourceRect = new Rectangle(0, 0, texture.textureWidth, texture.textureHeight); } - if (origin === void 0) { origin = sourceRect.getHalfSize(); } - this.uvs = new Rectangle(); - this.texture2D = texture; - this.sourceRect = sourceRect; - this.center = new Vector2(sourceRect.width * 0.5, sourceRect.height * 0.5); - this.origin = origin; - var inverseTexW = 1 / texture.textureWidth; - var 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; - } - return Sprite; -}()); -var SpriteAnimation = (function () { - function SpriteAnimation(sprites, frameRate) { - this.sprites = sprites; - this.frameRate = frameRate; - } - return SpriteAnimation; -}()); -var SpriteAnimator = (function (_super) { - __extends(SpriteAnimator, _super); - function SpriteAnimator(sprite) { - var _this = _super.call(this) || this; - _this.speed = 1; - _this.animationState = State.none; - _this._animations = new Map(); - _this._elapsedTime = 0; - if (sprite) - _this.setSprite(sprite); - return _this; - } - Object.defineProperty(SpriteAnimator.prototype, "isRunning", { - get: function () { - return this.animationState == State.running; - }, - enumerable: true, - configurable: true - }); - SpriteAnimator.prototype.addAnimation = function (name, animation) { - if (!this.sprite && animation.sprites.length > 0) - this.setSprite(animation.sprites[0]); - this._animations[name] = animation; - return this; - }; - SpriteAnimator.prototype.play = function (name, loopMode) { - if (loopMode === void 0) { 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; - }; - SpriteAnimator.prototype.isAnimationActive = function (name) { - return this.currentAnimation && this.currentAnimationName == name; - }; - SpriteAnimator.prototype.pause = function () { - this.animationState = State.paused; - }; - SpriteAnimator.prototype.unPause = function () { - this.animationState = State.running; - }; - SpriteAnimator.prototype.stop = function () { - this.currentAnimation = null; - this.currentAnimationName = null; - this.currentFrame = 0; - this.animationState = State.none; - }; - SpriteAnimator.prototype.update = function () { - if (this.animationState != State.running || !this.currentAnimation) - return; - var animation = this.currentAnimation; - var secondsPerFrame = 1 / (animation.frameRate * this.speed); - var iterationDuration = secondsPerFrame * animation.sprites.length; - this._elapsedTime += Time.deltaTime; - var 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; - } - var i = Math.floor(time / secondsPerFrame); - var n = animation.sprites.length; - if (n > 2 && (this._loopMode == LoopMode.pingPong || this._loopMode == LoopMode.pingPongOnce)) { - var maxIndex = n - 1; - this.currentFrame = maxIndex - Math.abs(maxIndex - i % (maxIndex * 2)); - } - else { - this.currentFrame = i % n; - } - this.sprite = animation.sprites[this.currentFrame]; - }; - return SpriteAnimator; -}(SpriteRenderer)); -var LoopMode; -(function (LoopMode) { - LoopMode[LoopMode["loop"] = 0] = "loop"; - LoopMode[LoopMode["once"] = 1] = "once"; - LoopMode[LoopMode["clampForever"] = 2] = "clampForever"; - LoopMode[LoopMode["pingPong"] = 3] = "pingPong"; - LoopMode[LoopMode["pingPongOnce"] = 4] = "pingPongOnce"; -})(LoopMode || (LoopMode = {})); -var State; -(function (State) { - State[State["none"] = 0] = "none"; - State[State["running"] = 1] = "running"; - State[State["paused"] = 2] = "paused"; - State[State["completed"] = 3] = "completed"; -})(State || (State = {})); -var Mover = (function (_super) { - __extends(Mover, _super); - function Mover() { - return _super !== null && _super.apply(this, arguments) || this; - } - Mover.prototype.onAddedToEntity = function () { - this._triggerHelper = new ColliderTriggerHelper(this.entity); - }; - Mover.prototype.calculateMovement = function (motion) { - var collisionResult = new CollisionResult(); - if (!this.entity.getComponent(Collider) || !this._triggerHelper) { return null; + }; + Core.prototype.onOrientationChanged = function () { + Core.emitter.emit(es.CoreEvents.OrientationChanged); + }; + Core.prototype.draw = function () { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + if (!this._sceneTransition) return [3, 4]; + this._sceneTransition.preRender(); + if (!(this._scene && !this._sceneTransition.hasPreviousSceneRender)) return [3, 2]; + this._scene.render(); + this._scene.postRender(); + return [4, this._sceneTransition.onBeginTransition()]; + case 1: + _a.sent(); + return [3, 3]; + case 2: + if (this._sceneTransition) { + if (this._scene && this._sceneTransition.isNewSceneLoaded) { + this._scene.render(); + this._scene.postRender(); + } + this._sceneTransition.render(); + } + _a.label = 3; + case 3: return [3, 5]; + case 4: + if (this._scene) { + this._scene.render(); + es.Debug.render(); + this._scene.postRender(); + } + _a.label = 5; + case 5: return [2]; + } + }); + }); + }; + Core.prototype.startDebugUpdate = function () { + es.TimeRuler.Instance.startFrame(); + es.TimeRuler.Instance.beginMark("update", 0x00FF00); + }; + Core.prototype.endDebugUpdate = function () { + es.TimeRuler.Instance.endMark("update"); + }; + Core.prototype.onSceneChanged = function () { + Core.emitter.emit(es.CoreEvents.SceneChanged); + es.Time.sceneChanged(); + }; + Core.prototype.onGraphicsDeviceReset = function () { + Core.emitter.emit(es.CoreEvents.GraphicsDeviceReset); + }; + Core.prototype.initialize = function () { + }; + Core.prototype.update = function () { + return __awaiter(this, void 0, void 0, function () { + var i; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + es.Time.update(egret.getTimer()); + if (!this._scene) return [3, 2]; + for (i = this._globalManagers.length - 1; i >= 0; i--) { + if (this._globalManagers[i].enabled) + this._globalManagers[i].update(); + } + if (!this._sceneTransition || + (this._sceneTransition && (!this._sceneTransition.loadsNewScene || this._sceneTransition.isNewSceneLoaded))) { + this._scene.update(); + } + if (!this._nextScene) return [3, 2]; + this.removeChild(this._scene); + this._scene.end(); + this._scene = this._nextScene; + this._nextScene = null; + this.onSceneChanged(); + this.addChild(this._scene); + return [4, this._scene.begin()]; + case 1: + _a.sent(); + _a.label = 2; + case 2: return [4, this.draw()]; + case 3: + _a.sent(); + return [2]; + } + }); + }); + }; + Core.prototype.onAddToStage = function () { + Core.graphicsDevice = new es.GraphicsDevice(); + this.addEventListener(egret.Event.RESIZE, this.onGraphicsDeviceReset, this); + this.addEventListener(egret.StageOrientationEvent.ORIENTATION_CHANGE, this.onOrientationChanged, this); + this.addEventListener(egret.Event.ENTER_FRAME, this.update, this); + es.Input.initialize(); + this.initialize(); + }; + return Core; + }(egret.DisplayObjectContainer)); + es.Core = Core; +})(es || (es = {})); +var es; +(function (es) { + var CoreEvents; + (function (CoreEvents) { + CoreEvents[CoreEvents["GraphicsDeviceReset"] = 0] = "GraphicsDeviceReset"; + CoreEvents[CoreEvents["SceneChanged"] = 1] = "SceneChanged"; + CoreEvents[CoreEvents["OrientationChanged"] = 2] = "OrientationChanged"; + })(CoreEvents = es.CoreEvents || (es.CoreEvents = {})); +})(es || (es = {})); +var es; +(function (es) { + var Entity = (function () { + function Entity(name) { + this.updateInterval = 1; + this._tag = 0; + this._enabled = true; + this._updateOrder = 0; + this.components = new es.ComponentList(this); + this.transform = new es.Transform(this); + this.name = name; + this.id = Entity._idGenerator++; + this.componentBits = new es.BitSet(); } - var colliders = this.entity.getComponents(Collider); - for (var i = 0; i < colliders.length; i++) { - var collider = colliders[i]; - if (collider.isTrigger) - continue; - var bounds = collider.bounds; - bounds.x += motion.x; - bounds.y += motion.y; - var boxcastResult = Physics.boxcastBroadphaseExcludingSelf(collider, bounds, collider.collidesWithLayers); - bounds = boxcastResult.bounds; - var neighbors = boxcastResult.tempHashSet; - for (var j = 0; j < neighbors.length; j++) { - var neighbor = neighbors[j]; - if (neighbor.isTrigger) - continue; - var _internalcollisionResult = collider.collidesWith(neighbor, motion); - if (_internalcollisionResult) { - motion = Vector2.subtract(motion, _internalcollisionResult.minimumTranslationVector); - if (_internalcollisionResult.collider) { - collisionResult = _internalcollisionResult; + Object.defineProperty(Entity.prototype, "isDestroyed", { + get: function () { + return this._isDestroyed; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Entity.prototype, "tag", { + get: function () { + return this._tag; + }, + set: function (value) { + this.setTag(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Entity.prototype, "enabled", { + get: function () { + return this._enabled; + }, + set: function (value) { + this.setEnabled(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Entity.prototype, "updateOrder", { + get: function () { + return this._updateOrder; + }, + set: function (value) { + this.setUpdateOrder(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Entity.prototype, "parent", { + get: function () { + return this.transform.parent; + }, + set: function (value) { + this.transform.setParent(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Entity.prototype, "childCount", { + get: function () { + return this.transform.childCount; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Entity.prototype, "position", { + get: function () { + return this.transform.position; + }, + set: function (value) { + this.transform.setPosition(value.x, value.y); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Entity.prototype, "localPosition", { + get: function () { + return this.transform.localPosition; + }, + set: function (value) { + this.transform.setLocalPosition(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Entity.prototype, "rotation", { + get: function () { + return this.transform.rotation; + }, + set: function (value) { + this.transform.setRotation(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Entity.prototype, "rotationDegrees", { + get: function () { + return this.transform.rotationDegrees; + }, + set: function (value) { + this.transform.setRotationDegrees(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Entity.prototype, "localRotation", { + get: function () { + return this.transform.localRotation; + }, + set: function (value) { + this.transform.setLocalRotation(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Entity.prototype, "localRotationDegrees", { + get: function () { + return this.transform.localRotationDegrees; + }, + set: function (value) { + this.transform.setLocalRotationDegrees(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Entity.prototype, "scale", { + get: function () { + return this.transform.scale; + }, + set: function (value) { + this.transform.setScale(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Entity.prototype, "localScale", { + get: function () { + return this.transform.localScale; + }, + set: function (value) { + this.transform.setLocalScale(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Entity.prototype, "worldInverseTransform", { + get: function () { + return this.transform.worldInverseTransform; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Entity.prototype, "localToWorldTransform", { + get: function () { + return this.transform.localToWorldTransform; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Entity.prototype, "worldToLocalTransform", { + get: function () { + return this.transform.worldToLocalTransform; + }, + enumerable: true, + configurable: true + }); + Entity.prototype.onTransformChanged = function (comp) { + this.components.onEntityTransformChanged(comp); + }; + Entity.prototype.setTag = function (tag) { + if (this._tag != tag) { + if (this.scene) + this.scene.entities.removeFromTagList(this); + this._tag = tag; + if (this.scene) + this.scene.entities.addToTagList(this); + } + return this; + }; + Entity.prototype.setEnabled = function (isEnabled) { + if (this._enabled != isEnabled) { + this._enabled = isEnabled; + if (this._enabled) + this.components.onEntityEnabled(); + else + this.components.onEntityDisabled(); + } + return this; + }; + Entity.prototype.setUpdateOrder = function (updateOrder) { + if (this._updateOrder != updateOrder) { + this._updateOrder = updateOrder; + if (this.scene) { + this.scene.entities.markEntityListUnsorted(); + this.scene.entities.markTagUnsorted(this.tag); + } + return this; + } + }; + Entity.prototype.destroy = function () { + this._isDestroyed = true; + this.scene.entities.remove(this); + this.transform.parent = null; + for (var i = this.transform.childCount - 1; i >= 0; i--) { + var child = this.transform.getChild(i); + child.entity.destroy(); + } + }; + Entity.prototype.detachFromScene = function () { + this.scene.entities.remove(this); + this.components.deregisterAllComponents(); + for (var i = 0; i < this.transform.childCount; i++) + this.transform.getChild(i).entity.detachFromScene(); + }; + Entity.prototype.attachToScene = function (newScene) { + this.scene = newScene; + newScene.entities.add(this); + this.components.registerAllComponents(); + for (var i = 0; i < this.transform.childCount; i++) { + this.transform.getChild(i).entity.attachToScene(newScene); + } + }; + Entity.prototype.clone = function (position) { + if (position === void 0) { position = new es.Vector2(); } + var entity = new Entity(this.name + "(clone)"); + entity.copyFrom(this); + entity.transform.position = position; + return entity; + }; + Entity.prototype.onAddedToScene = function () { + }; + Entity.prototype.onRemovedFromScene = function () { + if (this._isDestroyed) + this.components.removeAllComponents(); + }; + Entity.prototype.update = function () { + this.components.update(); + }; + Entity.prototype.addComponent = function (component) { + component.entity = this; + this.components.add(component); + component.initialize(); + return component; + }; + Entity.prototype.getComponent = function (type) { + return this.components.getComponent(type, false); + }; + Entity.prototype.hasComponent = function (type) { + return this.components.getComponent(type, false) != null; + }; + Entity.prototype.getOrCreateComponent = function (type) { + var comp = this.components.getComponent(type, true); + if (!comp) { + comp = this.addComponent(type); + } + return comp; + }; + Entity.prototype.getComponents = function (typeName, componentList) { + return this.components.getComponents(typeName, componentList); + }; + Entity.prototype.removeComponent = function (component) { + this.components.remove(component); + }; + Entity.prototype.removeComponentForType = function (type) { + var comp = this.getComponent(type); + if (comp) { + this.removeComponent(comp); + return true; + } + return false; + }; + Entity.prototype.removeAllComponents = function () { + for (var i = 0; i < this.components.count; i++) { + this.removeComponent(this.components.buffer[i]); + } + }; + Entity.prototype.compareTo = function (other) { + var compare = this._updateOrder - other._updateOrder; + if (compare == 0) + compare = this.id - other.id; + return compare; + }; + Entity.prototype.toString = function () { + return "[Entity: name: " + this.name + ", tag: " + this.tag + ", enabled: " + this.enabled + ", depth: " + this.updateOrder + "]"; + }; + Entity.prototype.copyFrom = function (entity) { + this.tag = entity.tag; + this.updateInterval = entity.updateInterval; + this.updateOrder = entity.updateOrder; + this.enabled = entity.enabled; + this.transform.scale = entity.transform.scale; + this.transform.rotation = entity.transform.rotation; + for (var i = 0; i < entity.components.count; i++) + this.addComponent(entity.components.buffer[i].clone()); + for (var i = 0; i < entity.components._componentsToAdd.length; i++) + this.addComponent(entity.components._componentsToAdd[i].clone()); + for (var i = 0; i < entity.transform.childCount; i++) { + var child = entity.transform.getChild(i).entity; + var childClone = child.clone(); + childClone.transform.copyFrom(child.transform); + childClone.transform.parent = this.transform; + } + }; + return Entity; + }()); + es.Entity = Entity; +})(es || (es = {})); +var es; +(function (es) { + var Scene = (function (_super) { + __extends(Scene, _super); + function Scene() { + var _this = _super.call(this) || this; + _this.enablePostProcessing = true; + _this._renderers = []; + _this._postProcessors = []; + _this.entities = new es.EntityList(_this); + _this.renderableComponents = new es.RenderableComponentList(); + _this.content = new es.ContentManager(); + _this.entityProcessors = new es.EntityProcessorList(); + _this.initialize(); + return _this; + } + Scene.createWithDefaultRenderer = function () { + var scene = new Scene(); + scene.addRenderer(new es.DefaultRenderer()); + return scene; + }; + Scene.prototype.initialize = function () { + }; + Scene.prototype.onStart = function () { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2]; + }); + }); + }; + Scene.prototype.unload = function () { + }; + Scene.prototype.onActive = function () { + }; + Scene.prototype.onDeactive = function () { + }; + Scene.prototype.begin = function () { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + if (this._renderers.length == 0) { + this.addRenderer(new es.DefaultRenderer()); + console.warn("场景开始时没有渲染器 自动添加DefaultRenderer以保证能够正常渲染"); + } + this.camera = this.createEntity("camera").getOrCreateComponent(new es.Camera()); + es.Physics.reset(); + if (this.entityProcessors) + this.entityProcessors.begin(); + this.addEventListener(egret.Event.ACTIVATE, this.onActive, this); + this.addEventListener(egret.Event.DEACTIVATE, this.onDeactive, this); + this.camera.onSceneSizeChanged(this.stage.stageWidth, this.stage.stageHeight); + this._didSceneBegin = true; + this.onStart(); + return [2]; + }); + }); + }; + Scene.prototype.end = function () { + this._didSceneBegin = false; + this.removeEventListener(egret.Event.DEACTIVATE, this.onDeactive, this); + this.removeEventListener(egret.Event.ACTIVATE, this.onActive, this); + for (var i = 0; i < this._renderers.length; i++) { + this._renderers[i].unload(); + } + for (var i = 0; i < this._postProcessors.length; i++) { + this._postProcessors[i].unload(); + } + this.entities.removeAllEntities(); + this.removeChildren(); + this.camera = null; + this.content.dispose(); + if (this.entityProcessors) + this.entityProcessors.end(); + if (this.parent) + this.parent.removeChild(this); + this.unload(); + }; + Scene.prototype.update = function () { + this.entities.updateLists(); + if (this.entityProcessors) + this.entityProcessors.update(); + this.entities.update(); + if (this.entityProcessors) + this.entityProcessors.lateUpdate(); + this.renderableComponents.updateList(); + }; + Scene.prototype.render = function () { + if (this._renderers.length == 0) { + console.error("there are no renderers in the scene!"); + return; + } + for (var i = 0; i < this._renderers.length; i++) { + this._renderers[i].render(this); + } + }; + Scene.prototype.postRender = function () { + if (this.enablePostProcessing) { + for (var i = 0; i < this._postProcessors.length; i++) { + if (this._postProcessors[i].enabled) { + this._postProcessors[i].process(); } } } - } - ListPool.free(colliders); - return { collisionResult: collisionResult, motion: motion }; - }; - Mover.prototype.applyMovement = function (motion) { - this.entity.position = Vector2.add(this.entity.position, motion); - if (this._triggerHelper) - this._triggerHelper.update(); - }; - Mover.prototype.move = function (motion) { - var movementResult = this.calculateMovement(motion); - var collisionResult = movementResult.collisionResult; - motion = movementResult.motion; - this.applyMovement(motion); - return collisionResult; - }; - return Mover; -}(Component)); -var Collider = (function (_super) { - __extends(Collider, _super); - function Collider() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this.physicsLayer = 1 << 0; - _this.registeredPhysicsBounds = new Rectangle(); - _this.shouldColliderScaleAndRotateWithTransform = true; - _this.collidesWithLayers = Physics.allLayers; - _this._localOffset = new Vector2(0, 0); - return _this; - } - Object.defineProperty(Collider.prototype, "bounds", { - get: function () { - var bds = this.entity.getBounds(); - return new Rectangle(bds.x, bds.y, bds.width, bds.height); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Collider.prototype, "localOffset", { - get: function () { - return new Vector2(this.x, this.y); - }, - set: function (value) { - this.setLocalOffset(value); - }, - enumerable: true, - configurable: true - }); - Collider.prototype.setLocalOffset = function (offset) { - if (this._localOffset != offset) { - this.unregisterColliderWithPhysicsSystem(); - this.$setX(offset.x); - this.$setY(offset.y); - this._localOffsetLength = this._localOffset.length(); - this.registerColliderWithPhysicsSystem(); - } - }; - Collider.prototype.registerColliderWithPhysicsSystem = function () { - if (this._isParentEntityAddedToScene && !this._isColliderRegistered) { - Physics.addCollider(this); - this._isColliderRegistered = true; - } - }; - Collider.prototype.unregisterColliderWithPhysicsSystem = function () { - if (this._isParentEntityAddedToScene && this._isColliderRegistered) { - Physics.removeCollider(this); - } - this._isColliderRegistered = false; - }; - Collider.prototype.overlaps = function (other) { - return this.shape.overlaps(other.shape); - }; - Collider.prototype.collidesWith = function (collider, motion) { - var oldPosition = this.shape.position; - this.shape.position = Vector2.add(this.shape.position, motion); - var result = this.shape.collidesWithShape(collider.shape); - if (result) - result.collider = collider; - this.shape.position = oldPosition; - return result; - }; - Collider.prototype.onAddedToEntity = function () { - if (this._colliderRequiresAutoSizing) { - if (!(this instanceof BoxCollider)) { - console.error("Only box and circle colliders can be created automatically"); + }; + Scene.prototype.addRenderer = function (renderer) { + this._renderers.push(renderer); + this._renderers.sort(); + renderer.onAddedToScene(this); + return renderer; + }; + Scene.prototype.getRenderer = function (type) { + for (var i = 0; i < this._renderers.length; i++) { + if (this._renderers[i] instanceof type) + return this._renderers[i]; } - var bounds = this.entity.getBounds(); - var renderbaleBounds = new Rectangle(bounds.x, bounds.y, bounds.width, bounds.height); - var width = renderbaleBounds.width / this.entity.scale.x; - var height = renderbaleBounds.height / this.entity.scale.y; - if (this instanceof BoxCollider) { - var boxCollider = this; - boxCollider.width = width; - boxCollider.height = height; - this.localOffset = Vector2.subtract(renderbaleBounds.center, this.entity.position); + return null; + }; + Scene.prototype.removeRenderer = function (renderer) { + if (!this._renderers.contains(renderer)) + return; + this._renderers.remove(renderer); + renderer.unload(); + }; + Scene.prototype.addPostProcessor = function (postProcessor) { + this._postProcessors.push(postProcessor); + this._postProcessors.sort(); + postProcessor.onAddedToScene(this); + if (this._didSceneBegin) { + postProcessor.onSceneBackBufferSizeChanged(this.stage.stageWidth, this.stage.stageHeight); } - } - this._isParentEntityAddedToScene = true; - this.registerColliderWithPhysicsSystem(); - }; - Collider.prototype.onRemovedFromEntity = function () { - this.unregisterColliderWithPhysicsSystem(); - this._isParentEntityAddedToScene = false; - }; - Collider.prototype.onEnabled = function () { - this.registerColliderWithPhysicsSystem(); - }; - Collider.prototype.onDisabled = function () { - this.unregisterColliderWithPhysicsSystem(); - }; - Collider.prototype.onEntityTransformChanged = function (comp) { - if (this._isColliderRegistered) - Physics.updateCollider(this); - }; - return Collider; -}(Component)); -var BoxCollider = (function (_super) { - __extends(BoxCollider, _super); - function BoxCollider() { - var _this = _super.call(this) || this; - _this.shape = new Box(1, 1); - _this._colliderRequiresAutoSizing = true; - return _this; - } - Object.defineProperty(BoxCollider.prototype, "width", { - get: function () { - return this.shape.width; - }, - set: function (value) { - this.setWidth(value); - }, - enumerable: true, - configurable: true - }); - BoxCollider.prototype.setWidth = function (width) { - this._colliderRequiresAutoSizing = false; - var box = this.shape; - if (width != box.width) { - box.updateBox(width, box.height); - if (this.entity && this._isParentEntityAddedToScene) - Physics.updateCollider(this); - } - return this; - }; - Object.defineProperty(BoxCollider.prototype, "height", { - get: function () { - return this.shape.height; - }, - set: function (value) { - this.setHeight(value); - }, - enumerable: true, - configurable: true - }); - BoxCollider.prototype.setHeight = function (height) { - this._colliderRequiresAutoSizing = false; - var box = this.shape; - if (height != box.height) { - box.updateBox(box.width, height); - if (this.entity && this._isParentEntityAddedToScene) - Physics.updateCollider(this); - } - }; - BoxCollider.prototype.setSize = function (width, height) { - this._colliderRequiresAutoSizing = false; - var box = this.shape; - if (width != box.width || height != box.height) { - box.updateBox(width, height); - if (this.entity && this._isParentEntityAddedToScene) - Physics.updateCollider(this); - } - return this; - }; - return BoxCollider; -}(Collider)); -var EntitySystem = (function () { - function EntitySystem(matcher) { - this._entities = []; - this._matcher = matcher ? matcher : Matcher.empty(); - } - Object.defineProperty(EntitySystem.prototype, "matcher", { - get: function () { - return this._matcher; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(EntitySystem.prototype, "scene", { - get: function () { - return this._scene; - }, - set: function (value) { - this._scene = value; - this._entities = []; - }, - enumerable: true, - configurable: true - }); - EntitySystem.prototype.initialize = function () { - }; - EntitySystem.prototype.onChanged = function (entity) { - var contains = this._entities.contains(entity); - var interest = this._matcher.IsIntersted(entity); - if (interest && !contains) - this.add(entity); - else if (!interest && contains) - this.remove(entity); - }; - EntitySystem.prototype.add = function (entity) { - this._entities.push(entity); - this.onAdded(entity); - }; - EntitySystem.prototype.onAdded = function (entity) { - }; - EntitySystem.prototype.remove = function (entity) { - this._entities.remove(entity); - this.onRemoved(entity); - }; - EntitySystem.prototype.onRemoved = function (entity) { - }; - EntitySystem.prototype.update = function () { - this.begin(); - this.process(this._entities); - }; - EntitySystem.prototype.lateUpdate = function () { - this.lateProcess(this._entities); - this.end(); - }; - EntitySystem.prototype.begin = function () { - }; - EntitySystem.prototype.process = function (entities) { - }; - EntitySystem.prototype.lateProcess = function (entities) { - }; - EntitySystem.prototype.end = function () { - }; - return EntitySystem; -}()); -var EntityProcessingSystem = (function (_super) { - __extends(EntityProcessingSystem, _super); - function EntityProcessingSystem(matcher) { - return _super.call(this, matcher) || this; - } - EntityProcessingSystem.prototype.lateProcessEntity = function (entity) { - }; - EntityProcessingSystem.prototype.process = function (entities) { - var _this = this; - entities.forEach(function (entity) { return _this.processEntity(entity); }); - }; - EntityProcessingSystem.prototype.lateProcess = function (entities) { - var _this = this; - entities.forEach(function (entity) { return _this.lateProcessEntity(entity); }); - }; - return EntityProcessingSystem; -}(EntitySystem)); -var PassiveSystem = (function (_super) { - __extends(PassiveSystem, _super); - function PassiveSystem() { - return _super !== null && _super.apply(this, arguments) || this; - } - PassiveSystem.prototype.onChanged = function (entity) { - }; - PassiveSystem.prototype.process = function (entities) { - this.begin(); - this.end(); - }; - return PassiveSystem; -}(EntitySystem)); -var ProcessingSystem = (function (_super) { - __extends(ProcessingSystem, _super); - function ProcessingSystem() { - return _super !== null && _super.apply(this, arguments) || this; - } - ProcessingSystem.prototype.onChanged = function (entity) { - }; - ProcessingSystem.prototype.process = function (entities) { - this.begin(); - this.processSystem(); - this.end(); - }; - return ProcessingSystem; -}(EntitySystem)); -var BitSet = (function () { - function BitSet(nbits) { - if (nbits === void 0) { nbits = 64; } - var length = nbits >> 6; - if ((nbits & BitSet.LONG_MASK) != 0) - length++; - this._bits = new Array(length); - } - BitSet.prototype.and = function (bs) { - var max = Math.min(this._bits.length, bs._bits.length); - var i; - for (var i_1 = 0; i_1 < max; ++i_1) - this._bits[i_1] &= bs._bits[i_1]; - while (i < this._bits.length) - this._bits[i++] = 0; - }; - BitSet.prototype.andNot = function (bs) { - var i = Math.min(this._bits.length, bs._bits.length); - while (--i >= 0) - this._bits[i] &= ~bs._bits[i]; - }; - BitSet.prototype.cardinality = function () { - var card = 0; - for (var i = this._bits.length - 1; i >= 0; i--) { - var a = this._bits[i]; - if (a == 0) - continue; - if (a == -1) { - card += 64; - continue; + return postProcessor; + }; + Scene.prototype.getPostProcessor = function (type) { + for (var i = 0; i < this._postProcessors.length; i++) { + if (this._postProcessors[i] instanceof type) + return this._postProcessors[i]; } - a = ((a >> 1) & 0x5555555555555555) + (a & 0x5555555555555555); - a = ((a >> 2) & 0x3333333333333333) + (a & 0x3333333333333333); - var b = ((a >> 32) + a); - b = ((b >> 4) & 0x0f0f0f0f) + (b & 0x0f0f0f0f); - b = ((b >> 8) & 0x00ff00ff) + (b & 0x00ff00ff); - card += ((b >> 16) & 0x0000ffff) + (b & 0x0000ffff); - } - return card; - }; - BitSet.prototype.clear = function (pos) { - if (pos != undefined) { - var offset = pos >> 6; - this.ensure(offset); - this._bits[offset] &= ~(1 << pos); - } - else { - for (var i = 0; i < this._bits.length; i++) - this._bits[i] = 0; - } - }; - BitSet.prototype.ensure = function (lastElt) { - if (lastElt >= this._bits.length) { - var nd = new Number[lastElt + 1]; - nd = this._bits.copyWithin(0, 0, this._bits.length); - this._bits = nd; - } - }; - BitSet.prototype.get = function (pos) { - var offset = pos >> 6; - if (offset >= this._bits.length) - return false; - return (this._bits[offset] & (1 << pos)) != 0; - }; - BitSet.prototype.intersects = function (set) { - var i = Math.min(this._bits.length, set._bits.length); - while (--i >= 0) { - if ((this._bits[i] & set._bits[i]) != 0) - return true; - } - return false; - }; - BitSet.prototype.isEmpty = function () { - for (var i = this._bits.length - 1; i >= 0; i--) { - if (this._bits[i]) - return false; - } - return true; - }; - BitSet.prototype.nextSetBit = function (from) { - var offset = from >> 6; - var mask = 1 << from; - while (offset < this._bits.length) { - var h = this._bits[offset]; - do { - if ((h & mask) != 0) - return from; - mask <<= 1; - from++; - } while (mask != 0); - mask = 1; - offset++; - } - return -1; - }; - BitSet.prototype.set = function (pos, value) { - if (value === void 0) { value = true; } - if (value) { - var offset = pos >> 6; - this.ensure(offset); - this._bits[offset] |= 1 << pos; - } - else { - this.clear(pos); - } - }; - BitSet.LONG_MASK = 0x3f; - return BitSet; -}()); -var ComponentList = (function () { - function ComponentList(entity) { - this._components = []; - this._componentsToAdd = []; - this._componentsToRemove = []; - this._tempBufferList = []; - this._entity = entity; - } - Object.defineProperty(ComponentList.prototype, "count", { - get: function () { - return this._components.length; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(ComponentList.prototype, "buffer", { - get: function () { - return this._components; - }, - enumerable: true, - configurable: true - }); - ComponentList.prototype.add = function (component) { - this._componentsToAdd.push(component); - }; - ComponentList.prototype.remove = function (component) { - if (this._componentsToAdd.contains(component)) { - this._componentsToAdd.remove(component); - return; - } - this._componentsToRemove.push(component); - }; - ComponentList.prototype.removeAllComponents = function () { - for (var i = 0; i < this._components.length; i++) { - this.handleRemove(this._components[i]); - } - this._components.length = 0; - this._componentsToAdd.length = 0; - this._componentsToRemove.length = 0; - }; - ComponentList.prototype.deregisterAllComponents = function () { - for (var i = 0; i < this._components.length; i++) { - var component = this._components[i]; - if (component instanceof RenderableComponent) - this._entity.scene.renderableComponents.remove(component); - this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component), false); - this._entity.scene.entityProcessors.onComponentRemoved(this._entity); - } - }; - ComponentList.prototype.registerAllComponents = function () { - for (var i = 0; i < this._components.length; i++) { - var component = this._components[i]; - if (component instanceof RenderableComponent) - this._entity.scene.renderableComponents.add(component); - this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component)); - this._entity.scene.entityProcessors.onComponentAdded(this._entity); - } - }; - ComponentList.prototype.updateLists = function () { - if (this._componentsToRemove.length > 0) { - for (var i = 0; i < this._componentsToRemove.length; i++) { - this.handleRemove(this._componentsToRemove[i]); - this._components.remove(this._componentsToRemove[i]); + return null; + }; + Scene.prototype.removePostProcessor = function (postProcessor) { + if (!this._postProcessors.contains(postProcessor)) + return; + this._postProcessors.remove(postProcessor); + postProcessor.unload(); + }; + Scene.prototype.createEntity = function (name) { + var entity = new es.Entity(name); + return this.addEntity(entity); + }; + Scene.prototype.addEntity = function (entity) { + if (this.entities.buffer.contains(entity)) + console.warn("You are attempting to add the same entity to a scene twice: " + entity); + this.entities.add(entity); + entity.scene = this; + for (var i = 0; i < entity.transform.childCount; i++) + this.addEntity(entity.transform.getChild(i).entity); + return entity; + }; + Scene.prototype.destroyAllEntities = function () { + for (var i = 0; i < this.entities.count; i++) { + this.entities.buffer[i].destroy(); } - this._componentsToRemove.length = 0; + }; + Scene.prototype.findEntity = function (name) { + return this.entities.findEntity(name); + }; + Scene.prototype.findEntitiesWithTag = function (tag) { + return this.entities.entitiesWithTag(tag); + }; + Scene.prototype.entitiesOfType = function (type) { + return this.entities.entitiesOfType(type); + }; + Scene.prototype.findComponentOfType = function (type) { + return this.entities.findComponentOfType(type); + }; + Scene.prototype.findComponentsOfType = function (type) { + return this.entities.findComponentsOfType(type); + }; + Scene.prototype.addEntityProcessor = function (processor) { + processor.scene = this; + this.entityProcessors.add(processor); + return processor; + }; + Scene.prototype.removeEntityProcessor = function (processor) { + this.entityProcessors.remove(processor); + }; + Scene.prototype.getEntityProcessor = function () { + return this.entityProcessors.getProcessor(); + }; + return Scene; + }(egret.DisplayObjectContainer)); + es.Scene = Scene; +})(es || (es = {})); +var transform; +(function (transform) { + var Component; + (function (Component) { + Component[Component["position"] = 0] = "position"; + Component[Component["scale"] = 1] = "scale"; + Component[Component["rotation"] = 2] = "rotation"; + })(Component = transform.Component || (transform.Component = {})); +})(transform || (transform = {})); +var es; +(function (es) { + var HashObject = egret.HashObject; + var DirtyType; + (function (DirtyType) { + DirtyType[DirtyType["clean"] = 0] = "clean"; + DirtyType[DirtyType["positionDirty"] = 1] = "positionDirty"; + DirtyType[DirtyType["scaleDirty"] = 2] = "scaleDirty"; + DirtyType[DirtyType["rotationDirty"] = 3] = "rotationDirty"; + })(DirtyType = es.DirtyType || (es.DirtyType = {})); + var Transform = (function (_super) { + __extends(Transform, _super); + function Transform(entity) { + var _this = _super.call(this) || this; + _this._localTransform = es.Matrix2D.create(); + _this._worldTransform = es.Matrix2D.create().identity(); + _this._rotationMatrix = es.Matrix2D.create(); + _this._translationMatrix = es.Matrix2D.create(); + _this._scaleMatrix = es.Matrix2D.create(); + _this._worldToLocalTransform = es.Matrix2D.create().identity(); + _this._worldInverseTransform = es.Matrix2D.create().identity(); + _this._position = es.Vector2.zero; + _this._scale = es.Vector2.one; + _this._rotation = 0; + _this._localPosition = es.Vector2.zero; + _this._localScale = es.Vector2.one; + _this._localRotation = 0; + _this.entity = entity; + _this.scale = es.Vector2.one; + _this._children = []; + return _this; } - if (this._componentsToAdd.length > 0) { - for (var i = 0, count = this._componentsToAdd.length; i < count; i++) { - var component = this._componentsToAdd[i]; - if (component instanceof RenderableComponent) - this._entity.scene.renderableComponents.add(component); - this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component)); - this._entity.scene.entityProcessors.onComponentAdded(this._entity); - this._components.push(component); - this._tempBufferList.push(component); + Object.defineProperty(Transform.prototype, "childCount", { + get: function () { + return this._children.length; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Transform.prototype, "rotationDegrees", { + get: function () { + return es.MathHelper.toDegrees(this._rotation); + }, + set: function (value) { + this.setRotation(es.MathHelper.toRadians(value)); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Transform.prototype, "localRotationDegrees", { + get: function () { + return es.MathHelper.toDegrees(this._localRotation); + }, + set: function (value) { + this.localRotation = es.MathHelper.toRadians(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Transform.prototype, "localToWorldTransform", { + get: function () { + this.updateTransform(); + return this._worldTransform; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Transform.prototype, "parent", { + get: function () { + return this._parent; + }, + set: function (value) { + this.setParent(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Transform.prototype, "worldToLocalTransform", { + get: function () { + if (this._worldToLocalDirty) { + if (!this.parent) { + this._worldToLocalTransform = es.Matrix2D.create().identity(); + } + else { + this.parent.updateTransform(); + this._worldToLocalTransform = this.parent._worldTransform.invert(); + } + this._worldToLocalDirty = false; + } + return this._worldToLocalTransform; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Transform.prototype, "worldInverseTransform", { + get: function () { + this.updateTransform(); + if (this._worldInverseDirty) { + this._worldInverseTransform = this._worldTransform.invert(); + this._worldInverseDirty = false; + } + return this._worldInverseTransform; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Transform.prototype, "position", { + get: function () { + this.updateTransform(); + if (this._positionDirty) { + if (!this.parent) { + this._position = this._localPosition; + } + else { + this.parent.updateTransform(); + this._position = es.Vector2Ext.transformR(this._localPosition, this.parent._worldTransform); + } + this._positionDirty = false; + } + return this._position; + }, + set: function (value) { + this.setPosition(value.x, value.y); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Transform.prototype, "scale", { + get: function () { + this.updateTransform(); + return this._scale; + }, + set: function (value) { + this.setScale(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Transform.prototype, "rotation", { + get: function () { + this.updateTransform(); + return this._rotation; + }, + set: function (value) { + this.setRotation(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Transform.prototype, "localPosition", { + get: function () { + this.updateTransform(); + return this._localPosition; + }, + set: function (value) { + this.setLocalPosition(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Transform.prototype, "localScale", { + get: function () { + this.updateTransform(); + return this._localScale; + }, + set: function (value) { + this.setLocalScale(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Transform.prototype, "localRotation", { + get: function () { + this.updateTransform(); + return this._localRotation; + }, + set: function (value) { + this.setLocalRotation(value); + }, + enumerable: true, + configurable: true + }); + Transform.prototype.getChild = function (index) { + return this._children[index]; + }; + Transform.prototype.setParent = function (parent) { + if (this._parent.equals(parent)) + return this; + if (!this._parent) { + this._parent._children.remove(this); + this._parent._children.push(this); } - this._componentsToAdd.length = 0; - for (var i = 0; i < this._tempBufferList.length; i++) { - var component = this._tempBufferList[i]; - component.onAddedToEntity(); - if (component.enabled) { - component.onEnabled(); + this._parent = parent; + this.setDirty(DirtyType.positionDirty); + return this; + }; + Transform.prototype.setPosition = function (x, y) { + var position = new es.Vector2(x, y); + if (position.equals(this._position)) + return this; + this._position = position; + if (this.parent) { + this.localPosition = es.Vector2Ext.transformR(this._position, this._worldToLocalTransform); + } + else { + this.localPosition = position; + } + this._positionDirty = false; + return this; + }; + Transform.prototype.setLocalPosition = function (localPosition) { + if (localPosition.equals(this._localPosition)) + return this; + this._localPosition = localPosition; + this._localDirty = this._positionDirty = this._localPositionDirty = this._localRotationDirty = this._localScaleDirty = true; + this.setDirty(DirtyType.positionDirty); + return this; + }; + Transform.prototype.setRotation = function (radians) { + this._rotation = radians; + if (this.parent) { + this.localRotation = this.parent.rotation + radians; + } + else { + this.localRotation = radians; + } + return this; + }; + Transform.prototype.setRotationDegrees = function (degrees) { + return this.setRotation(es.MathHelper.toRadians(degrees)); + }; + Transform.prototype.lookAt = function (pos) { + var sign = this.position.x > pos.x ? -1 : 1; + var vectorToAlignTo = es.Vector2.normalize(es.Vector2.subtract(this.position, pos)); + this.rotation = sign * Math.acos(es.Vector2.dot(vectorToAlignTo, es.Vector2.unitY)); + }; + Transform.prototype.setLocalRotation = function (radians) { + this._localRotation = radians; + this._localDirty = this._positionDirty = this._localPositionDirty = this._localRotationDirty = this._localScaleDirty = true; + this.setDirty(DirtyType.rotationDirty); + return this; + }; + Transform.prototype.setLocalRotationDegrees = function (degrees) { + return this.setLocalRotation(es.MathHelper.toRadians(degrees)); + }; + Transform.prototype.setScale = function (scale) { + this._scale = scale; + if (this.parent) { + this.localScale = es.Vector2.divide(scale, this.parent._scale); + } + else { + this.localScale = scale; + } + return this; + }; + Transform.prototype.setLocalScale = function (scale) { + this._localScale = scale; + this._localDirty = this._positionDirty = this._localScaleDirty = true; + this.setDirty(DirtyType.scaleDirty); + return this; + }; + Transform.prototype.roundPosition = function () { + this.position = this._position.round(); + }; + Transform.prototype.updateTransform = function () { + if (this.hierarchyDirty != DirtyType.clean) { + if (this.parent) + this.parent.updateTransform(); + if (this._localDirty) { + if (this._localPositionDirty) { + this._translationMatrix = es.Matrix2D.create().translate(this._localPosition.x, this._localPosition.y); + this._localPositionDirty = false; + } + if (this._localRotationDirty) { + this._rotationMatrix = es.Matrix2D.create().rotate(this._localRotation); + this._localRotationDirty = false; + } + if (this._localScaleDirty) { + this._scaleMatrix = es.Matrix2D.create().scale(this._localScale.x, this._localScale.y); + this._localScaleDirty = false; + } + this._localTransform = this._scaleMatrix.multiply(this._rotationMatrix); + this._localTransform = this._localTransform.multiply(this._translationMatrix); + if (!this.parent) { + this._worldTransform = this._localTransform; + this._rotation = this._localRotation; + this._scale = this._localScale; + this._worldInverseDirty = true; + } + this._localDirty = false; + } + if (this.parent) { + this._worldTransform = this._localTransform.multiply(this.parent._worldTransform); + this._rotation = this._localRotation + this.parent._rotation; + this._scale = es.Vector2.multiply(this.parent._scale, this._localScale); + this._worldInverseDirty = true; + } + this._worldToLocalDirty = true; + this._positionDirty = true; + this.hierarchyDirty = DirtyType.clean; + } + }; + Transform.prototype.setDirty = function (dirtyFlagType) { + if ((this.hierarchyDirty & dirtyFlagType) == 0) { + this.hierarchyDirty |= dirtyFlagType; + switch (dirtyFlagType) { + case es.DirtyType.positionDirty: + this.entity.onTransformChanged(transform.Component.position); + break; + case es.DirtyType.rotationDirty: + this.entity.onTransformChanged(transform.Component.rotation); + break; + case es.DirtyType.scaleDirty: + this.entity.onTransformChanged(transform.Component.scale); + break; + } + if (!this._children) + this._children = []; + for (var i = 0; i < this._children.length; i++) + this._children[i].setDirty(dirtyFlagType); + } + }; + Transform.prototype.copyFrom = function (transform) { + this._position = transform.position; + this._localPosition = transform._localPosition; + this._rotation = transform._rotation; + this._localRotation = transform._localRotation; + this._scale = transform._scale; + this._localScale = transform._localScale; + this.setDirty(DirtyType.positionDirty); + this.setDirty(DirtyType.rotationDirty); + this.setDirty(DirtyType.scaleDirty); + }; + Transform.prototype.toString = function () { + return "[Transform: parent: " + this.parent + ", position: " + this.position + ", rotation: " + this.rotation + ",\n scale: " + this.scale + ", localPosition: " + this._localPosition + ", localRotation: " + this._localRotation + ",\n localScale: " + this._localScale + "]"; + }; + Transform.prototype.equals = function (other) { + return other.hashCode == this.hashCode; + }; + return Transform; + }(HashObject)); + es.Transform = Transform; +})(es || (es = {})); +var es; +(function (es) { + var CameraStyle; + (function (CameraStyle) { + CameraStyle[CameraStyle["lockOn"] = 0] = "lockOn"; + CameraStyle[CameraStyle["cameraWindow"] = 1] = "cameraWindow"; + })(CameraStyle = es.CameraStyle || (es.CameraStyle = {})); + var CameraInset = (function () { + function CameraInset() { + this.left = 0; + this.right = 0; + this.top = 0; + this.bottom = 0; + } + return CameraInset; + }()); + es.CameraInset = CameraInset; + var Camera = (function (_super) { + __extends(Camera, _super); + function Camera(targetEntity, cameraStyle) { + if (targetEntity === void 0) { targetEntity = null; } + if (cameraStyle === void 0) { cameraStyle = CameraStyle.lockOn; } + var _this = _super.call(this) || this; + _this._inset = new CameraInset(); + _this._areMatrixedDirty = true; + _this._areBoundsDirty = true; + _this._isProjectionMatrixDirty = true; + _this.followLerp = 0.1; + _this.deadzone = new es.Rectangle(); + _this.focusOffset = es.Vector2.zero; + _this.mapLockEnabled = false; + _this.mapSize = es.Vector2.zero; + _this._desiredPositionDelta = new es.Vector2(); + _this._worldSpaceDeadZone = new es.Rectangle(); + _this._minimumZoom = 0.3; + _this._maximumZoom = 3; + _this._bounds = new es.Rectangle(); + _this._transformMatrix = new es.Matrix2D().identity(); + _this._inverseTransformMatrix = new es.Matrix2D().identity(); + _this._origin = es.Vector2.zero; + _this._targetEntity = targetEntity; + _this._cameraStyle = cameraStyle; + _this.setZoom(0); + return _this; + } + Object.defineProperty(Camera.prototype, "position", { + get: function () { + return this.entity.transform.position; + }, + set: function (value) { + this.entity.transform.position = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Camera.prototype, "rotation", { + get: function () { + return this.entity.transform.rotation; + }, + set: function (value) { + this.entity.transform.rotation = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Camera.prototype, "zoom", { + get: function () { + if (this._zoom == 0) + return 1; + if (this._zoom < 1) + return es.MathHelper.map(this._zoom, this._minimumZoom, 1, -1, 0); + return es.MathHelper.map(this._zoom, 1, this._maximumZoom, 0, 1); + }, + set: function (value) { + this.setZoom(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Camera.prototype, "minimumZoom", { + get: function () { + return this._minimumZoom; + }, + set: function (value) { + this.setMinimumZoom(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Camera.prototype, "maximumZoom", { + get: function () { + return this._maximumZoom; + }, + set: function (value) { + this.setMaximumZoom(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Camera.prototype, "bounds", { + get: function () { + if (this._areMatrixedDirty) + this.updateMatrixes(); + if (this._areBoundsDirty) { + var topLeft = this.screenToWorldPoint(new es.Vector2(this._inset.left, this._inset.top)); + var bottomRight = this.screenToWorldPoint(new es.Vector2(es.Core.graphicsDevice.viewport.width - this._inset.right, es.Core.graphicsDevice.viewport.height - this._inset.bottom)); + if (this.entity.transform.rotation != 0) { + var topRight = this.screenToWorldPoint(new es.Vector2(es.Core.graphicsDevice.viewport.width - this._inset.right, this._inset.top)); + var bottomLeft = this.screenToWorldPoint(new es.Vector2(this._inset.left, es.Core.graphicsDevice.viewport.height - this._inset.bottom)); + var minX = Math.min(topLeft.x, bottomRight.x, topRight.x, bottomLeft.x); + var maxX = Math.max(topLeft.x, bottomRight.x, topRight.x, bottomLeft.x); + var minY = Math.min(topLeft.y, bottomRight.y, topRight.y, bottomLeft.y); + var maxY = Math.max(topLeft.y, bottomRight.y, topRight.y, bottomLeft.y); + this._bounds.location = new es.Vector2(minX, minY); + this._bounds.width = maxX - minX; + this._bounds.height = maxY - minY; + } + else { + this._bounds.location = topLeft; + this._bounds.width = bottomRight.x - topLeft.x; + this._bounds.height = bottomRight.y - topLeft.y; + } + this._areBoundsDirty = false; + } + return this._bounds; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Camera.prototype, "transformMatrix", { + get: function () { + if (this._areMatrixedDirty) + this.updateMatrixes(); + return this._transformMatrix; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Camera.prototype, "inverseTransformMatrix", { + get: function () { + if (this._areMatrixedDirty) + this.updateMatrixes(); + return this._inverseTransformMatrix; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Camera.prototype, "origin", { + get: function () { + return this._origin; + }, + set: function (value) { + if (this._origin != value) { + this._origin = value; + this._areMatrixedDirty = true; + } + }, + enumerable: true, + configurable: true + }); + Camera.prototype.onSceneSizeChanged = function (newWidth, newHeight) { + var oldOrigin = this._origin; + this.origin = new es.Vector2(newWidth / 2, newHeight / 2); + this.entity.transform.position = es.Vector2.add(this.entity.transform.position, es.Vector2.subtract(this._origin, oldOrigin)); + }; + Camera.prototype.setInset = function (left, right, top, bottom) { + this._inset = new CameraInset(); + this._inset.left = left; + this._inset.right = right; + this._inset.top = top; + this._inset.bottom = bottom; + this._areBoundsDirty = true; + return this; + }; + Camera.prototype.setPosition = function (position) { + this.entity.transform.setPosition(position.x, position.y); + return this; + }; + Camera.prototype.setRotation = function (rotation) { + this.entity.transform.setRotation(rotation); + return this; + }; + Camera.prototype.setZoom = function (zoom) { + var newZoom = es.MathHelper.clamp(zoom, -1, 1); + if (newZoom == 0) { + this._zoom = 1; + } + else if (newZoom < 0) { + this._zoom = es.MathHelper.map(newZoom, -1, 0, this._minimumZoom, 1); + } + else { + this._zoom = es.MathHelper.map(newZoom, 0, 1, 1, this._maximumZoom); + } + this._areMatrixedDirty = true; + return this; + }; + Camera.prototype.setMinimumZoom = function (minZoom) { + if (minZoom <= 0) { + console.error("minimumZoom must be greater than zero"); + return; + } + if (this._zoom < minZoom) + this._zoom = this.minimumZoom; + this._minimumZoom = minZoom; + return this; + }; + Camera.prototype.setMaximumZoom = function (maxZoom) { + if (maxZoom <= 0) { + console.error("maximumZoom must be greater than zero"); + return; + } + if (this._zoom > maxZoom) + this._zoom = maxZoom; + this._maximumZoom = maxZoom; + return this; + }; + Camera.prototype.onEntityTransformChanged = function (comp) { + this._areMatrixedDirty = true; + }; + Camera.prototype.zoomIn = function (deltaZoom) { + this.zoom += deltaZoom; + }; + Camera.prototype.zoomOut = function (deltaZoom) { + this.zoom -= deltaZoom; + }; + Camera.prototype.worldToScreenPoint = function (worldPosition) { + this.updateMatrixes(); + worldPosition = es.Vector2.transform(worldPosition, this._transformMatrix); + return worldPosition; + }; + Camera.prototype.screenToWorldPoint = function (screenPosition) { + this.updateMatrixes(); + screenPosition = es.Vector2.transform(screenPosition, this._inverseTransformMatrix); + return screenPosition; + }; + Camera.prototype.mouseToWorldPoint = function () { + return this.screenToWorldPoint(es.Input.touchPosition); + }; + Camera.prototype.onAddedToEntity = function () { + this.follow(this._targetEntity, this._cameraStyle); + }; + Camera.prototype.update = function () { + var halfScreen = es.Vector2.multiply(new es.Vector2(this.bounds.width, this.bounds.height), new es.Vector2(0.5)); + this._worldSpaceDeadZone.x = this.position.x - halfScreen.x * es.Core.scene.scaleX + this.deadzone.x + this.focusOffset.x; + this._worldSpaceDeadZone.y = this.position.y - halfScreen.y * es.Core.scene.scaleY + this.deadzone.y + this.focusOffset.y; + this._worldSpaceDeadZone.width = this.deadzone.width; + this._worldSpaceDeadZone.height = this.deadzone.height; + if (this._targetEntity) + this.updateFollow(); + this.position = es.Vector2.lerp(this.position, es.Vector2.add(this.position, this._desiredPositionDelta), this.followLerp); + this.entity.transform.roundPosition(); + if (this.mapLockEnabled) { + this.position = this.clampToMapSize(this.position); + this.entity.transform.roundPosition(); + } + }; + Camera.prototype.clampToMapSize = function (position) { + var halfScreen = es.Vector2.multiply(new es.Vector2(this.bounds.width, this.bounds.height), new es.Vector2(0.5)); + var cameraMax = new es.Vector2(this.mapSize.x - halfScreen.x, this.mapSize.y - halfScreen.y); + return es.Vector2.clamp(position, halfScreen, cameraMax); + }; + Camera.prototype.updateFollow = function () { + this._desiredPositionDelta.x = this._desiredPositionDelta.y = 0; + if (this._cameraStyle == CameraStyle.lockOn) { + var targetX = this._targetEntity.transform.position.x; + var targetY = this._targetEntity.transform.position.y; + if (this._worldSpaceDeadZone.x > targetX) + this._desiredPositionDelta.x = targetX - this._worldSpaceDeadZone.x; + else if (this._worldSpaceDeadZone.x < targetX) + this._desiredPositionDelta.x = targetX - this._worldSpaceDeadZone.x; + if (this._worldSpaceDeadZone.y < targetY) + this._desiredPositionDelta.y = targetY - this._worldSpaceDeadZone.y; + else if (this._worldSpaceDeadZone.y > targetY) + this._desiredPositionDelta.y = targetY - this._worldSpaceDeadZone.y; + } + else { + if (!this._targetCollider) { + this._targetCollider = this._targetEntity.getComponent(es.Collider); + if (!this._targetCollider) + return; + } + var targetBounds = this._targetEntity.getComponent(es.Collider).bounds; + if (!this._worldSpaceDeadZone.containsRect(targetBounds)) { + if (this._worldSpaceDeadZone.left > targetBounds.left) + this._desiredPositionDelta.x = targetBounds.left - this._worldSpaceDeadZone.left; + else if (this._worldSpaceDeadZone.right < targetBounds.right) + this._desiredPositionDelta.x = targetBounds.right - this._worldSpaceDeadZone.right; + if (this._worldSpaceDeadZone.bottom < targetBounds.bottom) + this._desiredPositionDelta.y = targetBounds.bottom - this._worldSpaceDeadZone.bottom; + else if (this._worldSpaceDeadZone.top > targetBounds.top) + this._desiredPositionDelta.y = targetBounds.top - this._worldSpaceDeadZone.top; } } - this._tempBufferList.length = 0; + }; + Camera.prototype.follow = function (targetEntity, cameraStyle) { + if (cameraStyle === void 0) { cameraStyle = CameraStyle.cameraWindow; } + this._targetEntity = targetEntity; + this._cameraStyle = cameraStyle; + switch (this._cameraStyle) { + case CameraStyle.cameraWindow: + var w = this.bounds.width / 6; + var h = this.bounds.height / 3; + this.deadzone = new es.Rectangle((this.bounds.width - w) / 2, (this.bounds.height - h) / 2, w, h); + break; + case CameraStyle.lockOn: + this.deadzone = new es.Rectangle(this.bounds.width / 2, this.bounds.height / 2, 10, 10); + break; + } + }; + Camera.prototype.setCenteredDeadzone = function (width, height) { + this.deadzone = new es.Rectangle((this.bounds.width - width) / 2, (this.bounds.height - height) / 2, width, height); + }; + Camera.prototype.updateMatrixes = function () { + if (!this._areMatrixedDirty) + return; + var tempMat; + this._transformMatrix = es.Matrix2D.create().translate(-this.entity.transform.position.x, -this.entity.transform.position.y); + if (this._zoom != 1) { + tempMat = es.Matrix2D.create().scale(this._zoom, this._zoom); + this._transformMatrix = this._transformMatrix.multiply(tempMat); + } + if (this.entity.transform.rotation != 0) { + tempMat = es.Matrix2D.create().rotate(this.entity.transform.rotation); + this._transformMatrix = this._transformMatrix.multiply(tempMat); + } + tempMat = es.Matrix2D.create().translate(this._origin.x, this._origin.y); + this._transformMatrix = this._transformMatrix.multiply(tempMat); + this._inverseTransformMatrix = this._transformMatrix.invert(); + this._areBoundsDirty = true; + this._areMatrixedDirty = false; + }; + return Camera; + }(es.Component)); + es.Camera = Camera; +})(es || (es = {})); +var es; +(function (es) { + var ComponentPool = (function () { + function ComponentPool(typeClass) { + this._type = typeClass; + this._cache = []; } - }; - ComponentList.prototype.onEntityTransformChanged = function (comp) { - for (var i = 0; i < this._components.length; i++) { - if (this._components[i].enabled) - this._components[i].onEntityTransformChanged(comp); + ComponentPool.prototype.obtain = function () { + try { + return this._cache.length > 0 ? this._cache.shift() : new this._type(); + } + catch (err) { + throw new Error(this._type + err); + } + }; + ComponentPool.prototype.free = function (component) { + component.reset(); + this._cache.push(component); + }; + return ComponentPool; + }()); + es.ComponentPool = ComponentPool; +})(es || (es = {})); +var es; +(function (es) { + var IUpdatableComparer = (function () { + function IUpdatableComparer() { } - for (var i = 0; i < this._componentsToAdd.length; i++) { - if (this._componentsToAdd[i].enabled) - this._componentsToAdd[i].onEntityTransformChanged(comp); + IUpdatableComparer.prototype.compare = function (a, b) { + return a.updateOrder - b.updateOrder; + }; + return IUpdatableComparer; + }()); + es.IUpdatableComparer = IUpdatableComparer; +})(es || (es = {})); +var es; +(function (es) { + var PooledComponent = (function (_super) { + __extends(PooledComponent, _super); + function PooledComponent() { + return _super !== null && _super.apply(this, arguments) || this; } - }; - ComponentList.prototype.handleRemove = function (component) { - if (component instanceof RenderableComponent) - this._entity.scene.renderableComponents.remove(component); - this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component), false); - this._entity.scene.entityProcessors.onComponentRemoved(this._entity); - component.onRemovedFromEntity(); - component.entity = null; - }; - ComponentList.prototype.getComponent = function (type, onlyReturnInitializedComponents) { - for (var i = 0; i < this._components.length; i++) { - var component = this._components[i]; - if (component instanceof type) - return component; + return PooledComponent; + }(es.Component)); + es.PooledComponent = PooledComponent; +})(es || (es = {})); +var es; +(function (es) { + var RenderableComponent = (function (_super) { + __extends(RenderableComponent, _super); + function RenderableComponent() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.displayObject = new egret.DisplayObject(); + _this.color = 0x000000; + _this._areBoundsDirty = true; + _this._localOffset = es.Vector2.zero; + _this._renderLayer = 0; + _this._bounds = new es.Rectangle(); + return _this; } - if (!onlyReturnInitializedComponents) { - for (var i = 0; i < this._componentsToAdd.length; i++) { - var component = this._componentsToAdd[i]; + Object.defineProperty(RenderableComponent.prototype, "width", { + get: function () { + return this.bounds.width; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(RenderableComponent.prototype, "height", { + get: function () { + return this.bounds.height; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(RenderableComponent.prototype, "localOffset", { + get: function () { + return this._localOffset; + }, + set: function (value) { + this.setLocalOffset(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(RenderableComponent.prototype, "renderLayer", { + get: function () { + return this._renderLayer; + }, + set: function (value) { + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(RenderableComponent.prototype, "bounds", { + get: function () { + if (this._areBoundsDirty) { + this._bounds.calculateBounds(this.entity.transform.position, this._localOffset, es.Vector2.zero, this.entity.transform.scale, this.entity.transform.rotation, this.width, this.height); + this._areBoundsDirty = false; + } + return this._bounds; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(RenderableComponent.prototype, "isVisible", { + get: function () { + return this._isVisible; + }, + set: function (value) { + if (this._isVisible != value) { + this._isVisible = value; + if (this._isVisible) + this.onBecameVisible(); + else + this.onBecameInvisible(); + } + }, + enumerable: true, + configurable: true + }); + RenderableComponent.prototype.onEntityTransformChanged = function (comp) { + this._areBoundsDirty = true; + }; + RenderableComponent.prototype.isVisibleFromCamera = function (camera) { + this.isVisible = camera.bounds.intersects(this.bounds); + return this.isVisible; + }; + RenderableComponent.prototype.setRenderLayer = function (renderLayer) { + if (renderLayer != this._renderLayer) { + var oldRenderLayer = this._renderLayer; + this._renderLayer = renderLayer; + if (this.entity && this.entity.scene) + this.entity.scene.renderableComponents.updateRenderableRenderLayer(this, oldRenderLayer, this._renderLayer); + } + return this; + }; + RenderableComponent.prototype.setColor = function (color) { + this.color = color; + return this; + }; + RenderableComponent.prototype.setLocalOffset = function (offset) { + if (this._localOffset != offset) { + this._localOffset = offset; + } + return this; + }; + RenderableComponent.prototype.sync = function (camera) { + this.displayObject.x = this.entity.position.x + this.localOffset.x - camera.position.x + camera.origin.x; + this.displayObject.y = this.entity.position.y + this.localOffset.y - camera.position.y + camera.origin.y; + this.displayObject.scaleX = this.entity.scale.x; + this.displayObject.scaleY = this.entity.scale.y; + this.displayObject.rotation = this.entity.rotation; + }; + RenderableComponent.prototype.toString = function () { + return "[RenderableComponent] renderLayer: " + this.renderLayer; + }; + RenderableComponent.prototype.onBecameVisible = function () { + this.displayObject.visible = this.isVisible; + }; + RenderableComponent.prototype.onBecameInvisible = function () { + this.displayObject.visible = this.isVisible; + }; + return RenderableComponent; + }(es.Component)); + es.RenderableComponent = RenderableComponent; +})(es || (es = {})); +var es; +(function (es) { + var Mesh = (function (_super) { + __extends(Mesh, _super); + function Mesh() { + var _this = _super.call(this) || this; + _this._mesh = new egret.Mesh(); + return _this; + } + Mesh.prototype.setTexture = function (texture) { + this._mesh.texture = texture; + this._mesh.$renderNode = new egret.sys.RenderNode(); + return this; + }; + Mesh.prototype.reset = function () { + }; + Mesh.prototype.render = function (camera) { + }; + return Mesh; + }(es.RenderableComponent)); + es.Mesh = Mesh; +})(es || (es = {})); +var es; +(function (es) { + var Bitmap = egret.Bitmap; + var SpriteRenderer = (function (_super) { + __extends(SpriteRenderer, _super); + function SpriteRenderer(sprite) { + if (sprite === void 0) { sprite = null; } + var _this = _super.call(this) || this; + if (sprite instanceof es.Sprite) + _this.setSprite(sprite); + else if (sprite instanceof egret.Texture) + _this.setSprite(new es.Sprite(sprite)); + return _this; + } + Object.defineProperty(SpriteRenderer.prototype, "bounds", { + get: function () { + 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; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(SpriteRenderer.prototype, "originNormalized", { + get: function () { + return new es.Vector2(this._origin.x / this.width * this.entity.transform.scale.x, this._origin.y / this.height * this.entity.transform.scale.y); + }, + set: function (value) { + this.setOrigin(new es.Vector2(value.x * this.width / this.entity.transform.scale.x, value.y * this.height / this.entity.transform.scale.y)); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(SpriteRenderer.prototype, "origin", { + get: function () { + return this._origin; + }, + set: function (value) { + this.setOrigin(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(SpriteRenderer.prototype, "sprite", { + get: function () { + return this._sprite; + }, + set: function (value) { + this.setSprite(value); + }, + enumerable: true, + configurable: true + }); + SpriteRenderer.prototype.setSprite = function (sprite) { + 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; + }; + SpriteRenderer.prototype.setOrigin = function (origin) { + if (this._origin != origin) { + this._origin = origin; + this.displayObject.anchorOffsetX = this._origin.x; + this.displayObject.anchorOffsetY = this._origin.y; + this._areBoundsDirty = true; + } + return this; + }; + SpriteRenderer.prototype.setOriginNormalized = function (value) { + this.setOrigin(new es.Vector2(value.x * this.width / this.entity.transform.scale.x, value.y * this.height / this.entity.transform.scale.y)); + return this; + }; + SpriteRenderer.prototype.render = function (camera) { + this.sync(camera); + this.displayObject.x = this.entity.position.x - this.origin.x + this.localOffset.x - camera.position.x + camera.origin.x; + this.displayObject.y = this.entity.position.y - this.origin.y + this.localOffset.y - camera.position.y + camera.origin.y; + }; + return SpriteRenderer; + }(es.RenderableComponent)); + es.SpriteRenderer = SpriteRenderer; +})(es || (es = {})); +var es; +(function (es) { + var TiledSpriteRenderer = (function (_super) { + __extends(TiledSpriteRenderer, _super); + function TiledSpriteRenderer(sprite) { + var _this = _super.call(this, sprite) || this; + _this._sourceRect = new es.Rectangle(); + _this._textureScale = es.Vector2.one; + _this._inverseTexScale = es.Vector2.one; + _this._sourceRect = sprite.sourceRect; + var bitmap = _this.displayObject; + bitmap.$fillMode = egret.BitmapFillMode.REPEAT; + return _this; + } + Object.defineProperty(TiledSpriteRenderer.prototype, "bounds", { + get: function () { + 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; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(TiledSpriteRenderer.prototype, "scrollX", { + get: function () { + return this._sourceRect.x; + }, + set: function (value) { + this._sourceRect.x = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(TiledSpriteRenderer.prototype, "scrollY", { + get: function () { + return this._sourceRect.y; + }, + set: function (value) { + this._sourceRect.y = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(TiledSpriteRenderer.prototype, "textureScale", { + get: function () { + return this._textureScale; + }, + set: function (value) { + this._textureScale = value; + this._inverseTexScale = new es.Vector2(1 / this._textureScale.x, 1 / this._textureScale.y); + this._sourceRect.width = this._sprite.sourceRect.width * this._inverseTexScale.x; + this._sourceRect.height = this._sprite.sourceRect.height * this._inverseTexScale.y; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(TiledSpriteRenderer.prototype, "width", { + get: function () { + return this._sourceRect.width; + }, + set: function (value) { + this._areBoundsDirty = true; + this._sourceRect.width = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(TiledSpriteRenderer.prototype, "height", { + get: function () { + return this._sourceRect.height; + }, + set: function (value) { + this._areBoundsDirty = true; + this._sourceRect.height = value; + }, + enumerable: true, + configurable: true + }); + TiledSpriteRenderer.prototype.render = function (camera) { + var bitmap = this.displayObject; + bitmap.width = this.width; + bitmap.height = this.height; + _super.prototype.render.call(this, camera); + }; + return TiledSpriteRenderer; + }(es.SpriteRenderer)); + es.TiledSpriteRenderer = TiledSpriteRenderer; +})(es || (es = {})); +var es; +(function (es) { + var ScrollingSpriteRenderer = (function (_super) { + __extends(ScrollingSpriteRenderer, _super); + function ScrollingSpriteRenderer(sprite) { + var _this = _super.call(this, sprite) || this; + _this.scrollSpeedX = 15; + _this.scroolSpeedY = 0; + _this._scrollX = 0; + _this._scrollY = 0; + return _this; + } + Object.defineProperty(ScrollingSpriteRenderer.prototype, "textureScale", { + get: function () { + return this._textureScale; + }, + set: function (value) { + this._textureScale = value; + this._inverseTexScale = new es.Vector2(1 / this._textureScale.x, 1 / this._textureScale.y); + }, + enumerable: true, + configurable: true + }); + ScrollingSpriteRenderer.prototype.update = function () { + this._scrollX += this.scrollSpeedX * es.Time.deltaTime; + this._scrollY += this.scroolSpeedY * es.Time.deltaTime; + this._sourceRect.x = this._scrollX; + this._sourceRect.y = this._scrollY; + }; + return ScrollingSpriteRenderer; + }(es.TiledSpriteRenderer)); + es.ScrollingSpriteRenderer = ScrollingSpriteRenderer; +})(es || (es = {})); +var es; +(function (es) { + var Sprite = (function () { + function Sprite(texture, sourceRect, origin) { + if (sourceRect === void 0) { sourceRect = new es.Rectangle(0, 0, texture.textureWidth, texture.textureHeight); } + if (origin === void 0) { origin = sourceRect.getHalfSize(); } + this.uvs = new es.Rectangle(); + this.texture2D = texture; + this.sourceRect = sourceRect; + this.center = new es.Vector2(sourceRect.width * 0.5, sourceRect.height * 0.5); + this.origin = origin; + var inverseTexW = 1 / texture.textureWidth; + var 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; + } + return Sprite; + }()); + es.Sprite = Sprite; +})(es || (es = {})); +var es; +(function (es) { + var SpriteAnimation = (function () { + function SpriteAnimation(sprites, frameRate) { + this.sprites = sprites; + this.frameRate = frameRate; + } + return SpriteAnimation; + }()); + es.SpriteAnimation = SpriteAnimation; +})(es || (es = {})); +var es; +(function (es) { + var LoopMode; + (function (LoopMode) { + LoopMode[LoopMode["loop"] = 0] = "loop"; + LoopMode[LoopMode["once"] = 1] = "once"; + LoopMode[LoopMode["clampForever"] = 2] = "clampForever"; + LoopMode[LoopMode["pingPong"] = 3] = "pingPong"; + LoopMode[LoopMode["pingPongOnce"] = 4] = "pingPongOnce"; + })(LoopMode = es.LoopMode || (es.LoopMode = {})); + var State; + (function (State) { + State[State["none"] = 0] = "none"; + State[State["running"] = 1] = "running"; + State[State["paused"] = 2] = "paused"; + State[State["completed"] = 3] = "completed"; + })(State = es.State || (es.State = {})); + var SpriteAnimator = (function (_super) { + __extends(SpriteAnimator, _super); + function SpriteAnimator(sprite) { + var _this = _super.call(this, sprite) || this; + _this.speed = 1; + _this.animationState = State.none; + _this._elapsedTime = 0; + _this._animations = new Map(); + return _this; + } + Object.defineProperty(SpriteAnimator.prototype, "isRunning", { + get: function () { + return this.animationState == State.running; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(SpriteAnimator.prototype, "animations", { + get: function () { + return this._animations; + }, + enumerable: true, + configurable: true + }); + SpriteAnimator.prototype.update = function () { + if (this.animationState != State.running || !this.currentAnimation) + return; + var animation = this.currentAnimation; + var secondsPerFrame = 1 / (animation.frameRate * this.speed); + var iterationDuration = secondsPerFrame * animation.sprites.length; + this._elapsedTime += es.Time.deltaTime; + var 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; + } + var i = Math.floor(time / secondsPerFrame); + var n = animation.sprites.length; + if (n > 2 && (this._loopMode == LoopMode.pingPong || this._loopMode == LoopMode.pingPongOnce)) { + var maxIndex = n - 1; + this.currentFrame = maxIndex - Math.abs(maxIndex - i % (maxIndex * 2)); + } + else { + this.currentFrame = i % n; + } + this.sprite = animation.sprites[this.currentFrame]; + }; + SpriteAnimator.prototype.addAnimation = function (name, animation) { + if (!this.sprite && animation.sprites.length > 0) + this.setSprite(animation.sprites[0]); + this._animations[name] = animation; + return this; + }; + SpriteAnimator.prototype.play = function (name, loopMode) { + if (loopMode === void 0) { 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; + }; + SpriteAnimator.prototype.isAnimationActive = function (name) { + return this.currentAnimation && this.currentAnimationName == name; + }; + SpriteAnimator.prototype.pause = function () { + this.animationState = State.paused; + }; + SpriteAnimator.prototype.unPause = function () { + this.animationState = State.running; + }; + SpriteAnimator.prototype.stop = function () { + this.currentAnimation = null; + this.currentAnimationName = null; + this.currentFrame = 0; + this.animationState = State.none; + }; + return SpriteAnimator; + }(es.SpriteRenderer)); + es.SpriteAnimator = SpriteAnimator; +})(es || (es = {})); +var es; +(function (es) { + var Mover = (function (_super) { + __extends(Mover, _super); + function Mover() { + return _super !== null && _super.apply(this, arguments) || this; + } + Mover.prototype.onAddedToEntity = function () { + this._triggerHelper = new es.ColliderTriggerHelper(this.entity); + }; + Mover.prototype.calculateMovement = function (motion, collisionResult) { + if (!this.entity.getComponent(es.Collider) || !this._triggerHelper) { + return false; + } + var colliders = this.entity.getComponents(es.Collider); + for (var i = 0; i < colliders.length; i++) { + var collider = colliders[i]; + if (collider.isTrigger) + continue; + var bounds = collider.bounds; + bounds.x += motion.x; + bounds.y += motion.y; + var neighbors = es.Physics.boxcastBroadphaseExcludingSelf(collider, bounds, collider.collidesWithLayers); + for (var j = 0; j < neighbors.length; j++) { + var neighbor = neighbors[j]; + if (neighbor.isTrigger) + continue; + var _internalcollisionResult = new es.CollisionResult(); + if (collider.collidesWith(neighbor, motion, _internalcollisionResult)) { + motion = motion.subtract(_internalcollisionResult.minimumTranslationVector); + if (_internalcollisionResult.collider != null) { + collisionResult = _internalcollisionResult; + } + } + } + } + es.ListPool.free(colliders); + return collisionResult.collider != null; + }; + Mover.prototype.applyMovement = function (motion) { + this.entity.position = es.Vector2.add(this.entity.position, motion); + if (this._triggerHelper) + this._triggerHelper.update(); + }; + Mover.prototype.move = function (motion, collisionResult) { + this.calculateMovement(motion, collisionResult); + this.applyMovement(motion); + return collisionResult.collider != null; + }; + return Mover; + }(es.Component)); + es.Mover = Mover; +})(es || (es = {})); +var es; +(function (es) { + var ProjectileMover = (function (_super) { + __extends(ProjectileMover, _super); + function ProjectileMover() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this._tempTriggerList = []; + return _this; + } + ProjectileMover.prototype.onAddedToEntity = function () { + this._collider = this.entity.getComponent(es.Collider); + if (!this._collider) + console.warn("ProjectileMover has no Collider. ProjectilMover requires a Collider!"); + }; + ProjectileMover.prototype.move = function (motion) { + if (!this._collider) + return false; + var didCollide = false; + this.entity.position = es.Vector2.add(this.entity.position, motion); + var neighbors = es.Physics.boxcastBroadphase(this._collider.bounds, this._collider.collidesWithLayers); + for (var i = 0; i < neighbors.length; i++) { + var neighbor = neighbors[i]; + if (this._collider.overlaps(neighbor) && neighbor.enabled) { + didCollide = true; + this.notifyTriggerListeners(this._collider, neighbor); + } + } + return didCollide; + }; + ProjectileMover.prototype.notifyTriggerListeners = function (self, other) { + other.entity.getComponents("ITriggerListener", this._tempTriggerList); + for (var i = 0; i < this._tempTriggerList.length; i++) { + this._tempTriggerList[i].onTriggerEnter(self, other); + } + this._tempTriggerList.length = 0; + this.entity.getComponents("ITriggerListener", this._tempTriggerList); + for (var i = 0; i < this._tempTriggerList.length; i++) { + this._tempTriggerList[i].onTriggerEnter(other, self); + } + this._tempTriggerList.length = 0; + }; + return ProjectileMover; + }(es.Component)); + es.ProjectileMover = ProjectileMover; +})(es || (es = {})); +var es; +(function (es) { + var Collider = (function (_super) { + __extends(Collider, _super); + function Collider() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.physicsLayer = 1 << 0; + _this.collidesWithLayers = es.Physics.allLayers; + _this.shouldColliderScaleAndRotateWithTransform = true; + _this.registeredPhysicsBounds = new es.Rectangle(); + _this._isPositionDirty = true; + _this._isRotationDirty = true; + _this._localOffset = es.Vector2.zero; + return _this; + } + Object.defineProperty(Collider.prototype, "absolutePosition", { + get: function () { + return es.Vector2.add(this.entity.transform.position, this._localOffset); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Collider.prototype, "rotation", { + get: function () { + if (this.shouldColliderScaleAndRotateWithTransform && this.entity) + return this.entity.transform.rotation; + return 0; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Collider.prototype, "bounds", { + get: function () { + if (this._isPositionDirty || this._isRotationDirty) { + this.shape.recalculateBounds(this); + this._isPositionDirty = this._isRotationDirty = false; + } + return this.shape.bounds; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Collider.prototype, "localOffset", { + get: function () { + return this._localOffset; + }, + set: function (value) { + this.setLocalOffset(value); + }, + enumerable: true, + configurable: true + }); + Collider.prototype.setLocalOffset = function (offset) { + if (this._localOffset != offset) { + this.unregisterColliderWithPhysicsSystem(); + this._localOffset = offset; + this._localOffsetLength = this._localOffset.length(); + this._isPositionDirty = true; + this.registerColliderWithPhysicsSystem(); + } + return this; + }; + Collider.prototype.setShouldColliderScaleAndRotateWithTransform = function (shouldColliderScaleAndRotationWithTransform) { + this.shouldColliderScaleAndRotateWithTransform = shouldColliderScaleAndRotationWithTransform; + this._isPositionDirty = this._isRotationDirty = true; + return this; + }; + Collider.prototype.onAddedToEntity = function () { + if (this._colliderRequiresAutoSizing) { + if (!(this instanceof es.BoxCollider || this instanceof es.CircleCollider)) { + console.error("Only box and circle colliders can be created automatically"); + return; + } + var renderable = this.entity.getComponent(es.RenderableComponent); + if (renderable) { + var renderableBounds = renderable.bounds; + var width = renderableBounds.width / this.entity.scale.x; + var height = renderableBounds.height / this.entity.scale.y; + if (this instanceof es.CircleCollider) { + this.radius = Math.max(width, height) * 0.5; + } + else { + this.width = width; + this.height = height; + } + this.localOffset = es.Vector2.subtract(renderableBounds.center, this.entity.transform.position); + } + else { + console.warn("Collider has no shape and no RenderableComponent. Can't figure out how to size it."); + } + } + this._isParentEntityAddedToScene = true; + this.registerColliderWithPhysicsSystem(); + }; + Collider.prototype.onRemovedFromEntity = function () { + this.unregisterColliderWithPhysicsSystem(); + this._isParentEntityAddedToScene = false; + }; + Collider.prototype.onEntityTransformChanged = function (comp) { + switch (comp) { + case transform.Component.position: + this._isPositionDirty = true; + break; + case transform.Component.scale: + this._isPositionDirty = true; + break; + case transform.Component.rotation: + this._isRotationDirty = true; + break; + } + if (this._isColliderRegistered) + es.Physics.updateCollider(this); + }; + Collider.prototype.onEnabled = function () { + this.registerColliderWithPhysicsSystem(); + this._isPositionDirty = this._isRotationDirty = true; + }; + Collider.prototype.onDisabled = function () { + this.unregisterColliderWithPhysicsSystem(); + }; + Collider.prototype.registerColliderWithPhysicsSystem = function () { + if (this._isParentEntityAddedToScene && !this._isColliderRegistered) { + es.Physics.addCollider(this); + this._isColliderRegistered = true; + } + }; + Collider.prototype.unregisterColliderWithPhysicsSystem = function () { + if (this._isParentEntityAddedToScene && this._isColliderRegistered) { + es.Physics.removeCollider(this); + } + this._isColliderRegistered = false; + }; + Collider.prototype.overlaps = function (other) { + return this.shape.overlaps(other.shape); + }; + Collider.prototype.collidesWith = function (collider, motion, result) { + var oldPosition = this.entity.position; + this.entity.position = this.entity.position.add(motion); + var didCollide = this.shape.collidesWithShape(collider.shape, result); + if (didCollide) + result.collider = collider; + this.entity.position = oldPosition; + return didCollide; + }; + Collider.prototype.clone = function () { + var collider = ObjectUtils.clone(this); + collider.entity = null; + if (this.shape) + collider.shape = this.shape.clone(); + return collider; + }; + return Collider; + }(es.Component)); + es.Collider = Collider; +})(es || (es = {})); +var es; +(function (es) { + var BoxCollider = (function (_super) { + __extends(BoxCollider, _super); + function BoxCollider() { + var _this = _super.call(this) || this; + _this.shape = new es.Box(1, 1); + _this._colliderRequiresAutoSizing = true; + return _this; + } + Object.defineProperty(BoxCollider.prototype, "width", { + get: function () { + return this.shape.width; + }, + set: function (value) { + this.setWidth(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(BoxCollider.prototype, "height", { + get: function () { + return this.shape.height; + }, + set: function (value) { + this.setHeight(value); + }, + enumerable: true, + configurable: true + }); + BoxCollider.prototype.setSize = function (width, height) { + this._colliderRequiresAutoSizing = false; + var box = this.shape; + if (width != box.width || height != box.height) { + box.updateBox(width, height); + if (this.entity && this._isParentEntityAddedToScene) + es.Physics.updateCollider(this); + } + return this; + }; + BoxCollider.prototype.setWidth = function (width) { + this._colliderRequiresAutoSizing = false; + var box = this.shape; + if (width != box.width) { + box.updateBox(width, box.height); + if (this.entity && this._isParentEntityAddedToScene) + es.Physics.updateCollider(this); + } + return this; + }; + BoxCollider.prototype.setHeight = function (height) { + this._colliderRequiresAutoSizing = false; + var box = this.shape; + if (height != box.height) { + box.updateBox(box.width, height); + if (this.entity && this._isParentEntityAddedToScene) + es.Physics.updateCollider(this); + } + }; + BoxCollider.prototype.toString = function () { + return "[BoxCollider: bounds: " + this.bounds + "]"; + }; + return BoxCollider; + }(es.Collider)); + es.BoxCollider = BoxCollider; +})(es || (es = {})); +var es; +(function (es) { + var CircleCollider = (function (_super) { + __extends(CircleCollider, _super); + function CircleCollider(radius) { + var _this = _super.call(this) || this; + if (radius) + _this._colliderRequiresAutoSizing = true; + _this.shape = new es.Circle(radius ? radius : 1); + return _this; + } + Object.defineProperty(CircleCollider.prototype, "radius", { + get: function () { + return this.shape.radius; + }, + set: function (value) { + this.setRadius(value); + }, + enumerable: true, + configurable: true + }); + CircleCollider.prototype.setRadius = function (radius) { + this._colliderRequiresAutoSizing = false; + var circle = this.shape; + if (radius != circle.radius) { + circle.radius = radius; + circle._originalRadius = radius; + if (this.entity && this._isParentEntityAddedToScene) + es.Physics.updateCollider(this); + } + return this; + }; + CircleCollider.prototype.toString = function () { + return "[CircleCollider: bounds: " + this.bounds + ", radius: " + this.shape.radius + "]"; + }; + return CircleCollider; + }(es.Collider)); + es.CircleCollider = CircleCollider; +})(es || (es = {})); +var es; +(function (es) { + var PolygonCollider = (function (_super) { + __extends(PolygonCollider, _super); + function PolygonCollider(points) { + var _this = _super.call(this) || this; + var isPolygonClosed = points[0] == points[points.length - 1]; + if (isPolygonClosed) + points.splice(points.length - 1, 1); + var center = es.Polygon.findPolygonCenter(points); + _this.setLocalOffset(center); + es.Polygon.recenterPolygonVerts(points); + _this.shape = new es.Polygon(points); + return _this; + } + return PolygonCollider; + }(es.Collider)); + es.PolygonCollider = PolygonCollider; +})(es || (es = {})); +var es; +(function (es) { + var EntitySystem = (function () { + function EntitySystem(matcher) { + this._entities = []; + this._matcher = matcher ? matcher : es.Matcher.empty(); + } + Object.defineProperty(EntitySystem.prototype, "scene", { + get: function () { + return this._scene; + }, + set: function (value) { + this._scene = value; + this._entities = []; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(EntitySystem.prototype, "matcher", { + get: function () { + return this._matcher; + }, + enumerable: true, + configurable: true + }); + EntitySystem.prototype.initialize = function () { + }; + EntitySystem.prototype.onChanged = function (entity) { + var contains = this._entities.contains(entity); + var interest = this._matcher.IsIntersted(entity); + if (interest && !contains) + this.add(entity); + else if (!interest && contains) + this.remove(entity); + }; + EntitySystem.prototype.add = function (entity) { + this._entities.push(entity); + this.onAdded(entity); + }; + EntitySystem.prototype.onAdded = function (entity) { + }; + EntitySystem.prototype.remove = function (entity) { + this._entities.remove(entity); + this.onRemoved(entity); + }; + EntitySystem.prototype.onRemoved = function (entity) { + }; + EntitySystem.prototype.update = function () { + this.begin(); + this.process(this._entities); + }; + EntitySystem.prototype.lateUpdate = function () { + this.lateProcess(this._entities); + this.end(); + }; + EntitySystem.prototype.begin = function () { + }; + EntitySystem.prototype.process = function (entities) { + }; + EntitySystem.prototype.lateProcess = function (entities) { + }; + EntitySystem.prototype.end = function () { + }; + return EntitySystem; + }()); + es.EntitySystem = EntitySystem; +})(es || (es = {})); +var es; +(function (es) { + var EntityProcessingSystem = (function (_super) { + __extends(EntityProcessingSystem, _super); + function EntityProcessingSystem(matcher) { + return _super.call(this, matcher) || this; + } + EntityProcessingSystem.prototype.lateProcessEntity = function (entity) { + }; + EntityProcessingSystem.prototype.process = function (entities) { + var _this = this; + entities.forEach(function (entity) { return _this.processEntity(entity); }); + }; + EntityProcessingSystem.prototype.lateProcess = function (entities) { + var _this = this; + entities.forEach(function (entity) { return _this.lateProcessEntity(entity); }); + }; + return EntityProcessingSystem; + }(es.EntitySystem)); + es.EntityProcessingSystem = EntityProcessingSystem; +})(es || (es = {})); +var es; +(function (es) { + var PassiveSystem = (function (_super) { + __extends(PassiveSystem, _super); + function PassiveSystem() { + return _super !== null && _super.apply(this, arguments) || this; + } + PassiveSystem.prototype.onChanged = function (entity) { + }; + PassiveSystem.prototype.process = function (entities) { + this.begin(); + this.end(); + }; + return PassiveSystem; + }(es.EntitySystem)); + es.PassiveSystem = PassiveSystem; +})(es || (es = {})); +var es; +(function (es) { + var ProcessingSystem = (function (_super) { + __extends(ProcessingSystem, _super); + function ProcessingSystem() { + return _super !== null && _super.apply(this, arguments) || this; + } + ProcessingSystem.prototype.onChanged = function (entity) { + }; + ProcessingSystem.prototype.process = function (entities) { + this.begin(); + this.processSystem(); + this.end(); + }; + return ProcessingSystem; + }(es.EntitySystem)); + es.ProcessingSystem = ProcessingSystem; +})(es || (es = {})); +var es; +(function (es) { + var BitSet = (function () { + function BitSet(nbits) { + if (nbits === void 0) { nbits = 64; } + var length = nbits >> 6; + if ((nbits & BitSet.LONG_MASK) != 0) + length++; + this._bits = new Array(length); + } + BitSet.prototype.and = function (bs) { + var max = Math.min(this._bits.length, bs._bits.length); + var i; + for (var i_1 = 0; i_1 < max; ++i_1) + this._bits[i_1] &= bs._bits[i_1]; + while (i < this._bits.length) + this._bits[i++] = 0; + }; + BitSet.prototype.andNot = function (bs) { + var i = Math.min(this._bits.length, bs._bits.length); + while (--i >= 0) + this._bits[i] &= ~bs._bits[i]; + }; + BitSet.prototype.cardinality = function () { + var card = 0; + for (var i = this._bits.length - 1; i >= 0; i--) { + var a = this._bits[i]; + if (a == 0) + continue; + if (a == -1) { + card += 64; + continue; + } + a = ((a >> 1) & 0x5555555555555555) + (a & 0x5555555555555555); + a = ((a >> 2) & 0x3333333333333333) + (a & 0x3333333333333333); + var b = ((a >> 32) + a); + b = ((b >> 4) & 0x0f0f0f0f) + (b & 0x0f0f0f0f); + b = ((b >> 8) & 0x00ff00ff) + (b & 0x00ff00ff); + card += ((b >> 16) & 0x0000ffff) + (b & 0x0000ffff); + } + return card; + }; + BitSet.prototype.clear = function (pos) { + if (pos != undefined) { + var offset = pos >> 6; + this.ensure(offset); + this._bits[offset] &= ~(1 << pos); + } + else { + for (var i = 0; i < this._bits.length; i++) + this._bits[i] = 0; + } + }; + BitSet.prototype.get = function (pos) { + var offset = pos >> 6; + if (offset >= this._bits.length) + return false; + return (this._bits[offset] & (1 << pos)) != 0; + }; + BitSet.prototype.intersects = function (set) { + var i = Math.min(this._bits.length, set._bits.length); + while (--i >= 0) { + if ((this._bits[i] & set._bits[i]) != 0) + return true; + } + return false; + }; + BitSet.prototype.isEmpty = function () { + for (var i = this._bits.length - 1; i >= 0; i--) { + if (this._bits[i]) + return false; + } + return true; + }; + BitSet.prototype.nextSetBit = function (from) { + var offset = from >> 6; + var mask = 1 << from; + while (offset < this._bits.length) { + var h = this._bits[offset]; + do { + if ((h & mask) != 0) + return from; + mask <<= 1; + from++; + } while (mask != 0); + mask = 1; + offset++; + } + return -1; + }; + BitSet.prototype.set = function (pos, value) { + if (value === void 0) { value = true; } + if (value) { + var offset = pos >> 6; + this.ensure(offset); + this._bits[offset] |= 1 << pos; + } + else { + this.clear(pos); + } + }; + BitSet.prototype.ensure = function (lastElt) { + if (lastElt >= this._bits.length) { + var nd = new Number[lastElt + 1]; + nd = this._bits.copyWithin(0, 0, this._bits.length); + this._bits = nd; + } + }; + BitSet.LONG_MASK = 0x3f; + return BitSet; + }()); + es.BitSet = BitSet; +})(es || (es = {})); +var es; +(function (es) { + var ComponentList = (function () { + function ComponentList(entity) { + this._components = []; + this._componentsToAdd = []; + this._componentsToRemove = []; + this._tempBufferList = []; + this._entity = entity; + } + Object.defineProperty(ComponentList.prototype, "count", { + get: function () { + return this._components.length; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(ComponentList.prototype, "buffer", { + get: function () { + return this._components; + }, + enumerable: true, + configurable: true + }); + ComponentList.prototype.markEntityListUnsorted = function () { + this._isComponentListUnsorted = true; + }; + ComponentList.prototype.add = function (component) { + this._componentsToAdd.push(component); + }; + ComponentList.prototype.remove = function (component) { + if (this._componentsToRemove.contains(component)) + console.warn("You are trying to remove a Component (" + component + ") that you already removed"); + if (this._componentsToAdd.contains(component)) { + this._componentsToAdd.remove(component); + return; + } + this._componentsToRemove.push(component); + }; + ComponentList.prototype.removeAllComponents = function () { + for (var i = 0; i < this._components.length; i++) { + this.handleRemove(this._components[i]); + } + this._components.length = 0; + this._componentsToAdd.length = 0; + this._componentsToRemove.length = 0; + }; + ComponentList.prototype.deregisterAllComponents = function () { + for (var i = 0; i < this._components.length; i++) { + var component = this._components[i]; + if (component instanceof es.RenderableComponent) { + this._entity.scene.removeChild(component.displayObject); + this._entity.scene.renderableComponents.remove(component); + } + this._entity.componentBits.set(es.ComponentTypeManager.getIndexFor(component), false); + this._entity.scene.entityProcessors.onComponentRemoved(this._entity); + } + }; + ComponentList.prototype.registerAllComponents = function () { + for (var i = 0; i < this._components.length; i++) { + var component = this._components[i]; + if (component instanceof es.RenderableComponent) { + this._entity.scene.addChild(component.displayObject); + this._entity.scene.renderableComponents.add(component); + } + this._entity.componentBits.set(es.ComponentTypeManager.getIndexFor(component)); + this._entity.scene.entityProcessors.onComponentAdded(this._entity); + } + }; + ComponentList.prototype.updateLists = function () { + if (this._componentsToRemove.length > 0) { + for (var i = 0; i < this._componentsToRemove.length; i++) { + this.handleRemove(this._componentsToRemove[i]); + this._components.remove(this._componentsToRemove[i]); + } + this._componentsToRemove.length = 0; + } + if (this._componentsToAdd.length > 0) { + for (var i = 0, count = this._componentsToAdd.length; i < count; i++) { + var component = this._componentsToAdd[i]; + if (component instanceof es.RenderableComponent) { + this._entity.scene.addChild(component.displayObject); + this._entity.scene.renderableComponents.add(component); + } + this._entity.componentBits.set(es.ComponentTypeManager.getIndexFor(component)); + this._entity.scene.entityProcessors.onComponentAdded(this._entity); + this._components.push(component); + this._tempBufferList.push(component); + } + this._componentsToAdd.length = 0; + this._isComponentListUnsorted = true; + for (var i = 0; i < this._tempBufferList.length; i++) { + var component = this._tempBufferList[i]; + component.onAddedToEntity(); + if (component.enabled) { + component.onEnabled(); + } + } + this._tempBufferList.length = 0; + } + if (this._isComponentListUnsorted) { + this._components.sort(ComponentList.compareUpdatableOrder.compare); + this._isComponentListUnsorted = false; + } + }; + ComponentList.prototype.handleRemove = function (component) { + if (component instanceof es.RenderableComponent) { + this._entity.scene.removeChild(component.displayObject); + this._entity.scene.renderableComponents.remove(component); + } + this._entity.componentBits.set(es.ComponentTypeManager.getIndexFor(component), false); + this._entity.scene.entityProcessors.onComponentRemoved(this._entity); + component.onRemovedFromEntity(); + component.entity = null; + }; + ComponentList.prototype.getComponent = function (type, onlyReturnInitializedComponents) { + for (var i = 0; i < this._components.length; i++) { + var component = this._components[i]; if (component instanceof type) return component; } - } - return null; - }; - ComponentList.prototype.getComponents = function (typeName, components) { - if (!components) - components = []; - for (var i = 0; i < this._components.length; i++) { - var component = this._components[i]; - if (typeof (typeName) == "string") { - if (egret.is(component, typeName)) { - components.push(component); + if (!onlyReturnInitializedComponents) { + for (var i = 0; i < this._componentsToAdd.length; i++) { + var component = this._componentsToAdd[i]; + if (component instanceof type) + return component; } } - else { - if (component instanceof typeName) { - components.push(component); + return null; + }; + ComponentList.prototype.getComponents = function (typeName, components) { + if (!components) + components = []; + for (var i = 0; i < this._components.length; i++) { + var component = this._components[i]; + if (typeof (typeName) == "string") { + if (egret.is(component, typeName)) { + components.push(component); + } + } + else { + if (component instanceof typeName) { + components.push(component); + } } } - } - for (var i = 0; i < this._componentsToAdd.length; i++) { - var component = this._componentsToAdd[i]; - if (typeof (typeName) == "string") { - if (egret.is(component, typeName)) { - components.push(component); + for (var i = 0; i < this._componentsToAdd.length; i++) { + var component = this._componentsToAdd[i]; + if (typeof (typeName) == "string") { + if (egret.is(component, typeName)) { + components.push(component); + } + } + else { + if (component instanceof typeName) { + components.push(component); + } } } - else { - if (component instanceof typeName) { - components.push(component); - } + return components; + }; + ComponentList.prototype.update = function () { + this.updateLists(); + for (var i = 0; i < this._components.length; i++) { + var updatableComponent = this._components[i]; + if (updatableComponent.enabled && + (updatableComponent.updateInterval == 1 || + es.Time.frameCount % updatableComponent.updateInterval == 0)) + updatableComponent.update(); } + }; + ComponentList.prototype.onEntityTransformChanged = function (comp) { + for (var i = 0; i < this._components.length; i++) { + if (this._components[i].enabled) + this._components[i].onEntityTransformChanged(comp); + } + for (var i = 0; i < this._componentsToAdd.length; i++) { + if (this._componentsToAdd[i].enabled) + this._componentsToAdd[i].onEntityTransformChanged(comp); + } + }; + ComponentList.prototype.onEntityEnabled = function () { + for (var i = 0; i < this._components.length; i++) + this._components[i].onEnabled(); + }; + ComponentList.prototype.onEntityDisabled = function () { + for (var i = 0; i < this._components.length; i++) + this._components[i].onDisabled(); + }; + ComponentList.compareUpdatableOrder = new es.IUpdatableComparer(); + return ComponentList; + }()); + es.ComponentList = ComponentList; +})(es || (es = {})); +var es; +(function (es) { + var ComponentTypeManager = (function () { + function ComponentTypeManager() { } - return components; - }; - ComponentList.prototype.update = function () { - this.updateLists(); - for (var i = 0; i < this._components.length; i++) { - var component = this._components[i]; - if (component.enabled && (component.updateInterval == 1 || Time.frameCount % component.updateInterval == 0)) - component.update(); + ComponentTypeManager.add = function (type) { + if (!this._componentTypesMask.has(type)) + this._componentTypesMask[type] = this._componentTypesMask.size; + }; + ComponentTypeManager.getIndexFor = function (type) { + var v = -1; + if (!this._componentTypesMask.has(type)) { + this.add(type); + v = this._componentTypesMask.get(type); + } + return v; + }; + ComponentTypeManager._componentTypesMask = new Map(); + return ComponentTypeManager; + }()); + es.ComponentTypeManager = ComponentTypeManager; +})(es || (es = {})); +var es; +(function (es) { + var EntityList = (function () { + function EntityList(scene) { + this._entities = []; + this._entitiesToAdded = []; + this._entitiesToRemove = []; + this._entityDict = new Map(); + this._unsortedTags = []; + this._tempEntityList = []; + this.scene = scene; } - }; - return ComponentList; -}()); -var ComponentTypeManager = (function () { - function ComponentTypeManager() { - } - ComponentTypeManager.add = function (type) { - if (!this._componentTypesMask.has(type)) - this._componentTypesMask[type] = this._componentTypesMask.size; - }; - ComponentTypeManager.getIndexFor = function (type) { - var v = -1; - if (!this._componentTypesMask.has(type)) { - this.add(type); - v = this._componentTypesMask.get(type); - } - return v; - }; - ComponentTypeManager._componentTypesMask = new Map(); - return ComponentTypeManager; -}()); -var EntityList = (function () { - function EntityList(scene) { - this._entitiesToRemove = []; - this._entitiesToAdded = []; - this._tempEntityList = []; - this._entities = []; - this._entityDict = new Map(); - this._unsortedTags = []; - this.scene = scene; - } - Object.defineProperty(EntityList.prototype, "count", { - get: function () { - return this._entities.length; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(EntityList.prototype, "buffer", { - get: function () { - return this._entities; - }, - enumerable: true, - configurable: true - }); - EntityList.prototype.add = function (entity) { - if (this._entitiesToAdded.indexOf(entity) == -1) - this._entitiesToAdded.push(entity); - }; - EntityList.prototype.remove = function (entity) { - if (this._entitiesToAdded.contains(entity)) { - this._entitiesToAdded.remove(entity); - return; - } - if (!this._entitiesToRemove.contains(entity)) - this._entitiesToRemove.push(entity); - }; - EntityList.prototype.findEntity = function (name) { - for (var i = 0; i < this._entities.length; i++) { - if (this._entities[i].name == name) - return this._entities[i]; - } - return this._entitiesToAdded.firstOrDefault(function (entity) { return entity.name == name; }); - }; - EntityList.prototype.getTagList = function (tag) { - var list = this._entityDict.get(tag); - if (!list) { - list = []; - this._entityDict.set(tag, list); - } - return this._entityDict.get(tag); - }; - EntityList.prototype.addToTagList = function (entity) { - var list = this.getTagList(entity.tag); - if (!list.contains(entity)) { - list.push(entity); - this._unsortedTags.push(entity.tag); - } - }; - EntityList.prototype.removeFromTagList = function (entity) { - var list = this._entityDict.get(entity.tag); - if (list) { - list.remove(entity); - } - }; - EntityList.prototype.update = function () { - for (var i = 0; i < this._entities.length; i++) { - var entity = this._entities[i]; - if (entity.enabled) - entity.update(); - } - }; - EntityList.prototype.removeAllEntities = function () { - this._entitiesToAdded.length = 0; - this.updateLists(); - for (var i = 0; i < this._entities.length; i++) { - this._entities[i]._isDestoryed = true; - this._entities[i].onRemovedFromScene(); - this._entities[i].scene = null; - } - this._entities.length = 0; - this._entityDict.clear(); - }; - EntityList.prototype.updateLists = function () { - var _this = this; - if (this._entitiesToRemove.length > 0) { - var temp = this._entitiesToRemove; - this._entitiesToRemove = this._tempEntityList; - this._tempEntityList = temp; - this._tempEntityList.forEach(function (entity) { - _this._entities.remove(entity); - entity.scene = null; - _this.scene.entityProcessors.onEntityRemoved(entity); - }); - this._tempEntityList.length = 0; - } - if (this._entitiesToAdded.length > 0) { - var temp = this._entitiesToAdded; - this._entitiesToAdded = this._tempEntityList; - this._tempEntityList = temp; - this._tempEntityList.forEach(function (entity) { - if (!_this._entities.contains(entity)) { - _this._entities.push(entity); - entity.scene = _this.scene; - _this.scene.entityProcessors.onEntityAdded(entity); - } - }); - this._tempEntityList.forEach(function (entity) { return entity.onAddedToScene(); }); - this._tempEntityList.length = 0; - } - if (this._unsortedTags.length > 0) { - this._unsortedTags.forEach(function (tag) { - _this._entityDict.get(tag).sort(); - }); + Object.defineProperty(EntityList.prototype, "count", { + get: function () { + return this._entities.length; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(EntityList.prototype, "buffer", { + get: function () { + return this._entities; + }, + enumerable: true, + configurable: true + }); + EntityList.prototype.markEntityListUnsorted = function () { + this._isEntityListUnsorted = true; + }; + EntityList.prototype.markTagUnsorted = function (tag) { + this._unsortedTags.push(tag); + }; + EntityList.prototype.add = function (entity) { + if (this._entitiesToAdded.indexOf(entity) == -1) + this._entitiesToAdded.push(entity); + }; + EntityList.prototype.remove = function (entity) { + if (!this._entitiesToRemove.contains(entity)) { + console.warn("You are trying to remove an entity (" + entity.name + ") that you already removed"); + return; + } + if (this._entitiesToAdded.contains(entity)) { + this._entitiesToAdded.remove(entity); + return; + } + if (!this._entitiesToRemove.contains(entity)) + this._entitiesToRemove.push(entity); + }; + EntityList.prototype.removeAllEntities = function () { this._unsortedTags.length = 0; - } - }; - return EntityList; -}()); -var EntityProcessorList = (function () { - function EntityProcessorList() { - this._processors = []; - } - EntityProcessorList.prototype.add = function (processor) { - this._processors.push(processor); - }; - EntityProcessorList.prototype.remove = function (processor) { - this._processors.remove(processor); - }; - EntityProcessorList.prototype.onComponentAdded = function (entity) { - this.notifyEntityChanged(entity); - }; - EntityProcessorList.prototype.onComponentRemoved = function (entity) { - this.notifyEntityChanged(entity); - }; - EntityProcessorList.prototype.onEntityAdded = function (entity) { - this.notifyEntityChanged(entity); - }; - EntityProcessorList.prototype.onEntityRemoved = function (entity) { - this.removeFromProcessors(entity); - }; - EntityProcessorList.prototype.notifyEntityChanged = function (entity) { - for (var i = 0; i < this._processors.length; i++) { - this._processors[i].onChanged(entity); - } - }; - EntityProcessorList.prototype.removeFromProcessors = function (entity) { - for (var i = 0; i < this._processors.length; i++) { - this._processors[i].remove(entity); - } - }; - EntityProcessorList.prototype.begin = function () { - }; - EntityProcessorList.prototype.update = function () { - for (var i = 0; i < this._processors.length; i++) { - this._processors[i].update(); - } - }; - EntityProcessorList.prototype.lateUpdate = function () { - for (var i = 0; i < this._processors.length; i++) { - this._processors[i].lateUpdate(); - } - }; - EntityProcessorList.prototype.end = function () { - }; - EntityProcessorList.prototype.getProcessor = function () { - for (var i = 0; i < this._processors.length; i++) { - var processor = this._processors[i]; - if (processor instanceof EntitySystem) - return processor; - } - return null; - }; - return EntityProcessorList; -}()); -var Matcher = (function () { - function Matcher() { - this.allSet = new BitSet(); - this.exclusionSet = new BitSet(); - this.oneSet = new BitSet(); - } - Matcher.empty = function () { - return new Matcher(); - }; - Matcher.prototype.getAllSet = function () { - return this.allSet; - }; - Matcher.prototype.getExclusionSet = function () { - return this.exclusionSet; - }; - Matcher.prototype.getOneSet = function () { - return this.oneSet; - }; - Matcher.prototype.IsIntersted = function (e) { - if (!this.allSet.isEmpty()) { - for (var i = this.allSet.nextSetBit(0); i >= 0; i = this.allSet.nextSetBit(i + 1)) { - if (!e.componentBits.get(i)) - return false; + this._entitiesToAdded.length = 0; + this._isEntityListUnsorted = false; + this.updateLists(); + for (var i = 0; i < this._entities.length; i++) { + this._entities[i]._isDestroyed = true; + this._entities[i].onRemovedFromScene(); + this._entities[i].scene = null; } - } - if (!this.exclusionSet.isEmpty() && this.exclusionSet.intersects(e.componentBits)) - return false; - if (!this.oneSet.isEmpty() && !this.oneSet.intersects(e.componentBits)) - return false; - return true; - }; - Matcher.prototype.all = function () { - var _this = this; - var types = []; - for (var _i = 0; _i < arguments.length; _i++) { - types[_i] = arguments[_i]; - } - types.forEach(function (type) { - _this.allSet.set(ComponentTypeManager.getIndexFor(type)); - }); - return this; - }; - Matcher.prototype.exclude = function () { - var _this = this; - var types = []; - for (var _i = 0; _i < arguments.length; _i++) { - types[_i] = arguments[_i]; - } - types.forEach(function (type) { - _this.exclusionSet.set(ComponentTypeManager.getIndexFor(type)); - }); - return this; - }; - Matcher.prototype.one = function () { - var _this = this; - var types = []; - for (var _i = 0; _i < arguments.length; _i++) { - types[_i] = arguments[_i]; - } - types.forEach(function (type) { - _this.oneSet.set(ComponentTypeManager.getIndexFor(type)); - }); - return this; - }; - return Matcher; -}()); -var RenderableComponentList = (function () { - function RenderableComponentList() { - this._components = []; - } - Object.defineProperty(RenderableComponentList.prototype, "count", { - get: function () { - return this._components.length; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(RenderableComponentList.prototype, "buffer", { - get: function () { - return this._components; - }, - enumerable: true, - configurable: true - }); - RenderableComponentList.prototype.add = function (component) { - this._components.push(component); - }; - RenderableComponentList.prototype.remove = function (component) { - this._components.remove(component); - }; - RenderableComponentList.prototype.updateList = function () { - }; - return RenderableComponentList; -}()); -var Time = (function () { - function Time() { - } - ; - Time.update = function (currentTime) { - var dt = (currentTime - this._lastTime) / 1000; - this.deltaTime = dt * this.timeScale; - this.unscaledDeltaTime = dt; - this.frameCount++; - this._lastTime = currentTime; - }; - Time.deltaTime = 0; - Time.timeScale = 1; - Time.frameCount = 0; - Time._lastTime = 0; - return Time; -}()); -var GraphicsCapabilities = (function () { - function GraphicsCapabilities() { - } - GraphicsCapabilities.prototype.initialize = function (device) { - this.platformInitialize(device); - }; - GraphicsCapabilities.prototype.platformInitialize = function (device) { - var gl = new egret.sys.RenderBuffer().context.getInstance(); - this.supportsNonPowerOfTwo = false; - this.supportsTextureFilterAnisotropic = gl.getExtension("EXT_texture_filter_anisotropic") != null; - this.supportsDepth24 = true; - this.supportsPackedDepthStencil = true; - this.supportsDepthNonLinear = false; - this.supportsTextureMaxLevel = true; - this.supportsS3tc = gl.getExtension("WEBGL_compressed_texture_s3tc") != null || - gl.getExtension("WEBGL_compressed_texture_s3tc_srgb") != null; - this.supportsDxt1 = this.supportsS3tc; - this.supportsPvrtc = false; - this.supportsAtitc = gl.getExtension("WEBGL_compressed_texture_astc") != null; - this.supportsFramebufferObjectARB = false; - }; - return GraphicsCapabilities; -}()); -var GraphicsDevice = (function () { - function GraphicsDevice() { - this.graphicsCapabilities = new GraphicsCapabilities(); - this.graphicsCapabilities.initialize(this); - } - return GraphicsDevice; -}()); -var Viewport = (function () { - function Viewport(x, y, width, height) { - this._x = x; - this._y = y; - this._width = width; - this._height = height; - this._minDepth = 0; - this._maxDepth = 1; - } - Object.defineProperty(Viewport.prototype, "aspectRatio", { - get: function () { - if ((this._height != 0) && (this._width != 0)) - return (this._width / this._height); - return 0; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Viewport.prototype, "bounds", { - get: function () { - return new Rectangle(this._x, this._y, this._width, this._height); - }, - set: function (value) { - this._x = value.x; - this._y = value.y; - this._width = value.width; - this._height = value.height; - }, - enumerable: true, - configurable: true - }); - return Viewport; -}()); -var GaussianBlurEffect = (function (_super) { - __extends(GaussianBlurEffect, _super); - function GaussianBlurEffect() { - return _super.call(this, PostProcessor.default_vert, GaussianBlurEffect.blur_frag, { - screenWidth: SceneManager.stage.stageWidth, - screenHeight: SceneManager.stage.stageHeight - }) || this; - } - GaussianBlurEffect.blur_frag = "precision mediump float;\n" + - "uniform sampler2D uSampler;\n" + - "uniform float screenWidth;\n" + - "uniform float screenHeight;\n" + - "float normpdf(in float x, in float sigma)\n" + - "{\n" + - "return 0.39894*exp(-0.5*x*x/(sigma*sigma))/sigma;\n" + - "}\n" + - "void main()\n" + - "{\n" + - "vec3 c = texture2D(uSampler, gl_FragCoord.xy / vec2(screenWidth, screenHeight).xy).rgb;\n" + - "const int mSize = 11;\n" + - "const int kSize = (mSize - 1)/2;\n" + - "float kernel[mSize];\n" + - "vec3 final_colour = vec3(0.0);\n" + - "float sigma = 7.0;\n" + - "float z = 0.0;\n" + - "for (int j = 0; j <= kSize; ++j)\n" + - "{\n" + - "kernel[kSize+j] = kernel[kSize-j] = normpdf(float(j),sigma);\n" + - "}\n" + - "for (int j = 0; j < mSize; ++j)\n" + - "{\n" + - "z += kernel[j];\n" + - "}\n" + - "for (int i = -kSize; i <= kSize; ++i)\n" + - "{\n" + - "for (int j = -kSize; j <= kSize; ++j)\n" + - "{\n" + - "final_colour += kernel[kSize+j]*kernel[kSize+i]*texture2D(uSampler, (gl_FragCoord.xy+vec2(float(i),float(j))) / vec2(screenWidth, screenHeight).xy).rgb;\n" + - "}\n}\n" + - "gl_FragColor = vec4(final_colour/(z*z), 1.0);\n" + - "}"; - return GaussianBlurEffect; -}(egret.CustomFilter)); -var PolygonLightEffect = (function (_super) { - __extends(PolygonLightEffect, _super); - function PolygonLightEffect() { - return _super.call(this, PolygonLightEffect.vertSrc, PolygonLightEffect.fragmentSrc) || this; - } - PolygonLightEffect.vertSrc = "attribute vec2 aVertexPosition;\n" + - "attribute vec2 aTextureCoord;\n" + - "uniform vec2 projectionVector;\n" + - "varying vec2 vTextureCoord;\n" + - "const vec2 center = vec2(-1.0, 1.0);\n" + - "void main(void) {\n" + - " gl_Position = vec4( (aVertexPosition / projectionVector) + center , 0.0, 1.0);\n" + - " vTextureCoord = aTextureCoord;\n" + - "}"; - PolygonLightEffect.fragmentSrc = "precision lowp float;\n" + - "varying vec2 vTextureCoord;\n" + - "uniform sampler2D uSampler;\n" + - "#define SAMPLE_COUNT 15\n" + - "uniform vec2 _sampleOffsets[SAMPLE_COUNT];\n" + - "uniform float _sampleWeights[SAMPLE_COUNT];\n" + - "void main(void) {\n" + - "vec4 c = vec4(0, 0, 0, 0);\n" + - "for( int i = 0; i < SAMPLE_COUNT; i++ )\n" + - " c += texture2D( uSampler, vTextureCoord + _sampleOffsets[i] ) * _sampleWeights[i];\n" + - "gl_FragColor = c;\n" + - "}"; - return PolygonLightEffect; -}(egret.CustomFilter)); -var PostProcessor = (function () { - function PostProcessor(effect) { - if (effect === void 0) { effect = null; } - this.enable = true; - this.effect = effect; - } - PostProcessor.prototype.onAddedToScene = function (scene) { - this.scene = scene; - this.shape = new egret.Shape(); - this.shape.graphics.beginFill(0xFFFFFF, 1); - this.shape.graphics.drawRect(0, 0, SceneManager.stage.stageWidth, SceneManager.stage.stageHeight); - this.shape.graphics.endFill(); - scene.addChild(this.shape); - }; - PostProcessor.prototype.process = function () { - this.drawFullscreenQuad(); - }; - PostProcessor.prototype.onSceneBackBufferSizeChanged = function (newWidth, newHeight) { }; - PostProcessor.prototype.drawFullscreenQuad = function () { - this.scene.filters = [this.effect]; - }; - PostProcessor.prototype.unload = function () { - if (this.effect) { - this.effect = null; - } - this.scene.removeChild(this.shape); - this.scene = null; - }; - PostProcessor.default_vert = "attribute vec2 aVertexPosition;\n" + - "attribute vec2 aTextureCoord;\n" + - "attribute vec2 aColor;\n" + - "uniform vec2 projectionVector;\n" + - "varying vec2 vTextureCoord;\n" + - "varying vec4 vColor;\n" + - "const vec2 center = vec2(-1.0, 1.0);\n" + - "void main(void) {\n" + - "gl_Position = vec4( (aVertexPosition / projectionVector) + center , 0.0, 1.0);\n" + - "vTextureCoord = aTextureCoord;\n" + - "vColor = vec4(aColor.x, aColor.x, aColor.x, aColor.x);\n" + - "}"; - return PostProcessor; -}()); -var GaussianBlurPostProcessor = (function (_super) { - __extends(GaussianBlurPostProcessor, _super); - function GaussianBlurPostProcessor() { - return _super !== null && _super.apply(this, arguments) || this; - } - GaussianBlurPostProcessor.prototype.onAddedToScene = function (scene) { - _super.prototype.onAddedToScene.call(this, scene); - this.effect = new GaussianBlurEffect(); - }; - return GaussianBlurPostProcessor; -}(PostProcessor)); -var Renderer = (function () { - function Renderer() { - } - Renderer.prototype.onAddedToScene = function (scene) { }; - Renderer.prototype.beginRender = function (cam) { - }; - Renderer.prototype.unload = function () { }; - Renderer.prototype.renderAfterStateCheck = function (renderable, cam) { - renderable.render(cam); - }; - return Renderer; -}()); -var DefaultRenderer = (function (_super) { - __extends(DefaultRenderer, _super); - function DefaultRenderer() { - return _super !== null && _super.apply(this, arguments) || this; - } - DefaultRenderer.prototype.render = function (scene) { - var cam = this.camera ? this.camera : scene.camera; - this.beginRender(cam); - for (var i = 0; i < scene.renderableComponents.count; i++) { - var renderable = scene.renderableComponents.buffer[i]; - if (renderable.enabled && renderable.isVisibleFromCamera(cam)) - this.renderAfterStateCheck(renderable, cam); - } - }; - return DefaultRenderer; -}(Renderer)); -var ScreenSpaceRenderer = (function (_super) { - __extends(ScreenSpaceRenderer, _super); - function ScreenSpaceRenderer() { - return _super !== null && _super.apply(this, arguments) || this; - } - ScreenSpaceRenderer.prototype.render = function (scene) { - }; - return ScreenSpaceRenderer; -}(Renderer)); -var PolyLight = (function (_super) { - __extends(PolyLight, _super); - function PolyLight(radius, color, power) { - var _this = _super.call(this) || this; - _this._indices = []; - _this.radius = radius; - _this.power = power; - _this.color = color; - _this.computeTriangleIndices(); - return _this; - } - Object.defineProperty(PolyLight.prototype, "radius", { - get: function () { - return this._radius; - }, - set: function (value) { - this.setRadius(value); - }, - enumerable: true, - configurable: true - }); - PolyLight.prototype.computeTriangleIndices = function (totalTris) { - if (totalTris === void 0) { totalTris = 20; } - this._indices.length = 0; - for (var i = 0; i < totalTris; i += 2) { - this._indices.push(0); - this._indices.push(i + 2); - this._indices.push(i + 1); - } - }; - PolyLight.prototype.setRadius = function (radius) { - if (radius != this._radius) { - this._radius = radius; - this._areBoundsDirty = true; - } - }; - PolyLight.prototype.render = function (camera) { - }; - PolyLight.prototype.reset = function () { - }; - return PolyLight; -}(RenderableComponent)); -var SceneTransition = (function () { - function SceneTransition(sceneLoadAction) { - this.sceneLoadAction = sceneLoadAction; - this.loadsNewScene = sceneLoadAction != null; - } - Object.defineProperty(SceneTransition.prototype, "hasPreviousSceneRender", { - get: function () { - if (!this._hasPreviousSceneRender) { - this._hasPreviousSceneRender = true; - return false; + this._entities.length = 0; + this._entityDict.clear(); + }; + EntityList.prototype.contains = function (entity) { + return this._entities.contains(entity) || this._entitiesToAdded.contains(entity); + }; + EntityList.prototype.getTagList = function (tag) { + var list = this._entityDict.get(tag); + if (!list) { + list = []; + this._entityDict.set(tag, list); } - return true; - }, - enumerable: true, - configurable: true - }); - SceneTransition.prototype.preRender = function () { }; - SceneTransition.prototype.render = function () { - }; - SceneTransition.prototype.onBeginTransition = function () { - return __awaiter(this, void 0, void 0, function () { - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4, this.loadNextScene()]; - case 1: - _a.sent(); - this.transitionComplete(); - return [2]; - } - }); - }); - }; - SceneTransition.prototype.transitionComplete = function () { - SceneManager.sceneTransition = null; - if (this.onTransitionCompleted) { - this.onTransitionCompleted(); - } - }; - SceneTransition.prototype.loadNextScene = function () { - return __awaiter(this, void 0, void 0, function () { - var _a; - return __generator(this, function (_b) { - switch (_b.label) { - case 0: - if (this.onScreenObscured) - this.onScreenObscured(); - if (!this.loadsNewScene) { - this.isNewSceneLoaded = true; - } - _a = SceneManager; - return [4, this.sceneLoadAction()]; - case 1: - _a.scene = _b.sent(); - this.isNewSceneLoaded = true; - return [2]; - } - }); - }); - }; - SceneTransition.prototype.tickEffectProgressProperty = function (filter, duration, easeType, reverseDirection) { - if (reverseDirection === void 0) { reverseDirection = false; } - return new Promise(function (resolve) { - var start = reverseDirection ? 1 : 0; - var end = reverseDirection ? 0 : 1; - egret.Tween.get(filter.uniforms).set({ _progress: start }).to({ _progress: end }, duration * 1000, easeType).call(function () { - resolve(); - }); - }); - }; - return SceneTransition; -}()); -var FadeTransition = (function (_super) { - __extends(FadeTransition, _super); - function FadeTransition(sceneLoadAction) { - var _this = _super.call(this, sceneLoadAction) || this; - _this.fadeToColor = 0x000000; - _this.fadeOutDuration = 0.4; - _this.fadeEaseType = egret.Ease.quadInOut; - _this.delayBeforeFadeInDuration = 0.1; - _this._alpha = 0; - _this._mask = new egret.Shape(); - return _this; - } - FadeTransition.prototype.onBeginTransition = function () { - return __awaiter(this, void 0, void 0, function () { + return this._entityDict.get(tag); + }; + EntityList.prototype.addToTagList = function (entity) { + var list = this.getTagList(entity.tag); + if (!list.contains(entity)) { + list.push(entity); + this._unsortedTags.push(entity.tag); + } + }; + EntityList.prototype.removeFromTagList = function (entity) { + var list = this._entityDict.get(entity.tag); + if (list) { + list.remove(entity); + } + }; + EntityList.prototype.update = function () { + for (var i = 0; i < this._entities.length; i++) { + var entity = this._entities[i]; + if (entity.enabled && (entity.updateInterval == 1 || es.Time.frameCount % entity.updateInterval == 0)) + entity.update(); + } + }; + EntityList.prototype.updateLists = function () { var _this = this; - return __generator(this, function (_a) { - this._mask.graphics.beginFill(this.fadeToColor, 1); - this._mask.graphics.drawRect(0, 0, SceneManager.stage.stageWidth, SceneManager.stage.stageHeight); - this._mask.graphics.endFill(); - SceneManager.stage.addChild(this._mask); - egret.Tween.get(this).to({ _alpha: 1 }, this.fadeOutDuration * 1000, this.fadeEaseType) - .call(function () { return __awaiter(_this, void 0, void 0, function () { - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4, this.loadNextScene()]; - case 1: - _a.sent(); - return [2]; - } - }); - }); }).wait(this.delayBeforeFadeInDuration).call(function () { - egret.Tween.get(_this).to({ _alpha: 0 }, _this.fadeOutDuration * 1000, _this.fadeEaseType).call(function () { - _this.transitionComplete(); - SceneManager.stage.removeChild(_this._mask); - }); + if (this._entitiesToRemove.length > 0) { + var temp = this._entitiesToRemove; + this._entitiesToRemove = this._tempEntityList; + this._tempEntityList = temp; + this._tempEntityList.forEach(function (entity) { + _this.removeFromTagList(entity); + _this._entities.remove(entity); + entity.onRemovedFromScene(); + entity.scene = null; + _this.scene.entityProcessors.onEntityRemoved(entity); }); - return [2]; + this._tempEntityList.length = 0; + } + if (this._entitiesToAdded.length > 0) { + var temp = this._entitiesToAdded; + this._entitiesToAdded = this._tempEntityList; + this._tempEntityList = temp; + this._tempEntityList.forEach(function (entity) { + if (!_this._entities.contains(entity)) { + _this._entities.push(entity); + entity.scene = _this.scene; + _this.addToTagList(entity); + _this.scene.entityProcessors.onEntityAdded(entity); + } + }); + this._tempEntityList.forEach(function (entity) { return entity.onAddedToScene(); }); + this._tempEntityList.length = 0; + this._isEntityListUnsorted = true; + } + if (this._isEntityListUnsorted) { + this._entities.sort(); + this._isEntityListUnsorted = false; + } + if (this._unsortedTags.length > 0) { + this._unsortedTags.forEach(function (tag) { + _this._entityDict.get(tag).sort(); + }); + this._unsortedTags.length = 0; + } + }; + EntityList.prototype.findEntity = function (name) { + for (var i = 0; i < this._entities.length; i++) { + if (this._entities[i].name == name) + return this._entities[i]; + } + return this._entitiesToAdded.firstOrDefault(function (entity) { return entity.name == name; }); + }; + EntityList.prototype.entitiesWithTag = function (tag) { + var list = this.getTagList(tag); + var returnList = es.ListPool.obtain(); + for (var i = 0; i < list.length; i++) + returnList.push(list[i]); + return returnList; + }; + EntityList.prototype.entitiesOfType = function (type) { + var list = es.ListPool.obtain(); + for (var i = 0; i < this._entities.length; i++) { + if (this._entities[i] instanceof type) + list.push(this._entities[i]); + } + this._entitiesToAdded.forEach(function (entity) { + if (entity instanceof type) + list.push(entity); }); + return list; + }; + EntityList.prototype.findComponentOfType = function (type) { + for (var i = 0; i < this._entities.length; i++) { + if (this._entities[i].enabled) { + var comp = this._entities[i].getComponent(type); + if (comp) + return comp; + } + } + for (var i = 0; i < this._entitiesToAdded.length; i++) { + var entity = this._entitiesToAdded[i]; + if (entity.enabled) { + var comp = entity.getComponent(type); + if (comp) + return comp; + } + } + return null; + }; + EntityList.prototype.findComponentsOfType = function (type) { + var comps = es.ListPool.obtain(); + for (var i = 0; i < this._entities.length; i++) { + if (this._entities[i].enabled) + this._entities[i].getComponents(type, comps); + } + for (var i = 0; i < this._entitiesToAdded.length; i++) { + var entity = this._entitiesToAdded[i]; + if (entity.enabled) + entity.getComponents(type, comps); + } + return comps; + }; + return EntityList; + }()); + es.EntityList = EntityList; +})(es || (es = {})); +var es; +(function (es) { + var EntityProcessorList = (function () { + function EntityProcessorList() { + this._processors = []; + } + EntityProcessorList.prototype.add = function (processor) { + this._processors.push(processor); + }; + EntityProcessorList.prototype.remove = function (processor) { + this._processors.remove(processor); + }; + EntityProcessorList.prototype.onComponentAdded = function (entity) { + this.notifyEntityChanged(entity); + }; + EntityProcessorList.prototype.onComponentRemoved = function (entity) { + this.notifyEntityChanged(entity); + }; + EntityProcessorList.prototype.onEntityAdded = function (entity) { + this.notifyEntityChanged(entity); + }; + EntityProcessorList.prototype.onEntityRemoved = function (entity) { + this.removeFromProcessors(entity); + }; + EntityProcessorList.prototype.begin = function () { + }; + EntityProcessorList.prototype.update = function () { + for (var i = 0; i < this._processors.length; i++) { + this._processors[i].update(); + } + }; + EntityProcessorList.prototype.lateUpdate = function () { + for (var i = 0; i < this._processors.length; i++) { + this._processors[i].lateUpdate(); + } + }; + EntityProcessorList.prototype.end = function () { + }; + EntityProcessorList.prototype.getProcessor = function () { + for (var i = 0; i < this._processors.length; i++) { + var processor = this._processors[i]; + if (processor instanceof es.EntitySystem) + return processor; + } + return null; + }; + EntityProcessorList.prototype.notifyEntityChanged = function (entity) { + for (var i = 0; i < this._processors.length; i++) { + this._processors[i].onChanged(entity); + } + }; + EntityProcessorList.prototype.removeFromProcessors = function (entity) { + for (var i = 0; i < this._processors.length; i++) { + this._processors[i].remove(entity); + } + }; + return EntityProcessorList; + }()); + es.EntityProcessorList = EntityProcessorList; +})(es || (es = {})); +var es; +(function (es) { + var Matcher = (function () { + function Matcher() { + this.allSet = new es.BitSet(); + this.exclusionSet = new es.BitSet(); + this.oneSet = new es.BitSet(); + } + Matcher.empty = function () { + return new Matcher(); + }; + Matcher.prototype.getAllSet = function () { + return this.allSet; + }; + Matcher.prototype.getExclusionSet = function () { + return this.exclusionSet; + }; + Matcher.prototype.getOneSet = function () { + return this.oneSet; + }; + Matcher.prototype.IsIntersted = function (e) { + if (!this.allSet.isEmpty()) { + for (var i = this.allSet.nextSetBit(0); i >= 0; i = this.allSet.nextSetBit(i + 1)) { + if (!e.componentBits.get(i)) + return false; + } + } + if (!this.exclusionSet.isEmpty() && this.exclusionSet.intersects(e.componentBits)) + return false; + if (!this.oneSet.isEmpty() && !this.oneSet.intersects(e.componentBits)) + return false; + return true; + }; + Matcher.prototype.all = function () { + var _this = this; + var types = []; + for (var _i = 0; _i < arguments.length; _i++) { + types[_i] = arguments[_i]; + } + types.forEach(function (type) { + _this.allSet.set(es.ComponentTypeManager.getIndexFor(type)); + }); + return this; + }; + Matcher.prototype.exclude = function () { + var _this = this; + var types = []; + for (var _i = 0; _i < arguments.length; _i++) { + types[_i] = arguments[_i]; + } + types.forEach(function (type) { + _this.exclusionSet.set(es.ComponentTypeManager.getIndexFor(type)); + }); + return this; + }; + Matcher.prototype.one = function () { + var _this = this; + var types = []; + for (var _i = 0; _i < arguments.length; _i++) { + types[_i] = arguments[_i]; + } + types.forEach(function (type) { + _this.oneSet.set(es.ComponentTypeManager.getIndexFor(type)); + }); + return this; + }; + return Matcher; + }()); + es.Matcher = Matcher; +})(es || (es = {})); +var ObjectUtils = (function () { + function ObjectUtils() { + } + ObjectUtils.clone = function (p, c) { + if (c === void 0) { c = null; } + var c = c || {}; + for (var i in p) { + if (typeof p[i] === 'object') { + c[i] = p[i] instanceof Array ? [] : {}; + this.clone(p[i], c[i]); + } + else { + c[i] = p[i]; + } + } + return c; + }; + return ObjectUtils; +}()); +var es; +(function (es) { + var RenderableComparer = (function () { + function RenderableComparer() { + } + RenderableComparer.prototype.compare = function (self, other) { + return other.renderLayer - self.renderLayer; + }; + return RenderableComparer; + }()); + es.RenderableComparer = RenderableComparer; +})(es || (es = {})); +var es; +(function (es) { + var RenderableComponentList = (function () { + function RenderableComponentList() { + this._components = []; + this._componentsByRenderLayer = new Map(); + this._unsortedRenderLayers = []; + this._componentsNeedSort = true; + } + Object.defineProperty(RenderableComponentList.prototype, "count", { + get: function () { + return this._components.length; + }, + enumerable: true, + configurable: true }); + Object.defineProperty(RenderableComponentList.prototype, "buffer", { + get: function () { + return this._components; + }, + enumerable: true, + configurable: true + }); + RenderableComponentList.prototype.add = function (component) { + this._components.push(component); + this.addToRenderLayerList(component, component.renderLayer); + }; + RenderableComponentList.prototype.remove = function (component) { + this._components.remove(component); + this._componentsByRenderLayer.get(component.renderLayer).remove(component); + }; + RenderableComponentList.prototype.updateRenderableRenderLayer = function (component, oldRenderLayer, newRenderLayer) { + if (this._componentsByRenderLayer.has(oldRenderLayer) && this._componentsByRenderLayer.get(oldRenderLayer).contains(component)) { + this._componentsByRenderLayer.get(oldRenderLayer).remove(component); + this.addToRenderLayerList(component, newRenderLayer); + } + }; + RenderableComponentList.prototype.setRenderLayerNeedsComponentSort = function (renderLayer) { + if (!this._unsortedRenderLayers.contains(renderLayer)) + this._unsortedRenderLayers.push(renderLayer); + this._componentsNeedSort = true; + }; + RenderableComponentList.prototype.setNeedsComponentSort = function () { + this._componentsNeedSort = true; + }; + RenderableComponentList.prototype.addToRenderLayerList = function (component, renderLayer) { + var list = this.componentsWithRenderLayer(renderLayer); + if (!list.contains(component)) { + console.warn("Component renderLayer list already contains this component"); + return; + } + list.push(component); + if (!this._unsortedRenderLayers.contains(renderLayer)) + this._unsortedRenderLayers.push(renderLayer); + this._componentsNeedSort = true; + }; + RenderableComponentList.prototype.componentsWithRenderLayer = function (renderLayer) { + if (!this._componentsByRenderLayer.get(renderLayer)) { + this._componentsByRenderLayer.set(renderLayer, []); + } + return this._componentsByRenderLayer.get(renderLayer); + }; + RenderableComponentList.prototype.updateList = function () { + if (this._componentsNeedSort) { + this._components.sort(RenderableComponentList.compareUpdatableOrder.compare); + this._componentsNeedSort = false; + } + if (this._unsortedRenderLayers.length > 0) { + for (var i = 0, count = this._unsortedRenderLayers.length; i < count; i++) { + var renderLayerComponents = this._componentsByRenderLayer.get(this._unsortedRenderLayers[i]); + if (renderLayerComponents) { + renderLayerComponents.sort(RenderableComponentList.compareUpdatableOrder.compare); + } + } + this._unsortedRenderLayers.length = 0; + } + }; + RenderableComponentList.compareUpdatableOrder = new es.RenderableComparer(); + return RenderableComponentList; + }()); + es.RenderableComponentList = RenderableComponentList; +})(es || (es = {})); +var StringUtils = (function () { + function StringUtils() { + } + StringUtils.matchChineseWord = function (str) { + var patternA = /[\u4E00-\u9FA5]+/gim; + return str.match(patternA); }; - FadeTransition.prototype.render = function () { - this._mask.graphics.clear(); - this._mask.graphics.beginFill(this.fadeToColor, this._alpha); - this._mask.graphics.drawRect(0, 0, SceneManager.stage.stageWidth, SceneManager.stage.stageHeight); - this._mask.graphics.endFill(); + StringUtils.lTrim = function (target) { + var startIndex = 0; + while (this.isWhiteSpace(target.charAt(startIndex))) { + startIndex++; + } + return target.slice(startIndex, target.length); }; - return FadeTransition; -}(SceneTransition)); -var WindTransition = (function (_super) { - __extends(WindTransition, _super); - function WindTransition(sceneLoadAction) { - var _this = _super.call(this, sceneLoadAction) || this; - _this.duration = 1; - _this.easeType = egret.Ease.quadOut; - var vertexSrc = "attribute vec2 aVertexPosition;\n" + + StringUtils.rTrim = function (target) { + var endIndex = target.length - 1; + while (this.isWhiteSpace(target.charAt(endIndex))) { + endIndex--; + } + return target.slice(0, endIndex + 1); + }; + StringUtils.trim = function (target) { + if (target == null) { + return null; + } + return this.rTrim(this.lTrim(target)); + }; + StringUtils.isWhiteSpace = function (str) { + if (str == " " || str == "\t" || str == "\r" || str == "\n") + return true; + return false; + }; + StringUtils.replaceMatch = function (mainStr, targetStr, replaceStr, caseMark) { + if (caseMark === void 0) { caseMark = false; } + var len = mainStr.length; + var tempStr = ""; + var isMatch = false; + var tempTarget = caseMark == true ? targetStr.toLowerCase() : targetStr; + for (var i = 0; i < len; i++) { + isMatch = false; + if (mainStr.charAt(i) == tempTarget.charAt(0)) { + if (mainStr.substr(i, tempTarget.length) == tempTarget) { + isMatch = true; + } + } + if (isMatch) { + tempStr += replaceStr; + i = i + tempTarget.length - 1; + } + else { + tempStr += mainStr.charAt(i); + } + } + return tempStr; + }; + StringUtils.htmlSpecialChars = function (str, reversion) { + if (reversion === void 0) { reversion = false; } + var len = this.specialSigns.length; + for (var i = 0; i < len; i += 2) { + var from = void 0; + var to = void 0; + from = this.specialSigns[i]; + to = this.specialSigns[i + 1]; + if (reversion) { + var temp = from; + from = to; + to = temp; + } + str = this.replaceMatch(str, from, to); + } + return str; + }; + StringUtils.zfill = function (str, width) { + if (width === void 0) { width = 2; } + if (!str) { + return str; + } + width = Math.floor(width); + var slen = str.length; + if (slen >= width) { + return str; + } + var negative = false; + if (str.substr(0, 1) == '-') { + negative = true; + str = str.substr(1); + } + var len = width - slen; + for (var i = 0; i < len; i++) { + str = '0' + str; + } + if (negative) { + str = '-' + str; + } + return str; + }; + StringUtils.reverse = function (str) { + if (str.length > 1) + return this.reverse(str.substring(1)) + str.substring(0, 1); + else + return str; + }; + StringUtils.cutOff = function (str, start, len, order) { + if (order === void 0) { order = true; } + start = Math.floor(start); + len = Math.floor(len); + var length = str.length; + if (start > length) + start = length; + var s = start; + var e = start + len; + var newStr; + if (order) { + newStr = str.substring(0, s) + str.substr(e, length); + } + else { + s = length - 1 - start - len; + e = s + len; + newStr = str.substring(0, s + 1) + str.substr(e + 1, length); + } + return newStr; + }; + StringUtils.strReplace = function (str, rStr) { + var i = 0, len = rStr.length; + for (; i < len; i++) { + if (rStr[i] == null || rStr[i] == "") { + rStr[i] = "无"; + } + str = str.replace("{" + i + "}", rStr[i]); + } + return str; + }; + StringUtils.specialSigns = [ + '&', '&', + '<', '<', + '>', '>', + '"', '"', + "'", ''', + '®', '®', + '©', '©', + '™', '™', + ]; + return StringUtils; +}()); +var es; +(function (es) { + var TextureUtils = (function () { + function TextureUtils() { + } + TextureUtils.convertImageToCanvas = function (texture, rect) { + if (!this.sharedCanvas) { + this.sharedCanvas = egret.sys.createCanvas(); + this.sharedContext = this.sharedCanvas.getContext("2d"); + } + var w = texture.$getTextureWidth(); + var h = texture.$getTextureHeight(); + if (!rect) { + rect = egret.$TempRectangle; + rect.x = 0; + rect.y = 0; + rect.width = w; + rect.height = h; + } + rect.x = Math.min(rect.x, w - 1); + rect.y = Math.min(rect.y, h - 1); + rect.width = Math.min(rect.width, w - rect.x); + rect.height = Math.min(rect.height, h - rect.y); + var iWidth = Math.floor(rect.width); + var iHeight = Math.floor(rect.height); + var surface = this.sharedCanvas; + surface["style"]["width"] = iWidth + "px"; + surface["style"]["height"] = iHeight + "px"; + this.sharedCanvas.width = iWidth; + this.sharedCanvas.height = iHeight; + if (egret.Capabilities.renderMode == "webgl") { + var renderTexture = void 0; + if (!texture.$renderBuffer) { + if (egret.sys.systemRenderer["renderClear"]) { + egret.sys.systemRenderer["renderClear"](); + } + renderTexture = new egret.RenderTexture(); + renderTexture.drawToTexture(new egret.Bitmap(texture)); + } + else { + renderTexture = texture; + } + var pixels = renderTexture.$renderBuffer.getPixels(rect.x, rect.y, iWidth, iHeight); + var x = 0; + var y = 0; + for (var i = 0; i < pixels.length; i += 4) { + this.sharedContext.fillStyle = + 'rgba(' + pixels[i] + + ',' + pixels[i + 1] + + ',' + pixels[i + 2] + + ',' + (pixels[i + 3] / 255) + ')'; + this.sharedContext.fillRect(x, y, 1, 1); + x++; + if (x == iWidth) { + x = 0; + y++; + } + } + if (!texture.$renderBuffer) { + renderTexture.dispose(); + } + return surface; + } + else { + var bitmapData = texture; + var offsetX = Math.round(bitmapData.$offsetX); + var offsetY = Math.round(bitmapData.$offsetY); + var bitmapWidth = bitmapData.$bitmapWidth; + var bitmapHeight = bitmapData.$bitmapHeight; + var $TextureScaleFactor = es.Core._instance.stage.textureScaleFactor; + this.sharedContext.drawImage(bitmapData.$bitmapData.source, bitmapData.$bitmapX + rect.x / $TextureScaleFactor, bitmapData.$bitmapY + rect.y / $TextureScaleFactor, bitmapWidth * rect.width / w, bitmapHeight * rect.height / h, offsetX, offsetY, rect.width, rect.height); + return surface; + } + }; + TextureUtils.toDataURL = function (type, texture, rect, encoderOptions) { + try { + var surface = this.convertImageToCanvas(texture, rect); + var result = surface.toDataURL(type, encoderOptions); + return result; + } + catch (e) { + egret.$error(1033); + } + return null; + }; + TextureUtils.eliFoTevas = function (type, texture, filePath, rect, encoderOptions) { + var surface = this.convertImageToCanvas(texture, rect); + var result = surface.toTempFilePathSync({ + fileType: type.indexOf("png") >= 0 ? "png" : "jpg" + }); + wx.getFileSystemManager().saveFile({ + tempFilePath: result, + filePath: wx.env.USER_DATA_PATH + "/" + filePath, + success: function (res) { + } + }); + return result; + }; + TextureUtils.getPixel32 = function (texture, x, y) { + egret.$warn(1041, "getPixel32", "getPixels"); + return texture.getPixels(x, y); + }; + TextureUtils.getPixels = function (texture, x, y, width, height) { + if (width === void 0) { width = 1; } + if (height === void 0) { height = 1; } + if (egret.Capabilities.renderMode == "webgl") { + var renderTexture = void 0; + if (!texture.$renderBuffer) { + renderTexture = new egret.RenderTexture(); + renderTexture.drawToTexture(new egret.Bitmap(texture)); + } + else { + renderTexture = texture; + } + var pixels = renderTexture.$renderBuffer.getPixels(x, y, width, height); + return pixels; + } + try { + var surface = this.convertImageToCanvas(texture); + var result = this.sharedContext.getImageData(x, y, width, height).data; + return result; + } + catch (e) { + egret.$error(1039); + } + }; + return TextureUtils; + }()); + es.TextureUtils = TextureUtils; +})(es || (es = {})); +var es; +(function (es) { + var Time = (function () { + function Time() { + } + Time.update = function (currentTime) { + var dt = (currentTime - this._lastTime) / 1000; + this.deltaTime = dt * this.timeScale; + this.unscaledDeltaTime = dt; + this._timeSinceSceneLoad += dt; + this.frameCount++; + this._lastTime = currentTime; + }; + Time.sceneChanged = function () { + this._timeSinceSceneLoad = 0; + }; + Time.checkEvery = function (interval) { + return (this._timeSinceSceneLoad / interval) > ((this._timeSinceSceneLoad - this.deltaTime) / interval); + }; + Time.deltaTime = 0; + Time.timeScale = 1; + Time.frameCount = 0; + Time._lastTime = 0; + return Time; + }()); + es.Time = Time; +})(es || (es = {})); +var TimeUtils = (function () { + function TimeUtils() { + } + TimeUtils.monthId = function (d) { + if (d === void 0) { d = null; } + d = d ? d : new Date(); + var y = d.getFullYear(); + var m = d.getMonth() + 1; + var g = m < 10 ? "0" : ""; + return parseInt(y + g + m); + }; + TimeUtils.dateId = function (t) { + if (t === void 0) { t = null; } + t = t ? t : new Date(); + var m = t.getMonth() + 1; + var a = m < 10 ? "0" : ""; + var d = t.getDate(); + var b = d < 10 ? "0" : ""; + return parseInt(t.getFullYear() + a + m + b + d); + }; + TimeUtils.weekId = function (d, first) { + if (d === void 0) { d = null; } + if (first === void 0) { first = true; } + d = d ? d : new Date(); + var c = new Date(); + c.setTime(d.getTime()); + c.setDate(1); + c.setMonth(0); + var year = c.getFullYear(); + var firstDay = c.getDay(); + if (firstDay == 0) { + firstDay = 7; + } + var max = false; + if (firstDay <= 4) { + max = firstDay > 1; + c.setDate(c.getDate() - (firstDay - 1)); + } + else { + c.setDate(c.getDate() + 7 - firstDay + 1); + } + var num = this.diffDay(d, c, false); + if (num < 0) { + c.setDate(1); + c.setMonth(0); + c.setDate(c.getDate() - 1); + return this.weekId(c, false); + } + var week = num / 7; + var weekIdx = Math.floor(week) + 1; + if (weekIdx == 53) { + c.setTime(d.getTime()); + c.setDate(c.getDate() - 1); + var endDay = c.getDay(); + if (endDay == 0) { + endDay = 7; + } + if (first && (!max || endDay < 4)) { + c.setFullYear(c.getFullYear() + 1); + c.setDate(1); + c.setMonth(0); + return this.weekId(c, false); + } + } + var g = weekIdx > 9 ? "" : "0"; + var s = year + "00" + g + weekIdx; + return parseInt(s); + }; + TimeUtils.diffDay = function (a, b, fixOne) { + if (fixOne === void 0) { fixOne = false; } + var x = (a.getTime() - b.getTime()) / 86400000; + return fixOne ? Math.ceil(x) : Math.floor(x); + }; + TimeUtils.getFirstDayOfWeek = function (d) { + d = d ? d : new Date(); + var day = d.getDay() || 7; + return new Date(d.getFullYear(), d.getMonth(), d.getDate() + 1 - day, 0, 0, 0, 0); + }; + TimeUtils.getFirstOfDay = function (d) { + d = d ? d : new Date(); + d.setHours(0, 0, 0, 0); + return d; + }; + TimeUtils.getNextFirstOfDay = function (d) { + return new Date(this.getFirstOfDay(d).getTime() + 86400000); + }; + TimeUtils.formatDate = function (date) { + var y = date.getFullYear(); + var m = date.getMonth() + 1; + m = m < 10 ? '0' + m : m; + var d = date.getDate(); + d = d < 10 ? ('0' + d) : d; + return y + '-' + m + '-' + d; + }; + TimeUtils.formatDateTime = function (date) { + var y = date.getFullYear(); + var m = date.getMonth() + 1; + m = m < 10 ? ('0' + m) : m; + var d = date.getDate(); + d = d < 10 ? ('0' + d) : d; + var h = date.getHours(); + var i = date.getMinutes(); + i = i < 10 ? ('0' + i) : i; + var s = date.getSeconds(); + s = s < 10 ? ('0' + s) : s; + return y + '-' + m + '-' + d + ' ' + h + ':' + i + ":" + s; + }; + TimeUtils.parseDate = function (s) { + var t = Date.parse(s); + if (!isNaN(t)) { + return new Date(Date.parse(s.replace(/-/g, "/"))); + } + else { + return new Date(); + } + }; + TimeUtils.secondToTime = function (time, partition, showHour) { + if (time === void 0) { time = 0; } + if (partition === void 0) { partition = ":"; } + if (showHour === void 0) { showHour = true; } + var hours = Math.floor(time / 3600); + var minutes = Math.floor(time % 3600 / 60); + var seconds = Math.floor(time % 3600 % 60); + var h = hours.toString(); + var m = minutes.toString(); + var s = seconds.toString(); + if (hours < 10) + h = "0" + h; + if (minutes < 10) + m = "0" + m; + if (seconds < 10) + s = "0" + s; + var timeStr; + if (showHour) + timeStr = h + partition + m + partition + s; + else + timeStr = m + partition + s; + return timeStr; + }; + TimeUtils.timeToMillisecond = function (time, partition) { + if (partition === void 0) { partition = ":"; } + var _ary = time.split(partition); + var timeNum = 0; + var len = _ary.length; + for (var i = 0; i < len; i++) { + var n = _ary[i]; + timeNum += n * Math.pow(60, (len - 1 - i)); + } + timeNum *= 1000; + return timeNum.toString(); + }; + return TimeUtils; +}()); +var es; +(function (es) { + var GraphicsCapabilities = (function (_super) { + __extends(GraphicsCapabilities, _super); + function GraphicsCapabilities() { + return _super !== null && _super.apply(this, arguments) || this; + } + GraphicsCapabilities.prototype.initialize = function (device) { + this.platformInitialize(device); + }; + GraphicsCapabilities.prototype.platformInitialize = function (device) { + if (GraphicsCapabilities.runtimeType != egret.RuntimeType.WXGAME) + return; + var capabilities = this; + capabilities["isMobile"] = true; + var systemInfo = wx.getSystemInfoSync(); + var systemStr = systemInfo.system.toLowerCase(); + if (systemStr.indexOf("ios") > -1) { + capabilities["os"] = "iOS"; + } + else if (systemStr.indexOf("android") > -1) { + capabilities["os"] = "Android"; + } + var language = systemInfo.language; + if (language.indexOf('zh') > -1) { + language = "zh-CN"; + } + else { + language = "en-US"; + } + capabilities["language"] = language; + }; + return GraphicsCapabilities; + }(egret.Capabilities)); + es.GraphicsCapabilities = GraphicsCapabilities; +})(es || (es = {})); +var es; +(function (es) { + var GraphicsDevice = (function () { + function GraphicsDevice() { + this.setup(); + this.graphicsCapabilities = new es.GraphicsCapabilities(); + this.graphicsCapabilities.initialize(this); + } + Object.defineProperty(GraphicsDevice.prototype, "viewport", { + get: function () { + return this._viewport; + }, + enumerable: true, + configurable: true + }); + GraphicsDevice.prototype.setup = function () { + this._viewport = new es.Viewport(0, 0, es.Core._instance.stage.stageWidth, es.Core._instance.stage.stageHeight); + }; + return GraphicsDevice; + }()); + es.GraphicsDevice = GraphicsDevice; +})(es || (es = {})); +var es; +(function (es) { + var Viewport = (function () { + function Viewport(x, y, width, height) { + this._x = x; + this._y = y; + this._width = width; + this._height = height; + this._minDepth = 0; + this._maxDepth = 1; + } + Object.defineProperty(Viewport.prototype, "width", { + get: function () { + return this._width; + }, + set: function (value) { + this._width = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Viewport.prototype, "height", { + get: function () { + return this._height; + }, + set: function (value) { + this._height = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Viewport.prototype, "aspectRatio", { + get: function () { + if ((this._height != 0) && (this._width != 0)) + return (this._width / this._height); + return 0; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Viewport.prototype, "bounds", { + get: function () { + return new es.Rectangle(this._x, this._y, this._width, this._height); + }, + set: function (value) { + this._x = value.x; + this._y = value.y; + this._width = value.width; + this._height = value.height; + }, + enumerable: true, + configurable: true + }); + return Viewport; + }()); + es.Viewport = Viewport; +})(es || (es = {})); +var es; +(function (es) { + var GaussianBlurEffect = (function (_super) { + __extends(GaussianBlurEffect, _super); + function GaussianBlurEffect() { + return _super.call(this, es.PostProcessor.default_vert, GaussianBlurEffect.blur_frag, { + screenWidth: es.Core.graphicsDevice.viewport.width, + screenHeight: es.Core.graphicsDevice.viewport.height + }) || this; + } + GaussianBlurEffect.blur_frag = "precision mediump float;\n" + + "uniform sampler2D uSampler;\n" + + "uniform float screenWidth;\n" + + "uniform float screenHeight;\n" + + "float normpdf(in float x, in float sigma)\n" + + "{\n" + + "return 0.39894*exp(-0.5*x*x/(sigma*sigma))/sigma;\n" + + "}\n" + + "void main()\n" + + "{\n" + + "vec3 c = texture2D(uSampler, gl_FragCoord.xy / vec2(screenWidth, screenHeight).xy).rgb;\n" + + "const int mSize = 11;\n" + + "const int kSize = (mSize - 1)/2;\n" + + "float kernel[mSize];\n" + + "vec3 final_colour = vec3(0.0);\n" + + "float sigma = 7.0;\n" + + "float z = 0.0;\n" + + "for (int j = 0; j <= kSize; ++j)\n" + + "{\n" + + "kernel[kSize+j] = kernel[kSize-j] = normpdf(float(j),sigma);\n" + + "}\n" + + "for (int j = 0; j < mSize; ++j)\n" + + "{\n" + + "z += kernel[j];\n" + + "}\n" + + "for (int i = -kSize; i <= kSize; ++i)\n" + + "{\n" + + "for (int j = -kSize; j <= kSize; ++j)\n" + + "{\n" + + "final_colour += kernel[kSize+j]*kernel[kSize+i]*texture2D(uSampler, (gl_FragCoord.xy+vec2(float(i),float(j))) / vec2(screenWidth, screenHeight).xy).rgb;\n" + + "}\n}\n" + + "gl_FragColor = vec4(final_colour/(z*z), 1.0);\n" + + "}"; + return GaussianBlurEffect; + }(egret.CustomFilter)); + es.GaussianBlurEffect = GaussianBlurEffect; +})(es || (es = {})); +var es; +(function (es) { + var PolygonLightEffect = (function (_super) { + __extends(PolygonLightEffect, _super); + function PolygonLightEffect() { + return _super.call(this, PolygonLightEffect.vertSrc, PolygonLightEffect.fragmentSrc) || this; + } + PolygonLightEffect.vertSrc = "attribute vec2 aVertexPosition;\n" + "attribute vec2 aTextureCoord;\n" + "uniform vec2 projectionVector;\n" + "varying vec2 vTextureCoord;\n" + @@ -3236,1745 +4918,3745 @@ var WindTransition = (function (_super) { " gl_Position = vec4( (aVertexPosition / projectionVector) + center , 0.0, 1.0);\n" + " vTextureCoord = aTextureCoord;\n" + "}"; - var fragmentSrc = "precision lowp float;\n" + + PolygonLightEffect.fragmentSrc = "precision lowp float;\n" + "varying vec2 vTextureCoord;\n" + "uniform sampler2D uSampler;\n" + - "uniform float _progress;\n" + - "uniform float _size;\n" + - "uniform float _windSegments;\n" + + "#define SAMPLE_COUNT 15\n" + + "uniform vec2 _sampleOffsets[SAMPLE_COUNT];\n" + + "uniform float _sampleWeights[SAMPLE_COUNT];\n" + "void main(void) {\n" + - "vec2 co = floor(vec2(0.0, vTextureCoord.y * _windSegments));\n" + - "float x = sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453;\n" + - "float r = x - floor(x);\n" + - "float m = smoothstep(0.0, -_size, vTextureCoord.x * (1.0 - _size) + _size * r - (_progress * (1.0 + _size)));\n" + - "vec4 fg = texture2D(uSampler, vTextureCoord);\n" + - "gl_FragColor = mix(fg, vec4(0, 0, 0, 0), m);\n" + + "vec4 c = vec4(0, 0, 0, 0);\n" + + "for( int i = 0; i < SAMPLE_COUNT; i++ )\n" + + " c += texture2D( uSampler, vTextureCoord + _sampleOffsets[i] ) * _sampleWeights[i];\n" + + "gl_FragColor = c;\n" + "}"; - _this._windEffect = new egret.CustomFilter(vertexSrc, fragmentSrc, { - _progress: 0, - _size: 0.3, - _windSegments: 100 - }); - _this._mask = new egret.Shape(); - _this._mask.graphics.beginFill(0xFFFFFF, 1); - _this._mask.graphics.drawRect(0, 0, SceneManager.stage.stageWidth, SceneManager.stage.stageHeight); - _this._mask.graphics.endFill(); - _this._mask.filters = [_this._windEffect]; - SceneManager.stage.addChild(_this._mask); - return _this; - } - Object.defineProperty(WindTransition.prototype, "windSegments", { - set: function (value) { - this._windEffect.uniforms._windSegments = value; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(WindTransition.prototype, "size", { - set: function (value) { - this._windEffect.uniforms._size = value; - }, - enumerable: true, - configurable: true - }); - WindTransition.prototype.onBeginTransition = function () { - return __awaiter(this, void 0, void 0, function () { - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - this.loadNextScene(); - return [4, this.tickEffectProgressProperty(this._windEffect, this.duration, this.easeType)]; - case 1: - _a.sent(); - this.transitionComplete(); - SceneManager.stage.removeChild(this._mask); - return [2]; - } - }); - }); - }; - return WindTransition; -}(SceneTransition)); -var Flags = (function () { - function Flags() { - } - Flags.isFlagSet = function (self, flag) { - return (self & flag) != 0; - }; - Flags.isUnshiftedFlagSet = function (self, flag) { - flag = 1 << flag; - return (self & flag) != 0; - }; - Flags.setFlagExclusive = function (self, flag) { - return 1 << flag; - }; - Flags.setFlag = function (self, flag) { - return (self | 1 << flag); - }; - Flags.unsetFlag = function (self, flag) { - flag = 1 << flag; - return (self & (~flag)); - }; - Flags.invertFlags = function (self) { - return ~self; - }; - return Flags; -}()); -var MathHelper = (function () { - function MathHelper() { - } - MathHelper.toDegrees = function (radians) { - return radians * 57.295779513082320876798154814105; - }; - MathHelper.toRadians = function (degrees) { - return degrees * 0.017453292519943295769236907684886; - }; - MathHelper.map = function (value, leftMin, leftMax, rightMin, rightMax) { - return rightMin + (value - leftMin) * (rightMax - rightMin) / (leftMax - leftMin); - }; - MathHelper.lerp = function (value1, value2, amount) { - return value1 + (value2 - value1) * amount; - }; - MathHelper.clamp = function (value, min, max) { - if (value < min) - return min; - if (value > max) - return max; - return value; - }; - MathHelper.pointOnCirlce = function (circleCenter, radius, angleInDegrees) { - var radians = MathHelper.toRadians(angleInDegrees); - return new Vector2(Math.cos(radians) * radians + circleCenter.x, Math.sin(radians) * radians + circleCenter.y); - }; - MathHelper.isEven = function (value) { - return value % 2 == 0; - }; - MathHelper.Epsilon = 0.00001; - MathHelper.Rad2Deg = 57.29578; - MathHelper.Deg2Rad = 0.0174532924; - return MathHelper; -}()); -var Matrix2D = (function () { - function Matrix2D(m11, m12, m21, m22, m31, m32) { - this.m11 = 0; - this.m12 = 0; - this.m21 = 0; - this.m22 = 0; - this.m31 = 0; - this.m32 = 0; - this.m11 = m11 ? m11 : 1; - this.m12 = m12 ? m12 : 0; - this.m21 = m21 ? m21 : 0; - this.m22 = m22 ? m22 : 1; - this.m31 = m31 ? m31 : 0; - this.m32 = m32 ? m32 : 0; - } - Object.defineProperty(Matrix2D, "identity", { - get: function () { - return Matrix2D._identity; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Matrix2D.prototype, "translation", { - get: function () { - return new Vector2(this.m31, this.m32); - }, - set: function (value) { - this.m31 = value.x; - this.m32 = value.y; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Matrix2D.prototype, "rotation", { - get: function () { - return Math.atan2(this.m21, this.m11); - }, - set: function (value) { - var val1 = Math.cos(value); - var val2 = Math.sin(value); - this.m11 = val1; - this.m12 = val2; - this.m21 = -val2; - this.m22 = val1; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Matrix2D.prototype, "rotationDegrees", { - get: function () { - return MathHelper.toDegrees(this.rotation); - }, - set: function (value) { - this.rotation = MathHelper.toRadians(value); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Matrix2D.prototype, "scale", { - get: function () { - return new Vector2(this.m11, this.m22); - }, - set: function (value) { - this.m11 = value.x; - this.m12 = value.y; - }, - enumerable: true, - configurable: true - }); - Matrix2D.add = function (matrix1, matrix2) { - matrix1.m11 += matrix2.m11; - matrix1.m12 += matrix2.m12; - matrix1.m21 += matrix2.m21; - matrix1.m22 += matrix2.m22; - matrix1.m31 += matrix2.m31; - matrix1.m32 += matrix2.m32; - return matrix1; - }; - Matrix2D.divide = function (matrix1, matrix2) { - matrix1.m11 /= matrix2.m11; - matrix1.m12 /= matrix2.m12; - matrix1.m21 /= matrix2.m21; - matrix1.m22 /= matrix2.m22; - matrix1.m31 /= matrix2.m31; - matrix1.m32 /= matrix2.m32; - return matrix1; - }; - Matrix2D.multiply = function (matrix1, matrix2) { - var result = new Matrix2D(); - var m11 = (matrix1.m11 * matrix2.m11) + (matrix1.m12 * matrix2.m21); - var m12 = (matrix1.m11 * matrix2.m12) + (matrix1.m12 * matrix2.m22); - var m21 = (matrix1.m21 * matrix2.m11) + (matrix1.m22 * matrix2.m21); - var m22 = (matrix1.m21 * matrix2.m12) + (matrix1.m22 * matrix2.m22); - var m31 = (matrix1.m31 * matrix2.m11) + (matrix1.m32 * matrix2.m21) + matrix2.m31; - var m32 = (matrix1.m31 * matrix2.m12) + (matrix1.m32 * matrix2.m22) + matrix2.m32; - result.m11 = m11; - result.m12 = m12; - result.m21 = m21; - result.m22 = m22; - result.m31 = m31; - result.m32 = m32; - return result; - }; - Matrix2D.multiplyTranslation = function (matrix, x, y) { - var trans = Matrix2D.createTranslation(x, y); - return Matrix2D.multiply(matrix, trans); - }; - Matrix2D.prototype.determinant = function () { - return this.m11 * this.m22 - this.m12 * this.m21; - }; - Matrix2D.invert = function (matrix, result) { - if (result === void 0) { result = new Matrix2D(); } - var det = 1 / matrix.determinant(); - result.m11 = matrix.m22 * det; - result.m12 = -matrix.m12 * det; - result.m21 = -matrix.m21 * det; - result.m22 = matrix.m11 * det; - result.m31 = (matrix.m32 * matrix.m21 - matrix.m31 * matrix.m22) * det; - result.m32 = -(matrix.m32 * matrix.m11 - matrix.m31 * matrix.m12) * det; - return result; - }; - Matrix2D.createTranslation = function (xPosition, yPosition) { - var result = new Matrix2D(); - result.m11 = 1; - result.m12 = 0; - result.m21 = 0; - result.m22 = 1; - result.m31 = xPosition; - result.m32 = yPosition; - return result; - }; - Matrix2D.createTranslationVector = function (position) { - return this.createTranslation(position.x, position.y); - }; - Matrix2D.createRotation = function (radians, result) { - result = new Matrix2D(); - var val1 = Math.cos(radians); - var val2 = Math.sin(radians); - result.m11 = val1; - result.m12 = val2; - result.m21 = -val2; - result.m22 = val1; - return result; - }; - Matrix2D.createScale = function (xScale, yScale, result) { - if (result === void 0) { result = new Matrix2D(); } - result.m11 = xScale; - result.m12 = 0; - result.m21 = 0; - result.m22 = yScale; - result.m31 = 0; - result.m32 = 0; - return result; - }; - Matrix2D.prototype.toEgretMatrix = function () { - var matrix = new egret.Matrix(this.m11, this.m12, this.m21, this.m22, this.m31, this.m32); - return matrix; - }; - Matrix2D._identity = new Matrix2D(1, 0, 0, 1, 0, 0); - return Matrix2D; -}()); -var Rectangle = (function (_super) { - __extends(Rectangle, _super); - function Rectangle() { - return _super !== null && _super.apply(this, arguments) || this; - } - Object.defineProperty(Rectangle.prototype, "max", { - get: function () { - return new Vector2(this.right, this.bottom); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Rectangle.prototype, "center", { - get: function () { - return new Vector2(this.x + (this.width / 2), this.y + (this.height / 2)); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Rectangle.prototype, "location", { - get: function () { - return new Vector2(this.x, this.y); - }, - set: function (value) { - this.x = value.x; - this.y = value.y; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Rectangle.prototype, "size", { - get: function () { - return new Vector2(this.width, this.height); - }, - set: function (value) { - this.width = value.x; - this.height = value.y; - }, - enumerable: true, - configurable: true - }); - Rectangle.prototype.intersects = function (value) { - return value.left < this.right && - this.left < value.right && - value.top < this.bottom && - this.top < value.bottom; - }; - Rectangle.prototype.containsInVec = function (value) { - return ((((this.x <= value.x) && (value.x < (this.x + this.width))) && - (this.y <= value.y)) && - (value.y < (this.y + this.height))); - }; - Rectangle.prototype.containsRect = function (value) { - return ((((this.x <= value.x) && (value.x < (this.x + this.width))) && - (this.y <= value.y)) && - (value.y < (this.y + this.height))); - }; - Rectangle.prototype.getHalfSize = function () { - return new Vector2(this.width * 0.5, this.height * 0.5); - }; - Rectangle.fromMinMax = function (minX, minY, maxX, maxY) { - return new Rectangle(minX, minY, maxX - minX, maxY - minY); - }; - Rectangle.prototype.getClosestPointOnRectangleBorderToPoint = function (point) { - var edgeNormal = Vector2.zero; - var res = new Vector2(); - res.x = MathHelper.clamp(point.x, this.left, this.right); - res.y = MathHelper.clamp(point.y, this.top, this.bottom); - if (this.containsInVec(res)) { - var dl = res.x - this.left; - var dr = this.right - res.x; - var dt = res.y - this.top; - var db = this.bottom - res.y; - var min = Math.min(dl, dr, dt, db); - if (min == dt) { - res.y = this.top; - edgeNormal.y = -1; - } - else if (min == db) { - res.y = this.bottom; - edgeNormal.y = 1; - } - else if (min == dl) { - res.x = this.left; - edgeNormal.x = -1; - } - else { - res.x = this.right; - edgeNormal.x = 1; - } + return PolygonLightEffect; + }(egret.CustomFilter)); + es.PolygonLightEffect = PolygonLightEffect; +})(es || (es = {})); +var es; +(function (es) { + var PostProcessor = (function () { + function PostProcessor(effect) { + if (effect === void 0) { effect = null; } + this.enabled = true; + this.effect = effect; } - else { - if (res.x == this.left) - edgeNormal.x = -1; - if (res.x == this.right) - edgeNormal.x = 1; - if (res.y == this.top) - edgeNormal.y = -1; - if (res.y == this.bottom) - edgeNormal.y = 1; - } - return { res: res, edgeNormal: edgeNormal }; - }; - Rectangle.prototype.getClosestPointOnBoundsToOrigin = function () { - var max = this.max; - var minDist = Math.abs(this.location.x); - var boundsPoint = new Vector2(this.location.x, 0); - if (Math.abs(max.x) < minDist) { - minDist = Math.abs(max.x); - boundsPoint.x = max.x; - boundsPoint.y = 0; - } - if (Math.abs(max.y) < minDist) { - minDist = Math.abs(max.y); - boundsPoint.x = 0; - boundsPoint.y = max.y; - } - if (Math.abs(this.location.y) < minDist) { - minDist = Math.abs(this.location.y); - boundsPoint.x = 0; - boundsPoint.y = this.location.y; - } - return boundsPoint; - }; - Rectangle.rectEncompassingPoints = function (points) { - var minX = Number.POSITIVE_INFINITY; - var minY = Number.POSITIVE_INFINITY; - var maxX = Number.NEGATIVE_INFINITY; - var maxY = Number.NEGATIVE_INFINITY; - for (var i = 0; i < points.length; i++) { - var pt = points[i]; - if (pt.x < minX) - minX = pt.x; - if (pt.x > maxX) - maxX = pt.x; - if (pt.y < minY) - minY = pt.y; - if (pt.y > maxY) - maxY = pt.y; - } - return this.fromMinMax(minX, minY, maxX, maxY); - }; - return Rectangle; -}(egret.Rectangle)); -var Vector3 = (function () { - function Vector3(x, y, z) { - this.x = x; - this.y = y; - this.z = z; - } - return Vector3; -}()); -var ColliderTriggerHelper = (function () { - function ColliderTriggerHelper(entity) { - this._activeTriggerIntersections = []; - this._previousTriggerIntersections = []; - this._tempTriggerList = []; - this._entity = entity; - } - ColliderTriggerHelper.prototype.update = function () { - var colliders = this._entity.getComponents(Collider); - for (var i = 0; i < colliders.length; i++) { - var collider = colliders[i]; - var boxcastResult = Physics.boxcastBroadphase(collider.bounds, collider.collidesWithLayers); - collider.bounds = boxcastResult.rect; - var neighbors = boxcastResult.colliders; - var _loop_5 = function (j) { - var neighbor = neighbors[j]; - if (!collider.isTrigger && !neighbor.isTrigger) - return "continue"; - if (collider.overlaps(neighbor)) { - var pair_1 = new Pair(collider, neighbor); - var shouldReportTriggerEvent = this_1._activeTriggerIntersections.findIndex(function (value) { - return value.first == pair_1.first && value.second == pair_1.second; - }) == -1 && this_1._previousTriggerIntersections.findIndex(function (value) { - return value.first == pair_1.first && value.second == pair_1.second; - }) == -1; - if (shouldReportTriggerEvent) - this_1.notifyTriggerListeners(pair_1, true); - if (!this_1._activeTriggerIntersections.contains(pair_1)) - this_1._activeTriggerIntersections.push(pair_1); - } - }; - var this_1 = this; - for (var j = 0; j < neighbors.length; j++) { - _loop_5(j); - } - } - ListPool.free(colliders); - this.checkForExitedColliders(); - }; - ColliderTriggerHelper.prototype.checkForExitedColliders = function () { - var _this = this; - var _loop_6 = function (i) { - var index = this_2._previousTriggerIntersections.findIndex(function (value) { - if (value.first == _this._activeTriggerIntersections[i].first && value.second == _this._activeTriggerIntersections[i].second) - return true; - return false; - }); - if (index != -1) - this_2._previousTriggerIntersections.removeAt(index); + PostProcessor.prototype.onAddedToScene = function (scene) { + this.scene = scene; + this.shape = new egret.Shape(); + this.shape.graphics.beginFill(0xFFFFFF, 1); + this.shape.graphics.drawRect(0, 0, es.Core.graphicsDevice.viewport.width, es.Core.graphicsDevice.viewport.height); + this.shape.graphics.endFill(); + scene.addChild(this.shape); }; - var this_2 = this; - for (var i = 0; i < this._activeTriggerIntersections.length; i++) { - _loop_6(i); - } - for (var i = 0; i < this._previousTriggerIntersections.length; i++) { - this.notifyTriggerListeners(this._previousTriggerIntersections[i], false); - } - this._previousTriggerIntersections.length = 0; - for (var i = 0; i < this._activeTriggerIntersections.length; i++) { - if (!this._previousTriggerIntersections.contains(this._activeTriggerIntersections[i])) { - this._previousTriggerIntersections.push(this._activeTriggerIntersections[i]); + PostProcessor.prototype.process = function () { + this.drawFullscreenQuad(); + }; + PostProcessor.prototype.onSceneBackBufferSizeChanged = function (newWidth, newHeight) { + }; + PostProcessor.prototype.unload = function () { + if (this.effect) { + this.effect = null; } + this.scene.removeChild(this.shape); + this.scene = null; + }; + PostProcessor.prototype.drawFullscreenQuad = function () { + this.scene.filters = [this.effect]; + }; + PostProcessor.default_vert = "attribute vec2 aVertexPosition;\n" + + "attribute vec2 aTextureCoord;\n" + + "attribute vec2 aColor;\n" + + "uniform vec2 projectionVector;\n" + + "varying vec2 vTextureCoord;\n" + + "varying vec4 vColor;\n" + + "const vec2 center = vec2(-1.0, 1.0);\n" + + "void main(void) {\n" + + "gl_Position = vec4( (aVertexPosition / projectionVector) + center , 0.0, 1.0);\n" + + "vTextureCoord = aTextureCoord;\n" + + "vColor = vec4(aColor.x, aColor.x, aColor.x, aColor.x);\n" + + "}"; + return PostProcessor; + }()); + es.PostProcessor = PostProcessor; +})(es || (es = {})); +var es; +(function (es) { + var GaussianBlurPostProcessor = (function (_super) { + __extends(GaussianBlurPostProcessor, _super); + function GaussianBlurPostProcessor() { + return _super !== null && _super.apply(this, arguments) || this; } - this._activeTriggerIntersections.length = 0; - }; - ColliderTriggerHelper.prototype.notifyTriggerListeners = function (collisionPair, isEntering) { - collisionPair.first.entity.getComponents("ITriggerListener", this._tempTriggerList); - for (var i = 0; i < this._tempTriggerList.length; i++) { - if (isEntering) { - this._tempTriggerList[i].onTriggerEnter(collisionPair.second, collisionPair.first); + GaussianBlurPostProcessor.prototype.onAddedToScene = function (scene) { + _super.prototype.onAddedToScene.call(this, scene); + this.effect = new es.GaussianBlurEffect(); + }; + return GaussianBlurPostProcessor; + }(es.PostProcessor)); + es.GaussianBlurPostProcessor = GaussianBlurPostProcessor; +})(es || (es = {})); +var es; +(function (es) { + var Renderer = (function () { + function Renderer(renderOrder, camera) { + if (camera === void 0) { camera = null; } + this.renderOrder = 0; + this.camera = camera; + this.renderOrder = renderOrder; + } + Renderer.prototype.onAddedToScene = function (scene) { + }; + Renderer.prototype.unload = function () { + }; + Renderer.prototype.onSceneBackBufferSizeChanged = function (newWidth, newHeight) { + }; + Renderer.prototype.compareTo = function (other) { + return this.renderOrder - other.renderOrder; + }; + Renderer.prototype.beginRender = function (cam) { + }; + Renderer.prototype.renderAfterStateCheck = function (renderable, cam) { + renderable.render(cam); + }; + return Renderer; + }()); + es.Renderer = Renderer; +})(es || (es = {})); +var es; +(function (es) { + var DefaultRenderer = (function (_super) { + __extends(DefaultRenderer, _super); + function DefaultRenderer() { + return _super.call(this, 0, null) || this; + } + DefaultRenderer.prototype.render = function (scene) { + var cam = this.camera ? this.camera : scene.camera; + this.beginRender(cam); + for (var i = 0; i < scene.renderableComponents.count; i++) { + var renderable = scene.renderableComponents.buffer[i]; + if (renderable.enabled && renderable.isVisibleFromCamera(cam)) + this.renderAfterStateCheck(renderable, cam); + } + }; + return DefaultRenderer; + }(es.Renderer)); + es.DefaultRenderer = DefaultRenderer; +})(es || (es = {})); +var es; +(function (es) { + var ScreenSpaceRenderer = (function (_super) { + __extends(ScreenSpaceRenderer, _super); + function ScreenSpaceRenderer() { + return _super !== null && _super.apply(this, arguments) || this; + } + ScreenSpaceRenderer.prototype.render = function (scene) { + }; + return ScreenSpaceRenderer; + }(es.Renderer)); + es.ScreenSpaceRenderer = ScreenSpaceRenderer; +})(es || (es = {})); +var es; +(function (es) { + var PolyLight = (function (_super) { + __extends(PolyLight, _super); + function PolyLight(radius, color, power) { + var _this = _super.call(this) || this; + _this._indices = []; + _this.radius = radius; + _this.power = power; + _this.color = color; + _this.computeTriangleIndices(); + return _this; + } + Object.defineProperty(PolyLight.prototype, "radius", { + get: function () { + return this._radius; + }, + set: function (value) { + this.setRadius(value); + }, + enumerable: true, + configurable: true + }); + PolyLight.prototype.setRadius = function (radius) { + if (radius != this._radius) { + this._radius = radius; + this._areBoundsDirty = true; + } + }; + PolyLight.prototype.render = function (camera) { + }; + PolyLight.prototype.reset = function () { + }; + PolyLight.prototype.computeTriangleIndices = function (totalTris) { + if (totalTris === void 0) { totalTris = 20; } + this._indices.length = 0; + for (var i = 0; i < totalTris; i += 2) { + this._indices.push(0); + this._indices.push(i + 2); + this._indices.push(i + 1); + } + }; + return PolyLight; + }(es.RenderableComponent)); + es.PolyLight = PolyLight; +})(es || (es = {})); +var es; +(function (es) { + var SceneTransition = (function () { + function SceneTransition(sceneLoadAction) { + this.sceneLoadAction = sceneLoadAction; + this.loadsNewScene = sceneLoadAction != null; + } + Object.defineProperty(SceneTransition.prototype, "hasPreviousSceneRender", { + get: function () { + if (!this._hasPreviousSceneRender) { + this._hasPreviousSceneRender = true; + return false; + } + return true; + }, + enumerable: true, + configurable: true + }); + SceneTransition.prototype.preRender = function () { + }; + SceneTransition.prototype.render = function () { + }; + SceneTransition.prototype.onBeginTransition = function () { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4, this.loadNextScene()]; + case 1: + _a.sent(); + this.transitionComplete(); + return [2]; + } + }); + }); + }; + SceneTransition.prototype.tickEffectProgressProperty = function (filter, duration, easeType, reverseDirection) { + if (reverseDirection === void 0) { reverseDirection = false; } + return new Promise(function (resolve) { + var start = reverseDirection ? 1 : 0; + var end = reverseDirection ? 0 : 1; + egret.Tween.get(filter.uniforms).set({ _progress: start }).to({ _progress: end }, duration * 1000, easeType).call(function () { + resolve(); + }); + }); + }; + SceneTransition.prototype.transitionComplete = function () { + es.Core._instance._sceneTransition = null; + if (this.onTransitionCompleted) { + this.onTransitionCompleted(); + } + }; + SceneTransition.prototype.loadNextScene = function () { + return __awaiter(this, void 0, void 0, function () { + var _a; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + if (this.onScreenObscured) + this.onScreenObscured(); + if (!this.loadsNewScene) { + this.isNewSceneLoaded = true; + } + _a = es.Core; + return [4, this.sceneLoadAction()]; + case 1: + _a.scene = _b.sent(); + this.isNewSceneLoaded = true; + return [2]; + } + }); + }); + }; + return SceneTransition; + }()); + es.SceneTransition = SceneTransition; +})(es || (es = {})); +var es; +(function (es) { + var FadeTransition = (function (_super) { + __extends(FadeTransition, _super); + function FadeTransition(sceneLoadAction) { + var _this = _super.call(this, sceneLoadAction) || this; + _this.fadeToColor = 0x000000; + _this.fadeOutDuration = 0.4; + _this.fadeEaseType = egret.Ease.quadInOut; + _this.delayBeforeFadeInDuration = 0.1; + _this._alpha = 0; + _this._mask = new egret.Shape(); + return _this; + } + FadeTransition.prototype.onBeginTransition = function () { + return __awaiter(this, void 0, void 0, function () { + var _this = this; + return __generator(this, function (_a) { + this._mask.graphics.beginFill(this.fadeToColor, 1); + this._mask.graphics.drawRect(0, 0, es.Core.graphicsDevice.viewport.width, es.Core.graphicsDevice.viewport.height); + this._mask.graphics.endFill(); + egret.Tween.get(this).to({ _alpha: 1 }, this.fadeOutDuration * 1000, this.fadeEaseType) + .call(function () { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4, this.loadNextScene()]; + case 1: + _a.sent(); + return [2]; + } + }); + }); }).wait(this.delayBeforeFadeInDuration).call(function () { + egret.Tween.get(_this).to({ _alpha: 0 }, _this.fadeOutDuration * 1000, _this.fadeEaseType).call(function () { + _this.transitionComplete(); + }); + }); + return [2]; + }); + }); + }; + FadeTransition.prototype.render = function () { + this._mask.graphics.clear(); + this._mask.graphics.beginFill(this.fadeToColor, this._alpha); + this._mask.graphics.drawRect(0, 0, es.Core.graphicsDevice.viewport.width, es.Core.graphicsDevice.viewport.height); + this._mask.graphics.endFill(); + }; + return FadeTransition; + }(es.SceneTransition)); + es.FadeTransition = FadeTransition; +})(es || (es = {})); +var es; +(function (es) { + var WindTransition = (function (_super) { + __extends(WindTransition, _super); + function WindTransition(sceneLoadAction) { + var _this = _super.call(this, sceneLoadAction) || this; + _this.duration = 1; + _this.easeType = egret.Ease.quadOut; + var vertexSrc = "attribute vec2 aVertexPosition;\n" + + "attribute vec2 aTextureCoord;\n" + + "uniform vec2 projectionVector;\n" + + "varying vec2 vTextureCoord;\n" + + "const vec2 center = vec2(-1.0, 1.0);\n" + + "void main(void) {\n" + + " gl_Position = vec4( (aVertexPosition / projectionVector) + center , 0.0, 1.0);\n" + + " vTextureCoord = aTextureCoord;\n" + + "}"; + var fragmentSrc = "precision lowp float;\n" + + "varying vec2 vTextureCoord;\n" + + "uniform sampler2D uSampler;\n" + + "uniform float _progress;\n" + + "uniform float _size;\n" + + "uniform float _windSegments;\n" + + "void main(void) {\n" + + "vec2 co = floor(vec2(0.0, vTextureCoord.y * _windSegments));\n" + + "float x = sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453;\n" + + "float r = x - floor(x);\n" + + "float m = smoothstep(0.0, -_size, vTextureCoord.x * (1.0 - _size) + _size * r - (_progress * (1.0 + _size)));\n" + + "vec4 fg = texture2D(uSampler, vTextureCoord);\n" + + "gl_FragColor = mix(fg, vec4(0, 0, 0, 0), m);\n" + + "}"; + _this._windEffect = new egret.CustomFilter(vertexSrc, fragmentSrc, { + _progress: 0, + _size: 0.3, + _windSegments: 100 + }); + _this._mask = new egret.Shape(); + _this._mask.graphics.beginFill(0xFFFFFF, 1); + _this._mask.graphics.drawRect(0, 0, es.Core.graphicsDevice.viewport.width, es.Core.graphicsDevice.viewport.height); + _this._mask.graphics.endFill(); + _this._mask.filters = [_this._windEffect]; + return _this; + } + Object.defineProperty(WindTransition.prototype, "windSegments", { + set: function (value) { + this._windEffect.uniforms._windSegments = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(WindTransition.prototype, "size", { + set: function (value) { + this._windEffect.uniforms._size = value; + }, + enumerable: true, + configurable: true + }); + WindTransition.prototype.onBeginTransition = function () { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + this.loadNextScene(); + return [4, this.tickEffectProgressProperty(this._windEffect, this.duration, this.easeType)]; + case 1: + _a.sent(); + this.transitionComplete(); + return [2]; + } + }); + }); + }; + return WindTransition; + }(es.SceneTransition)); + es.WindTransition = WindTransition; +})(es || (es = {})); +var es; +(function (es) { + var Bezier = (function () { + function Bezier() { + } + Bezier.getPoint = function (p0, p1, p2, t) { + t = es.MathHelper.clamp01(t); + var oneMinusT = 1 - t; + return es.Vector2.add(es.Vector2.add(es.Vector2.multiply(new es.Vector2(oneMinusT * oneMinusT), p0), es.Vector2.multiply(new es.Vector2(2 * oneMinusT * t), p1)), es.Vector2.multiply(new es.Vector2(t * t), p2)); + }; + Bezier.getFirstDerivative = function (p0, p1, p2, t) { + return es.Vector2.add(es.Vector2.multiply(new es.Vector2(2 * (1 - t)), es.Vector2.subtract(p1, p0)), es.Vector2.multiply(new es.Vector2(2 * t), es.Vector2.subtract(p2, p1))); + }; + Bezier.getFirstDerivativeThree = function (start, firstControlPoint, secondControlPoint, end, t) { + t = es.MathHelper.clamp01(t); + var oneMunusT = 1 - t; + return es.Vector2.add(es.Vector2.add(es.Vector2.multiply(new es.Vector2(3 * oneMunusT * oneMunusT), es.Vector2.subtract(firstControlPoint, start)), es.Vector2.multiply(new es.Vector2(6 * oneMunusT * t), es.Vector2.subtract(secondControlPoint, firstControlPoint))), es.Vector2.multiply(new es.Vector2(3 * t * t), es.Vector2.subtract(end, secondControlPoint))); + }; + Bezier.getPointThree = function (start, firstControlPoint, secondControlPoint, end, t) { + t = es.MathHelper.clamp01(t); + var oneMunusT = 1 - t; + return es.Vector2.add(es.Vector2.add(es.Vector2.add(es.Vector2.multiply(new es.Vector2(oneMunusT * oneMunusT * oneMunusT), start), es.Vector2.multiply(new es.Vector2(3 * oneMunusT * oneMunusT * t), firstControlPoint)), es.Vector2.multiply(new es.Vector2(3 * oneMunusT * t * t), secondControlPoint)), es.Vector2.multiply(new es.Vector2(t * t * t), end)); + }; + Bezier.getOptimizedDrawingPoints = function (start, firstCtrlPoint, secondCtrlPoint, end, distanceTolerance) { + if (distanceTolerance === void 0) { distanceTolerance = 1; } + var points = es.ListPool.obtain(); + points.push(start); + this.recursiveGetOptimizedDrawingPoints(start, firstCtrlPoint, secondCtrlPoint, end, points, distanceTolerance); + points.push(end); + return points; + }; + Bezier.recursiveGetOptimizedDrawingPoints = function (start, firstCtrlPoint, secondCtrlPoint, end, points, distanceTolerance) { + var pt12 = es.Vector2.divide(es.Vector2.add(start, firstCtrlPoint), new es.Vector2(2)); + var pt23 = es.Vector2.divide(es.Vector2.add(firstCtrlPoint, secondCtrlPoint), new es.Vector2(2)); + var pt34 = es.Vector2.divide(es.Vector2.add(secondCtrlPoint, end), new es.Vector2(2)); + var pt123 = es.Vector2.divide(es.Vector2.add(pt12, pt23), new es.Vector2(2)); + var pt234 = es.Vector2.divide(es.Vector2.add(pt23, pt34), new es.Vector2(2)); + var pt1234 = es.Vector2.divide(es.Vector2.add(pt123, pt234), new es.Vector2(2)); + var deltaLine = es.Vector2.subtract(end, start); + var d2 = Math.abs(((firstCtrlPoint.x, end.x) * deltaLine.y - (firstCtrlPoint.y - end.y) * deltaLine.x)); + var d3 = Math.abs(((secondCtrlPoint.x - end.x) * deltaLine.y - (secondCtrlPoint.y - end.y) * deltaLine.x)); + if ((d2 + d3) * (d2 + d3) < distanceTolerance * (deltaLine.x * deltaLine.x + deltaLine.y * deltaLine.y)) { + points.push(pt1234); + return; + } + this.recursiveGetOptimizedDrawingPoints(start, pt12, pt123, pt1234, points, distanceTolerance); + this.recursiveGetOptimizedDrawingPoints(pt1234, pt234, pt34, end, points, distanceTolerance); + }; + return Bezier; + }()); + es.Bezier = Bezier; +})(es || (es = {})); +var es; +(function (es) { + var Flags = (function () { + function Flags() { + } + Flags.isFlagSet = function (self, flag) { + return (self & flag) != 0; + }; + Flags.isUnshiftedFlagSet = function (self, flag) { + flag = 1 << flag; + return (self & flag) != 0; + }; + Flags.setFlagExclusive = function (self, flag) { + return 1 << flag; + }; + Flags.setFlag = function (self, flag) { + return (self | 1 << flag); + }; + Flags.unsetFlag = function (self, flag) { + flag = 1 << flag; + return (self & (~flag)); + }; + Flags.invertFlags = function (self) { + return ~self; + }; + return Flags; + }()); + es.Flags = Flags; +})(es || (es = {})); +var es; +(function (es) { + var MathHelper = (function () { + function MathHelper() { + } + MathHelper.toDegrees = function (radians) { + return radians * 57.295779513082320876798154814105; + }; + MathHelper.toRadians = function (degrees) { + return degrees * 0.017453292519943295769236907684886; + }; + MathHelper.map = function (value, leftMin, leftMax, rightMin, rightMax) { + return rightMin + (value - leftMin) * (rightMax - rightMin) / (leftMax - leftMin); + }; + MathHelper.lerp = function (value1, value2, amount) { + return value1 + (value2 - value1) * amount; + }; + MathHelper.clamp = function (value, min, max) { + if (value < min) + return min; + if (value > max) + return max; + return value; + }; + MathHelper.pointOnCirlce = function (circleCenter, radius, angleInDegrees) { + var radians = MathHelper.toRadians(angleInDegrees); + return new es.Vector2(Math.cos(radians) * radians + circleCenter.x, Math.sin(radians) * radians + circleCenter.y); + }; + MathHelper.isEven = function (value) { + return value % 2 == 0; + }; + MathHelper.clamp01 = function (value) { + if (value < 0) + return 0; + if (value > 1) + return 1; + return value; + }; + MathHelper.angleBetweenVectors = function (from, to) { + return Math.atan2(to.y - from.y, to.x - from.x); + }; + MathHelper.Epsilon = 0.00001; + MathHelper.Rad2Deg = 57.29578; + MathHelper.Deg2Rad = 0.0174532924; + return MathHelper; + }()); + es.MathHelper = MathHelper; +})(es || (es = {})); +var es; +(function (es) { + es.matrixPool = []; + var Matrix2D = (function (_super) { + __extends(Matrix2D, _super); + function Matrix2D() { + return _super !== null && _super.apply(this, arguments) || this; + } + Object.defineProperty(Matrix2D.prototype, "m11", { + get: function () { + return this.a; + }, + set: function (value) { + this.a = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Matrix2D.prototype, "m12", { + get: function () { + return this.b; + }, + set: function (value) { + this.b = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Matrix2D.prototype, "m21", { + get: function () { + return this.c; + }, + set: function (value) { + this.c = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Matrix2D.prototype, "m22", { + get: function () { + return this.d; + }, + set: function (value) { + this.d = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Matrix2D.prototype, "m31", { + get: function () { + return this.tx; + }, + set: function (value) { + this.tx = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Matrix2D.prototype, "m32", { + get: function () { + return this.ty; + }, + set: function (value) { + this.ty = value; + }, + enumerable: true, + configurable: true + }); + Matrix2D.create = function () { + var matrix = es.matrixPool.pop(); + if (!matrix) + matrix = new Matrix2D(); + return matrix; + }; + Matrix2D.prototype.identity = function () { + this.a = this.d = 1; + this.b = this.c = this.tx = this.ty = 0; + return this; + }; + Matrix2D.prototype.translate = function (dx, dy) { + this.tx += dx; + this.ty += dy; + return this; + }; + Matrix2D.prototype.scale = function (sx, sy) { + if (sx !== 1) { + this.a *= sx; + this.c *= sx; + this.tx *= sx; + } + if (sy !== 1) { + this.b *= sy; + this.d *= sy; + this.ty *= sy; + } + return this; + }; + Matrix2D.prototype.rotate = function (angle) { + angle = +angle; + if (angle !== 0) { + angle = angle / DEG_TO_RAD; + var u = Math.cos(angle); + var v = Math.sin(angle); + var ta = this.a; + var tb = this.b; + var tc = this.c; + var td = this.d; + var ttx = this.tx; + var tty = this.ty; + this.a = ta * u - tb * v; + this.b = ta * v + tb * u; + this.c = tc * u - td * v; + this.d = tc * v + td * u; + this.tx = ttx * u - tty * v; + this.ty = ttx * v + tty * u; + } + return this; + }; + Matrix2D.prototype.invert = function () { + this.$invertInto(this); + return this; + }; + Matrix2D.prototype.add = function (matrix) { + this.m11 += matrix.m11; + this.m12 += matrix.m12; + this.m21 += matrix.m21; + this.m22 += matrix.m22; + this.m31 += matrix.m31; + this.m32 += matrix.m32; + return this; + }; + Matrix2D.prototype.substract = function (matrix) { + this.m11 -= matrix.m11; + this.m12 -= matrix.m12; + this.m21 -= matrix.m21; + this.m22 -= matrix.m22; + this.m31 -= matrix.m31; + this.m32 -= matrix.m32; + return this; + }; + Matrix2D.prototype.divide = function (matrix) { + this.m11 /= matrix.m11; + this.m12 /= matrix.m12; + this.m21 /= matrix.m21; + this.m22 /= matrix.m22; + this.m31 /= matrix.m31; + this.m32 /= matrix.m32; + return this; + }; + Matrix2D.prototype.multiply = function (matrix) { + var m11 = (this.m11 * matrix.m11) + (this.m12 * matrix.m21); + var m12 = (this.m11 * matrix.m12) + (this.m12 * matrix.m22); + var m21 = (this.m21 * matrix.m11) + (this.m22 * matrix.m21); + var m22 = (this.m21 * matrix.m12) + (this.m22 * matrix.m22); + var m31 = (this.m31 * matrix.m11) + (this.m32 * matrix.m21) + matrix.m31; + var m32 = (this.m31 * matrix.m12) + (this.m32 * matrix.m22) + matrix.m32; + this.m11 = m11; + this.m12 = m12; + this.m21 = m21; + this.m22 = m22; + this.m31 = m31; + this.m32 = m32; + return this; + }; + Matrix2D.prototype.determinant = function () { + return this.m11 * this.m22 - this.m12 * this.m21; + }; + Matrix2D.prototype.release = function (matrix) { + if (!matrix) + return; + es.matrixPool.push(matrix); + }; + return Matrix2D; + }(egret.Matrix)); + es.Matrix2D = Matrix2D; +})(es || (es = {})); +var es; +(function (es) { + var Rectangle = (function (_super) { + __extends(Rectangle, _super); + function Rectangle() { + return _super !== null && _super.apply(this, arguments) || this; + } + Object.defineProperty(Rectangle.prototype, "max", { + get: function () { + return new es.Vector2(this.right, this.bottom); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Rectangle.prototype, "center", { + get: function () { + return new es.Vector2(this.x + (this.width / 2), this.y + (this.height / 2)); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Rectangle.prototype, "location", { + get: function () { + return new es.Vector2(this.x, this.y); + }, + set: function (value) { + this.x = value.x; + this.y = value.y; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Rectangle.prototype, "size", { + get: function () { + return new es.Vector2(this.width, this.height); + }, + set: function (value) { + this.width = value.x; + this.height = value.y; + }, + enumerable: true, + configurable: true + }); + Rectangle.fromMinMax = function (minX, minY, maxX, maxY) { + return new Rectangle(minX, minY, maxX - minX, maxY - minY); + }; + Rectangle.rectEncompassingPoints = function (points) { + var minX = Number.POSITIVE_INFINITY; + var minY = Number.POSITIVE_INFINITY; + var maxX = Number.NEGATIVE_INFINITY; + var maxY = Number.NEGATIVE_INFINITY; + for (var i = 0; i < points.length; i++) { + var pt = points[i]; + if (pt.x < minX) + minX = pt.x; + if (pt.x > maxX) + maxX = pt.x; + if (pt.y < minY) + minY = pt.y; + if (pt.y > maxY) + maxY = pt.y; + } + return this.fromMinMax(minX, minY, maxX, maxY); + }; + Rectangle.prototype.intersects = function (value) { + return value.left < this.right && + this.left < value.right && + value.top < this.bottom && + this.top < value.bottom; + }; + Rectangle.prototype.rayIntersects = function (ray) { + var distance = 0; + var maxValue = Number.MAX_VALUE; + if (Math.abs(ray.direction.x) < 1E-06) { + if ((ray.start.x < this.x) || (ray.start.x > this.x + this.width)) + return distance; } else { - this._tempTriggerList[i].onTriggerExit(collisionPair.second, collisionPair.first); + var num11 = 1 / ray.direction.x; + var num8 = (this.x - ray.start.x) * num11; + var num7 = (this.x + this.width - ray.start.x) * num11; + if (num8 > num7) { + var num14 = num8; + num8 = num7; + num7 = num14; + } + distance = Math.max(num8, distance); + maxValue = Math.min(num7, maxValue); + if (distance > maxValue) + return distance; } - this._tempTriggerList.length = 0; - if (collisionPair.second.entity) { - collisionPair.second.entity.getComponents("ITriggerListener", this._tempTriggerList); - for (var i_2 = 0; i_2 < this._tempTriggerList.length; i_2++) { - if (isEntering) { - this._tempTriggerList[i_2].onTriggerEnter(collisionPair.first, collisionPair.second); - } - else { - this._tempTriggerList[i_2].onTriggerExit(collisionPair.first, collisionPair.second); + if (Math.abs(ray.direction.y) < 1E-06) { + if ((ray.start.y < this.y) || (ray.start.y > this.y + this.height)) + return distance; + } + else { + var num10 = 1 / ray.direction.y; + var num6 = (this.y - ray.start.y) * num10; + var num5 = (this.y + this.height - ray.start.y) * num10; + if (num6 > num5) { + var num13 = num6; + num6 = num5; + num5 = num13; + } + distance = Math.max(num6, distance); + maxValue = Math.max(num5, maxValue); + if (distance > maxValue) + return distance; + } + return distance; + }; + Rectangle.prototype.containsRect = function (value) { + return ((((this.x <= value.x) && (value.x < (this.x + this.width))) && + (this.y <= value.y)) && + (value.y < (this.y + this.height))); + }; + Rectangle.prototype.contains = function (x, y) { + return ((((this.x <= x) && (x < (this.x + this.width))) && (this.y <= y)) && (y < (this.y + this.height))); + }; + Rectangle.prototype.getHalfSize = function () { + return new es.Vector2(this.width * 0.5, this.height * 0.5); + }; + Rectangle.prototype.getClosestPointOnRectangleBorderToPoint = function (point, edgeNormal) { + edgeNormal = es.Vector2.zero; + var res = new es.Vector2(); + res.x = es.MathHelper.clamp(point.x, this.left, this.right); + res.y = es.MathHelper.clamp(point.y, this.top, this.bottom); + if (this.contains(res.x, res.y)) { + var dl = res.x - this.left; + var dr = this.right - res.x; + var dt = res.y - this.top; + var db = this.bottom - res.y; + var min = Math.min(dl, dr, dt, db); + if (min == dt) { + res.y = this.top; + edgeNormal.y = -1; + } + else if (min == db) { + res.y = this.bottom; + edgeNormal.y = 1; + } + else if (min == dl) { + res.x = this.left; + edgeNormal.x = -1; + } + else { + res.x = this.right; + edgeNormal.x = 1; + } + } + else { + if (res.x == this.left) + edgeNormal.x = -1; + if (res.x == this.right) + edgeNormal.x = 1; + if (res.y == this.top) + edgeNormal.y = -1; + if (res.y == this.bottom) + edgeNormal.y = 1; + } + return res; + }; + Rectangle.prototype.getClosestPointOnBoundsToOrigin = function () { + var max = this.max; + var minDist = Math.abs(this.location.x); + var boundsPoint = new es.Vector2(this.location.x, 0); + if (Math.abs(max.x) < minDist) { + minDist = Math.abs(max.x); + boundsPoint.x = max.x; + boundsPoint.y = 0; + } + if (Math.abs(max.y) < minDist) { + minDist = Math.abs(max.y); + boundsPoint.x = 0; + boundsPoint.y = max.y; + } + if (Math.abs(this.location.y) < minDist) { + minDist = Math.abs(this.location.y); + boundsPoint.x = 0; + boundsPoint.y = this.location.y; + } + return boundsPoint; + }; + Rectangle.prototype.calculateBounds = function (parentPosition, position, origin, scale, rotation, width, height) { + if (rotation == 0) { + this.x = parentPosition.x + position.x - origin.x * scale.x; + this.y = parentPosition.y + position.y - origin.y * scale.y; + this.width = width * scale.x; + this.height = height * scale.y; + } + else { + var worldPosX = parentPosition.x + position.x; + var worldPosY = parentPosition.y + position.y; + this._transformMat = es.Matrix2D.create().translate(-worldPosX - origin.x, -worldPosY - origin.y); + this._tempMat = es.Matrix2D.create().scale(scale.x, scale.y); + this._transformMat = this._transformMat.multiply(this._tempMat); + this._tempMat = es.Matrix2D.create().rotate(rotation); + this._transformMat = this._transformMat.multiply(this._tempMat); + this._tempMat = es.Matrix2D.create().translate(worldPosX, worldPosY); + this._transformMat = this._transformMat.multiply(this._tempMat); + var topLeft = new es.Vector2(worldPosX, worldPosY); + var topRight = new es.Vector2(worldPosX + width, worldPosY); + var bottomLeft = new es.Vector2(worldPosX, worldPosY + height); + var bottomRight = new es.Vector2(worldPosX + width, worldPosY + height); + topLeft = es.Vector2Ext.transformR(topLeft, this._transformMat); + topRight = es.Vector2Ext.transformR(topRight, this._transformMat); + bottomLeft = es.Vector2Ext.transformR(bottomLeft, this._transformMat); + bottomRight = es.Vector2Ext.transformR(bottomRight, this._transformMat); + var minX = Math.min(topLeft.x, bottomRight.x, topRight.x, bottomLeft.x); + var maxX = Math.max(topLeft.x, bottomRight.x, topRight.x, bottomLeft.x); + var minY = Math.min(topLeft.y, bottomRight.y, topRight.y, bottomLeft.y); + var maxY = Math.max(topLeft.y, bottomRight.y, topRight.y, bottomLeft.y); + this.location = new es.Vector2(minX, minY); + this.width = maxX - minX; + this.height = maxY - minY; + } + }; + return Rectangle; + }(egret.Rectangle)); + es.Rectangle = Rectangle; +})(es || (es = {})); +var es; +(function (es) { + var Vector3 = (function () { + function Vector3(x, y, z) { + this.x = x; + this.y = y; + this.z = z; + } + return Vector3; + }()); + es.Vector3 = Vector3; +})(es || (es = {})); +var es; +(function (es) { + var ColliderTriggerHelper = (function () { + function ColliderTriggerHelper(entity) { + this._activeTriggerIntersections = []; + this._previousTriggerIntersections = []; + this._tempTriggerList = []; + this._entity = entity; + } + ColliderTriggerHelper.prototype.update = function () { + var colliders = this._entity.getComponents(es.Collider); + for (var i = 0; i < colliders.length; i++) { + var collider = colliders[i]; + var neighbors = es.Physics.boxcastBroadphase(collider.bounds, collider.collidesWithLayers); + var _loop_5 = function (j) { + var neighbor = neighbors[j]; + if (!collider.isTrigger && !neighbor.isTrigger) + return "continue"; + if (collider.overlaps(neighbor)) { + var pair_1 = new es.Pair(collider, neighbor); + var shouldReportTriggerEvent = this_1._activeTriggerIntersections.findIndex(function (value) { + return value.first == pair_1.first && value.second == pair_1.second; + }) == -1 && this_1._previousTriggerIntersections.findIndex(function (value) { + return value.first == pair_1.first && value.second == pair_1.second; + }) == -1; + if (shouldReportTriggerEvent) + this_1.notifyTriggerListeners(pair_1, true); + if (!this_1._activeTriggerIntersections.contains(pair_1)) + this_1._activeTriggerIntersections.push(pair_1); } + }; + var this_1 = this; + for (var j = 0; j < neighbors.length; j++) { + _loop_5(j); + } + } + es.ListPool.free(colliders); + this.checkForExitedColliders(); + }; + ColliderTriggerHelper.prototype.checkForExitedColliders = function () { + var _this = this; + var _loop_6 = function (i) { + var index = this_2._previousTriggerIntersections.findIndex(function (value) { + if (value.first == _this._activeTriggerIntersections[i].first && value.second == _this._activeTriggerIntersections[i].second) + return true; + return false; + }); + if (index != -1) + this_2._previousTriggerIntersections.removeAt(index); + }; + var this_2 = this; + for (var i = 0; i < this._activeTriggerIntersections.length; i++) { + _loop_6(i); + } + for (var i = 0; i < this._previousTriggerIntersections.length; i++) { + this.notifyTriggerListeners(this._previousTriggerIntersections[i], false); + } + this._previousTriggerIntersections.length = 0; + for (var i = 0; i < this._activeTriggerIntersections.length; i++) { + if (!this._previousTriggerIntersections.contains(this._activeTriggerIntersections[i])) { + this._previousTriggerIntersections.push(this._activeTriggerIntersections[i]); + } + } + this._activeTriggerIntersections.length = 0; + }; + ColliderTriggerHelper.prototype.notifyTriggerListeners = function (collisionPair, isEntering) { + collisionPair.first.entity.getComponents("ITriggerListener", this._tempTriggerList); + for (var i = 0; i < this._tempTriggerList.length; i++) { + if (isEntering) { + this._tempTriggerList[i].onTriggerEnter(collisionPair.second, collisionPair.first); + } + else { + this._tempTriggerList[i].onTriggerExit(collisionPair.second, collisionPair.first); } this._tempTriggerList.length = 0; + if (collisionPair.second.entity) { + collisionPair.second.entity.getComponents("ITriggerListener", this._tempTriggerList); + for (var i_2 = 0; i_2 < this._tempTriggerList.length; i_2++) { + if (isEntering) { + this._tempTriggerList[i_2].onTriggerEnter(collisionPair.first, collisionPair.second); + } + else { + this._tempTriggerList[i_2].onTriggerExit(collisionPair.first, collisionPair.second); + } + } + this._tempTriggerList.length = 0; + } } + }; + return ColliderTriggerHelper; + }()); + es.ColliderTriggerHelper = ColliderTriggerHelper; +})(es || (es = {})); +var es; +(function (es) { + var PointSectors; + (function (PointSectors) { + PointSectors[PointSectors["center"] = 0] = "center"; + PointSectors[PointSectors["top"] = 1] = "top"; + PointSectors[PointSectors["bottom"] = 2] = "bottom"; + PointSectors[PointSectors["topLeft"] = 9] = "topLeft"; + PointSectors[PointSectors["topRight"] = 5] = "topRight"; + PointSectors[PointSectors["left"] = 8] = "left"; + PointSectors[PointSectors["right"] = 4] = "right"; + PointSectors[PointSectors["bottomLeft"] = 10] = "bottomLeft"; + PointSectors[PointSectors["bottomRight"] = 6] = "bottomRight"; + })(PointSectors = es.PointSectors || (es.PointSectors = {})); + var Collisions = (function () { + function Collisions() { } - }; - return ColliderTriggerHelper; -}()); -var PointSectors; -(function (PointSectors) { - PointSectors[PointSectors["center"] = 0] = "center"; - PointSectors[PointSectors["top"] = 1] = "top"; - PointSectors[PointSectors["bottom"] = 2] = "bottom"; - PointSectors[PointSectors["topLeft"] = 9] = "topLeft"; - PointSectors[PointSectors["topRight"] = 5] = "topRight"; - PointSectors[PointSectors["left"] = 8] = "left"; - PointSectors[PointSectors["right"] = 4] = "right"; - PointSectors[PointSectors["bottomLeft"] = 10] = "bottomLeft"; - PointSectors[PointSectors["bottomRight"] = 6] = "bottomRight"; -})(PointSectors || (PointSectors = {})); -var Collisions = (function () { - function Collisions() { - } - Collisions.isLineToLine = function (a1, a2, b1, b2) { - var b = Vector2.subtract(a2, a1); - var d = Vector2.subtract(b2, b1); - var bDotDPerp = b.x * d.y - b.y * d.x; - if (bDotDPerp == 0) - return false; - var c = Vector2.subtract(b1, a1); - var t = (c.x * d.y - c.y * d.x) / bDotDPerp; - if (t < 0 || t > 1) - return false; - var u = (c.x * b.y - c.y * b.x) / bDotDPerp; - if (u < 0 || u > 1) - return false; - return true; - }; - Collisions.lineToLineIntersection = function (a1, a2, b1, b2) { - var intersection = new Vector2(0, 0); - var b = Vector2.subtract(a2, a1); - var d = Vector2.subtract(b2, b1); - var bDotDPerp = b.x * d.y - b.y * d.x; - if (bDotDPerp == 0) - return intersection; - var c = Vector2.subtract(b1, a1); - var t = (c.x * d.y - c.y * d.x) / bDotDPerp; - if (t < 0 || t > 1) - return intersection; - var u = (c.x * b.y - c.y * b.x) / bDotDPerp; - if (u < 0 || u > 1) - return intersection; - intersection = Vector2.add(a1, new Vector2(t * b.x, t * b.y)); - return intersection; - }; - Collisions.closestPointOnLine = function (lineA, lineB, closestTo) { - var v = Vector2.subtract(lineB, lineA); - var w = Vector2.subtract(closestTo, lineA); - var t = Vector2.dot(w, v) / Vector2.dot(v, v); - t = MathHelper.clamp(t, 0, 1); - return Vector2.add(lineA, new Vector2(v.x * t, v.y * t)); - }; - Collisions.isCircleToCircle = function (circleCenter1, circleRadius1, circleCenter2, circleRadius2) { - return Vector2.distanceSquared(circleCenter1, circleCenter2) < (circleRadius1 + circleRadius2) * (circleRadius1 + circleRadius2); - }; - Collisions.isCircleToLine = function (circleCenter, radius, lineFrom, lineTo) { - return Vector2.distanceSquared(circleCenter, this.closestPointOnLine(lineFrom, lineTo, circleCenter)) < radius * radius; - }; - Collisions.isCircleToPoint = function (circleCenter, radius, point) { - return Vector2.distanceSquared(circleCenter, point) < radius * radius; - }; - Collisions.isRectToCircle = function (rect, cPosition, cRadius) { - var ew = rect.width * 0.5; - var eh = rect.height * 0.5; - var vx = Math.max(0, Math.max(cPosition.x - rect.x) - ew); - var vy = Math.max(0, Math.max(cPosition.y - rect.y) - eh); - return vx * vx + vy * vy < cRadius * cRadius; - }; - Collisions.isRectToLine = function (rect, lineFrom, lineTo) { - var fromSector = this.getSector(rect.x, rect.y, rect.width, rect.height, lineFrom); - var toSector = this.getSector(rect.x, rect.y, rect.width, rect.height, lineTo); - if (fromSector == PointSectors.center || toSector == PointSectors.center) { + Collisions.isLineToLine = function (a1, a2, b1, b2) { + var b = es.Vector2.subtract(a2, a1); + var d = es.Vector2.subtract(b2, b1); + var bDotDPerp = b.x * d.y - b.y * d.x; + if (bDotDPerp == 0) + return false; + var c = es.Vector2.subtract(b1, a1); + var t = (c.x * d.y - c.y * d.x) / bDotDPerp; + if (t < 0 || t > 1) + return false; + var u = (c.x * b.y - c.y * b.x) / bDotDPerp; + if (u < 0 || u > 1) + return false; return true; - } - else if ((fromSector & toSector) != 0) { + }; + Collisions.lineToLineIntersection = function (a1, a2, b1, b2) { + var intersection = new es.Vector2(0, 0); + var b = es.Vector2.subtract(a2, a1); + var d = es.Vector2.subtract(b2, b1); + var bDotDPerp = b.x * d.y - b.y * d.x; + if (bDotDPerp == 0) + return intersection; + var c = es.Vector2.subtract(b1, a1); + var t = (c.x * d.y - c.y * d.x) / bDotDPerp; + if (t < 0 || t > 1) + return intersection; + var u = (c.x * b.y - c.y * b.x) / bDotDPerp; + if (u < 0 || u > 1) + return intersection; + intersection = es.Vector2.add(a1, new es.Vector2(t * b.x, t * b.y)); + return intersection; + }; + Collisions.closestPointOnLine = function (lineA, lineB, closestTo) { + var v = es.Vector2.subtract(lineB, lineA); + var w = es.Vector2.subtract(closestTo, lineA); + var t = es.Vector2.dot(w, v) / es.Vector2.dot(v, v); + t = es.MathHelper.clamp(t, 0, 1); + return es.Vector2.add(lineA, new es.Vector2(v.x * t, v.y * t)); + }; + Collisions.isCircleToCircle = function (circleCenter1, circleRadius1, circleCenter2, circleRadius2) { + return es.Vector2.distanceSquared(circleCenter1, circleCenter2) < (circleRadius1 + circleRadius2) * (circleRadius1 + circleRadius2); + }; + Collisions.isCircleToLine = function (circleCenter, radius, lineFrom, lineTo) { + return es.Vector2.distanceSquared(circleCenter, this.closestPointOnLine(lineFrom, lineTo, circleCenter)) < radius * radius; + }; + Collisions.isCircleToPoint = function (circleCenter, radius, point) { + return es.Vector2.distanceSquared(circleCenter, point) < radius * radius; + }; + Collisions.isRectToCircle = function (rect, cPosition, cRadius) { + var ew = rect.width * 0.5; + var eh = rect.height * 0.5; + var vx = Math.max(0, Math.max(cPosition.x - rect.x) - ew); + var vy = Math.max(0, Math.max(cPosition.y - rect.y) - eh); + return vx * vx + vy * vy < cRadius * cRadius; + }; + Collisions.isRectToLine = function (rect, lineFrom, lineTo) { + var fromSector = this.getSector(rect.x, rect.y, rect.width, rect.height, lineFrom); + var toSector = this.getSector(rect.x, rect.y, rect.width, rect.height, lineTo); + if (fromSector == PointSectors.center || toSector == PointSectors.center) { + return true; + } + else if ((fromSector & toSector) != 0) { + return false; + } + else { + var both = fromSector | toSector; + var edgeFrom = void 0; + var edgeTo = void 0; + if ((both & PointSectors.top) != 0) { + edgeFrom = new es.Vector2(rect.x, rect.y); + edgeTo = new es.Vector2(rect.x + rect.width, rect.y); + if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo)) + return true; + } + if ((both & PointSectors.bottom) != 0) { + edgeFrom = new es.Vector2(rect.x, rect.y + rect.height); + edgeTo = new es.Vector2(rect.x + rect.width, rect.y + rect.height); + if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo)) + return true; + } + if ((both & PointSectors.left) != 0) { + edgeFrom = new es.Vector2(rect.x, rect.y); + edgeTo = new es.Vector2(rect.x, rect.y + rect.height); + if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo)) + return true; + } + if ((both & PointSectors.right) != 0) { + edgeFrom = new es.Vector2(rect.x + rect.width, rect.y); + edgeTo = new es.Vector2(rect.x + rect.width, rect.y + rect.height); + if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo)) + return true; + } + } return false; + }; + Collisions.isRectToPoint = function (rX, rY, rW, rH, point) { + return point.x >= rX && point.y >= rY && point.x < rX + rW && point.y < rY + rH; + }; + Collisions.getSector = function (rX, rY, rW, rH, point) { + var sector = PointSectors.center; + if (point.x < rX) + sector |= PointSectors.left; + else if (point.x >= rX + rW) + sector |= PointSectors.right; + if (point.y < rY) + sector |= PointSectors.top; + else if (point.y >= rY + rH) + sector |= PointSectors.bottom; + return sector; + }; + return Collisions; + }()); + es.Collisions = Collisions; +})(es || (es = {})); +var es; +(function (es) { + var Physics = (function () { + function Physics() { } - else { - var both = fromSector | toSector; - var edgeFrom = void 0; - var edgeTo = void 0; - if ((both & PointSectors.top) != 0) { - edgeFrom = new Vector2(rect.x, rect.y); - edgeTo = new Vector2(rect.x + rect.width, rect.y); - if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo)) + Physics.reset = function () { + this._spatialHash = new es.SpatialHash(this.spatialHashCellSize); + }; + Physics.clear = function () { + this._spatialHash.clear(); + }; + Physics.overlapCircleAll = function (center, randius, results, layerMask) { + if (layerMask === void 0) { layerMask = -1; } + if (results.length == 0) { + console.error("An empty results array was passed in. No results will ever be returned."); + return; + } + return this._spatialHash.overlapCircle(center, randius, results, layerMask); + }; + Physics.boxcastBroadphase = function (rect, layerMask) { + if (layerMask === void 0) { layerMask = this.allLayers; } + return this._spatialHash.aabbBroadphase(rect, null, layerMask); + }; + Physics.boxcastBroadphaseExcludingSelf = function (collider, rect, layerMask) { + if (layerMask === void 0) { layerMask = this.allLayers; } + return this._spatialHash.aabbBroadphase(rect, collider, layerMask); + }; + Physics.addCollider = function (collider) { + Physics._spatialHash.register(collider); + }; + Physics.removeCollider = function (collider) { + Physics._spatialHash.remove(collider); + }; + Physics.updateCollider = function (collider) { + this._spatialHash.remove(collider); + this._spatialHash.register(collider); + }; + Physics.debugDraw = function (secondsToDisplay) { + this._spatialHash.debugDraw(secondsToDisplay, 2); + }; + Physics.spatialHashCellSize = 100; + Physics.allLayers = -1; + Physics.raycastsHitTriggers = false; + Physics.raycastsStartInColliders = false; + return Physics; + }()); + es.Physics = Physics; +})(es || (es = {})); +var es; +(function (es) { + var Ray2D = (function () { + function Ray2D(position, end) { + this.start = position; + this.end = end; + this.direction = es.Vector2.subtract(this.end, this.start); + } + return Ray2D; + }()); + es.Ray2D = Ray2D; +})(es || (es = {})); +var es; +(function (es) { + var RaycastHit = (function () { + function RaycastHit(collider, fraction, distance, point, normal) { + this.fraction = 0; + this.distance = 0; + this.point = es.Vector2.zero; + this.normal = es.Vector2.zero; + this.collider = collider; + this.fraction = fraction; + this.distance = distance; + this.point = point; + this.centroid = es.Vector2.zero; + } + RaycastHit.prototype.setValues = function (collider, fraction, distance, point) { + this.collider = collider; + this.fraction = fraction; + this.distance = distance; + this.point = point; + }; + RaycastHit.prototype.setValuesNonCollider = function (fraction, distance, point, normal) { + this.fraction = fraction; + this.distance = distance; + this.point = point; + this.normal = normal; + }; + RaycastHit.prototype.reset = function () { + this.collider = null; + this.fraction = this.distance = 0; + }; + RaycastHit.prototype.toString = function () { + return "[RaycastHit] fraction: " + this.fraction + ", distance: " + this.distance + ", normal: " + this.normal + ", centroid: " + this.centroid + ", point: " + this.point; + }; + return RaycastHit; + }()); + es.RaycastHit = RaycastHit; +})(es || (es = {})); +var es; +(function (es) { + var Shape = (function () { + function Shape() { + } + Shape.prototype.clone = function () { + return ObjectUtils.clone(this); + }; + return Shape; + }()); + es.Shape = Shape; +})(es || (es = {})); +var es; +(function (es) { + var Polygon = (function (_super) { + __extends(Polygon, _super); + function Polygon(points, isBox) { + var _this = _super.call(this) || this; + _this._areEdgeNormalsDirty = true; + _this.isUnrotated = true; + _this.setPoints(points); + _this.isBox = isBox; + return _this; + } + Object.defineProperty(Polygon.prototype, "edgeNormals", { + get: function () { + if (this._areEdgeNormalsDirty) + this.buildEdgeNormals(); + return this._edgeNormals; + }, + enumerable: true, + configurable: true + }); + Polygon.prototype.setPoints = function (points) { + this.points = points; + this.recalculateCenterAndEdgeNormals(); + this._originalPoints = []; + for (var i = 0; i < this.points.length; i++) { + this._originalPoints.push(this.points[i]); + } + }; + Polygon.prototype.recalculateCenterAndEdgeNormals = function () { + this._polygonCenter = Polygon.findPolygonCenter(this.points); + this._areEdgeNormalsDirty = true; + }; + Polygon.prototype.buildEdgeNormals = function () { + var totalEdges = this.isBox ? 2 : this.points.length; + if (this._edgeNormals == null || this._edgeNormals.length != totalEdges) + this._edgeNormals = new Array(totalEdges); + var p2; + for (var i = 0; i < totalEdges; i++) { + var p1 = this.points[i]; + if (i + 1 >= this.points.length) + p2 = this.points[0]; + else + p2 = this.points[i + 1]; + var perp = es.Vector2Ext.perpendicular(p1, p2); + perp = es.Vector2.normalize(perp); + this._edgeNormals[i] = perp; + } + }; + Polygon.buildSymmetricalPolygon = function (vertCount, radius) { + var verts = new Array(vertCount); + for (var i = 0; i < vertCount; i++) { + var a = 2 * Math.PI * (i / vertCount); + verts[i] = es.Vector2.multiply(new es.Vector2(Math.cos(a), Math.sin(a)), new es.Vector2(radius)); + } + return verts; + }; + Polygon.recenterPolygonVerts = function (points) { + var center = this.findPolygonCenter(points); + for (var i = 0; i < points.length; i++) + points[i] = es.Vector2.subtract(points[i], center); + }; + Polygon.findPolygonCenter = function (points) { + var x = 0, y = 0; + for (var i = 0; i < points.length; i++) { + x += points[i].x; + y += points[i].y; + } + return new es.Vector2(x / points.length, y / points.length); + }; + Polygon.getFarthestPointInDirection = function (points, direction) { + var index = 0; + var maxDot = es.Vector2.dot(points[index], direction); + for (var i = 1; i < points.length; i++) { + var dot = es.Vector2.dot(points[i], direction); + if (dot > maxDot) { + maxDot = dot; + index = i; + } + } + return points[index]; + }; + Polygon.getClosestPointOnPolygonToPoint = function (points, point, distanceSquared, edgeNormal) { + distanceSquared = Number.MAX_VALUE; + edgeNormal = new es.Vector2(0, 0); + var closestPoint = new es.Vector2(0, 0); + var tempDistanceSquared; + for (var i = 0; i < points.length; i++) { + var j = i + 1; + if (j == points.length) + j = 0; + var closest = es.ShapeCollisions.closestPointOnLine(points[i], points[j], point); + tempDistanceSquared = es.Vector2.distanceSquared(point, closest); + if (tempDistanceSquared < distanceSquared) { + distanceSquared = tempDistanceSquared; + closestPoint = closest; + var line = es.Vector2.subtract(points[j], points[i]); + edgeNormal = new es.Vector2(-line.y, line.x); + } + } + es.Vector2Ext.normalize(edgeNormal); + return closestPoint; + }; + Polygon.rotatePolygonVerts = function (radians, originalPoints, rotatedPoints) { + var cos = Math.cos(radians); + var sin = Math.sign(radians); + for (var i = 0; i < originalPoints.length; i++) { + var position = originalPoints[i]; + rotatedPoints[i] = new es.Vector2(position.x * cos + position.y * -sin, position.x * sin + position.y * cos); + } + }; + Polygon.prototype.recalculateBounds = function (collider) { + this.center = collider.localOffset; + if (collider.shouldColliderScaleAndRotateWithTransform) { + var hasUnitScale = true; + var tempMat = void 0; + var combinedMatrix = es.Matrix2D.create().translate(-this._polygonCenter.x, -this._polygonCenter.y); + if (collider.entity.transform.scale != es.Vector2.zero) { + tempMat = es.Matrix2D.create().scale(collider.entity.transform.scale.x, collider.entity.transform.scale.y); + combinedMatrix = combinedMatrix.multiply(tempMat); + hasUnitScale = false; + this.center = es.Vector2.multiply(collider.localOffset, collider.entity.transform.scale); + } + if (collider.entity.transform.rotation != 0) { + tempMat = es.Matrix2D.create().rotate(collider.entity.transform.rotation); + combinedMatrix = combinedMatrix.multiply(tempMat); + var offsetAngle = Math.atan2(collider.localOffset.y, collider.localOffset.x) * es.MathHelper.Rad2Deg; + var offsetLength = hasUnitScale ? collider._localOffsetLength : + es.Vector2.multiply(collider.localOffset, collider.entity.transform.scale).length(); + this.center = es.MathHelper.pointOnCirlce(es.Vector2.zero, offsetLength, collider.entity.transform.rotation + offsetAngle); + } + tempMat = es.Matrix2D.create().translate(this._polygonCenter.x, this._polygonCenter.y); + combinedMatrix = combinedMatrix.multiply(tempMat); + es.Vector2Ext.transform(this._originalPoints, combinedMatrix, this.points); + this.isUnrotated = collider.entity.transform.rotation == 0; + if (collider._isRotationDirty) + this._areEdgeNormalsDirty = true; + } + this.position = es.Vector2.add(collider.entity.transform.position, this.center); + this.bounds = es.Rectangle.rectEncompassingPoints(this.points); + this.bounds.location = this.bounds.location.add(this.position); + }; + Polygon.prototype.overlaps = function (other) { + var result = new es.CollisionResult(); + if (other instanceof Polygon) + return es.ShapeCollisions.polygonToPolygon(this, other, result); + if (other instanceof es.Circle) { + if (es.ShapeCollisions.circleToPolygon(other, this, result)) { + result.invertResult(); return true; + } + return false; } - if ((both & PointSectors.bottom) != 0) { - edgeFrom = new Vector2(rect.x, rect.y + rect.height); - edgeTo = new Vector2(rect.x + rect.width, rect.y + rect.height); - if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo)) + throw new Error("overlaps of Pologon to " + other + " are not supported"); + }; + Polygon.prototype.collidesWithShape = function (other, result) { + if (other instanceof Polygon) { + return es.ShapeCollisions.polygonToPolygon(this, other, result); + } + if (other instanceof es.Circle) { + if (es.ShapeCollisions.circleToPolygon(other, this, result)) { + result.invertResult(); return true; + } + return false; } - if ((both & PointSectors.left) != 0) { - edgeFrom = new Vector2(rect.x, rect.y); - edgeTo = new Vector2(rect.x, rect.y + rect.height); - if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo)) - return true; + throw new Error("overlaps of Polygon to " + other + " are not supported"); + }; + Polygon.prototype.collidesWithLine = function (start, end, hit) { + return es.ShapeCollisions.lineToPoly(start, end, this, hit); + }; + Polygon.prototype.containsPoint = function (point) { + point = es.Vector2.subtract(point, this.position); + var isInside = false; + for (var i = 0, j = this.points.length - 1; i < this.points.length; j = i++) { + if (((this.points[i].y > point.y) != (this.points[j].y > point.y)) && + (point.x < (this.points[j].x - this.points[i].x) * (point.y - this.points[i].y) / (this.points[j].y - this.points[i].y) + + this.points[i].x)) { + isInside = !isInside; + } } - if ((both & PointSectors.right) != 0) { - edgeFrom = new Vector2(rect.x + rect.width, rect.y); - edgeTo = new Vector2(rect.x + rect.width, rect.y + rect.height); - if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo)) - return true; + return isInside; + }; + Polygon.prototype.pointCollidesWithShape = function (point, result) { + return es.ShapeCollisions.pointToPoly(point, this, result); + }; + return Polygon; + }(es.Shape)); + es.Polygon = Polygon; +})(es || (es = {})); +var es; +(function (es) { + var Box = (function (_super) { + __extends(Box, _super); + function Box(width, height) { + var _this = _super.call(this, Box.buildBox(width, height), true) || this; + _this.width = width; + _this.height = height; + return _this; + } + Box.buildBox = function (width, height) { + var halfWidth = width / 2; + var halfHeight = height / 2; + var verts = new Array(4); + verts[0] = new es.Vector2(-halfWidth, -halfHeight); + verts[1] = new es.Vector2(halfWidth, -halfHeight); + verts[2] = new es.Vector2(halfWidth, halfHeight); + verts[3] = new es.Vector2(-halfWidth, halfHeight); + return verts; + }; + Box.prototype.updateBox = function (width, height) { + this.width = width; + this.height = height; + var halfWidth = width / 2; + var halfHeight = height / 2; + this.points[0] = new es.Vector2(-halfWidth, -halfHeight); + this.points[1] = new es.Vector2(halfWidth, -halfHeight); + this.points[2] = new es.Vector2(halfWidth, halfHeight); + this.points[3] = new es.Vector2(-halfWidth, halfHeight); + for (var i = 0; i < this.points.length; i++) + this._originalPoints[i] = this.points[i]; + }; + Box.prototype.overlaps = function (other) { + if (this.isUnrotated) { + if (other instanceof Box && other.isUnrotated) + return this.bounds.intersects(other.bounds); + if (other instanceof es.Circle) + return es.Collisions.isRectToCircle(this.bounds, other.position, other.radius); } - } - return false; - }; - Collisions.isRectToPoint = function (rX, rY, rW, rH, point) { - return point.x >= rX && point.y >= rY && point.x < rX + rW && point.y < rY + rH; - }; - Collisions.getSector = function (rX, rY, rW, rH, point) { - var sector = PointSectors.center; - if (point.x < rX) - sector |= PointSectors.left; - else if (point.x >= rX + rW) - sector |= PointSectors.right; - if (point.y < rY) - sector |= PointSectors.top; - else if (point.y >= rY + rH) - sector |= PointSectors.bottom; - return sector; - }; - return Collisions; -}()); -var Physics = (function () { - function Physics() { - } - Physics.reset = function () { - this._spatialHash = new SpatialHash(this.spatialHashCellSize); - }; - Physics.clear = function () { - this._spatialHash.clear(); - }; - Physics.overlapCircleAll = function (center, randius, results, layerMask) { - if (layerMask === void 0) { layerMask = -1; } - return this._spatialHash.overlapCircle(center, randius, results, layerMask); - }; - Physics.boxcastBroadphase = function (rect, layerMask) { - if (layerMask === void 0) { layerMask = this.allLayers; } - var boxcastResult = this._spatialHash.aabbBroadphase(rect, null, layerMask); - return { colliders: boxcastResult.tempHashSet, rect: boxcastResult.bounds }; - }; - Physics.boxcastBroadphaseExcludingSelf = function (collider, rect, layerMask) { - if (layerMask === void 0) { layerMask = this.allLayers; } - return this._spatialHash.aabbBroadphase(rect, collider, layerMask); - }; - Physics.addCollider = function (collider) { - Physics._spatialHash.register(collider); - }; - Physics.removeCollider = function (collider) { - Physics._spatialHash.remove(collider); - }; - Physics.updateCollider = function (collider) { - this._spatialHash.remove(collider); - this._spatialHash.register(collider); - }; - Physics.spatialHashCellSize = 100; - Physics.allLayers = -1; - return Physics; -}()); -var Shape = (function () { - function Shape() { - } - return Shape; -}()); -var Polygon = (function (_super) { - __extends(Polygon, _super); - function Polygon(points, isBox) { - var _this = _super.call(this) || this; - _this.isUnrotated = true; - _this._areEdgeNormalsDirty = true; - _this.setPoints(points); - _this.isBox = isBox; - return _this; - } - Object.defineProperty(Polygon.prototype, "edgeNormals", { - get: function () { - if (this._areEdgeNormalsDirty) - this.buildEdgeNormals(); - return this._edgeNormals; - }, - enumerable: true, - configurable: true - }); - Polygon.prototype.buildEdgeNormals = function () { - var totalEdges = this.isBox ? 2 : this.points.length; - if (this._edgeNormals == null || this._edgeNormals.length != totalEdges) - this._edgeNormals = new Array(totalEdges); - var p2; - for (var i = 0; i < totalEdges; i++) { - var p1 = this.points[i]; - if (i + 1 >= this.points.length) - p2 = this.points[0]; - else - p2 = this.points[i + 1]; - var perp = Vector2Ext.perpendicular(p1, p2); - perp = Vector2.normalize(perp); - this._edgeNormals[i] = perp; - } - }; - Polygon.prototype.setPoints = function (points) { - this.points = points; - this.recalculateCenterAndEdgeNormals(); - this._originalPoints = []; - for (var i = 0; i < this.points.length; i++) { - this._originalPoints.push(this.points[i]); - } - }; - Polygon.prototype.collidesWithShape = function (other) { - var result = new CollisionResult(); - if (other instanceof Polygon) { - return ShapeCollisions.polygonToPolygon(this, other); - } - if (other instanceof Circle) { - result = ShapeCollisions.circleToPolygon(other, this); - if (result) { - result.invertResult(); - return result; + return _super.prototype.overlaps.call(this, other); + }; + Box.prototype.collidesWithShape = function (other, result) { + if (other instanceof Box && other.isUnrotated) { + return es.ShapeCollisions.boxToBox(this, other, result); } - return null; + return _super.prototype.collidesWithShape.call(this, other, result); + }; + Box.prototype.containsPoint = function (point) { + if (this.isUnrotated) + return this.bounds.contains(point.x, point.y); + return _super.prototype.containsPoint.call(this, point); + }; + Box.prototype.pointCollidesWithShape = function (point, result) { + if (this.isUnrotated) + return es.ShapeCollisions.pointToBox(point, this, result); + return _super.prototype.pointCollidesWithShape.call(this, point, result); + }; + return Box; + }(es.Polygon)); + es.Box = Box; +})(es || (es = {})); +var es; +(function (es) { + var Circle = (function (_super) { + __extends(Circle, _super); + function Circle(radius) { + var _this = _super.call(this) || this; + _this.radius = radius; + _this._originalRadius = radius; + return _this; } - throw new Error("overlaps of Polygon to " + other + " are not supported"); - }; - Polygon.prototype.recalculateCenterAndEdgeNormals = function () { - this._polygonCenter = Polygon.findPolygonCenter(this.points); - this._areEdgeNormalsDirty = true; - }; - Polygon.prototype.overlaps = function (other) { - var result; - if (other instanceof Polygon) - return ShapeCollisions.polygonToPolygon(this, other); - if (other instanceof Circle) { - result = ShapeCollisions.circleToPolygon(other, this); - if (result) { - result.invertResult(); + Circle.prototype.recalculateBounds = function (collider) { + this.center = collider.localOffset; + if (collider.shouldColliderScaleAndRotateWithTransform) { + var scale = collider.entity.transform.scale; + var hasUnitScale = scale.x == 1 && scale.y == 1; + var maxScale = Math.max(scale.x, scale.y); + this.radius = this._originalRadius * maxScale; + if (collider.entity.transform.rotation != 0) { + var offsetAngle = Math.atan2(collider.localOffset.y, collider.localOffset.x) * es.MathHelper.Rad2Deg; + var offsetLength = hasUnitScale ? collider._localOffsetLength : es.Vector2.multiply(collider.localOffset, collider.entity.transform.scale).length(); + this.center = es.MathHelper.pointOnCirlce(es.Vector2.zero, offsetLength, collider.entity.transform.rotation + offsetAngle); + } + } + this.position = es.Vector2.add(collider.transform.position, this.center); + this.bounds = new es.Rectangle(this.position.x - this.radius, this.position.y - this.radius, this.radius * 2, this.radius * 2); + }; + Circle.prototype.overlaps = function (other) { + var result = new es.CollisionResult(); + if (other instanceof es.Box && other.isUnrotated) + return es.Collisions.isRectToCircle(other.bounds, this.position, this.radius); + if (other instanceof Circle) + return es.Collisions.isCircleToCircle(this.position, this.radius, other.position, other.radius); + if (other instanceof es.Polygon) + return es.ShapeCollisions.circleToPolygon(this, other, result); + throw new Error("overlaps of circle to " + other + " are not supported"); + }; + Circle.prototype.collidesWithShape = function (other, result) { + if (other instanceof es.Box && other.isUnrotated) { + return es.ShapeCollisions.circleToBox(this, other, result); + } + if (other instanceof Circle) { + return es.ShapeCollisions.circleToCircle(this, other, result); + } + if (other instanceof es.Polygon) { + return es.ShapeCollisions.circleToPolygon(this, other, result); + } + throw new Error("Collisions of Circle to " + other + " are not supported"); + }; + Circle.prototype.collidesWithLine = function (start, end, hit) { + return es.ShapeCollisions.lineToCircle(start, end, this, hit); + }; + Circle.prototype.containsPoint = function (point) { + return (es.Vector2.subtract(point, this.position)).lengthSquared() <= this.radius * this.radius; + }; + Circle.prototype.pointCollidesWithShape = function (point, result) { + return es.ShapeCollisions.pointToCircle(point, this, result); + }; + return Circle; + }(es.Shape)); + es.Circle = Circle; +})(es || (es = {})); +var es; +(function (es) { + var CollisionResult = (function () { + function CollisionResult() { + this.normal = es.Vector2.zero; + this.minimumTranslationVector = es.Vector2.zero; + this.point = es.Vector2.zero; + } + CollisionResult.prototype.removeHorizontal = function (deltaMovement) { + if (Math.sign(this.normal.x) != Math.sign(deltaMovement.x) || (deltaMovement.x == 0 && this.normal.x != 0)) { + var responseDistance = this.minimumTranslationVector.length(); + var fix = responseDistance / this.normal.y; + if (Math.abs(this.normal.x) != 1 && Math.abs(fix) < Math.abs(deltaMovement.y * 3)) { + this.minimumTranslationVector = new es.Vector2(0, -fix); + } + } + }; + CollisionResult.prototype.invertResult = function () { + this.minimumTranslationVector = es.Vector2.negate(this.minimumTranslationVector); + this.normal = es.Vector2.negate(this.normal); + return this; + }; + CollisionResult.prototype.toString = function () { + return "[CollisionResult] normal: " + this.normal + ", minimumTranslationVector: " + this.minimumTranslationVector; + }; + return CollisionResult; + }()); + es.CollisionResult = CollisionResult; +})(es || (es = {})); +var es; +(function (es) { + var RealtimeCollisions = (function () { + function RealtimeCollisions() { + } + RealtimeCollisions.intersectMovingCircleToBox = function (s, b, movement) { + var e = b.bounds; + e.inflate(s.radius, s.radius); + var ray = new es.Ray2D(es.Vector2.subtract(s.position, movement), s.position); + var time = e.rayIntersects(ray); + if (time > 1) + return time; + var point = es.Vector2.add(ray.start, es.Vector2.add(ray.direction, new es.Vector2(time))); + var u, v = 0; + if (point.x < b.bounds.left) + u |= 1; + if (point.x > b.bounds.right) + v |= 1; + if (point.y < b.bounds.top) + u |= 2; + if (point.y > b.bounds.bottom) + v |= 2; + var m = u + v; + if (m == 3) { + console.log("m == 3. corner " + es.Time.frameCount); + } + if ((m & (m - 1)) == 0) { + return time; + } + return time; + }; + return RealtimeCollisions; + }()); + es.RealtimeCollisions = RealtimeCollisions; +})(es || (es = {})); +var es; +(function (es) { + var ShapeCollisions = (function () { + function ShapeCollisions() { + } + ShapeCollisions.polygonToPolygon = function (first, second, result) { + var isIntersecting = true; + var firstEdges = first.edgeNormals; + var secondEdges = second.edgeNormals; + var minIntervalDistance = Number.POSITIVE_INFINITY; + var translationAxis = new es.Vector2(); + var polygonOffset = es.Vector2.subtract(first.position, second.position); + var axis; + for (var edgeIndex = 0; edgeIndex < firstEdges.length + secondEdges.length; edgeIndex++) { + if (edgeIndex < firstEdges.length) { + axis = firstEdges[edgeIndex]; + } + else { + axis = secondEdges[edgeIndex - firstEdges.length]; + } + var minA = 0; + var minB = 0; + var maxA = 0; + var maxB = 0; + var intervalDist = 0; + var ta = this.getInterval(axis, first, minA, maxA); + minA = ta.min; + minB = ta.max; + var tb = this.getInterval(axis, second, minB, maxB); + minB = tb.min; + maxB = tb.max; + var relativeIntervalOffset = es.Vector2.dot(polygonOffset, axis); + minA += relativeIntervalOffset; + maxA += relativeIntervalOffset; + intervalDist = this.intervalDistance(minA, maxA, minB, maxB); + if (intervalDist > 0) + isIntersecting = false; + if (!isIntersecting) + return false; + intervalDist = Math.abs(intervalDist); + if (intervalDist < minIntervalDistance) { + minIntervalDistance = intervalDist; + translationAxis = axis; + if (es.Vector2.dot(translationAxis, polygonOffset) < 0) + translationAxis = new es.Vector2(-translationAxis); + } + } + result.normal = translationAxis; + result.minimumTranslationVector = es.Vector2.multiply(new es.Vector2(-translationAxis.x, -translationAxis.y), new es.Vector2(minIntervalDistance)); + return true; + }; + ShapeCollisions.intervalDistance = function (minA, maxA, minB, maxB) { + if (minA < minB) + return minB - maxA; + return minA - minB; + }; + ShapeCollisions.getInterval = function (axis, polygon, min, max) { + var dot = es.Vector2.dot(polygon.points[0], axis); + min = max = dot; + for (var i = 1; i < polygon.points.length; i++) { + dot = es.Vector2.dot(polygon.points[i], axis); + if (dot < min) { + min = dot; + } + else if (dot > max) { + max = dot; + } + } + return { min: min, max: max }; + }; + ShapeCollisions.circleToPolygon = function (circle, polygon, result) { + var poly2Circle = es.Vector2.subtract(circle.position, polygon.position); + var distanceSquared = 0; + var closestPoint = es.Polygon.getClosestPointOnPolygonToPoint(polygon.points, poly2Circle, distanceSquared, result.normal); + var circleCenterInsidePoly = polygon.containsPoint(circle.position); + if (distanceSquared > circle.radius * circle.radius && !circleCenterInsidePoly) + return false; + var mtv; + if (circleCenterInsidePoly) { + mtv = es.Vector2.multiply(result.normal, new es.Vector2(Math.sqrt(distanceSquared) - circle.radius)); + } + else { + if (distanceSquared == 0) { + mtv = es.Vector2.multiply(result.normal, new es.Vector2(circle.radius)); + } + else { + var distance = Math.sqrt(distanceSquared); + mtv = es.Vector2.multiply(new es.Vector2(-es.Vector2.subtract(poly2Circle, closestPoint)), new es.Vector2((circle.radius - distanceSquared) / distance)); + } + } + result.minimumTranslationVector = mtv; + result.point = es.Vector2.add(closestPoint, polygon.position); + return true; + }; + ShapeCollisions.circleToBox = function (circle, box, result) { + var closestPointOnBounds = box.bounds.getClosestPointOnRectangleBorderToPoint(circle.position, result.normal); + if (box.containsPoint(circle.position)) { + result.point = closestPointOnBounds; + var safePlace = es.Vector2.add(closestPointOnBounds, es.Vector2.multiply(result.normal, new es.Vector2(circle.radius))); + result.minimumTranslationVector = es.Vector2.subtract(circle.position, safePlace); + return true; + } + var sqrDistance = es.Vector2.distanceSquared(closestPointOnBounds, circle.position); + if (sqrDistance == 0) { + result.minimumTranslationVector = es.Vector2.multiply(result.normal, new es.Vector2(circle.radius)); + } + else if (sqrDistance <= circle.radius * circle.radius) { + result.normal = es.Vector2.subtract(circle.position, closestPointOnBounds); + var depth = result.normal.length() - circle.radius; + result.point = closestPointOnBounds; + result.normal = es.Vector2Ext.normalize(result.normal); + result.minimumTranslationVector = es.Vector2.multiply(new es.Vector2(depth), result.normal); return true; } return false; - } - throw new Error("overlaps of Pologon to " + other + " are not supported"); - }; - Polygon.findPolygonCenter = function (points) { - var x = 0, y = 0; - for (var i = 0; i < points.length; i++) { - x += points[i].x; - y += points[i].y; - } - return new Vector2(x / points.length, y / points.length); - }; - Polygon.getClosestPointOnPolygonToPoint = function (points, point) { - var distanceSquared = Number.MAX_VALUE; - var edgeNormal = new Vector2(0, 0); - var closestPoint = new Vector2(0, 0); - var tempDistanceSquared; - for (var i = 0; i < points.length; i++) { - var j = i + 1; - if (j == points.length) - j = 0; - var closest = ShapeCollisions.closestPointOnLine(points[i], points[j], point); - tempDistanceSquared = Vector2.distanceSquared(point, closest); - if (tempDistanceSquared < distanceSquared) { - distanceSquared = tempDistanceSquared; - closestPoint = closest; - var line = Vector2.subtract(points[j], points[i]); - edgeNormal.x = -line.y; - edgeNormal.y = line.x; + }; + ShapeCollisions.pointToCircle = function (point, circle, result) { + var distanceSquared = es.Vector2.distanceSquared(point, circle.position); + var sumOfRadii = 1 + circle.radius; + var collided = distanceSquared < sumOfRadii * sumOfRadii; + if (collided) { + result.normal = es.Vector2.normalize(es.Vector2.subtract(point, circle.position)); + var depth = sumOfRadii - Math.sqrt(distanceSquared); + result.minimumTranslationVector = es.Vector2.multiply(new es.Vector2(-depth, -depth), result.normal); + result.point = es.Vector2.add(circle.position, es.Vector2.multiply(result.normal, new es.Vector2(circle.radius, circle.radius))); + return true; } - } - edgeNormal = Vector2.normalize(edgeNormal); - return { closestPoint: closestPoint, distanceSquared: distanceSquared, edgeNormal: edgeNormal }; - }; - Polygon.prototype.pointCollidesWithShape = function (point) { - return ShapeCollisions.pointToPoly(point, this); - }; - Polygon.prototype.containsPoint = function (point) { - point = Vector2.subtract(point, this.position); - var isInside = false; - for (var i = 0, j = this.points.length - 1; i < this.points.length; j = i++) { - if (((this.points[i].y > point.y) != (this.points[j].y > point.y)) && - (point.x < (this.points[j].x - this.points[i].x) * (point.y - this.points[i].y) / (this.points[j].y - this.points[i].y) + - this.points[i].x)) { - isInside = !isInside; + return false; + }; + ShapeCollisions.pointToBox = function (point, box, result) { + if (box.containsPoint(point)) { + result.point = box.bounds.getClosestPointOnRectangleBorderToPoint(point, result.normal); + result.minimumTranslationVector = es.Vector2.subtract(point, result.point); + return true; } - } - return isInside; - }; - Polygon.buildSymmertricalPolygon = function (vertCount, radius) { - var verts = new Array(vertCount); - for (var i = 0; i < vertCount; i++) { - var a = 2 * Math.PI * (i / vertCount); - verts[i] = new Vector2(Math.cos(a), Math.sin(a) * radius); - } - return verts; - }; - Polygon.prototype.recalculateBounds = function (collider) { - this.center = collider.localOffset; - if (collider.shouldColliderScaleAndRotateWithTransform) { - var hasUnitScale = true; - var tempMat = void 0; - var combinedMatrix = Matrix2D.createTranslation(-this._polygonCenter.x, -this._polygonCenter.y); - if (collider.entity.scale != Vector2.one) { - tempMat = Matrix2D.createScale(collider.entity.scale.x, collider.entity.scale.y); - combinedMatrix = Matrix2D.multiply(combinedMatrix, tempMat); - hasUnitScale = false; - var scaledOffset = Vector2.multiply(collider.localOffset, collider.entity.scale); - this.center = scaledOffset; + return false; + }; + ShapeCollisions.closestPointOnLine = function (lineA, lineB, closestTo) { + var v = es.Vector2.subtract(lineB, lineA); + var w = es.Vector2.subtract(closestTo, lineA); + var t = es.Vector2.dot(w, v) / es.Vector2.dot(v, v); + t = es.MathHelper.clamp(t, 0, 1); + return es.Vector2.add(lineA, es.Vector2.multiply(v, new es.Vector2(t, t))); + }; + ShapeCollisions.pointToPoly = function (point, poly, result) { + if (poly.containsPoint(point)) { + var distanceSquared = 0; + var closestPoint = es.Polygon.getClosestPointOnPolygonToPoint(poly.points, es.Vector2.subtract(point, poly.position), distanceSquared, result.normal); + result.minimumTranslationVector = es.Vector2.multiply(result.normal, new es.Vector2(Math.sqrt(distanceSquared), Math.sqrt(distanceSquared))); + result.point = es.Vector2.add(closestPoint, poly.position); + return true; } - if (collider.entity.rotation != 0) { - tempMat = Matrix2D.createRotation(collider.entity.rotation, tempMat); - combinedMatrix = Matrix2D.multiply(combinedMatrix, tempMat); - var offsetAngle = Math.atan2(collider.localOffset.y, collider.localOffset.x) * MathHelper.Rad2Deg; - var offsetLength = hasUnitScale ? collider._localOffsetLength : (Vector2.multiply(collider.localOffset, collider.entity.scale)).length(); - this.center = MathHelper.pointOnCirlce(Vector2.zero, offsetLength, MathHelper.toDegrees(collider.entity.rotation) + offsetAngle); + return false; + }; + ShapeCollisions.circleToCircle = function (first, second, result) { + var distanceSquared = es.Vector2.distanceSquared(first.position, second.position); + var sumOfRadii = first.radius + second.radius; + var collided = distanceSquared < sumOfRadii * sumOfRadii; + if (collided) { + result.normal = es.Vector2.normalize(es.Vector2.subtract(first.position, second.position)); + var depth = sumOfRadii - Math.sqrt(distanceSquared); + result.minimumTranslationVector = es.Vector2.multiply(new es.Vector2(-depth), result.normal); + result.point = es.Vector2.add(second.position, es.Vector2.multiply(result.normal, new es.Vector2(second.radius))); + return true; } - tempMat = Matrix2D.createTranslation(this._polygonCenter.x, this._polygonCenter.y); - combinedMatrix = Matrix2D.multiply(combinedMatrix, tempMat); - Vector2Ext.transform(this._originalPoints, combinedMatrix, this.points); - this.isUnrotated = collider.entity.rotation == 0; - } - this.position = Vector2.add(collider.entity.position, this.center); - this.bounds = Rectangle.rectEncompassingPoints(this.points); - this.bounds.location = Vector2.add(this.bounds.location, this.position); - }; - return Polygon; -}(Shape)); -var Box = (function (_super) { - __extends(Box, _super); - function Box(width, height) { - var _this = _super.call(this, Box.buildBox(width, height), true) || this; - _this.width = width; - _this.height = height; - return _this; - } - Box.buildBox = function (width, height) { - var halfWidth = width / 2; - var halfHeight = height / 2; - var verts = new Array(4); - verts[0] = new Vector2(-halfWidth, -halfHeight); - verts[1] = new Vector2(halfWidth, -halfHeight); - verts[2] = new Vector2(halfWidth, halfHeight); - verts[3] = new Vector2(-halfWidth, halfHeight); - return verts; - }; - Box.prototype.overlaps = function (other) { - if (this.isUnrotated) { - if (other instanceof Box && other.isUnrotated) - return this.bounds.intersects(other.bounds); - if (other instanceof Circle) - return Collisions.isRectToCircle(this.bounds, other.position, other.radius); - } - return _super.prototype.overlaps.call(this, other); - }; - Box.prototype.collidesWithShape = function (other) { - if (this.isUnrotated && other instanceof Box && other.isUnrotated) { - return ShapeCollisions.boxToBox(this, other); - } - return _super.prototype.collidesWithShape.call(this, other); - }; - Box.prototype.updateBox = function (width, height) { - this.width = width; - this.height = height; - var halfWidth = width / 2; - var halfHeight = height / 2; - this.points[0] = new Vector2(-halfWidth, -halfHeight); - this.points[1] = new Vector2(halfWidth, -halfHeight); - this.points[2] = new Vector2(halfWidth, halfHeight); - this.points[3] = new Vector2(-halfWidth, halfHeight); - for (var i = 0; i < this.points.length; i++) - this._originalPoints[i] = this.points[i]; - }; - Box.prototype.containsPoint = function (point) { - if (this.isUnrotated) - return this.bounds.containsInVec(point); - return _super.prototype.containsPoint.call(this, point); - }; - return Box; -}(Polygon)); -var Circle = (function (_super) { - __extends(Circle, _super); - function Circle(radius) { - var _this = _super.call(this) || this; - _this.radius = radius; - _this._originalRadius = radius; - return _this; - } - Circle.prototype.pointCollidesWithShape = function (point) { - return ShapeCollisions.pointToCircle(point, this); - }; - Circle.prototype.collidesWithShape = function (other) { - if (other instanceof Box && other.isUnrotated) { - return ShapeCollisions.circleToBox(this, other); - } - if (other instanceof Circle) { - return ShapeCollisions.circleToCircle(this, other); - } - if (other instanceof Polygon) { - return ShapeCollisions.circleToPolygon(this, other); - } - throw new Error("Collisions of Circle to " + other + " are not supported"); - }; - Circle.prototype.recalculateBounds = function (collider) { - this.center = collider.localOffset; - if (collider.shouldColliderScaleAndRotateWithTransform) { - var scale = collider.entity.scale; - var hasUnitScale = scale.x == 1 && scale.y == 1; - var maxScale = Math.max(scale.x, scale.y); - this.radius = this._originalRadius * maxScale; - if (collider.entity.rotation != 0) { - var offsetAngle = Math.atan2(collider.localOffset.y, collider.localOffset.x) * MathHelper.Rad2Deg; - var offsetLength = hasUnitScale ? collider._localOffsetLength : (Vector2.multiply(collider.localOffset, collider.entity.scale)).length(); - this.center = MathHelper.pointOnCirlce(Vector2.zero, offsetLength, MathHelper.toDegrees(collider.entity.rotation) + offsetAngle); + return false; + }; + ShapeCollisions.boxToBox = function (first, second, result) { + var minkowskiDiff = this.minkowskiDifference(first, second); + if (minkowskiDiff.contains(0, 0)) { + result.minimumTranslationVector = minkowskiDiff.getClosestPointOnBoundsToOrigin(); + if (result.minimumTranslationVector.equals(es.Vector2.zero)) + return false; + result.normal = new es.Vector2(-result.minimumTranslationVector.x, -result.minimumTranslationVector.y); + result.normal = result.normal.normalize(); + return true; } - } - this.position = Vector2.add(collider.entity.position, this.center); - this.bounds = new Rectangle(this.position.x - this.radius, this.position.y - this.radius, this.radius * 2, this.radius * 2); - }; - Circle.prototype.overlaps = function (other) { - if (other instanceof Box && other.isUnrotated) - return Collisions.isRectToCircle(other.bounds, this.position, this.radius); - if (other instanceof Circle) - return Collisions.isCircleToCircle(this.position, this.radius, other.position, other.radius); - if (other instanceof Polygon) - return ShapeCollisions.circleToPolygon(this, other); - throw new Error("overlaps of circle to " + other + " are not supported"); - }; - return Circle; -}(Shape)); -var CollisionResult = (function () { - function CollisionResult() { - this.minimumTranslationVector = Vector2.zero; - this.normal = Vector2.zero; - this.point = Vector2.zero; - } - CollisionResult.prototype.invertResult = function () { - this.minimumTranslationVector = Vector2.negate(this.minimumTranslationVector); - this.normal = Vector2.negate(this.normal); - }; - return CollisionResult; -}()); -var ShapeCollisions = (function () { - function ShapeCollisions() { - } - ShapeCollisions.polygonToPolygon = function (first, second) { - var result = new CollisionResult(); - var isIntersecting = true; - var firstEdges = first.edgeNormals; - var secondEdges = second.edgeNormals; - var minIntervalDistance = Number.POSITIVE_INFINITY; - var translationAxis = new Vector2(); - var polygonOffset = Vector2.subtract(first.position, second.position); - var axis; - for (var edgeIndex = 0; edgeIndex < firstEdges.length + secondEdges.length; edgeIndex++) { - if (edgeIndex < firstEdges.length) { - axis = firstEdges[edgeIndex]; - } - else { - axis = secondEdges[edgeIndex - firstEdges.length]; - } - var minA = 0; - var minB = 0; - var maxA = 0; - var maxB = 0; - var intervalDist = 0; - var ta = this.getInterval(axis, first, minA, maxA); - minA = ta.min; - minB = ta.max; - var tb = this.getInterval(axis, second, minB, maxB); - minB = tb.min; - maxB = tb.max; - var relativeIntervalOffset = Vector2.dot(polygonOffset, axis); - minA += relativeIntervalOffset; - maxA += relativeIntervalOffset; - intervalDist = this.intervalDistance(minA, maxA, minB, maxB); - if (intervalDist > 0) - isIntersecting = false; - if (!isIntersecting) - return null; - intervalDist = Math.abs(intervalDist); - if (intervalDist < minIntervalDistance) { - minIntervalDistance = intervalDist; - translationAxis = axis; - if (Vector2.dot(translationAxis, polygonOffset) < 0) - translationAxis = new Vector2(-translationAxis); - } - } - result.normal = translationAxis; - result.minimumTranslationVector = Vector2.multiply(new Vector2(-translationAxis.x, -translationAxis.y), new Vector2(minIntervalDistance)); - return result; - }; - ShapeCollisions.intervalDistance = function (minA, maxA, minB, maxB) { - if (minA < minB) - return minB - maxA; - return minA - minB; - }; - ShapeCollisions.getInterval = function (axis, polygon, min, max) { - var dot = Vector2.dot(polygon.points[0], axis); - min = max = dot; - for (var i = 1; i < polygon.points.length; i++) { - dot = Vector2.dot(polygon.points[i], axis); - if (dot < min) { - min = dot; - } - else if (dot > max) { - max = dot; - } - } - return { min: min, max: max }; - }; - ShapeCollisions.circleToPolygon = function (circle, polygon) { - var result = new CollisionResult(); - var poly2Circle = Vector2.subtract(circle.position, polygon.position); - var gpp = Polygon.getClosestPointOnPolygonToPoint(polygon.points, poly2Circle); - var closestPoint = gpp.closestPoint; - var distanceSquared = gpp.distanceSquared; - result.normal = gpp.edgeNormal; - var circleCenterInsidePoly = polygon.containsPoint(circle.position); - if (distanceSquared > circle.radius * circle.radius && !circleCenterInsidePoly) - return null; - var mtv; - if (circleCenterInsidePoly) { - mtv = Vector2.multiply(result.normal, new Vector2(Math.sqrt(distanceSquared) - circle.radius)); - } - else { - if (distanceSquared == 0) { - mtv = Vector2.multiply(result.normal, new Vector2(circle.radius)); - } - else { - var distance = Math.sqrt(distanceSquared); - mtv = Vector2.multiply(new Vector2(-Vector2.subtract(poly2Circle, closestPoint)), new Vector2((circle.radius - distanceSquared) / distance)); - } - } - result.minimumTranslationVector = mtv; - result.point = Vector2.add(closestPoint, polygon.position); - return result; - }; - ShapeCollisions.circleToBox = function (circle, box) { - var result = new CollisionResult(); - var closestPointOnBounds = box.bounds.getClosestPointOnRectangleBorderToPoint(circle.position).res; - if (box.containsPoint(circle.position)) { - result.point = closestPointOnBounds; - var safePlace = Vector2.add(closestPointOnBounds, Vector2.subtract(result.normal, new Vector2(circle.radius))); - result.minimumTranslationVector = Vector2.subtract(circle.position, safePlace); - return result; - } - var sqrDistance = Vector2.distanceSquared(closestPointOnBounds, circle.position); - if (sqrDistance == 0) { - result.minimumTranslationVector = Vector2.multiply(result.normal, new Vector2(circle.radius)); - } - else if (sqrDistance <= circle.radius * circle.radius) { - result.normal = Vector2.subtract(circle.position, closestPointOnBounds); - var depth = result.normal.length() - circle.radius; - result.normal = Vector2Ext.normalize(result.normal); - result.minimumTranslationVector = Vector2.multiply(new Vector2(depth), result.normal); - return result; - } - return null; - }; - ShapeCollisions.pointToCircle = function (point, circle) { - var result = new CollisionResult(); - var distanceSquared = Vector2.distanceSquared(point, circle.position); - var sumOfRadii = 1 + circle.radius; - var collided = distanceSquared < sumOfRadii * sumOfRadii; - if (collided) { - result.normal = Vector2.normalize(Vector2.subtract(point, circle.position)); - var depth = sumOfRadii - Math.sqrt(distanceSquared); - result.minimumTranslationVector = Vector2.multiply(new Vector2(-depth, -depth), result.normal); - result.point = Vector2.add(circle.position, Vector2.multiply(result.normal, new Vector2(circle.radius, circle.radius))); - return result; - } - return null; - }; - ShapeCollisions.closestPointOnLine = function (lineA, lineB, closestTo) { - var v = Vector2.subtract(lineB, lineA); - var w = Vector2.subtract(closestTo, lineA); - var t = Vector2.dot(w, v) / Vector2.dot(v, v); - t = MathHelper.clamp(t, 0, 1); - return Vector2.add(lineA, Vector2.multiply(v, new Vector2(t, t))); - }; - ShapeCollisions.pointToPoly = function (point, poly) { - var result = new CollisionResult(); - if (poly.containsPoint(point)) { - var distanceSquared = void 0; - var gpp = Polygon.getClosestPointOnPolygonToPoint(poly.points, Vector2.subtract(point, poly.position)); - var closestPoint = gpp.closestPoint; - distanceSquared = gpp.distanceSquared; - result.normal = gpp.edgeNormal; - result.minimumTranslationVector = Vector2.multiply(result.normal, new Vector2(Math.sqrt(distanceSquared), Math.sqrt(distanceSquared))); - result.point = Vector2.add(closestPoint, poly.position); - return result; - } - return null; - }; - ShapeCollisions.circleToCircle = function (first, second) { - var result = new CollisionResult(); - var distanceSquared = Vector2.distanceSquared(first.position, second.position); - var sumOfRadii = first.radius + second.radius; - var collided = distanceSquared < sumOfRadii * sumOfRadii; - if (collided) { - result.normal = Vector2.normalize(Vector2.subtract(first.position, second.position)); - var depth = sumOfRadii - Math.sqrt(distanceSquared); - result.minimumTranslationVector = Vector2.multiply(new Vector2(-depth), result.normal); - result.point = Vector2.add(second.position, Vector2.multiply(result.normal, new Vector2(second.radius))); - return result; - } - return null; - }; - ShapeCollisions.boxToBox = function (first, second) { - var result = new CollisionResult(); - var minkowskiDiff = this.minkowskiDifference(first, second); - if (minkowskiDiff.containsInVec(new Vector2(0, 0))) { - result.minimumTranslationVector = minkowskiDiff.getClosestPointOnBoundsToOrigin(); - if (result.minimumTranslationVector.x == 0 && result.minimumTranslationVector.y == 0) - return null; - result.normal = new Vector2(-result.minimumTranslationVector.x, -result.minimumTranslationVector.y); - result.normal.normalize(); - return result; - } - return null; - }; - ShapeCollisions.minkowskiDifference = function (first, second) { - var positionOffset = Vector2.subtract(first.position, Vector2.add(first.bounds.location, Vector2.divide(first.bounds.size, new Vector2(2)))); - var topLeft = Vector2.subtract(Vector2.add(first.bounds.location, positionOffset), second.bounds.max); - var fullSize = Vector2.add(first.bounds.size, second.bounds.size); - return new Rectangle(topLeft.x, topLeft.y, fullSize.x, fullSize.y); - }; - return ShapeCollisions; -}()); -var SpatialHash = (function () { - function SpatialHash(cellSize) { - if (cellSize === void 0) { cellSize = 100; } - this.gridBounds = new Rectangle(); - this._overlapTestCircle = new Circle(0); - this._tempHashSet = []; - this._cellDict = new NumberDictionary(); - this._cellSize = cellSize; - this._inverseCellSize = 1 / this._cellSize; - this._raycastParser = new RaycastResultParser(); - } - SpatialHash.prototype.remove = function (collider) { - var bounds = collider.registeredPhysicsBounds; - var p1 = this.cellCoords(bounds.x, bounds.y); - var p2 = this.cellCoords(bounds.right, bounds.bottom); - for (var x = p1.x; x <= p2.x; x++) { - for (var y = p1.y; y <= p2.y; y++) { - var cell = this.cellAtPosition(x, y); - if (!cell) - console.error("removing Collider [" + collider + "] from a cell that it is not present in"); - else - cell.remove(collider); - } - } - }; - SpatialHash.prototype.register = function (collider) { - var bounds = collider.bounds; - collider.registeredPhysicsBounds = bounds; - var p1 = this.cellCoords(bounds.x, bounds.y); - var p2 = this.cellCoords(bounds.right, bounds.bottom); - if (!this.gridBounds.containsInVec(new Vector2(p1.x, p1.y))) { - this.gridBounds = RectangleExt.union(this.gridBounds, p1); - } - if (!this.gridBounds.containsInVec(new Vector2(p2.x, p2.y))) { - this.gridBounds = RectangleExt.union(this.gridBounds, p2); - } - for (var x = p1.x; x <= p2.x; x++) { - for (var y = p1.y; y <= p2.y; y++) { - var c = this.cellAtPosition(x, y, true); - c.push(collider); - } - } - }; - SpatialHash.prototype.clear = function () { - this._cellDict.clear(); - }; - SpatialHash.prototype.overlapCircle = function (circleCenter, radius, results, layerMask) { - var bounds = new Rectangle(circleCenter.x - radius, circleCenter.y - radius, radius * 2, radius * 2); - this._overlapTestCircle.radius = radius; - this._overlapTestCircle.position = circleCenter; - var resultCounter = 0; - var aabbBroadphaseResult = this.aabbBroadphase(bounds, null, layerMask); - bounds = aabbBroadphaseResult.bounds; - var potentials = aabbBroadphaseResult.tempHashSet; - for (var i = 0; i < potentials.length; i++) { - var collider = potentials[i]; - if (collider instanceof BoxCollider) { - results[resultCounter] = collider; - resultCounter++; - } - else { - throw new Error("overlapCircle against this collider type is not implemented!"); - } - if (resultCounter == results.length) - return resultCounter; - } - return resultCounter; - }; - SpatialHash.prototype.aabbBroadphase = function (bounds, excludeCollider, layerMask) { - this._tempHashSet.length = 0; - var p1 = this.cellCoords(bounds.x, bounds.y); - var p2 = this.cellCoords(bounds.right, bounds.bottom); - for (var x = p1.x; x <= p2.x; x++) { - for (var y = p1.y; y <= p2.y; y++) { - var cell = this.cellAtPosition(x, y); - if (!cell) - continue; - for (var i = 0; i < cell.length; i++) { - var collider = cell[i]; - if (collider == excludeCollider || !Flags.isFlagSet(layerMask, collider.physicsLayer)) - continue; - if (bounds.intersects(collider.bounds)) { - if (this._tempHashSet.indexOf(collider) == -1) - this._tempHashSet.push(collider); + return false; + }; + ShapeCollisions.minkowskiDifference = function (first, second) { + var positionOffset = es.Vector2.subtract(first.position, es.Vector2.add(first.bounds.location, es.Vector2.divide(first.bounds.size, new es.Vector2(2)))); + var topLeft = es.Vector2.subtract(es.Vector2.add(first.bounds.location, positionOffset), second.bounds.max); + var fullSize = es.Vector2.add(first.bounds.size, second.bounds.size); + return new es.Rectangle(topLeft.x, topLeft.y, fullSize.x, fullSize.y); + }; + ShapeCollisions.lineToPoly = function (start, end, polygon, hit) { + var normal = es.Vector2.zero; + var intersectionPoint = es.Vector2.zero; + var fraction = Number.MAX_VALUE; + var hasIntersection = false; + for (var j = polygon.points.length - 1, i = 0; i < polygon.points.length; j = i, i++) { + var edge1 = es.Vector2.add(polygon.position, polygon.points[j]); + var edge2 = es.Vector2.add(polygon.position, polygon.points[i]); + var intersection = es.Vector2.zero; + if (this.lineToLine(edge1, edge2, start, end, intersection)) { + hasIntersection = true; + var distanceFraction = (intersection.x - start.x) / (end.x - start.x); + if (Number.isNaN(distanceFraction) || Number.isFinite(distanceFraction)) + distanceFraction = (intersection.y - start.y) / (end.y - start.y); + if (distanceFraction < fraction) { + var edge = es.Vector2.subtract(edge2, edge1); + normal = new es.Vector2(edge.y, -edge.x); + fraction = distanceFraction; + intersectionPoint = intersection; } } } - } - return { tempHashSet: this._tempHashSet, bounds: bounds }; - }; - SpatialHash.prototype.cellAtPosition = function (x, y, createCellIfEmpty) { - if (createCellIfEmpty === void 0) { createCellIfEmpty = false; } - var cell = this._cellDict.tryGetValue(x, y); - if (!cell) { - if (createCellIfEmpty) { - cell = []; - this._cellDict.add(x, y, cell); + if (hasIntersection) { + normal = normal.normalize(); + var distance = es.Vector2.distance(start, intersectionPoint); + hit.setValuesNonCollider(fraction, distance, intersectionPoint, normal); + return true; } - } - return cell; - }; - SpatialHash.prototype.cellCoords = function (x, y) { - return new Vector2(Math.floor(x * this._inverseCellSize), Math.floor(y * this._inverseCellSize)); - }; - return SpatialHash; -}()); -var RaycastResultParser = (function () { - function RaycastResultParser() { - } - return RaycastResultParser; -}()); -var NumberDictionary = (function () { - function NumberDictionary() { - this._store = new Map(); - } - NumberDictionary.prototype.getKey = function (x, y) { - return Long.fromNumber(x).shiftLeft(32).or(this.intToUint(y)).toString(); - }; - NumberDictionary.prototype.intToUint = function (i) { - if (i >= 0) - return i; - else - return 4294967296 + i; - }; - NumberDictionary.prototype.add = function (x, y, list) { - this._store.set(this.getKey(x, y), list); - }; - NumberDictionary.prototype.remove = function (obj) { - this._store.forEach(function (list) { - if (list.contains(obj)) - list.remove(obj); - }); - }; - NumberDictionary.prototype.tryGetValue = function (x, y) { - return this._store.get(this.getKey(x, y)); - }; - NumberDictionary.prototype.clear = function () { - this._store.clear(); - }; - return NumberDictionary; -}()); -var ContentManager = (function () { - function ContentManager() { - this.loadedAssets = new Map(); - } - ContentManager.prototype.loadRes = function (name, local) { - var _this = this; - if (local === void 0) { local = true; } - return new Promise(function (resolve, reject) { - var res = _this.loadedAssets.get(name); - if (res) { - resolve(res); - return; - } - if (local) { - RES.getResAsync(name).then(function (data) { - _this.loadedAssets.set(name, data); - resolve(data); - }).catch(function (err) { - console.error("资源加载错误:", name, err); - reject(err); - }); + return false; + }; + ShapeCollisions.lineToLine = function (a1, a2, b1, b2, intersection) { + var b = es.Vector2.subtract(a2, a1); + var d = es.Vector2.subtract(b2, b1); + var bDotDPerp = b.x * d.y - b.y * d.x; + if (bDotDPerp == 0) + return false; + var c = es.Vector2.subtract(b1, a1); + var t = (c.x * d.y - c.y * d.x) / bDotDPerp; + if (t < 0 || t > 1) + return false; + var u = (c.x * b.y - c.y * b.x) / bDotDPerp; + if (u < 0 || u > 1) + return false; + intersection = intersection.add(a1).add(es.Vector2.multiply(new es.Vector2(t), b)); + return true; + }; + ShapeCollisions.lineToCircle = function (start, end, s, hit) { + var lineLength = es.Vector2.distance(start, end); + var d = es.Vector2.divide(es.Vector2.subtract(end, start), new es.Vector2(lineLength)); + var m = es.Vector2.subtract(start, s.position); + var b = es.Vector2.dot(m, d); + var c = es.Vector2.dot(m, m) - s.radius * s.radius; + if (c > 0 && b > 0) + return false; + var discr = b * b - c; + if (discr < 0) + return false; + hit.fraction = -b - Math.sqrt(discr); + if (hit.fraction < 0) + hit.fraction = 0; + hit.point = es.Vector2.add(start, es.Vector2.multiply(new es.Vector2(hit.fraction), d)); + hit.distance = es.Vector2.distance(start, hit.point); + hit.normal = es.Vector2.normalize(es.Vector2.subtract(hit.point, s.position)); + hit.fraction = hit.distance / lineLength; + return true; + }; + ShapeCollisions.boxToBoxCast = function (first, second, movement, hit) { + var minkowskiDiff = this.minkowskiDifference(first, second); + if (minkowskiDiff.contains(0, 0)) { + var mtv = minkowskiDiff.getClosestPointOnBoundsToOrigin(); + if (mtv.equals(es.Vector2.zero)) + return false; + hit.normal = new es.Vector2(-mtv.x); + hit.normal = hit.normal.normalize(); + hit.distance = 0; + hit.fraction = 0; + return true; } else { - RES.getResByUrl(name).then(function (data) { - _this.loadedAssets.set(name, data); - resolve(data); - }).catch(function (err) { - console.error("资源加载错误:", name, err); - reject(err); - }); + var ray = new es.Ray2D(es.Vector2.zero, new es.Vector2(-movement.x)); + var fraction = minkowskiDiff.rayIntersects(ray); + if (fraction <= 1) { + hit.fraction = fraction; + hit.distance = movement.length() * fraction; + hit.normal = new es.Vector2(-movement.x); + hit.normal = hit.normal.normalize(); + hit.centroid = es.Vector2.add(first.bounds.center, es.Vector2.multiply(movement, new es.Vector2(fraction))); + return true; + } } - }); - }; - ContentManager.prototype.dispose = function () { - this.loadedAssets.forEach(function (value) { - var assetsToRemove = value; - assetsToRemove.dispose(); - }); - this.loadedAssets.clear(); - }; - return ContentManager; -}()); -var Emitter = (function () { - function Emitter() { - this._messageTable = new Map(); + return false; + }; + return ShapeCollisions; + }()); + es.ShapeCollisions = ShapeCollisions; +})(es || (es = {})); +var es; +(function (es) { + var SpatialHash = (function () { + function SpatialHash(cellSize) { + if (cellSize === void 0) { cellSize = 100; } + this.gridBounds = new es.Rectangle(); + this._overlapTestCircle = new es.Circle(0); + this._cellDict = new NumberDictionary(); + this._tempHashSet = []; + this._cellSize = cellSize; + this._inverseCellSize = 1 / this._cellSize; + this._raycastParser = new RaycastResultParser(); + } + SpatialHash.prototype.register = function (collider) { + var bounds = collider.bounds; + collider.registeredPhysicsBounds = bounds; + var p1 = this.cellCoords(bounds.x, bounds.y); + var p2 = this.cellCoords(bounds.right, bounds.bottom); + if (!this.gridBounds.contains(p1.x, p1.y)) { + this.gridBounds = es.RectangleExt.union(this.gridBounds, p1); + } + if (!this.gridBounds.contains(p2.x, p2.y)) { + this.gridBounds = es.RectangleExt.union(this.gridBounds, p2); + } + for (var x = p1.x; x <= p2.x; x++) { + for (var y = p1.y; y <= p2.y; y++) { + var c = this.cellAtPosition(x, y, true); + if (!c.firstOrDefault(function (c) { return c.hashCode == collider.hashCode; })) + c.push(collider); + } + } + }; + SpatialHash.prototype.remove = function (collider) { + var bounds = collider.registeredPhysicsBounds; + var p1 = this.cellCoords(bounds.x, bounds.y); + var p2 = this.cellCoords(bounds.right, bounds.bottom); + for (var x = p1.x; x <= p2.x; x++) { + for (var y = p1.y; y <= p2.y; y++) { + var cell = this.cellAtPosition(x, y); + if (!cell) + console.error("removing Collider [" + collider + "] from a cell that it is not present in"); + else + cell.remove(collider); + } + } + }; + SpatialHash.prototype.removeWithBruteForce = function (obj) { + this._cellDict.remove(obj); + }; + SpatialHash.prototype.clear = function () { + this._cellDict.clear(); + }; + SpatialHash.prototype.debugDraw = function (secondsToDisplay, textScale) { + if (textScale === void 0) { textScale = 1; } + for (var x = this.gridBounds.x; x <= this.gridBounds.right; x++) { + for (var y = this.gridBounds.y; y <= this.gridBounds.bottom; y++) { + var cell = this.cellAtPosition(x, y); + if (cell && cell.length > 0) + this.debugDrawCellDetails(x, y, cell.length, secondsToDisplay, textScale); + } + } + }; + SpatialHash.prototype.aabbBroadphase = function (bounds, excludeCollider, layerMask) { + this._tempHashSet.length = 0; + var p1 = this.cellCoords(bounds.x, bounds.y); + var p2 = this.cellCoords(bounds.right, bounds.bottom); + for (var x = p1.x; x <= p2.x; x++) { + for (var y = p1.y; y <= p2.y; y++) { + var cell = this.cellAtPosition(x, y); + if (!cell) + continue; + var _loop_7 = function (i) { + var collider = cell[i]; + if (collider == excludeCollider || !es.Flags.isFlagSet(layerMask, collider.physicsLayer)) + return "continue"; + if (bounds.intersects(collider.bounds)) { + if (!this_3._tempHashSet.firstOrDefault(function (c) { return c.hashCode == collider.hashCode; })) + this_3._tempHashSet.push(collider); + } + }; + var this_3 = this; + for (var i = 0; i < cell.length; i++) { + _loop_7(i); + } + } + } + return this._tempHashSet; + }; + SpatialHash.prototype.overlapCircle = function (circleCenter, radius, results, layerMask) { + var bounds = new es.Rectangle(circleCenter.x - radius, circleCenter.y - radius, radius * 2, radius * 2); + this._overlapTestCircle.radius = radius; + this._overlapTestCircle.position = circleCenter; + var resultCounter = 0; + var potentials = this.aabbBroadphase(bounds, null, layerMask); + for (var i = 0; i < potentials.length; i++) { + var collider = potentials[i]; + if (collider instanceof es.BoxCollider) { + results[resultCounter] = collider; + resultCounter++; + } + else if (collider instanceof es.CircleCollider) { + if (collider.shape.overlaps(this._overlapTestCircle)) { + results[resultCounter] = collider; + resultCounter++; + } + } + else if (collider instanceof es.PolygonCollider) { + if (collider.shape.overlaps(this._overlapTestCircle)) { + results[resultCounter] = collider; + resultCounter++; + } + } + else { + throw new Error("overlapCircle against this collider type is not implemented!"); + } + if (resultCounter == results.length) + return resultCounter; + } + return resultCounter; + }; + SpatialHash.prototype.cellCoords = function (x, y) { + return new es.Vector2(Math.floor(x * this._inverseCellSize), Math.floor(y * this._inverseCellSize)); + }; + SpatialHash.prototype.cellAtPosition = function (x, y, createCellIfEmpty) { + if (createCellIfEmpty === void 0) { createCellIfEmpty = false; } + var cell = this._cellDict.tryGetValue(x, y); + if (!cell) { + if (createCellIfEmpty) { + cell = []; + this._cellDict.add(x, y, cell); + } + } + return cell; + }; + SpatialHash.prototype.debugDrawCellDetails = function (x, y, cellCount, secondsToDisplay, textScale) { + if (secondsToDisplay === void 0) { secondsToDisplay = 0.5; } + if (textScale === void 0) { textScale = 1; } + }; + return SpatialHash; + }()); + es.SpatialHash = SpatialHash; + var NumberDictionary = (function () { + function NumberDictionary() { + this._store = new Map(); + } + NumberDictionary.prototype.add = function (x, y, list) { + this._store.set(this.getKey(x, y), list); + }; + NumberDictionary.prototype.remove = function (obj) { + this._store.forEach(function (list) { + if (list.contains(obj)) + list.remove(obj); + }); + }; + NumberDictionary.prototype.tryGetValue = function (x, y) { + return this._store.get(this.getKey(x, y)); + }; + NumberDictionary.prototype.clear = function () { + this._store.clear(); + }; + NumberDictionary.prototype.getKey = function (x, y) { + return Long.fromNumber(x).shiftLeft(32).or(Long.fromNumber(y, true)).toString(); + }; + return NumberDictionary; + }()); + es.NumberDictionary = NumberDictionary; + var RaycastResultParser = (function () { + function RaycastResultParser() { + this._checkedColliders = []; + this._cellHits = []; + } + RaycastResultParser.prototype.start = function (ray, hits, layerMask) { + this._ray = ray; + this._hits = hits; + this._layerMask = layerMask; + this.hitCounter = 0; + }; + RaycastResultParser.prototype.checkRayIntersection = function (cellX, cellY, cell) { + var fraction = 0; + for (var i = 0; i < cell.length; i++) { + var potential = cell[i]; + if (this._checkedColliders.contains(potential)) + continue; + this._checkedColliders.push(potential); + if (potential.isTrigger && !es.Physics.raycastsHitTriggers) + continue; + if (!es.Flags.isFlagSet(this._layerMask, potential.physicsLayer)) + continue; + var colliderBounds = potential.bounds; + var fraction_1 = colliderBounds.rayIntersects(this._ray); + if (fraction_1 <= 1) { + if (potential.shape.collidesWithLine(this._ray.start, this._ray.end, this._tempHit)) { + if (!es.Physics.raycastsStartInColliders && potential.shape.containsPoint(this._ray.start)) + continue; + this._tempHit.collider = potential; + this._cellHits.push(this._tempHit); + } + } + } + if (this._cellHits.length == 0) + return false; + this._cellHits.sort(RaycastResultParser.compareRaycastHits); + for (var i = 0; i < this._cellHits.length; i++) { + this._hits[this.hitCounter] = this._cellHits[i]; + this.hitCounter++; + if (this.hitCounter == this._hits.length) + return true; + } + return false; + }; + RaycastResultParser.prototype.reset = function () { + this._hits = null; + this._checkedColliders.length = 0; + this._cellHits.length = 0; + }; + RaycastResultParser.compareRaycastHits = function (a, b) { + return a.distance - b.distance; + }; + return RaycastResultParser; + }()); + es.RaycastResultParser = RaycastResultParser; +})(es || (es = {})); +var ArrayUtils = (function () { + function ArrayUtils() { } - Emitter.prototype.addObserver = function (eventType, handler) { - var list = this._messageTable.get(eventType); - if (!list) { - list = []; - this._messageTable.set(eventType, list); - } - if (list.contains(handler)) - console.warn("您试图添加相同的观察者两次"); - list.push(handler); - }; - Emitter.prototype.removeObserver = function (eventType, handler) { - this._messageTable.get(eventType).remove(handler); - }; - Emitter.prototype.emit = function (eventType, data) { - var list = this._messageTable.get(eventType); - if (list) { - for (var i = list.length - 1; i >= 0; i--) - list[i](data); - } - }; - return Emitter; -}()); -var GlobalManager = (function () { - function GlobalManager() { - } - Object.defineProperty(GlobalManager.prototype, "enabled", { - get: function () { - return this._enabled; - }, - set: function (value) { - this.setEnabled(value); - }, - enumerable: true, - configurable: true - }); - GlobalManager.prototype.setEnabled = function (isEnabled) { - if (this._enabled != isEnabled) { - this._enabled = isEnabled; - if (this._enabled) { - this.onEnabled(); - } - else { - this.onDisabled(); + ArrayUtils.bubbleSort = function (ary) { + var isExchange = false; + for (var i = 0; i < ary.length; i++) { + isExchange = false; + for (var j = ary.length - 1; j > i; j--) { + if (ary[j] < ary[j - 1]) { + var temp = ary[j]; + ary[j] = ary[j - 1]; + ary[j - 1] = temp; + isExchange = true; + } } + if (!isExchange) + break; } }; - GlobalManager.prototype.onEnabled = function () { }; - GlobalManager.prototype.onDisabled = function () { }; - GlobalManager.prototype.update = function () { }; - GlobalManager.registerGlobalManager = function (manager) { - this.globalManagers.push(manager); - manager.enabled = true; + ArrayUtils.insertionSort = function (ary) { + var len = ary.length; + for (var i = 1; i < len; i++) { + var val = ary[i]; + for (var j = i; j > 0 && ary[j - 1] > val; j--) { + ary[j] = ary[j - 1]; + } + ary[j] = val; + } }; - GlobalManager.unregisterGlobalManager = function (manager) { - this.globalManagers.remove(manager); - manager.enabled = false; + ArrayUtils.binarySearch = function (ary, value) { + var startIndex = 0; + var endIndex = ary.length; + var sub = (startIndex + endIndex) >> 1; + while (startIndex < endIndex) { + if (value <= ary[sub]) + endIndex = sub; + else if (value >= ary[sub]) + startIndex = sub + 1; + sub = (startIndex + endIndex) >> 1; + } + if (ary[startIndex] == value) + return startIndex; + return -1; }; - GlobalManager.getGlobalManager = function (type) { - for (var i = 0; i < this.globalManagers.length; i++) { - if (this.globalManagers[i] instanceof type) - return this.globalManagers[i]; + ArrayUtils.findElementIndex = function (ary, num) { + var len = ary.length; + for (var i = 0; i < len; ++i) { + if (ary[i] == num) + return i; } return null; }; - GlobalManager.globalManagers = []; - return GlobalManager; -}()); -var TouchState = (function () { - function TouchState() { - this.x = 0; - this.y = 0; - this.touchPoint = -1; - this.touchDown = false; - } - Object.defineProperty(TouchState.prototype, "position", { - get: function () { - return new Vector2(this.x, this.y); - }, - enumerable: true, - configurable: true - }); - TouchState.prototype.reset = function () { - this.x = 0; - this.y = 0; - this.touchDown = false; - this.touchPoint = -1; + ArrayUtils.getMaxElementIndex = function (ary) { + var matchIndex = 0; + var len = ary.length; + for (var j = 1; j < len; j++) { + if (ary[j] > ary[matchIndex]) + matchIndex = j; + } + return matchIndex; }; - return TouchState; -}()); -var Input = (function () { - function Input() { - } - Object.defineProperty(Input, "touchPosition", { - get: function () { - if (!this._gameTouchs[0]) - return Vector2.zero; - return this._gameTouchs[0].position; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Input, "maxSupportedTouch", { - get: function () { - return this._stage.maxTouches; - }, - set: function (value) { - this._stage.maxTouches = value; - this.initTouchCache(); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Input, "resolutionScale", { - get: function () { - return this._resolutionScale; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Input, "totalTouchCount", { - get: function () { - return this._totalTouchCount; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Input, "gameTouchs", { - get: function () { - return this._gameTouchs; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Input, "touchPositionDelta", { - get: function () { - var delta = Vector2.subtract(this.touchPosition, this._previousTouchState.position); - if (delta.length() > 0) { - this.setpreviousTouchState(this._gameTouchs[0]); + ArrayUtils.getMinElementIndex = function (ary) { + var matchIndex = 0; + var len = ary.length; + for (var j = 1; j < len; j++) { + if (ary[j] < ary[matchIndex]) + matchIndex = j; + } + return matchIndex; + }; + ArrayUtils.getUniqueAry = function (ary) { + var uAry = []; + var newAry = []; + var count = ary.length; + for (var i = 0; i < count; ++i) { + var value = ary[i]; + if (uAry.indexOf(value) == -1) + uAry.push(value); + } + count = uAry.length; + for (var i = count - 1; i >= 0; --i) { + newAry.unshift(uAry[i]); + } + return newAry; + }; + ArrayUtils.getDifferAry = function (aryA, aryB) { + aryA = this.getUniqueAry(aryA); + aryB = this.getUniqueAry(aryB); + var ary = aryA.concat(aryB); + var uObj = {}; + var newAry = []; + var count = ary.length; + for (var j = 0; j < count; ++j) { + if (!uObj[ary[j]]) { + uObj[ary[j]] = {}; + uObj[ary[j]].count = 0; + uObj[ary[j]].key = ary[j]; + uObj[ary[j]].count++; } - return delta; - }, - enumerable: true, - configurable: true - }); - Input.initialize = function (stage) { - if (this._init) + else { + if (uObj[ary[j]] instanceof Object) { + uObj[ary[j]].count++; + } + } + } + for (var i in uObj) { + if (uObj[i].count != 2) { + newAry.unshift(uObj[i].key); + } + } + return newAry; + }; + ArrayUtils.swap = function (array, index1, index2) { + var temp = array[index1]; + array[index1] = array[index2]; + array[index2] = temp; + }; + ArrayUtils.clearList = function (ary) { + if (!ary) return; - this._init = true; - this._stage = stage; - this._stage.addEventListener(egret.TouchEvent.TOUCH_BEGIN, this.touchBegin, this); - this._stage.addEventListener(egret.TouchEvent.TOUCH_MOVE, this.touchMove, this); - this._stage.addEventListener(egret.TouchEvent.TOUCH_END, this.touchEnd, this); - this._stage.addEventListener(egret.TouchEvent.TOUCH_CANCEL, this.touchEnd, this); - this._stage.addEventListener(egret.TouchEvent.TOUCH_RELEASE_OUTSIDE, this.touchEnd, this); - this.initTouchCache(); - }; - Input.initTouchCache = function () { - this._totalTouchCount = 0; - this._touchIndex = 0; - this._gameTouchs.length = 0; - for (var i = 0; i < this.maxSupportedTouch; i++) { - this._gameTouchs.push(new TouchState()); + var length = ary.length; + for (var i = length - 1; i >= 0; i -= 1) { + ary.splice(i, 1); } }; - Input.touchBegin = function (evt) { - if (this._touchIndex < this.maxSupportedTouch) { - this._gameTouchs[this._touchIndex].touchPoint = evt.touchPointID; - this._gameTouchs[this._touchIndex].touchDown = evt.touchDown; - this._gameTouchs[this._touchIndex].x = evt.stageX; - this._gameTouchs[this._touchIndex].y = evt.stageY; - if (this._touchIndex == 0) { - this.setpreviousTouchState(this._gameTouchs[0]); - } - this._touchIndex++; - this._totalTouchCount++; - } + ArrayUtils.cloneList = function (ary) { + if (!ary) + return null; + return ary.slice(0, ary.length); }; - Input.touchMove = function (evt) { - if (evt.touchPointID == this._gameTouchs[0].touchPoint) { - this.setpreviousTouchState(this._gameTouchs[0]); - } - var touchIndex = this._gameTouchs.findIndex(function (touch) { return touch.touchPoint == evt.touchPointID; }); - if (touchIndex != -1) { - var touchData = this._gameTouchs[touchIndex]; - touchData.x = evt.stageX; - touchData.y = evt.stageY; - } - }; - Input.touchEnd = function (evt) { - var touchIndex = this._gameTouchs.findIndex(function (touch) { return touch.touchPoint == evt.touchPointID; }); - if (touchIndex != -1) { - var touchData = this._gameTouchs[touchIndex]; - touchData.reset(); - if (touchIndex == 0) - this._previousTouchState.reset(); - this._totalTouchCount--; - if (this.totalTouchCount == 0) { - this._touchIndex = 0; - } - } - }; - Input.setpreviousTouchState = function (touchState) { - this._previousTouchState = new TouchState(); - this._previousTouchState.x = touchState.position.x; - this._previousTouchState.y = touchState.position.y; - this._previousTouchState.touchPoint = touchState.touchPoint; - this._previousTouchState.touchDown = touchState.touchDown; - }; - Input.scaledPosition = function (position) { - var scaledPos = new Vector2(position.x - this._resolutionOffset.x, position.y - this._resolutionOffset.y); - return Vector2.multiply(scaledPos, this.resolutionScale); - }; - Input._init = false; - Input._previousTouchState = new TouchState(); - Input._gameTouchs = []; - Input._resolutionOffset = new Vector2(); - Input._resolutionScale = Vector2.one; - Input._touchIndex = 0; - Input._totalTouchCount = 0; - return Input; -}()); -var ListPool = (function () { - function ListPool() { - } - ListPool.warmCache = function (cacheCount) { - cacheCount -= this._objectQueue.length; - if (cacheCount > 0) { - for (var i = 0; i < cacheCount; i++) { - this._objectQueue.unshift([]); - } - } - }; - ListPool.trimCache = function (cacheCount) { - while (cacheCount > this._objectQueue.length) - this._objectQueue.shift(); - }; - ListPool.clearCache = function () { - this._objectQueue.length = 0; - }; - ListPool.obtain = function () { - if (this._objectQueue.length > 0) - return this._objectQueue.shift(); - return []; - }; - ListPool.free = function (obj) { - this._objectQueue.unshift(obj); - obj.length = 0; - }; - ListPool._objectQueue = []; - return ListPool; -}()); -var Pair = (function () { - function Pair(first, second) { - this.first = first; - this.second = second; - } - Pair.prototype.clear = function () { - this.first = this.second = null; - }; - Pair.prototype.equals = function (other) { - return this.first == other.first && this.second == other.second; - }; - return Pair; -}()); -var RectangleExt = (function () { - function RectangleExt() { - } - RectangleExt.union = function (first, point) { - var rect = new Rectangle(point.x, point.y, 0, 0); - return this.unionR(first, rect); - }; - RectangleExt.unionR = function (value1, value2) { - var result = new Rectangle(); - result.x = Math.min(value1.x, value2.x); - result.y = Math.min(value1.y, value2.y); - result.width = Math.max(value1.right, value2.right) - result.x; - result.height = Math.max(value1.bottom, value2.bottom) - result.y; - return result; - }; - return RectangleExt; -}()); -var Triangulator = (function () { - function Triangulator() { - this.triangleIndices = []; - this._triPrev = new Array(12); - this._triNext = new Array(12); - } - Triangulator.prototype.triangulate = function (points, arePointsCCW) { - if (arePointsCCW === void 0) { arePointsCCW = true; } - var count = points.length; - this.initialize(count); - var iterations = 0; - var index = 0; - while (count > 3 && iterations < 500) { - iterations++; - var isEar = true; - var a = points[this._triPrev[index]]; - var b = points[index]; - var c = points[this._triNext[index]]; - if (Vector2Ext.isTriangleCCW(a, b, c)) { - var k = this._triNext[this._triNext[index]]; - do { - if (Triangulator.testPointTriangle(points[k], a, b, c)) { - isEar = false; - break; - } - k = this._triNext[k]; - } while (k != this._triPrev[index]); - } - else { - isEar = false; - } - if (isEar) { - this.triangleIndices.push(this._triPrev[index]); - this.triangleIndices.push(index); - this.triangleIndices.push(this._triNext[index]); - this._triNext[this._triPrev[index]] = this._triNext[index]; - this._triPrev[this._triNext[index]] = this._triPrev[index]; - count--; - index = this._triPrev[index]; - } - else { - index = this._triNext[index]; - } - } - this.triangleIndices.push(this._triPrev[index]); - this.triangleIndices.push(index); - this.triangleIndices.push(this._triNext[index]); - if (!arePointsCCW) - this.triangleIndices.reverse(); - }; - Triangulator.prototype.initialize = function (count) { - this.triangleIndices.length = 0; - if (this._triNext.length < count) { - this._triNext.reverse(); - this._triNext = new Array(Math.max(this._triNext.length * 2, count)); - } - if (this._triPrev.length < count) { - this._triPrev.reverse(); - this._triPrev = new Array(Math.max(this._triPrev.length * 2, count)); - } - for (var i = 0; i < count; i++) { - this._triPrev[i] = i - 1; - this._triNext[i] = i + 1; - } - this._triPrev[0] = count - 1; - this._triNext[count - 1] = 0; - }; - Triangulator.testPointTriangle = function (point, a, b, c) { - if (Vector2Ext.cross(Vector2.subtract(point, a), Vector2.subtract(b, a)) < 0) - return false; - if (Vector2Ext.cross(Vector2.subtract(point, b), Vector2.subtract(c, b)) < 0) - return false; - if (Vector2Ext.cross(Vector2.subtract(point, c), Vector2.subtract(a, c)) < 0) + ArrayUtils.equals = function (ary1, ary2) { + if (ary1 == ary2) + return true; + var length = ary1.length; + if (length != ary2.length) return false; + while (length--) { + if (ary1[length] != ary2[length]) + return false; + } return true; }; - return Triangulator; -}()); -var Vector2Ext = (function () { - function Vector2Ext() { - } - Vector2Ext.isTriangleCCW = function (a, center, c) { - return this.cross(Vector2.subtract(center, a), Vector2.subtract(c, center)) < 0; - }; - Vector2Ext.cross = function (u, v) { - return u.y * v.x - u.x * v.y; - }; - Vector2Ext.perpendicular = function (first, second) { - return new Vector2(-1 * (second.y - first.y), second.x - first.x); - }; - Vector2Ext.normalize = function (vec) { - var magnitude = Math.sqrt((vec.x * vec.x) + (vec.y * vec.y)); - if (magnitude > MathHelper.Epsilon) { - vec = Vector2.divide(vec, new Vector2(magnitude)); - } + ArrayUtils.insert = function (ary, index, value) { + if (!ary) + return null; + var length = ary.length; + if (index > length) + index = length; + if (index < 0) + index = 0; + if (index == length) + ary.push(value); + else if (index == 0) + ary.unshift(value); else { - vec.x = vec.y = 0; + for (var i = length - 1; i >= index; i -= 1) { + ary[i + 1] = ary[i]; + } + ary[index] = value; } - return vec; + return value; }; - Vector2Ext.transformA = function (sourceArray, sourceIndex, matrix, destinationArray, destinationIndex, length) { - for (var i = 0; i < length; i++) { - var position = sourceArray[sourceIndex + i]; - var destination = destinationArray[destinationIndex + i]; - destination.x = (position.x * matrix.m11) + (position.y * matrix.m21) + matrix.m31; - destination.y = (position.x * matrix.m12) + (position.y * matrix.m22) + matrix.m32; - destinationArray[destinationIndex + i] = destination; - } - }; - Vector2Ext.transformR = function (position, matrix) { - var x = (position.x * matrix.m11) + (position.y * matrix.m21) + matrix.m31; - var y = (position.x * matrix.m12) + (position.y * matrix.m22) + matrix.m32; - return new Vector2(x, y); - }; - Vector2Ext.transform = function (sourceArray, matrix, destinationArray) { - this.transformA(sourceArray, 0, matrix, destinationArray, 0, sourceArray.length); - }; - Vector2Ext.round = function (vec) { - return new Vector2(Math.round(vec.x), Math.round(vec.y)); - }; - return Vector2Ext; + return ArrayUtils; }()); +var Base64Utils = (function () { + function Base64Utils() { + } + Base64Utils.decode = function (input, isNotStr) { + if (isNotStr === void 0) { isNotStr = true; } + var output = ""; + var chr1, chr2, chr3; + var enc1, enc2, enc3, enc4; + var i = 0; + input = this.getConfKey(input); + input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); + while (i < input.length) { + enc1 = this._keyAll.indexOf(input.charAt(i++)); + enc2 = this._keyAll.indexOf(input.charAt(i++)); + enc3 = this._keyAll.indexOf(input.charAt(i++)); + enc4 = this._keyAll.indexOf(input.charAt(i++)); + chr1 = (enc1 << 2) | (enc2 >> 4); + chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); + chr3 = ((enc3 & 3) << 6) | enc4; + output = output + String.fromCharCode(chr1); + if (enc3 != 64) { + if (chr2 == 0) { + if (isNotStr) + output = output + String.fromCharCode(chr2); + } + else { + output = output + String.fromCharCode(chr2); + } + } + if (enc4 != 64) { + if (chr3 == 0) { + if (isNotStr) + output = output + String.fromCharCode(chr3); + } + else { + output = output + String.fromCharCode(chr3); + } + } + } + output = this._utf8_decode(output); + return output; + }; + Base64Utils._utf8_encode = function (string) { + string = string.replace(/\r\n/g, "\n"); + var utftext = ""; + for (var n = 0; n < string.length; n++) { + var c = string.charCodeAt(n); + if (c < 128) { + utftext += String.fromCharCode(c); + } + else if ((c > 127) && (c < 2048)) { + utftext += String.fromCharCode((c >> 6) | 192); + utftext += String.fromCharCode((c & 63) | 128); + } + else { + utftext += String.fromCharCode((c >> 12) | 224); + utftext += String.fromCharCode(((c >> 6) & 63) | 128); + utftext += String.fromCharCode((c & 63) | 128); + } + } + return utftext; + }; + Base64Utils._utf8_decode = function (utftext) { + var string = ""; + var i = 0; + var c = 0; + var c1 = 0; + var c2 = 0; + var c3 = 0; + while (i < utftext.length) { + c = utftext.charCodeAt(i); + if (c < 128) { + string += String.fromCharCode(c); + i++; + } + else if ((c > 191) && (c < 224)) { + c2 = utftext.charCodeAt(i + 1); + string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); + i += 2; + } + else { + c2 = utftext.charCodeAt(i + 1); + c3 = utftext.charCodeAt(i + 2); + string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); + i += 3; + } + } + return string; + }; + Base64Utils.getConfKey = function (key) { + return key.slice(1, key.length); + }; + Base64Utils._keyNum = "0123456789+/"; + Base64Utils._keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + Base64Utils._keyAll = Base64Utils._keyNum + Base64Utils._keyStr; + Base64Utils.encode = function (input) { + var output = ""; + var chr1, chr2, chr3, enc1, enc2, enc3, enc4; + var i = 0; + input = this._utf8_encode(input); + while (i < input.length) { + chr1 = input.charCodeAt(i++); + chr2 = input.charCodeAt(i++); + chr3 = input.charCodeAt(i++); + enc1 = chr1 >> 2; + enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); + enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); + enc4 = chr3 & 63; + if (isNaN(chr2)) { + enc3 = enc4 = 64; + } + else if (isNaN(chr3)) { + enc4 = 64; + } + output = output + + this._keyAll.charAt(enc1) + this._keyAll.charAt(enc2) + + this._keyAll.charAt(enc3) + this._keyAll.charAt(enc4); + } + return this._keyStr.charAt(Math.floor((Math.random() * this._keyStr.length))) + output; + }; + return Base64Utils; +}()); +var es; +(function (es) { + var ContentManager = (function () { + function ContentManager() { + this.loadedAssets = new Map(); + } + ContentManager.prototype.loadRes = function (name, local) { + var _this = this; + if (local === void 0) { local = true; } + return new Promise(function (resolve, reject) { + var res = _this.loadedAssets.get(name); + if (res) { + resolve(res); + return; + } + if (local) { + RES.getResAsync(name).then(function (data) { + _this.loadedAssets.set(name, data); + resolve(data); + }).catch(function (err) { + console.error("资源加载错误:", name, err); + reject(err); + }); + } + else { + RES.getResByUrl(name).then(function (data) { + _this.loadedAssets.set(name, data); + resolve(data); + }).catch(function (err) { + console.error("资源加载错误:", name, err); + reject(err); + }); + } + }); + }; + ContentManager.prototype.dispose = function () { + this.loadedAssets.forEach(function (value) { + var assetsToRemove = value; + assetsToRemove.dispose(); + }); + this.loadedAssets.clear(); + }; + return ContentManager; + }()); + es.ContentManager = ContentManager; +})(es || (es = {})); +var es; +(function (es) { + var DrawUtils = (function () { + function DrawUtils() { + } + DrawUtils.drawLine = function (shape, start, end, color, thickness) { + if (thickness === void 0) { thickness = 1; } + this.drawLineAngle(shape, start, es.MathHelper.angleBetweenVectors(start, end), es.Vector2.distance(start, end), color, thickness); + }; + DrawUtils.drawLineAngle = function (shape, start, radians, length, color, thickness) { + if (thickness === void 0) { thickness = 1; } + shape.graphics.beginFill(color); + shape.graphics.drawRect(start.x, start.y, 1, 1); + shape.graphics.endFill(); + shape.scaleX = length; + shape.scaleY = thickness; + shape.$anchorOffsetX = 0; + shape.$anchorOffsetY = 0; + shape.rotation = radians; + }; + DrawUtils.drawHollowRect = function (shape, rect, color, thickness) { + if (thickness === void 0) { thickness = 1; } + this.drawHollowRectR(shape, rect.x, rect.y, rect.width, rect.height, color, thickness); + }; + DrawUtils.drawHollowRectR = function (shape, x, y, width, height, color, thickness) { + if (thickness === void 0) { thickness = 1; } + var tl = new es.Vector2(x, y).round(); + var tr = new es.Vector2(x + width, y).round(); + var br = new es.Vector2(x + width, y + height).round(); + var bl = new es.Vector2(x, y + height).round(); + this.drawLine(shape, tl, tr, color, thickness); + this.drawLine(shape, tr, br, color, thickness); + this.drawLine(shape, br, bl, color, thickness); + this.drawLine(shape, bl, tl, color, thickness); + }; + DrawUtils.drawPixel = function (shape, position, color, size) { + if (size === void 0) { size = 1; } + var destRect = new es.Rectangle(position.x, position.y, size, size); + if (size != 1) { + destRect.x -= size * 0.5; + destRect.y -= size * 0.5; + } + shape.graphics.beginFill(color); + shape.graphics.drawRect(destRect.x, destRect.y, destRect.width, destRect.height); + shape.graphics.endFill(); + }; + DrawUtils.getColorMatrix = function (color) { + var colorMatrix = [ + 1, 0, 0, 0, 0, + 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, + 0, 0, 0, 1, 0 + ]; + colorMatrix[0] = Math.floor(color / 256 / 256) / 255; + colorMatrix[6] = Math.floor(color / 256 % 256) / 255; + colorMatrix[12] = color % 256 / 255; + return new egret.ColorMatrixFilter(colorMatrix); + }; + return DrawUtils; + }()); + es.DrawUtils = DrawUtils; +})(es || (es = {})); +var es; +(function (es) { + var FuncPack = (function () { + function FuncPack(func, context) { + this.func = func; + this.context = context; + } + return FuncPack; + }()); + es.FuncPack = FuncPack; + var Emitter = (function () { + function Emitter() { + this._messageTable = new Map(); + } + Emitter.prototype.addObserver = function (eventType, handler, context) { + var list = this._messageTable.get(eventType); + if (!list) { + list = []; + this._messageTable.set(eventType, list); + } + if (list.findIndex(function (funcPack) { return funcPack.func == handler; }) != -1) + console.warn("您试图添加相同的观察者两次"); + list.push(new FuncPack(handler, context)); + }; + Emitter.prototype.removeObserver = function (eventType, handler) { + var messageData = this._messageTable.get(eventType); + var index = messageData.findIndex(function (data) { return data.func == handler; }); + if (index != -1) + messageData.removeAt(index); + }; + Emitter.prototype.emit = function (eventType, data) { + var list = this._messageTable.get(eventType); + if (list) { + for (var i = list.length - 1; i >= 0; i--) + list[i].func.call(list[i].context, data); + } + }; + return Emitter; + }()); + es.Emitter = Emitter; +})(es || (es = {})); +var es; +(function (es) { + var GlobalManager = (function () { + function GlobalManager() { + } + Object.defineProperty(GlobalManager.prototype, "enabled", { + get: function () { + return this._enabled; + }, + set: function (value) { + this.setEnabled(value); + }, + enumerable: true, + configurable: true + }); + GlobalManager.prototype.setEnabled = function (isEnabled) { + if (this._enabled != isEnabled) { + this._enabled = isEnabled; + if (this._enabled) { + this.onEnabled(); + } + else { + this.onDisabled(); + } + } + }; + GlobalManager.prototype.onEnabled = function () { + }; + GlobalManager.prototype.onDisabled = function () { + }; + GlobalManager.prototype.update = function () { + }; + return GlobalManager; + }()); + es.GlobalManager = GlobalManager; +})(es || (es = {})); +var es; +(function (es) { + var TouchState = (function () { + function TouchState() { + this.x = 0; + this.y = 0; + this.touchPoint = -1; + this.touchDown = false; + } + Object.defineProperty(TouchState.prototype, "position", { + get: function () { + return new es.Vector2(this.x, this.y); + }, + enumerable: true, + configurable: true + }); + TouchState.prototype.reset = function () { + this.x = 0; + this.y = 0; + this.touchDown = false; + this.touchPoint = -1; + }; + return TouchState; + }()); + es.TouchState = TouchState; + var Input = (function () { + function Input() { + } + Object.defineProperty(Input, "gameTouchs", { + get: function () { + return this._gameTouchs; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Input, "resolutionScale", { + get: function () { + return this._resolutionScale; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Input, "totalTouchCount", { + get: function () { + return this._totalTouchCount; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Input, "touchPosition", { + get: function () { + if (!this._gameTouchs[0]) + return es.Vector2.zero; + return this._gameTouchs[0].position; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Input, "maxSupportedTouch", { + get: function () { + return es.Core._instance.stage.maxTouches; + }, + set: function (value) { + es.Core._instance.stage.maxTouches = value; + this.initTouchCache(); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Input, "touchPositionDelta", { + get: function () { + var delta = es.Vector2.subtract(this.touchPosition, this._previousTouchState.position); + if (delta.length() > 0) { + this.setpreviousTouchState(this._gameTouchs[0]); + } + return delta; + }, + enumerable: true, + configurable: true + }); + Input.initialize = function () { + if (this._init) + return; + this._init = true; + es.Core._instance.stage.addEventListener(egret.TouchEvent.TOUCH_BEGIN, this.touchBegin, this); + es.Core._instance.stage.addEventListener(egret.TouchEvent.TOUCH_MOVE, this.touchMove, this); + es.Core._instance.stage.addEventListener(egret.TouchEvent.TOUCH_END, this.touchEnd, this); + es.Core._instance.stage.addEventListener(egret.TouchEvent.TOUCH_CANCEL, this.touchEnd, this); + es.Core._instance.stage.addEventListener(egret.TouchEvent.TOUCH_RELEASE_OUTSIDE, this.touchEnd, this); + this.initTouchCache(); + }; + Input.scaledPosition = function (position) { + var scaledPos = new es.Vector2(position.x - this._resolutionOffset.x, position.y - this._resolutionOffset.y); + return es.Vector2.multiply(scaledPos, this.resolutionScale); + }; + Input.initTouchCache = function () { + this._totalTouchCount = 0; + this._touchIndex = 0; + this._gameTouchs.length = 0; + for (var i = 0; i < this.maxSupportedTouch; i++) { + this._gameTouchs.push(new TouchState()); + } + }; + Input.touchBegin = function (evt) { + if (this._touchIndex < this.maxSupportedTouch) { + this._gameTouchs[this._touchIndex].touchPoint = evt.touchPointID; + this._gameTouchs[this._touchIndex].touchDown = evt.touchDown; + this._gameTouchs[this._touchIndex].x = evt.stageX; + this._gameTouchs[this._touchIndex].y = evt.stageY; + if (this._touchIndex == 0) { + this.setpreviousTouchState(this._gameTouchs[0]); + } + this._touchIndex++; + this._totalTouchCount++; + } + }; + Input.touchMove = function (evt) { + if (evt.touchPointID == this._gameTouchs[0].touchPoint) { + this.setpreviousTouchState(this._gameTouchs[0]); + } + var touchIndex = this._gameTouchs.findIndex(function (touch) { return touch.touchPoint == evt.touchPointID; }); + if (touchIndex != -1) { + var touchData = this._gameTouchs[touchIndex]; + touchData.x = evt.stageX; + touchData.y = evt.stageY; + } + }; + Input.touchEnd = function (evt) { + var touchIndex = this._gameTouchs.findIndex(function (touch) { return touch.touchPoint == evt.touchPointID; }); + if (touchIndex != -1) { + var touchData = this._gameTouchs[touchIndex]; + touchData.reset(); + if (touchIndex == 0) + this._previousTouchState.reset(); + this._totalTouchCount--; + if (this.totalTouchCount == 0) { + this._touchIndex = 0; + } + } + }; + Input.setpreviousTouchState = function (touchState) { + this._previousTouchState = new TouchState(); + this._previousTouchState.x = touchState.position.x; + this._previousTouchState.y = touchState.position.y; + this._previousTouchState.touchPoint = touchState.touchPoint; + this._previousTouchState.touchDown = touchState.touchDown; + }; + Input._init = false; + Input._previousTouchState = new TouchState(); + Input._resolutionOffset = new es.Vector2(); + Input._touchIndex = 0; + Input._gameTouchs = []; + Input._resolutionScale = es.Vector2.one; + Input._totalTouchCount = 0; + return Input; + }()); + es.Input = Input; +})(es || (es = {})); +var KeyboardUtils = (function () { + function KeyboardUtils() { + } + KeyboardUtils.init = function () { + this.keyDownDict = {}; + this.keyUpDict = {}; + document.addEventListener("keydown", this.onKeyDonwHander); + document.addEventListener("keyup", this.onKeyUpHander); + }; + KeyboardUtils.registerKey = function (key, fun, thisObj, type) { + if (type === void 0) { type = 0; } + var args = []; + for (var _i = 4; _i < arguments.length; _i++) { + args[_i - 4] = arguments[_i]; + } + var keyDict = type ? this.keyUpDict : this.keyDownDict; + keyDict[key] = { "fun": fun, args: args, "thisObj": thisObj }; + }; + KeyboardUtils.unregisterKey = function (key, type) { + if (type === void 0) { type = 0; } + var keyDict = type ? this.keyUpDict : this.keyDownDict; + delete keyDict[key]; + }; + KeyboardUtils.destroy = function () { + this.keyDownDict = null; + this.keyUpDict = null; + document.removeEventListener("keydown", this.onKeyDonwHander); + document.removeEventListener("keyup", this.onKeyUpHander); + }; + KeyboardUtils.onKeyDonwHander = function (event) { + if (!this.keyDownDict) + return; + var key = this.keyCodeToString(event.keyCode); + var o = this.keyDownDict[key]; + if (o) { + var fun = o["fun"]; + var thisObj = o["thisObj"]; + var args = o["args"]; + fun.apply(thisObj, args); + } + }; + KeyboardUtils.onKeyUpHander = function (event) { + if (!this.keyUpDict) + return; + var key = this.keyCodeToString(event.keyCode); + var o = this.keyUpDict[key]; + if (o) { + var fun = o["fun"]; + var thisObj = o["thisObj"]; + var args = o["args"]; + fun.apply(thisObj, args); + } + }; + KeyboardUtils.keyCodeToString = function (keyCode) { + switch (keyCode) { + case 8: + return this.BACK_SPACE; + case 9: + return this.TAB; + case 13: + return this.ENTER; + case 16: + return this.SHIFT; + case 17: + return this.CTRL; + case 19: + return this.PAUSE_BREAK; + case 20: + return this.CAPS_LOCK; + case 27: + return this.ESC; + case 32: + return this.SPACE; + case 33: + return this.PAGE_UP; + case 34: + return this.PAGE_DOWN; + case 35: + return this.END; + case 36: + return this.HOME; + case 37: + return this.LEFT; + case 38: + return this.UP; + case 39: + return this.RIGHT; + case 40: + return this.DOWN; + case 45: + return this.INSERT; + case 46: + return this.DELETE; + case 91: + return this.WINDOWS; + case 112: + return this.F1; + case 113: + return this.F2; + case 114: + return this.F3; + case 115: + return this.F4; + case 116: + return this.F5; + case 117: + return this.F6; + case 118: + return this.F7; + case 119: + return this.F8; + case 120: + return this.F9; + case 122: + return this.F11; + case 123: + return this.F12; + case 144: + return this.NUM_LOCK; + case 145: + return this.SCROLL_LOCK; + default: + return String.fromCharCode(keyCode); + } + }; + KeyboardUtils.TYPE_KEY_DOWN = 0; + KeyboardUtils.TYPE_KEY_UP = 1; + KeyboardUtils.A = "A"; + KeyboardUtils.B = "B"; + KeyboardUtils.C = "C"; + KeyboardUtils.D = "D"; + KeyboardUtils.E = "E"; + KeyboardUtils.F = "F"; + KeyboardUtils.G = "G"; + KeyboardUtils.H = "H"; + KeyboardUtils.I = "I"; + KeyboardUtils.J = "J"; + KeyboardUtils.K = "K"; + KeyboardUtils.L = "L"; + KeyboardUtils.M = "M"; + KeyboardUtils.N = "N"; + KeyboardUtils.O = "O"; + KeyboardUtils.P = "P"; + KeyboardUtils.Q = "Q"; + KeyboardUtils.R = "R"; + KeyboardUtils.S = "S"; + KeyboardUtils.T = "T"; + KeyboardUtils.U = "U"; + KeyboardUtils.V = "V"; + KeyboardUtils.W = "W"; + KeyboardUtils.X = "X"; + KeyboardUtils.Y = "Y"; + KeyboardUtils.Z = "Z"; + KeyboardUtils.ESC = "Esc"; + KeyboardUtils.F1 = "F1"; + KeyboardUtils.F2 = "F2"; + KeyboardUtils.F3 = "F3"; + KeyboardUtils.F4 = "F4"; + KeyboardUtils.F5 = "F5"; + KeyboardUtils.F6 = "F6"; + KeyboardUtils.F7 = "F7"; + KeyboardUtils.F8 = "F8"; + KeyboardUtils.F9 = "F9"; + KeyboardUtils.F10 = "F10"; + KeyboardUtils.F11 = "F11"; + KeyboardUtils.F12 = "F12"; + KeyboardUtils.NUM_1 = "1"; + KeyboardUtils.NUM_2 = "2"; + KeyboardUtils.NUM_3 = "3"; + KeyboardUtils.NUM_4 = "4"; + KeyboardUtils.NUM_5 = "5"; + KeyboardUtils.NUM_6 = "6"; + KeyboardUtils.NUM_7 = "7"; + KeyboardUtils.NUM_8 = "8"; + KeyboardUtils.NUM_9 = "9"; + KeyboardUtils.NUM_0 = "0"; + KeyboardUtils.TAB = "Tab"; + KeyboardUtils.CTRL = "Ctrl"; + KeyboardUtils.ALT = "Alt"; + KeyboardUtils.SHIFT = "Shift"; + KeyboardUtils.CAPS_LOCK = "Caps Lock"; + KeyboardUtils.ENTER = "Enter"; + KeyboardUtils.SPACE = "Space"; + KeyboardUtils.BACK_SPACE = "Back Space"; + KeyboardUtils.INSERT = "Insert"; + KeyboardUtils.DELETE = "Page Down"; + KeyboardUtils.HOME = "Home"; + KeyboardUtils.END = "Page Down"; + KeyboardUtils.PAGE_UP = "Page Up"; + KeyboardUtils.PAGE_DOWN = "Page Down"; + KeyboardUtils.LEFT = "Left"; + KeyboardUtils.RIGHT = "Right"; + KeyboardUtils.UP = "Up"; + KeyboardUtils.DOWN = "Down"; + KeyboardUtils.PAUSE_BREAK = "Pause Break"; + KeyboardUtils.NUM_LOCK = "Num Lock"; + KeyboardUtils.SCROLL_LOCK = "Scroll Lock"; + KeyboardUtils.WINDOWS = "Windows"; + return KeyboardUtils; +}()); +var es; +(function (es) { + var ListPool = (function () { + function ListPool() { + } + ListPool.warmCache = function (cacheCount) { + cacheCount -= this._objectQueue.length; + if (cacheCount > 0) { + for (var i = 0; i < cacheCount; i++) { + this._objectQueue.unshift([]); + } + } + }; + ListPool.trimCache = function (cacheCount) { + while (cacheCount > this._objectQueue.length) + this._objectQueue.shift(); + }; + ListPool.clearCache = function () { + this._objectQueue.length = 0; + }; + ListPool.obtain = function () { + if (this._objectQueue.length > 0) + return this._objectQueue.shift(); + return []; + }; + ListPool.free = function (obj) { + this._objectQueue.unshift(obj); + obj.length = 0; + }; + ListPool._objectQueue = []; + return ListPool; + }()); + es.ListPool = ListPool; +})(es || (es = {})); +var THREAD_ID = Math.floor(Math.random() * 1000) + "-" + Date.now(); +var nextTick = function (fn) { + setTimeout(fn, 0); +}; +var LockUtils = (function () { + function LockUtils(key) { + this._keyX = "mutex_key_" + key + "_X"; + this._keyY = "mutex_key_" + key + "_Y"; + this.setItem = egret.localStorage.setItem.bind(localStorage); + this.getItem = egret.localStorage.getItem.bind(localStorage); + this.removeItem = egret.localStorage.removeItem.bind(localStorage); + } + LockUtils.prototype.lock = function () { + var _this = this; + return new Promise(function (resolve, reject) { + var fn = function () { + _this.setItem(_this._keyX, THREAD_ID); + if (!_this.getItem(_this._keyY) === null) { + nextTick(fn); + } + _this.setItem(_this._keyY, THREAD_ID); + if (_this.getItem(_this._keyX) !== THREAD_ID) { + setTimeout(function () { + if (_this.getItem(_this._keyY) !== THREAD_ID) { + nextTick(fn); + return; + } + resolve(); + _this.removeItem(_this._keyY); + }, 10); + } + else { + resolve(); + _this.removeItem(_this._keyY); + } + }; + fn(); + }); + }; + return LockUtils; +}()); +var es; +(function (es) { + var Pair = (function () { + function Pair(first, second) { + this.first = first; + this.second = second; + } + Pair.prototype.clear = function () { + this.first = this.second = null; + }; + Pair.prototype.equals = function (other) { + return this.first == other.first && this.second == other.second; + }; + return Pair; + }()); + es.Pair = Pair; +})(es || (es = {})); +var RandomUtils = (function () { + function RandomUtils() { + } + RandomUtils.randrange = function (start, stop, step) { + if (step === void 0) { step = 1; } + if (step == 0) + throw new Error('step 不能为 0'); + var width = stop - start; + if (width == 0) + throw new Error('没有可用的范围(' + start + ',' + stop + ')'); + if (width < 0) + width = start - stop; + var n = Math.floor((width + step - 1) / step); + return Math.floor(this.random() * n) * step + Math.min(start, stop); + }; + RandomUtils.randint = function (a, b) { + a = Math.floor(a); + b = Math.floor(b); + if (a > b) + a++; + else + b++; + return this.randrange(a, b); + }; + RandomUtils.randnum = function (a, b) { + return this.random() * (b - a) + a; + }; + RandomUtils.shuffle = function (array) { + array.sort(this._randomCompare); + return array; + }; + RandomUtils.choice = function (sequence) { + if (!sequence.hasOwnProperty("length")) + throw new Error('无法对此对象执行此操作'); + var index = Math.floor(this.random() * sequence.length); + if (sequence instanceof String) + return String(sequence).charAt(index); + else + return sequence[index]; + }; + RandomUtils.sample = function (sequence, num) { + var len = sequence.length; + if (num <= 0 || len < num) + throw new Error("采样数量不够"); + var selected = []; + var indices = []; + for (var i = 0; i < num; i++) { + var index = Math.floor(this.random() * len); + while (indices.indexOf(index) >= 0) + index = Math.floor(this.random() * len); + selected.push(sequence[index]); + indices.push(index); + } + return selected; + }; + RandomUtils.random = function () { + return Math.random(); + }; + RandomUtils.boolean = function (chance) { + if (chance === void 0) { chance = .5; } + return (this.random() < chance) ? true : false; + }; + RandomUtils._randomCompare = function (a, b) { + return (this.random() > .5) ? 1 : -1; + }; + return RandomUtils; +}()); +var es; +(function (es) { + var RectangleExt = (function () { + function RectangleExt() { + } + RectangleExt.union = function (first, point) { + var rect = new es.Rectangle(point.x, point.y, 0, 0); + var result = new es.Rectangle(); + result.x = Math.min(first.x, rect.x); + result.y = Math.min(first.y, rect.y); + result.width = Math.max(first.right, rect.right) - result.x; + result.height = Math.max(first.bottom, result.bottom) - result.y; + return result; + }; + return RectangleExt; + }()); + es.RectangleExt = RectangleExt; +})(es || (es = {})); +var es; +(function (es) { + var Triangulator = (function () { + function Triangulator() { + this.triangleIndices = []; + this._triPrev = new Array(12); + this._triNext = new Array(12); + } + Triangulator.testPointTriangle = function (point, a, b, c) { + if (es.Vector2Ext.cross(es.Vector2.subtract(point, a), es.Vector2.subtract(b, a)) < 0) + return false; + if (es.Vector2Ext.cross(es.Vector2.subtract(point, b), es.Vector2.subtract(c, b)) < 0) + return false; + if (es.Vector2Ext.cross(es.Vector2.subtract(point, c), es.Vector2.subtract(a, c)) < 0) + return false; + return true; + }; + Triangulator.prototype.triangulate = function (points, arePointsCCW) { + if (arePointsCCW === void 0) { arePointsCCW = true; } + var count = points.length; + this.initialize(count); + var iterations = 0; + var index = 0; + while (count > 3 && iterations < 500) { + iterations++; + var isEar = true; + var a = points[this._triPrev[index]]; + var b = points[index]; + var c = points[this._triNext[index]]; + if (es.Vector2Ext.isTriangleCCW(a, b, c)) { + var k = this._triNext[this._triNext[index]]; + do { + if (Triangulator.testPointTriangle(points[k], a, b, c)) { + isEar = false; + break; + } + k = this._triNext[k]; + } while (k != this._triPrev[index]); + } + else { + isEar = false; + } + if (isEar) { + this.triangleIndices.push(this._triPrev[index]); + this.triangleIndices.push(index); + this.triangleIndices.push(this._triNext[index]); + this._triNext[this._triPrev[index]] = this._triNext[index]; + this._triPrev[this._triNext[index]] = this._triPrev[index]; + count--; + index = this._triPrev[index]; + } + else { + index = this._triNext[index]; + } + } + this.triangleIndices.push(this._triPrev[index]); + this.triangleIndices.push(index); + this.triangleIndices.push(this._triNext[index]); + if (!arePointsCCW) + this.triangleIndices.reverse(); + }; + Triangulator.prototype.initialize = function (count) { + this.triangleIndices.length = 0; + if (this._triNext.length < count) { + this._triNext.reverse(); + this._triNext = new Array(Math.max(this._triNext.length * 2, count)); + } + if (this._triPrev.length < count) { + this._triPrev.reverse(); + this._triPrev = new Array(Math.max(this._triPrev.length * 2, count)); + } + for (var i = 0; i < count; i++) { + this._triPrev[i] = i - 1; + this._triNext[i] = i + 1; + } + this._triPrev[0] = count - 1; + this._triNext[count - 1] = 0; + }; + return Triangulator; + }()); + es.Triangulator = Triangulator; +})(es || (es = {})); +var es; +(function (es) { + var Vector2Ext = (function () { + function Vector2Ext() { + } + Vector2Ext.isTriangleCCW = function (a, center, c) { + return this.cross(es.Vector2.subtract(center, a), es.Vector2.subtract(c, center)) < 0; + }; + Vector2Ext.cross = function (u, v) { + return u.y * v.x - u.x * v.y; + }; + Vector2Ext.perpendicular = function (first, second) { + return new es.Vector2(-1 * (second.y - first.y), second.x - first.x); + }; + Vector2Ext.normalize = function (vec) { + var magnitude = Math.sqrt((vec.x * vec.x) + (vec.y * vec.y)); + if (magnitude > es.MathHelper.Epsilon) { + vec = es.Vector2.divide(vec, new es.Vector2(magnitude)); + } + else { + vec.x = vec.y = 0; + } + return vec; + }; + Vector2Ext.transformA = function (sourceArray, sourceIndex, matrix, destinationArray, destinationIndex, length) { + for (var i = 0; i < length; i++) { + var position = sourceArray[sourceIndex + i]; + var destination = destinationArray[destinationIndex + i]; + destination.x = (position.x * matrix.m11) + (position.y * matrix.m21) + matrix.m31; + destination.y = (position.x * matrix.m12) + (position.y * matrix.m22) + matrix.m32; + destinationArray[destinationIndex + i] = destination; + } + }; + Vector2Ext.transformR = function (position, matrix) { + var x = (position.x * matrix.m11) + (position.y * matrix.m21) + matrix.m31; + var y = (position.x * matrix.m12) + (position.y * matrix.m22) + matrix.m32; + return new es.Vector2(x, y); + }; + Vector2Ext.transform = function (sourceArray, matrix, destinationArray) { + this.transformA(sourceArray, 0, matrix, destinationArray, 0, sourceArray.length); + }; + Vector2Ext.round = function (vec) { + return new es.Vector2(Math.round(vec.x), Math.round(vec.y)); + }; + return Vector2Ext; + }()); + es.Vector2Ext = Vector2Ext; +})(es || (es = {})); +var WebGLUtils = (function () { + function WebGLUtils() { + } + WebGLUtils.getContext = function () { + var canvas = document.getElementsByTagName('canvas')[0]; + return canvas.getContext('2d'); + }; + return WebGLUtils; +}()); +var es; +(function (es) { + var Layout = (function () { + function Layout() { + this.clientArea = new es.Rectangle(0, 0, es.Core.graphicsDevice.viewport.width, es.Core.graphicsDevice.viewport.height); + this.safeArea = this.clientArea; + } + Layout.prototype.place = function (size, horizontalMargin, verticalMargine, alignment) { + var rc = new es.Rectangle(0, 0, size.x, size.y); + if ((alignment & Alignment.left) != 0) { + rc.x = this.clientArea.x + (this.clientArea.width * horizontalMargin); + } + else if ((alignment & Alignment.right) != 0) { + rc.x = this.clientArea.x + (this.clientArea.width * (1 - horizontalMargin)) - rc.width; + } + else if ((alignment & Alignment.horizontalCenter) != 0) { + rc.x = this.clientArea.x + (this.clientArea.width - rc.width) / 2 + (horizontalMargin * this.clientArea.width); + } + else { + } + if ((alignment & Alignment.top) != 0) { + rc.y = this.clientArea.y + (this.clientArea.height * verticalMargine); + } + else if ((alignment & Alignment.bottom) != 0) { + rc.y = this.clientArea.y + (this.clientArea.height * (1 - verticalMargine)) - rc.height; + } + else if ((alignment & Alignment.verticalCenter) != 0) { + rc.y = this.clientArea.y + (this.clientArea.height - rc.height) / 2 + (verticalMargine * this.clientArea.height); + } + else { + } + if (rc.left < this.safeArea.left) + rc.x = this.safeArea.left; + if (rc.right > this.safeArea.right) + rc.x = this.safeArea.right - rc.width; + if (rc.top < this.safeArea.top) + rc.y = this.safeArea.top; + if (rc.bottom > this.safeArea.bottom) + rc.y = this.safeArea.bottom - rc.height; + return rc; + }; + return Layout; + }()); + es.Layout = Layout; + var Alignment; + (function (Alignment) { + Alignment[Alignment["none"] = 0] = "none"; + Alignment[Alignment["left"] = 1] = "left"; + Alignment[Alignment["right"] = 2] = "right"; + Alignment[Alignment["horizontalCenter"] = 4] = "horizontalCenter"; + Alignment[Alignment["top"] = 8] = "top"; + Alignment[Alignment["bottom"] = 16] = "bottom"; + Alignment[Alignment["verticalCenter"] = 32] = "verticalCenter"; + Alignment[Alignment["topLeft"] = 9] = "topLeft"; + Alignment[Alignment["topRight"] = 10] = "topRight"; + Alignment[Alignment["topCenter"] = 12] = "topCenter"; + Alignment[Alignment["bottomLeft"] = 17] = "bottomLeft"; + Alignment[Alignment["bottomRight"] = 18] = "bottomRight"; + Alignment[Alignment["bottomCenter"] = 20] = "bottomCenter"; + Alignment[Alignment["centerLeft"] = 33] = "centerLeft"; + Alignment[Alignment["centerRight"] = 34] = "centerRight"; + Alignment[Alignment["center"] = 36] = "center"; + })(Alignment = es.Alignment || (es.Alignment = {})); +})(es || (es = {})); +var stopwatch; +(function (stopwatch) { + var Stopwatch = (function () { + function Stopwatch(getSystemTime) { + if (getSystemTime === void 0) { getSystemTime = _defaultSystemTimeGetter; } + this.getSystemTime = getSystemTime; + this._stopDuration = 0; + this._completeSlices = []; + } + Stopwatch.prototype.getState = function () { + if (this._startSystemTime === undefined) { + return State.IDLE; + } + else if (this._stopSystemTime === undefined) { + return State.RUNNING; + } + else { + return State.STOPPED; + } + }; + Stopwatch.prototype.isIdle = function () { + return this.getState() === State.IDLE; + }; + Stopwatch.prototype.isRunning = function () { + return this.getState() === State.RUNNING; + }; + Stopwatch.prototype.isStopped = function () { + return this.getState() === State.STOPPED; + }; + Stopwatch.prototype.slice = function () { + return this.recordPendingSlice(); + }; + Stopwatch.prototype.getCompletedSlices = function () { + return Array.from(this._completeSlices); + }; + Stopwatch.prototype.getCompletedAndPendingSlices = function () { + return this._completeSlices.concat([this.getPendingSlice()]); + }; + Stopwatch.prototype.getPendingSlice = function () { + return this.calculatePendingSlice(); + }; + Stopwatch.prototype.getTime = function () { + return this.caculateStopwatchTime(); + }; + Stopwatch.prototype.reset = function () { + this._startSystemTime = this._pendingSliceStartStopwatchTime = this._stopSystemTime = undefined; + this._stopDuration = 0; + this._completeSlices = []; + }; + Stopwatch.prototype.start = function (forceReset) { + if (forceReset === void 0) { forceReset = false; } + if (forceReset) { + this.reset(); + } + if (this._stopSystemTime !== undefined) { + var systemNow = this.getSystemTime(); + var stopDuration = systemNow - this._stopSystemTime; + this._stopDuration += stopDuration; + this._stopSystemTime = undefined; + } + else if (this._startSystemTime === undefined) { + var systemNow = this.getSystemTime(); + this._startSystemTime = systemNow; + this._pendingSliceStartStopwatchTime = 0; + } + }; + Stopwatch.prototype.stop = function (recordPendingSlice) { + if (recordPendingSlice === void 0) { recordPendingSlice = false; } + if (this._startSystemTime === undefined) { + return 0; + } + var systemTimeOfStopwatchTime = this.getSystemTimeOfCurrentStopwatchTime(); + if (recordPendingSlice) { + this.recordPendingSlice(this.caculateStopwatchTime(systemTimeOfStopwatchTime)); + } + this._stopSystemTime = systemTimeOfStopwatchTime; + return this.getTime(); + }; + Stopwatch.prototype.calculatePendingSlice = function (endStopwatchTime) { + if (this._pendingSliceStartStopwatchTime === undefined) { + return Object.freeze({ startTime: 0, endTime: 0, duration: 0 }); + } + if (endStopwatchTime === undefined) { + endStopwatchTime = this.getTime(); + } + return Object.freeze({ + startTime: this._pendingSliceStartStopwatchTime, + endTime: endStopwatchTime, + duration: endStopwatchTime - this._pendingSliceStartStopwatchTime + }); + }; + Stopwatch.prototype.caculateStopwatchTime = function (endSystemTime) { + if (this._startSystemTime === undefined) + return 0; + if (endSystemTime === undefined) + endSystemTime = this.getSystemTimeOfCurrentStopwatchTime(); + return endSystemTime - this._startSystemTime - this._stopDuration; + }; + Stopwatch.prototype.getSystemTimeOfCurrentStopwatchTime = function () { + return this._stopSystemTime === undefined ? this.getSystemTime() : this._stopSystemTime; + }; + Stopwatch.prototype.recordPendingSlice = function (endStopwatchTime) { + if (this._pendingSliceStartStopwatchTime !== undefined) { + if (endStopwatchTime === undefined) { + endStopwatchTime = this.getTime(); + } + var slice = this.calculatePendingSlice(endStopwatchTime); + this._pendingSliceStartStopwatchTime = slice.endTime; + this._completeSlices.push(slice); + return slice; + } + else { + return this.calculatePendingSlice(); + } + }; + return Stopwatch; + }()); + stopwatch.Stopwatch = Stopwatch; + var State; + (function (State) { + State["IDLE"] = "IDLE"; + State["RUNNING"] = "RUNNING"; + State["STOPPED"] = "STOPPED"; + })(State || (State = {})); + function setDefaultSystemTimeGetter(systemTimeGetter) { + if (systemTimeGetter === void 0) { systemTimeGetter = Date.now; } + _defaultSystemTimeGetter = systemTimeGetter; + } + stopwatch.setDefaultSystemTimeGetter = setDefaultSystemTimeGetter; + var _defaultSystemTimeGetter = Date.now; +})(stopwatch || (stopwatch = {})); +var es; +(function (es) { + var TimeRuler = (function () { + function TimeRuler() { + this.showLog = false; + this._frameKey = 'frame'; + this._logKey = 'log'; + this.markers = []; + this.stopwacth = new stopwatch.Stopwatch(); + this._markerNameToIdMap = new Map(); + this._logs = new Array(2); + for (var i = 0; i < this._logs.length; ++i) + this._logs[i] = new FrameLog(); + this.sampleFrames = this.targetSampleFrames = 1; + this.width = es.Core.graphicsDevice.viewport.width * 0.8; + es.Core.emitter.addObserver(es.CoreEvents.GraphicsDeviceReset, this.onGraphicsDeviceReset, this); + this.onGraphicsDeviceReset(); + } + Object.defineProperty(TimeRuler, "Instance", { + get: function () { + if (!this._instance) + this._instance = new TimeRuler(); + return this._instance; + }, + enumerable: true, + configurable: true + }); + TimeRuler.prototype.startFrame = function () { + var _this = this; + var lock = new LockUtils(this._frameKey); + lock.lock().then(function () { + _this._updateCount = parseInt(egret.localStorage.getItem(_this._frameKey), 10); + if (isNaN(_this._updateCount)) + _this._updateCount = 0; + var count = _this._updateCount; + count += 1; + egret.localStorage.setItem(_this._frameKey, count.toString()); + if (_this.enabled && (1 < count && count < TimeRuler.maxSampleFrames)) + return; + _this._prevLog = _this._logs[_this.frameCount++ & 0x1]; + _this._curLog = _this._logs[_this.frameCount & 0x1]; + var endFrameTime = _this.stopwacth.getTime(); + for (var barIndex = 0; barIndex < _this._prevLog.bars.length; ++barIndex) { + var prevBar = _this._prevLog.bars[barIndex]; + var nextBar = _this._curLog.bars[barIndex]; + for (var nest = 0; nest < prevBar.nestCount; ++nest) { + var markerIdx = prevBar.markerNests[nest]; + prevBar.markers[markerIdx].endTime = endFrameTime; + nextBar.markerNests[nest] = nest; + nextBar.markers[nest].markerId = prevBar.markers[markerIdx].markerId; + nextBar.markers[nest].beginTime = 0; + nextBar.markers[nest].endTime = -1; + nextBar.markers[nest].color = prevBar.markers[markerIdx].color; + } + for (var markerIdx = 0; markerIdx < prevBar.markCount; ++markerIdx) { + var duration = prevBar.markers[markerIdx].endTime - prevBar.markers[markerIdx].beginTime; + var markerId = prevBar.markers[markerIdx].markerId; + var m = _this.markers[markerId]; + m.logs[barIndex].color = prevBar.markers[markerIdx].color; + if (!m.logs[barIndex].initialized) { + m.logs[barIndex].min = duration; + m.logs[barIndex].max = duration; + m.logs[barIndex].avg = duration; + m.logs[barIndex].initialized = true; + } + else { + m.logs[barIndex].min = Math.min(m.logs[barIndex].min, duration); + m.logs[barIndex].max = Math.min(m.logs[barIndex].max, duration); + m.logs[barIndex].avg += duration; + m.logs[barIndex].avg *= 0.5; + if (m.logs[barIndex].samples++ >= TimeRuler.logSnapDuration) { + m.logs[barIndex].snapMin = m.logs[barIndex].min; + m.logs[barIndex].snapMax = m.logs[barIndex].max; + m.logs[barIndex].snapAvg = m.logs[barIndex].avg; + m.logs[barIndex].samples = 0; + } + } + } + nextBar.markCount = prevBar.nestCount; + nextBar.nestCount = prevBar.nestCount; + } + _this.stopwacth.reset(); + _this.stopwacth.start(); + }); + }; + TimeRuler.prototype.beginMark = function (markerName, color, barIndex) { + var _this = this; + if (barIndex === void 0) { barIndex = 0; } + var lock = new LockUtils(this._frameKey); + lock.lock().then(function () { + if (barIndex < 0 || barIndex >= TimeRuler.maxBars) + throw new Error("barIndex argument out of range"); + var bar = _this._curLog.bars[barIndex]; + if (bar.markCount >= TimeRuler.maxSamples) { + throw new Error("exceeded sample count. either set larger number to timeruler.maxsaple or lower sample count"); + } + if (bar.nestCount >= TimeRuler.maxNestCall) { + throw new Error("exceeded nest count. either set larger number to timeruler.maxnestcall or lower nest calls"); + } + var markerId = _this._markerNameToIdMap.get(markerName); + if (isNaN(markerId)) { + markerId = _this.markers.length; + _this._markerNameToIdMap.set(markerName, markerId); + } + bar.markerNests[bar.nestCount++] = bar.markCount; + bar.markers[bar.markCount].markerId = markerId; + bar.markers[bar.markCount].color = color; + bar.markers[bar.markCount].beginTime = _this.stopwacth.getTime(); + bar.markers[bar.markCount].endTime = -1; + }); + }; + TimeRuler.prototype.endMark = function (markerName, barIndex) { + var _this = this; + if (barIndex === void 0) { barIndex = 0; } + var lock = new LockUtils(this._frameKey); + lock.lock().then(function () { + if (barIndex < 0 || barIndex >= TimeRuler.maxBars) + throw new Error("barIndex argument out of range"); + var bar = _this._curLog.bars[barIndex]; + if (bar.nestCount <= 0) { + throw new Error("call beginMark method before calling endMark method"); + } + var markerId = _this._markerNameToIdMap.get(markerName); + if (isNaN(markerId)) { + throw new Error("Marker " + markerName + " is not registered. Make sure you specifed same name as you used for beginMark method"); + } + var markerIdx = bar.markerNests[--bar.nestCount]; + if (bar.markers[markerIdx].markerId != markerId) { + throw new Error("Incorrect call order of beginMark/endMark method. beginMark(A), beginMark(B), endMark(B), endMark(A) But you can't called it like beginMark(A), beginMark(B), endMark(A), endMark(B)."); + } + bar.markers[markerIdx].endTime = _this.stopwacth.getTime(); + }); + }; + TimeRuler.prototype.getAverageTime = function (barIndex, markerName) { + if (barIndex < 0 || barIndex >= TimeRuler.maxBars) { + throw new Error("barIndex argument out of range"); + } + var result = 0; + var markerId = this._markerNameToIdMap.get(markerName); + if (markerId) { + result = this.markers[markerId].logs[barIndex].avg; + } + return result; + }; + TimeRuler.prototype.resetLog = function () { + var _this = this; + var lock = new LockUtils(this._logKey); + lock.lock().then(function () { + var count = parseInt(egret.localStorage.getItem(_this._logKey), 10); + count += 1; + egret.localStorage.setItem(_this._logKey, count.toString()); + _this.markers.forEach(function (markerInfo) { + for (var i = 0; i < markerInfo.logs.length; ++i) { + markerInfo.logs[i].initialized = false; + markerInfo.logs[i].snapMin = 0; + markerInfo.logs[i].snapMax = 0; + markerInfo.logs[i].snapAvg = 0; + markerInfo.logs[i].min = 0; + markerInfo.logs[i].max = 0; + markerInfo.logs[i].avg = 0; + markerInfo.logs[i].samples = 0; + } + }); + }); + }; + TimeRuler.prototype.render = function (position, width) { + if (position === void 0) { position = this._position; } + if (width === void 0) { width = this.width; } + egret.localStorage.setItem(this._frameKey, "0"); + if (!this.showLog) + return; + var height = 0; + var maxTime = 0; + this._prevLog.bars.forEach(function (bar) { + if (bar.markCount > 0) { + height += TimeRuler.barHeight + TimeRuler.barPadding * 2; + maxTime = Math.max(maxTime, bar.markers[bar.markCount - 1].endTime); + } + }); + var frameSpan = 1 / 60 * 1000; + var sampleSpan = this.sampleFrames * frameSpan; + if (maxTime > sampleSpan) { + this._frameAdjust = Math.max(0, this._frameAdjust) + 1; + } + else { + this._frameAdjust = Math.min(0, this._frameAdjust) - 1; + } + if (Math.max(this._frameAdjust) > TimeRuler.autoAdjustDelay) { + this.sampleFrames = Math.min(TimeRuler.maxSampleFrames, this.sampleFrames); + this.sampleFrames = Math.max(this.targetSampleFrames, (maxTime / frameSpan) + 1); + this._frameAdjust = 0; + } + var msToPs = width / sampleSpan; + var startY = position.y - (height - TimeRuler.barHeight); + var y = startY; + }; + TimeRuler.prototype.onGraphicsDeviceReset = function () { + var layout = new es.Layout(); + this._position = layout.place(new es.Vector2(this.width, TimeRuler.barHeight), 0, 0.01, es.Alignment.bottomCenter).location; + }; + TimeRuler.maxBars = 8; + TimeRuler.maxSamples = 256; + TimeRuler.maxNestCall = 32; + TimeRuler.barHeight = 8; + TimeRuler.maxSampleFrames = 4; + TimeRuler.logSnapDuration = 120; + TimeRuler.barPadding = 2; + TimeRuler.autoAdjustDelay = 30; + return TimeRuler; + }()); + es.TimeRuler = TimeRuler; + var FrameLog = (function () { + function FrameLog() { + this.bars = new Array(TimeRuler.maxBars); + this.bars.fill(new MarkerCollection(), 0, TimeRuler.maxBars); + } + return FrameLog; + }()); + es.FrameLog = FrameLog; + var MarkerCollection = (function () { + function MarkerCollection() { + this.markers = new Array(TimeRuler.maxSamples); + this.markCount = 0; + this.markerNests = new Array(TimeRuler.maxNestCall); + this.nestCount = 0; + this.markers.fill(new Marker(), 0, TimeRuler.maxSamples); + this.markerNests.fill(0, 0, TimeRuler.maxNestCall); + } + return MarkerCollection; + }()); + es.MarkerCollection = MarkerCollection; + var Marker = (function () { + function Marker() { + this.markerId = 0; + this.beginTime = 0; + this.endTime = 0; + this.color = 0x000000; + } + return Marker; + }()); + es.Marker = Marker; + var MarkerInfo = (function () { + function MarkerInfo(name) { + this.logs = new Array(TimeRuler.maxBars); + this.name = name; + this.logs.fill(new MarkerLog(), 0, TimeRuler.maxBars); + } + return MarkerInfo; + }()); + es.MarkerInfo = MarkerInfo; + var MarkerLog = (function () { + function MarkerLog() { + this.snapMin = 0; + this.snapMax = 0; + this.snapAvg = 0; + this.min = 0; + this.max = 0; + this.avg = 0; + this.samples = 0; + this.color = 0x000000; + this.initialized = false; + } + return MarkerLog; + }()); + es.MarkerLog = MarkerLog; +})(es || (es = {})); diff --git a/demo/libs/framework/framework.min.js b/demo/libs/framework/framework.min.js index e9723556..e6cf4f42 100644 --- a/demo/libs/framework/framework.min.js +++ b/demo/libs/framework/framework.min.js @@ -1 +1 @@ -window.framework={},window.__extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])};return function(e,n){function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}();var __awaiter=this&&this.__awaiter||function(t,e,n,i){return new(n||(n=Promise))(function(o,r){function s(t){try{c(i.next(t))}catch(t){r(t)}}function a(t){try{c(i.throw(t))}catch(t){r(t)}}function c(t){t.done?o(t.value):new n(function(e){e(t.value)}).then(s,a)}c((i=i.apply(t,e||[])).next())})},__generator=this&&this.__generator||function(t,e){var n,i,o,r,s={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return r={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(r[Symbol.iterator]=function(){return this}),r;function a(r){return function(a){return function(r){if(n)throw new TypeError("Generator is already executing.");for(;s;)try{if(n=1,i&&(o=2&r[0]?i.return:r[0]?i.throw||((o=i.return)&&o.call(i),0):i.next)&&!(o=o.call(i,r[1])).done)return o;switch(i=0,o&&(r=[2&r[0],o.value]),r[0]){case 0:case 1:o=r;break;case 4:return s.label++,{value:r[1],done:!1};case 5:s.label++,i=r[1],r=[0];continue;case 7:r=s.ops.pop(),s.trys.pop();continue;default:if(!(o=(o=s.trys).length>0&&o[o.length-1])&&(6===r[0]||2===r[0])){s=0;continue}if(3===r[0]&&(!o||r[1]>o[0]&&r[1]-1}(this,t)},Array.prototype.firstOrDefault=function(t){return function(t,e){var n=t.findIndex(e);return-1==n?null:t[n]}(this,t)},Array.prototype.find=function(t){return function(t,e){return t.firstOrDefault(e)}(this,t)},Array.prototype.where=function(t){return function(t,e){if("function"==typeof t.reduce)return t.reduce(function(n,i,o){return e.call(arguments[2],i,o,t)&&n.push(i),n},[]);for(var n=[],i=0,o=t.length;i=0&&t.splice(n,1)}while(n>=0)}(this,t)},Array.prototype.remove=function(t){return function(t,e){var n=t.findIndex(function(t){return t===e});return n>=0&&(t.splice(n,1),!0)}(this,t)},Array.prototype.removeAt=function(t){return function(t,e){t.splice(e,1)}(this,t)},Array.prototype.removeRange=function(t,e){return function(t,e,n){t.splice(e,n)}(this,t,e)},Array.prototype.select=function(t){return function(t,e){if("function"==typeof t.reduce)return t.reduce(function(n,i,o){return n.push(e.call(arguments[2],i,o,t)),n},[]);for(var n=[],i=0,o=t.length;ir?1:-1}),t}(this,t,e)},Array.prototype.orderByDescending=function(t,e){return function(t,e,n){return t.sort(function(t,i){var o=e(t),r=e(i);return n?-n(o,r):o0;){if("break"===c())break}return o?this.recontructPath(r,e,n):null},t.hasKey=function(t,e){for(var n,i=t.keys();!(n=i.next()).done;)if(JSON.stringify(n.value)==JSON.stringify(e))return!0;return!1},t.getKey=function(t,e){for(var n,i,o=t.keys(),r=t.values();n=o.next(),i=r.next(),!n.done;)if(JSON.stringify(n.value)==JSON.stringify(e))return i.value;return null},t.recontructPath=function(t,e,n){var i=[],o=n;for(i.push(n);o!=e;)o=this.getKey(t,o),i.push(o);return i.reverse(),i},t}(),AStarNode=function(t){function e(e){var n=t.call(this)||this;return n.data=e,n}return __extends(e,t),e}(PriorityQueueNode),AstarGridGraph=function(){function t(t,e){this.dirs=[new Vector2(1,0),new Vector2(0,-1),new Vector2(-1,0),new Vector2(0,1)],this.walls=[],this.weightedNodes=[],this.defaultWeight=1,this.weightedNodeWeight=5,this._neighbors=new Array(4),this._width=t,this._height=e}return t.prototype.isNodeInBounds=function(t){return 0<=t.x&&t.x0&&this.hasHigherPriority(t,n)?this.cascadeUp(t):this.cascadeDown(t)},t.prototype.cascadeDown=function(t){for(var e,n=t.queueIndex;;){e=t;var i=2*n;if(i>this._numNodes){t.queueIndex=n,this._nodes[n]=t;break}var o=this._nodes[i];this.hasHigherPriority(o,e)&&(e=o);var r=i+1;if(r<=this._numNodes){var s=this._nodes[r];this.hasHigherPriority(s,e)&&(e=s)}if(e==t){t.queueIndex=n,this._nodes[n]=t;break}this._nodes[n]=e;var a=e.queueIndex;e.queueIndex=n,n=a}},t.prototype.cascadeUp=function(t){for(var e=Math.floor(t.queueIndex/2);e>=1;){var n=this._nodes[e];if(this.hasHigherPriority(n,t))break;this.swap(t,n),e=Math.floor(t.queueIndex/2)}},t.prototype.swap=function(t,e){this._nodes[t.queueIndex]=e,this._nodes[e.queueIndex]=t;var n=t.queueIndex;t.queueIndex=e.queueIndex,e.queueIndex=n},t.prototype.hasHigherPriority=function(t,e){return t.priority0;){if("break"===a())break}return o?AStarPathfinder.recontructPath(s,e,n):null},t.hasKey=function(t,e){for(var n,i=t.keys();!(n=i.next()).done;)if(JSON.stringify(n.value)==JSON.stringify(e))return!0;return!1},t}(),UnweightedGraph=function(){function t(){this.edges=new Map}return t.prototype.addEdgesForNode=function(t,e){return this.edges.set(t,e),this},t.prototype.getNeighbors=function(t){return this.edges.get(t)},t}(),Vector2=function(){function t(t,e){this.x=0,this.y=0,this.x=t||0,this.y=e||this.x}return Object.defineProperty(t,"zero",{get:function(){return t.zeroVector2},enumerable:!0,configurable:!0}),Object.defineProperty(t,"one",{get:function(){return t.unitVector2},enumerable:!0,configurable:!0}),Object.defineProperty(t,"unitX",{get:function(){return t.unitXVector},enumerable:!0,configurable:!0}),Object.defineProperty(t,"unitY",{get:function(){return t.unitYVector},enumerable:!0,configurable:!0}),t.add=function(e,n){var i=new t(0,0);return i.x=e.x+n.x,i.y=e.y+n.y,i},t.divide=function(e,n){var i=new t(0,0);return i.x=e.x/n.x,i.y=e.y/n.y,i},t.multiply=function(e,n){var i=new t(0,0);return i.x=e.x*n.x,i.y=e.y*n.y,i},t.subtract=function(e,n){var i=new t(0,0);return i.x=e.x-n.x,i.y=e.y-n.y,i},t.prototype.normalize=function(){var t=1/Math.sqrt(this.x*this.x+this.y*this.y);this.x*=t,this.y*=t},t.prototype.length=function(){return Math.sqrt(this.x*this.x+this.y*this.y)},t.prototype.round=function(){return new t(Math.round(this.x),Math.round(this.y))},t.normalize=function(t){var e=1/Math.sqrt(t.x*t.x+t.y*t.y);return t.x*=e,t.y*=e,t},t.dot=function(t,e){return t.x*e.x+t.y*e.y},t.distanceSquared=function(t,e){var n=t.x-e.x,i=t.y-e.y;return n*n+i*i},t.clamp=function(e,n,i){return new t(MathHelper.clamp(e.x,n.x,i.x),MathHelper.clamp(e.y,n.y,i.y))},t.lerp=function(e,n,i){return new t(MathHelper.lerp(e.x,n.x,i),MathHelper.lerp(e.y,n.y,i))},t.transform=function(e,n){return new t(e.x*n.m11+e.y*n.m21,e.x*n.m12+e.y*n.m22)},t.distance=function(t,e){var n=t.x-e.x,i=t.y-e.y;return Math.sqrt(n*n+i*i)},t.negate=function(e){var n=new t;return n.x=-e.x,n.y=-e.y,n},t.unitYVector=new t(0,1),t.unitXVector=new t(1,0),t.unitVector2=new t(1,1),t.zeroVector2=new t(0,0),t}(),UnweightedGridGraph=function(){function t(e,n,i){void 0===i&&(i=!1),this.walls=[],this._neighbors=new Array(4),this._width=e,this._hegiht=n,this._dirs=i?t.COMPASS_DIRS:t.CARDINAL_DIRS}return t.prototype.isNodeInBounds=function(t){return 0<=t.x&&t.x0;){if("break"===c())break}return o?this.recontructPath(r,e,n):null},t.hasKey=function(t,e){for(var n,i=t.keys();!(n=i.next()).done;)if(JSON.stringify(n.value)==JSON.stringify(e))return!0;return!1},t.getKey=function(t,e){for(var n,i,o=t.keys(),r=t.values();n=o.next(),i=r.next(),!n.done;)if(JSON.stringify(n.value)==JSON.stringify(e))return i.value;return null},t.recontructPath=function(t,e,n){var i=[],o=n;for(i.push(n);o!=e;)o=this.getKey(t,o),i.push(o);return i.reverse(),i},t}(),DebugDefaults=function(){function t(){}return t.verletParticle=14431326,t.verletConstraintEdge=4406838,t}(),Component=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e._enabled=!0,e.updateInterval=1,e}return __extends(e,t),Object.defineProperty(e.prototype,"enabled",{get:function(){return this.entity?this.entity.enabled&&this._enabled:this._enabled},set:function(t){this.setEnabled(t)},enumerable:!0,configurable:!0}),e.prototype.setEnabled=function(t){return this._enabled!=t&&(this._enabled=t,this._enabled?this.onEnabled():this.onDisabled()),this},e.prototype.initialize=function(){},e.prototype.onAddedToEntity=function(){},e.prototype.onRemovedFromEntity=function(){},e.prototype.onEnabled=function(){},e.prototype.onDisabled=function(){},e.prototype.update=function(){},e.prototype.debugRender=function(){},e.prototype.onEntityTransformChanged=function(t){},e.prototype.registerComponent=function(){this.entity.componentBits.set(ComponentTypeManager.getIndexFor(this),!1),this.entity.scene.entityProcessors.onComponentAdded(this.entity)},e.prototype.deregisterComponent=function(){this.entity.componentBits.set(ComponentTypeManager.getIndexFor(this)),this.entity.scene.entityProcessors.onComponentRemoved(this.entity)},e}(egret.DisplayObjectContainer),Entity=function(t){function e(n){var i=t.call(this)||this;return i._updateOrder=0,i._enabled=!0,i._tag=0,i.name=n,i.components=new ComponentList(i),i.id=e._idGenerator++,i.componentBits=new BitSet,i}return __extends(e,t),Object.defineProperty(e.prototype,"isDestoryed",{get:function(){return this._isDestoryed},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"position",{get:function(){return new Vector2(this.x,this.y)},set:function(t){this.$setX(t.x),this.$setY(t.y),this.onEntityTransformChanged(TransformComponent.position)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"scale",{get:function(){return new Vector2(this.scaleX,this.scaleY)},set:function(t){this.$setScaleX(t.x),this.$setScaleY(t.y),this.onEntityTransformChanged(TransformComponent.scale)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"rotation",{set:function(t){this.$setRotation(t),this.onEntityTransformChanged(TransformComponent.rotation)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"enabled",{get:function(){return this._enabled},set:function(t){this.setEnabled(t)},enumerable:!0,configurable:!0}),e.prototype.setEnabled=function(t){return this._enabled!=t&&(this._enabled=t),this},Object.defineProperty(e.prototype,"tag",{get:function(){return this._tag},set:function(t){this.setTag(t)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"stage",{get:function(){return this.scene?this.scene.stage:null},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"updateOrder",{get:function(){return this._updateOrder},set:function(t){this.setUpdateOrder(t)},enumerable:!0,configurable:!0}),e.prototype.roundPosition=function(){this.position=Vector2Ext.round(this.position)},e.prototype.setUpdateOrder=function(t){if(this._updateOrder!=t)return this._updateOrder=t,this.scene,this},e.prototype.setTag=function(t){return this._tag!=t&&(this.scene&&this.scene.entities.removeFromTagList(this),this._tag=t,this.scene&&this.scene.entities.addToTagList(this)),this},e.prototype.attachToScene=function(t){this.scene=t,t.entities.add(this),this.components.registerAllComponents();for(var e=0;e=0;t--){this.getChildAt(t).entity.destroy()}},e}(egret.DisplayObjectContainer);!function(t){t[t.rotation=0]="rotation",t[t.scale=1]="scale",t[t.position=2]="position"}(TransformComponent||(TransformComponent={}));var CameraStyle,Scene=function(t){function e(){var e=t.call(this)||this;return e.enablePostProcessing=!0,e._renderers=[],e._postProcessors=[],e.entityProcessors=new EntityProcessorList,e.renderableComponents=new RenderableComponentList,e.entities=new EntityList(e),e.content=new ContentManager,e.width=SceneManager.stage.stageWidth,e.height=SceneManager.stage.stageHeight,e.addEventListener(egret.Event.ACTIVATE,e.onActive,e),e.addEventListener(egret.Event.DEACTIVATE,e.onDeactive,e),e}return __extends(e,t),e.prototype.createEntity=function(t){var e=new Entity(t);return e.position=new Vector2(0,0),this.addEntity(e)},e.prototype.addEntity=function(t){this.entities.add(t),t.scene=this,this.addChild(t);for(var e=0;e=0;e--)GlobalManager.globalManagers[e].enabled&&GlobalManager.globalManagers[e].update();if(t.sceneTransition&&(!t.sceneTransition||t.sceneTransition.loadsNewScene&&!t.sceneTransition.isNewSceneLoaded)||t._scene.update(),t._nextScene){t._scene.end();for(e=0;et&&(this._zoom=t),this._maximumZoom=t,this},e.prototype.setZoom=function(t){var e=MathHelper.clamp(t,-1,1);return this._zoom=0==e?1:e<0?MathHelper.map(e,-1,0,this._minimumZoom,1):MathHelper.map(e,0,1,1,this._maximumZoom),SceneManager.scene.scaleX=this._zoom,SceneManager.scene.scaleY=this._zoom,this},e.prototype.setRotation=function(t){return SceneManager.scene.rotation=t,this},e.prototype.setPosition=function(t){return this.entity.position=t,this},e.prototype.follow=function(t,e){void 0===e&&(e=CameraStyle.cameraWindow),this.targetEntity=t,this.cameraStyle=e;var n=new Rectangle(0,0,SceneManager.stage.stageWidth,SceneManager.stage.stageHeight);switch(this.cameraStyle){case CameraStyle.cameraWindow:var i=n.width/6,o=n.height/3;this.deadzone=new Rectangle((n.width-i)/2,(n.height-o)/2,i,o);break;case CameraStyle.lockOn:this.deadzone=new Rectangle(n.width/2,n.height/2,10,10)}},e.prototype.update=function(){var t=new Rectangle(0,0,SceneManager.stage.stageWidth,SceneManager.stage.stageHeight),e=Vector2.multiply(new Vector2(t.width,t.height),new Vector2(.5));this._worldSpaceDeadZone.x=this.position.x-e.x+this.deadzone.x+this.focusOffset.x,this._worldSpaceDeadZone.y=this.position.y-e.y+this.deadzone.y+this.focusOffset.y,this._worldSpaceDeadZone.width=this.deadzone.width,this._worldSpaceDeadZone.height=this.deadzone.height,this.targetEntity&&this.updateFollow(),this.position=Vector2.lerp(this.position,Vector2.add(this.position,this._desiredPositionDelta),this.followLerp),this.entity.roundPosition(),this.mapLockEnabled&&(this.position=this.clampToMapSize(this.position),this.entity.roundPosition())},e.prototype.clampToMapSize=function(t){var e=new Rectangle(0,0,SceneManager.stage.stageWidth,SceneManager.stage.stageHeight),n=Vector2.multiply(new Vector2(e.width,e.height),new Vector2(.5)),i=new Vector2(this.mapSize.x-n.x,this.mapSize.y-n.y);return Vector2.clamp(t,n,i)},e.prototype.updateFollow=function(){if(this._desiredPositionDelta.x=this._desiredPositionDelta.y=0,this.cameraStyle==CameraStyle.lockOn){var t=this.targetEntity.position.x,e=this.targetEntity.position.y;this._worldSpaceDeadZone.x>t?this._desiredPositionDelta.x=t-this._worldSpaceDeadZone.x:this._worldSpaceDeadZone.xe&&(this._desiredPositionDelta.y=e-this._worldSpaceDeadZone.y)}else{if(!this._targetCollider&&(this._targetCollider=this.targetEntity.getComponent(Collider),!this._targetCollider))return;var n=this.targetEntity.getComponent(Collider).bounds;this._worldSpaceDeadZone.containsRect(n)||(this._worldSpaceDeadZone.left>n.left?this._desiredPositionDelta.x=n.left-this._worldSpaceDeadZone.left:this._worldSpaceDeadZone.rightn.top&&(this._desiredPositionDelta.y=n.top-this._worldSpaceDeadZone.top))}},e}(Component);!function(t){t[t.lockOn=0]="lockOn",t[t.cameraWindow=1]="cameraWindow"}(CameraStyle||(CameraStyle={}));var LoopMode,State,ComponentPool=function(){function t(t){this._type=t,this._cache=[]}return t.prototype.obtain=function(){try{return this._cache.length>0?this._cache.shift():new this._type}catch(t){throw new Error(this._type+t)}},t.prototype.free=function(t){t.reset(),this._cache.push(t)},t}(),PooledComponent=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return __extends(e,t),e}(Component),RenderableComponent=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e._areBoundsDirty=!0,e._bounds=new Rectangle,e._localOffset=Vector2.zero,e.color=0,e}return __extends(e,t),Object.defineProperty(e.prototype,"width",{get:function(){return this.getWidth()},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"height",{get:function(){return this.getHeight()},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"isVisible",{get:function(){return this._isVisible},set:function(t){this._isVisible=t,this._isVisible?this.onBecameVisible():this.onBecameInvisible()},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"bounds",{get:function(){return new Rectangle(this.getBounds().x,this.getBounds().y,this.getBounds().width,this.getBounds().height)},enumerable:!0,configurable:!0}),e.prototype.getWidth=function(){return this.bounds.width},e.prototype.getHeight=function(){return this.bounds.height},e.prototype.onBecameVisible=function(){},e.prototype.onBecameInvisible=function(){},e.prototype.isVisibleFromCamera=function(t){return this.isVisible=t.getBounds().intersects(this.getBounds()),this.isVisible},e}(PooledComponent),Mesh=function(t){function e(){var e=t.call(this)||this;return e._mesh=new egret.Mesh,e}return __extends(e,t),e.prototype.setTexture=function(t){return this._mesh.texture=t,this},e.prototype.onAddedToEntity=function(){this.addChild(this._mesh)},e.prototype.onRemovedFromEntity=function(){this.removeChild(this._mesh)},e.prototype.render=function(t){this.x=this.entity.position.x-t.position.x+t.origin.x,this.y=this.entity.position.y-t.position.y+t.origin.y},e.prototype.reset=function(){},e}(RenderableComponent),Sprite=function(){return function(t,e,n){void 0===e&&(e=new Rectangle(0,0,t.textureWidth,t.textureHeight)),void 0===n&&(n=e.getHalfSize()),this.uvs=new Rectangle,this.texture2D=t,this.sourceRect=e,this.center=new Vector2(.5*e.width,.5*e.height),this.origin=n;var i=1/t.textureWidth,o=1/t.textureHeight;this.uvs.x=e.x*i,this.uvs.y=e.y*o,this.uvs.width=e.width*i,this.uvs.height=e.height*o}}(),SpriteAnimation=function(){return function(t,e){this.sprites=t,this.frameRate=e}}(),SpriteRenderer=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return __extends(e,t),Object.defineProperty(e.prototype,"sprite",{get:function(){return this._sprite},set:function(t){this.setSprite(t)},enumerable:!0,configurable:!0}),e.prototype.setSprite=function(t){return this.removeChildren(),this._sprite=t,this._sprite&&(this.anchorOffsetX=this._sprite.origin.x/this._sprite.sourceRect.width,this.anchorOffsetY=this._sprite.origin.y/this._sprite.sourceRect.height),this.bitmap=new egret.Bitmap(t.texture2D),this.addChild(this.bitmap),this},e.prototype.setColor=function(t){var e=[1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0];e[0]=Math.floor(t/256/256)/255,e[6]=Math.floor(t/256%256)/255,e[12]=t%256/255;var n=new egret.ColorMatrixFilter(e);return this.filters=[n],this},e.prototype.isVisibleFromCamera=function(t){return this.isVisible=new Rectangle(0,0,this.stage.stageWidth,this.stage.stageHeight).intersects(this.bounds),this.visible=this.isVisible,this.isVisible},e.prototype.render=function(t){this.x=-t.position.x+t.origin.x,this.y=-t.position.y+t.origin.y},e.prototype.onRemovedFromEntity=function(){this.parent&&this.parent.removeChild(this)},e.prototype.reset=function(){},e}(RenderableComponent),SpriteAnimator=function(t){function e(e){var n=t.call(this)||this;return n.speed=1,n.animationState=State.none,n._animations=new Map,n._elapsedTime=0,e&&n.setSprite(e),n}return __extends(e,t),Object.defineProperty(e.prototype,"isRunning",{get:function(){return this.animationState==State.running},enumerable:!0,configurable:!0}),e.prototype.addAnimation=function(t,e){return!this.sprite&&e.sprites.length>0&&this.setSprite(e.sprites[0]),this._animations[t]=e,this},e.prototype.play=function(t,e){void 0===e&&(e=null),this.currentAnimation=this._animations[t],this.currentAnimationName=t,this.currentFrame=0,this.animationState=State.running,this.sprite=this.currentAnimation.sprites[0],this._elapsedTime=0,this._loopMode=e||LoopMode.loop},e.prototype.isAnimationActive=function(t){return this.currentAnimation&&this.currentAnimationName==t},e.prototype.pause=function(){this.animationState=State.paused},e.prototype.unPause=function(){this.animationState=State.running},e.prototype.stop=function(){this.currentAnimation=null,this.currentAnimationName=null,this.currentFrame=0,this.animationState=State.none},e.prototype.update=function(){if(this.animationState==State.running&&this.currentAnimation){var t=this.currentAnimation,e=1/(t.frameRate*this.speed),n=e*t.sprites.length;this._elapsedTime+=Time.deltaTime;var i=Math.abs(this._elapsedTime);if(this._loopMode==LoopMode.once&&i>n||this._loopMode==LoopMode.pingPongOnce&&i>2*n)return this.animationState=State.completed,this._elapsedTime=0,this.currentFrame=0,void(this.sprite=t.sprites[this.currentFrame]);var o=Math.floor(i/e),r=t.sprites.length;if(r>2&&(this._loopMode==LoopMode.pingPong||this._loopMode==LoopMode.pingPongOnce)){var s=r-1;this.currentFrame=s-Math.abs(s-o%(2*s))}else this.currentFrame=o%r;this.sprite=t.sprites[this.currentFrame]}},e}(SpriteRenderer);!function(t){t[t.loop=0]="loop",t[t.once=1]="once",t[t.clampForever=2]="clampForever",t[t.pingPong=3]="pingPong",t[t.pingPongOnce=4]="pingPongOnce"}(LoopMode||(LoopMode={})),function(t){t[t.none=0]="none",t[t.running=1]="running",t[t.paused=2]="paused",t[t.completed=3]="completed"}(State||(State={}));var PointSectors,TiledSpriteRenderer=function(t){function e(e){var n=t.call(this)||this;return n.setSprite(e),n.sourceRect=e.sourceRect,n}return __extends(e,t),Object.defineProperty(e.prototype,"scrollX",{get:function(){return this.sourceRect.x},set:function(t){this.sourceRect.x=t},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"scrollY",{get:function(){return this.sourceRect.y},set:function(t){this.sourceRect.y=t},enumerable:!0,configurable:!0}),e.prototype.render=function(e){if(this.sprite){t.prototype.render.call(this,e);var n=new egret.RenderTexture,i=new egret.Bitmap(this.sprite.texture2D),o=new egret.Rectangle(this.sourceRect.x,this.sourceRect.y,this.sourceRect.width,this.sourceRect.height);n.drawToTexture(i,o),this.bitmap.texture=n}},e}(SpriteRenderer),Mover=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return __extends(e,t),e.prototype.onAddedToEntity=function(){this._triggerHelper=new ColliderTriggerHelper(this.entity)},e.prototype.calculateMovement=function(t){var e=new CollisionResult;if(!this.entity.getComponent(Collider)||!this._triggerHelper)return null;for(var n=this.entity.getComponents(Collider),i=0;i>6;0!=(e&t.LONG_MASK)&&n++,this._bits=new Array(n)}return t.prototype.and=function(t){for(var e,n=Math.min(this._bits.length,t._bits.length),i=0;i=0;)this._bits[e]&=~t._bits[e]},t.prototype.cardinality=function(){for(var t=0,e=this._bits.length-1;e>=0;e--){var n=this._bits[e];if(0!=n)if(-1!=n){var i=((n=((n=(n>>1&0x5555555555555400)+(0x5555555555555400&n))>>2&0x3333333333333400)+(0x3333333333333400&n))>>32)+n;t+=((i=((i=(i>>4&252645135)+(252645135&i))>>8&16711935)+(16711935&i))>>16&65535)+(65535&i)}else t+=64}return t},t.prototype.clear=function(t){if(null!=t){var e=t>>6;this.ensure(e),this._bits[e]&=~(1<=this._bits.length){var e=new Number[t+1];e=this._bits.copyWithin(0,0,this._bits.length),this._bits=e}},t.prototype.get=function(t){var e=t>>6;return!(e>=this._bits.length)&&0!=(this._bits[e]&1<=0;)if(0!=(this._bits[e]&t._bits[e]))return!0;return!1},t.prototype.isEmpty=function(){for(var t=this._bits.length-1;t>=0;t--)if(this._bits[t])return!1;return!0},t.prototype.nextSetBit=function(t){for(var e=t>>6,n=1<>6;this.ensure(n),this._bits[n]|=1<0){for(var t=0;t0){t=0;for(var e=this._componentsToAdd.length;t0){var e=this._entitiesToRemove;this._entitiesToRemove=this._tempEntityList,this._tempEntityList=e,this._tempEntityList.forEach(function(e){t._entities.remove(e),e.scene=null,t.scene.entityProcessors.onEntityRemoved(e)}),this._tempEntityList.length=0}if(this._entitiesToAdded.length>0){e=this._entitiesToAdded;this._entitiesToAdded=this._tempEntityList,this._tempEntityList=e,this._tempEntityList.forEach(function(e){t._entities.contains(e)||(t._entities.push(e),e.scene=t.scene,t.scene.entityProcessors.onEntityAdded(e))}),this._tempEntityList.forEach(function(t){return t.onAddedToScene()}),this._tempEntityList.length=0}this._unsortedTags.length>0&&(this._unsortedTags.forEach(function(e){t._entityDict.get(e).sort()}),this._unsortedTags.length=0)},t}(),EntityProcessorList=function(){function t(){this._processors=[]}return t.prototype.add=function(t){this._processors.push(t)},t.prototype.remove=function(t){this._processors.remove(t)},t.prototype.onComponentAdded=function(t){this.notifyEntityChanged(t)},t.prototype.onComponentRemoved=function(t){this.notifyEntityChanged(t)},t.prototype.onEntityAdded=function(t){this.notifyEntityChanged(t)},t.prototype.onEntityRemoved=function(t){this.removeFromProcessors(t)},t.prototype.notifyEntityChanged=function(t){for(var e=0;e=0;e=this.allSet.nextSetBit(e+1))if(!t.componentBits.get(e))return!1;return!(!this.exclusionSet.isEmpty()&&this.exclusionSet.intersects(t.componentBits))&&!(!this.oneSet.isEmpty()&&!this.oneSet.intersects(t.componentBits))},t.prototype.all=function(){for(var t=this,e=[],n=0;nn?n:t},t.pointOnCirlce=function(e,n,i){var o=t.toRadians(i);return new Vector2(Math.cos(o)*o+e.x,Math.sin(o)*o+e.y)},t.isEven=function(t){return t%2==0},t.Epsilon=1e-5,t.Rad2Deg=57.29578,t.Deg2Rad=.0174532924,t}(),Matrix2D=function(){function t(t,e,n,i,o,r){this.m11=0,this.m12=0,this.m21=0,this.m22=0,this.m31=0,this.m32=0,this.m11=t||1,this.m12=e||0,this.m21=n||0,this.m22=i||1,this.m31=o||0,this.m32=r||0}return Object.defineProperty(t,"identity",{get:function(){return t._identity},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"translation",{get:function(){return new Vector2(this.m31,this.m32)},set:function(t){this.m31=t.x,this.m32=t.y},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"rotation",{get:function(){return Math.atan2(this.m21,this.m11)},set:function(t){var e=Math.cos(t),n=Math.sin(t);this.m11=e,this.m12=n,this.m21=-n,this.m22=e},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"rotationDegrees",{get:function(){return MathHelper.toDegrees(this.rotation)},set:function(t){this.rotation=MathHelper.toRadians(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"scale",{get:function(){return new Vector2(this.m11,this.m22)},set:function(t){this.m11=t.x,this.m12=t.y},enumerable:!0,configurable:!0}),t.add=function(t,e){return t.m11+=e.m11,t.m12+=e.m12,t.m21+=e.m21,t.m22+=e.m22,t.m31+=e.m31,t.m32+=e.m32,t},t.divide=function(t,e){return t.m11/=e.m11,t.m12/=e.m12,t.m21/=e.m21,t.m22/=e.m22,t.m31/=e.m31,t.m32/=e.m32,t},t.multiply=function(e,n){var i=new t,o=e.m11*n.m11+e.m12*n.m21,r=e.m11*n.m12+e.m12*n.m22,s=e.m21*n.m11+e.m22*n.m21,a=e.m21*n.m12+e.m22*n.m22,c=e.m31*n.m11+e.m32*n.m21+n.m31,h=e.m31*n.m12+e.m32*n.m22+n.m32;return i.m11=o,i.m12=r,i.m21=s,i.m22=a,i.m31=c,i.m32=h,i},t.multiplyTranslation=function(e,n,i){var o=t.createTranslation(n,i);return t.multiply(e,o)},t.prototype.determinant=function(){return this.m11*this.m22-this.m12*this.m21},t.invert=function(e,n){void 0===n&&(n=new t);var i=1/e.determinant();return n.m11=e.m22*i,n.m12=-e.m12*i,n.m21=-e.m21*i,n.m22=e.m11*i,n.m31=(e.m32*e.m21-e.m31*e.m22)*i,n.m32=-(e.m32*e.m11-e.m31*e.m12)*i,n},t.createTranslation=function(e,n){var i=new t;return i.m11=1,i.m12=0,i.m21=0,i.m22=1,i.m31=e,i.m32=n,i},t.createTranslationVector=function(t){return this.createTranslation(t.x,t.y)},t.createRotation=function(e,n){n=new t;var i=Math.cos(e),o=Math.sin(e);return n.m11=i,n.m12=o,n.m21=-o,n.m22=i,n},t.createScale=function(e,n,i){return void 0===i&&(i=new t),i.m11=e,i.m12=0,i.m21=0,i.m22=n,i.m31=0,i.m32=0,i},t.prototype.toEgretMatrix=function(){return new egret.Matrix(this.m11,this.m12,this.m21,this.m22,this.m31,this.m32)},t._identity=new t(1,0,0,1,0,0),t}(),Rectangle=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return __extends(e,t),Object.defineProperty(e.prototype,"max",{get:function(){return new Vector2(this.right,this.bottom)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"center",{get:function(){return new Vector2(this.x+this.width/2,this.y+this.height/2)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"location",{get:function(){return new Vector2(this.x,this.y)},set:function(t){this.x=t.x,this.y=t.y},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"size",{get:function(){return new Vector2(this.width,this.height)},set:function(t){this.width=t.x,this.height=t.y},enumerable:!0,configurable:!0}),e.prototype.intersects=function(t){return t.lefti&&(i=s.x),s.yo&&(o=s.y)}return this.fromMinMax(e,n,i,o)},e}(egret.Rectangle),Vector3=function(){return function(t,e,n){this.x=t,this.y=e,this.z=n}}(),ColliderTriggerHelper=function(){function t(t){this._activeTriggerIntersections=[],this._previousTriggerIntersections=[],this._tempTriggerList=[],this._entity=t}return t.prototype.update=function(){for(var t=this._entity.getComponents(Collider),e=0;e1)return!1;var h=(a.x*o.y-a.y*o.x)/s;return!(h<0||h>1)},t.lineToLineIntersection=function(t,e,n,i){var o=new Vector2(0,0),r=Vector2.subtract(e,t),s=Vector2.subtract(i,n),a=r.x*s.y-r.y*s.x;if(0==a)return o;var c=Vector2.subtract(n,t),h=(c.x*s.y-c.y*s.x)/a;if(h<0||h>1)return o;var u=(c.x*r.y-c.y*r.x)/a;return u<0||u>1?o:o=Vector2.add(t,new Vector2(h*r.x,h*r.y))},t.closestPointOnLine=function(t,e,n){var i=Vector2.subtract(e,t),o=Vector2.subtract(n,t),r=Vector2.dot(o,i)/Vector2.dot(i,i);return r=MathHelper.clamp(r,0,1),Vector2.add(t,new Vector2(i.x*r,i.y*r))},t.isCircleToCircle=function(t,e,n,i){return Vector2.distanceSquared(t,n)<(e+i)*(e+i)},t.isCircleToLine=function(t,e,n,i){return Vector2.distanceSquared(t,this.closestPointOnLine(n,i,t))=t&&o.y>=e&&o.x=t+n&&(r|=PointSectors.right),o.y=e+i&&(r|=PointSectors.bottom),r},t}(),Physics=function(){function t(){}return t.reset=function(){this._spatialHash=new SpatialHash(this.spatialHashCellSize)},t.clear=function(){this._spatialHash.clear()},t.overlapCircleAll=function(t,e,n,i){return void 0===i&&(i=-1),this._spatialHash.overlapCircle(t,e,n,i)},t.boxcastBroadphase=function(t,e){void 0===e&&(e=this.allLayers);var n=this._spatialHash.aabbBroadphase(t,null,e);return{colliders:n.tempHashSet,rect:n.bounds}},t.boxcastBroadphaseExcludingSelf=function(t,e,n){return void 0===n&&(n=this.allLayers),this._spatialHash.aabbBroadphase(e,t,n)},t.addCollider=function(e){t._spatialHash.register(e)},t.removeCollider=function(e){t._spatialHash.remove(e)},t.updateCollider=function(t){this._spatialHash.remove(t),this._spatialHash.register(t)},t.spatialHashCellSize=100,t.allLayers=-1,t}(),Shape=function(){return function(){}}(),Polygon=function(t){function e(e,n){var i=t.call(this)||this;return i.isUnrotated=!0,i._areEdgeNormalsDirty=!0,i.setPoints(e),i.isBox=n,i}return __extends(e,t),Object.defineProperty(e.prototype,"edgeNormals",{get:function(){return this._areEdgeNormalsDirty&&this.buildEdgeNormals(),this._edgeNormals},enumerable:!0,configurable:!0}),e.prototype.buildEdgeNormals=function(){var t,e=this.isBox?2:this.points.length;null!=this._edgeNormals&&this._edgeNormals.length==e||(this._edgeNormals=new Array(e));for(var n=0;n=this.points.length?this.points[0]:this.points[n+1];var o=Vector2Ext.perpendicular(i,t);o=Vector2.normalize(o),this._edgeNormals[n]=o}},e.prototype.setPoints=function(t){this.points=t,this.recalculateCenterAndEdgeNormals(),this._originalPoints=[];for(var e=0;et.y!=this.points[i].y>t.y&&t.x<(this.points[i].x-this.points[n].x)*(t.y-this.points[n].y)/(this.points[i].y-this.points[n].y)+this.points[n].x&&(e=!e);return e},e.buildSymmertricalPolygon=function(t,e){for(var n=new Array(t),i=0;i0&&(o=!1),!o)return null;(g=Math.abs(g))i&&(i=o);return{min:n,max:i}},t.circleToPolygon=function(t,e){var n=new CollisionResult,i=Vector2.subtract(t.position,e.position),o=Polygon.getClosestPointOnPolygonToPoint(e.points,i),r=o.closestPoint,s=o.distanceSquared;n.normal=o.edgeNormal;var a,c=e.containsPoint(t.position);if(s>t.radius*t.radius&&!c)return null;if(c)a=Vector2.multiply(n.normal,new Vector2(Math.sqrt(s)-t.radius));else if(0==s)a=Vector2.multiply(n.normal,new Vector2(t.radius));else{var h=Math.sqrt(s);a=Vector2.multiply(new Vector2(-Vector2.subtract(i,r)),new Vector2((t.radius-s)/h))}return n.minimumTranslationVector=a,n.point=Vector2.add(r,e.position),n},t.circleToBox=function(t,e){var n=new CollisionResult,i=e.bounds.getClosestPointOnRectangleBorderToPoint(t.position).res;if(e.containsPoint(t.position)){n.point=i;var o=Vector2.add(i,Vector2.subtract(n.normal,new Vector2(t.radius)));return n.minimumTranslationVector=Vector2.subtract(t.position,o),n}var r=Vector2.distanceSquared(i,t.position);if(0==r)n.minimumTranslationVector=Vector2.multiply(n.normal,new Vector2(t.radius));else if(r<=t.radius*t.radius){n.normal=Vector2.subtract(t.position,i);var s=n.normal.length()-t.radius;return n.normal=Vector2Ext.normalize(n.normal),n.minimumTranslationVector=Vector2.multiply(new Vector2(s),n.normal),n}return null},t.pointToCircle=function(t,e){var n=new CollisionResult,i=Vector2.distanceSquared(t,e.position),o=1+e.radius;if(i=0?t:4294967296+t},t.prototype.add=function(t,e,n){this._store.set(this.getKey(t,e),n)},t.prototype.remove=function(t){this._store.forEach(function(e){e.contains(t)&&e.remove(t)})},t.prototype.tryGetValue=function(t,e){return this._store.get(this.getKey(t,e))},t.prototype.clear=function(){this._store.clear()},t}(),ContentManager=function(){function t(){this.loadedAssets=new Map}return t.prototype.loadRes=function(t,e){var n=this;return void 0===e&&(e=!0),new Promise(function(i,o){var r=n.loadedAssets.get(t);r?i(r):e?RES.getResAsync(t).then(function(e){n.loadedAssets.set(t,e),i(e)}).catch(function(e){console.error("资源加载错误:",t,e),o(e)}):RES.getResByUrl(t).then(function(e){n.loadedAssets.set(t,e),i(e)}).catch(function(e){console.error("资源加载错误:",t,e),o(e)})})},t.prototype.dispose=function(){this.loadedAssets.forEach(function(t){t.dispose()}),this.loadedAssets.clear()},t}(),Emitter=function(){function t(){this._messageTable=new Map}return t.prototype.addObserver=function(t,e){var n=this._messageTable.get(t);n||(n=[],this._messageTable.set(t,n)),n.contains(e)&&console.warn("您试图添加相同的观察者两次"),n.push(e)},t.prototype.removeObserver=function(t,e){this._messageTable.get(t).remove(e)},t.prototype.emit=function(t,e){var n=this._messageTable.get(t);if(n)for(var i=n.length-1;i>=0;i--)n[i](e)},t}(),GlobalManager=function(){function t(){}return Object.defineProperty(t.prototype,"enabled",{get:function(){return this._enabled},set:function(t){this.setEnabled(t)},enumerable:!0,configurable:!0}),t.prototype.setEnabled=function(t){this._enabled!=t&&(this._enabled=t,this._enabled?this.onEnabled():this.onDisabled())},t.prototype.onEnabled=function(){},t.prototype.onDisabled=function(){},t.prototype.update=function(){},t.registerGlobalManager=function(t){this.globalManagers.push(t),t.enabled=!0},t.unregisterGlobalManager=function(t){this.globalManagers.remove(t),t.enabled=!1},t.getGlobalManager=function(t){for(var e=0;e0&&this.setpreviousTouchState(this._gameTouchs[0]),t},enumerable:!0,configurable:!0}),t.initialize=function(t){this._init||(this._init=!0,this._stage=t,this._stage.addEventListener(egret.TouchEvent.TOUCH_BEGIN,this.touchBegin,this),this._stage.addEventListener(egret.TouchEvent.TOUCH_MOVE,this.touchMove,this),this._stage.addEventListener(egret.TouchEvent.TOUCH_END,this.touchEnd,this),this._stage.addEventListener(egret.TouchEvent.TOUCH_CANCEL,this.touchEnd,this),this._stage.addEventListener(egret.TouchEvent.TOUCH_RELEASE_OUTSIDE,this.touchEnd,this),this.initTouchCache())},t.initTouchCache=function(){this._totalTouchCount=0,this._touchIndex=0,this._gameTouchs.length=0;for(var t=0;t0)for(var e=0;ethis._objectQueue.length;)this._objectQueue.shift()},t.clearCache=function(){this._objectQueue.length=0},t.obtain=function(){return this._objectQueue.length>0?this._objectQueue.shift():[]},t.free=function(t){this._objectQueue.unshift(t),t.length=0},t._objectQueue=[],t}(),Pair=function(){function t(t,e){this.first=t,this.second=e}return t.prototype.clear=function(){this.first=this.second=null},t.prototype.equals=function(t){return this.first==t.first&&this.second==t.second},t}(),RectangleExt=function(){function t(){}return t.union=function(t,e){var n=new Rectangle(e.x,e.y,0,0);return this.unionR(t,n)},t.unionR=function(t,e){var n=new Rectangle;return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n.width=Math.max(t.right,e.right)-n.x,n.height=Math.max(t.bottom,e.bottom)-n.y,n},t}(),Triangulator=function(){function t(){this.triangleIndices=[],this._triPrev=new Array(12),this._triNext=new Array(12)}return t.prototype.triangulate=function(e,n){void 0===n&&(n=!0);var i=e.length;this.initialize(i);for(var o=0,r=0;i>3&&o<500;){o++;var s=!0,a=e[this._triPrev[r]],c=e[r],h=e[this._triNext[r]];if(Vector2Ext.isTriangleCCW(a,c,h)){var u=this._triNext[this._triNext[r]];do{if(t.testPointTriangle(e[u],a,c,h)){s=!1;break}u=this._triNext[u]}while(u!=this._triPrev[r])}else s=!1;s?(this.triangleIndices.push(this._triPrev[r]),this.triangleIndices.push(r),this.triangleIndices.push(this._triNext[r]),this._triNext[this._triPrev[r]]=this._triNext[r],this._triPrev[this._triNext[r]]=this._triPrev[r],i--,r=this._triPrev[r]):r=this._triNext[r]}this.triangleIndices.push(this._triPrev[r]),this.triangleIndices.push(r),this.triangleIndices.push(this._triNext[r]),n||this.triangleIndices.reverse()},t.prototype.initialize=function(t){this.triangleIndices.length=0,this._triNext.lengthMathHelper.Epsilon?t=Vector2.divide(t,new Vector2(e)):t.x=t.y=0,t},t.transformA=function(t,e,n,i,o,r){for(var s=0;s0&&r[r.length-1])&&(6===o[0]||2===o[0])){s=0;continue}if(3===o[0]&&(!r||o[1]>r[0]&&o[1]-1}(this,t)},Array.prototype.firstOrDefault=function(t){return function(t,e){var n=t.findIndex(e);return-1==n?null:t[n]}(this,t)},Array.prototype.find=function(t){return function(t,e){return t.firstOrDefault(e)}(this,t)},Array.prototype.where=function(t){return function(t,e){if("function"==typeof t.reduce)return t.reduce(function(n,i,r){return e.call(arguments[2],i,r,t)&&n.push(i),n},[]);for(var n=[],i=0,r=t.length;i=0&&t.splice(n,1)}while(n>=0)}(this,t)},Array.prototype.remove=function(t){return function(t,e){var n=t.findIndex(function(t){return t===e});return n>=0&&(t.splice(n,1),!0)}(this,t)},Array.prototype.removeAt=function(t){return function(t,e){t.splice(e,1)}(this,t)},Array.prototype.removeRange=function(t,e){return function(t,e,n){t.splice(e,n)}(this,t,e)},Array.prototype.select=function(t){return function(t,e){if("function"==typeof t.reduce)return t.reduce(function(n,i,r){return n.push(e.call(arguments[2],i,r,t)),n},[]);for(var n=[],i=0,r=t.length;io?1:-1}),t}(this,t,e)},Array.prototype.orderByDescending=function(t,e){return function(t,e,n){return t.sort(function(t,i){var r=e(t),o=e(i);return n?-n(r,o):r0;){if("break"===u())break}return s?this.recontructPath(a,i,r):null},e.recontructPath=function(t,e,n){var i=[],r=n;for(i.push(n);r!=e;)r=this.getKey(t,r),i.push(r);return i.reverse(),i},e.hasKey=function(t,e){for(var n,i=t.keys();!(n=i.next()).done;)if(JSON.stringify(n.value)==JSON.stringify(e))return!0;return!1},e.getKey=function(t,e){for(var n,i,r=t.keys(),o=t.values();n=r.next(),i=o.next(),!n.done;)if(JSON.stringify(n.value)==JSON.stringify(e))return i.value;return null},e}();t.AStarPathfinder=e;var n=function(t){function e(e){var n=t.call(this)||this;return n.data=e,n}return __extends(e,t),e}(t.PriorityQueueNode);t.AStarNode=n}(es||(es={})),function(t){var e=function(){function e(e,n){this.dirs=[new t.Vector2(1,0),new t.Vector2(0,-1),new t.Vector2(-1,0),new t.Vector2(0,1)],this.walls=[],this.weightedNodes=[],this.defaultWeight=1,this.weightedNodeWeight=5,this._neighbors=new Array(4),this._width=e,this._height=n}return e.prototype.isNodeInBounds=function(t){return 0<=t.x&&t.x=this._nodes.length?(console.error("node.QueueIndex has been corrupted. Did you change it manually? Or add this node to another queue?"),!1):this._nodes[t.queueIndex]==t:(console.error("node cannot be null"),!1)},t.prototype.enqueue=function(t,e){t.priority=e,this._numNodes++,this._nodes[this._numNodes]=t,t.queueIndex=this._numNodes,t.insertionIndex=this._numNodesEverEnqueued++,this.cascadeUp(this._nodes[this._numNodes])},t.prototype.dequeue=function(){var t=this._nodes[1];return this.remove(t),t},t.prototype.remove=function(t){if(t.queueIndex==this._numNodes)return this._nodes[this._numNodes]=null,void this._numNodes--;var e=this._nodes[this._numNodes];this.swap(t,e),delete this._nodes[this._numNodes],this._numNodes--,this.onNodeUpdated(e)},t.prototype.isValidQueue=function(){for(var t=1;t0&&this.hasHigherPriority(t,n)?this.cascadeUp(t):this.cascadeDown(t)},t.prototype.cascadeDown=function(t){for(var e,n=t.queueIndex;;){e=t;var i=2*n;if(i>this._numNodes){t.queueIndex=n,this._nodes[n]=t;break}var r=this._nodes[i];this.hasHigherPriority(r,e)&&(e=r);var o=i+1;if(o<=this._numNodes){var s=this._nodes[o];this.hasHigherPriority(s,e)&&(e=s)}if(e==t){t.queueIndex=n,this._nodes[n]=t;break}this._nodes[n]=e;var a=e.queueIndex;e.queueIndex=n,n=a}},t.prototype.cascadeUp=function(t){for(var e=Math.floor(t.queueIndex/2);e>=1;){var n=this._nodes[e];if(this.hasHigherPriority(n,t))break;this.swap(t,n),e=Math.floor(t.queueIndex/2)}},t.prototype.swap=function(t,e){this._nodes[t.queueIndex]=e,this._nodes[e.queueIndex]=t;var n=t.queueIndex;t.queueIndex=e.queueIndex,e.queueIndex=n},t.prototype.hasHigherPriority=function(t,e){return t.priority0;){if("break"===c())break}return o?t.AStarPathfinder.recontructPath(a,n,i):null},e.hasKey=function(t,e){for(var n,i=t.keys();!(n=i.next()).done;)if(JSON.stringify(n.value)==JSON.stringify(e))return!0;return!1},e}();t.BreadthFirstPathfinder=e}(es||(es={})),function(t){var e=function(){function t(){this.edges=new Map}return t.prototype.addEdgesForNode=function(t,e){return this.edges.set(t,e),this},t.prototype.getNeighbors=function(t){return this.edges.get(t)},t}();t.UnweightedGraph=e}(es||(es={})),function(t){var e=function(){function e(t,e){this.x=0,this.y=0,this.x=t||0,this.y=null!=e?e:this.x}return Object.defineProperty(e,"zero",{get:function(){return e.zeroVector2},enumerable:!0,configurable:!0}),Object.defineProperty(e,"one",{get:function(){return e.unitVector2},enumerable:!0,configurable:!0}),Object.defineProperty(e,"unitX",{get:function(){return e.unitXVector},enumerable:!0,configurable:!0}),Object.defineProperty(e,"unitY",{get:function(){return e.unitYVector},enumerable:!0,configurable:!0}),e.add=function(t,n){var i=new e(0,0);return i.x=t.x+n.x,i.y=t.y+n.y,i},e.divide=function(t,n){var i=new e(0,0);return i.x=t.x/n.x,i.y=t.y/n.y,i},e.multiply=function(t,n){var i=new e(0,0);return i.x=t.x*n.x,i.y=t.y*n.y,i},e.subtract=function(t,n){var i=new e(0,0);return i.x=t.x-n.x,i.y=t.y-n.y,i},e.normalize=function(t){var e=1/Math.sqrt(t.x*t.x+t.y*t.y);return t.x*=e,t.y*=e,t},e.dot=function(t,e){return t.x*e.x+t.y*e.y},e.distanceSquared=function(t,e){var n=t.x-e.x,i=t.y-e.y;return n*n+i*i},e.clamp=function(n,i,r){return new e(t.MathHelper.clamp(n.x,i.x,r.x),t.MathHelper.clamp(n.y,i.y,r.y))},e.lerp=function(n,i,r){return new e(t.MathHelper.lerp(n.x,i.x,r),t.MathHelper.lerp(n.y,i.y,r))},e.transform=function(t,n){return new e(t.x*n.m11+t.y*n.m21+n.m31,t.x*n.m12+t.y*n.m22+n.m32)},e.distance=function(t,e){var n=t.x-e.x,i=t.y-e.y;return Math.sqrt(n*n+i*i)},e.negate=function(t){var n=new e;return n.x=-t.x,n.y=-t.y,n},e.prototype.add=function(t){return this.x+=t.x,this.y+=t.y,this},e.prototype.divide=function(t){return this.x/=t.x,this.y/=t.y,this},e.prototype.multiply=function(t){return this.x*=t.x,this.y*=t.y,this},e.prototype.subtract=function(t){return this.x-=t.x,this.y-=t.y,this},e.prototype.normalize=function(){var t=1/Math.sqrt(this.x*this.x+this.y*this.y);return this.x*=t,this.y*=t,this},e.prototype.length=function(){return Math.sqrt(this.x*this.x+this.y*this.y)},e.prototype.lengthSquared=function(){return this.x*this.x+this.y*this.y},e.prototype.round=function(){return new e(Math.round(this.x),Math.round(this.y))},e.prototype.equals=function(t){return t.x==this.x&&t.y==this.y},e.unitYVector=new e(0,1),e.unitXVector=new e(1,0),e.unitVector2=new e(1,1),e.zeroVector2=new e(0,0),e}();t.Vector2=e}(es||(es={})),function(t){var e=function(){function e(t,n,i){void 0===i&&(i=!1),this.walls=[],this._neighbors=new Array(4),this._width=t,this._hegiht=n,this._dirs=i?e.COMPASS_DIRS:e.CARDINAL_DIRS}return e.prototype.isNodeInBounds=function(t){return 0<=t.x&&t.x0;){if("break"===u())break}return s?this.recontructPath(a,i,r):null},n.recontructPath=function(t,e,n){var i=[],r=n;for(i.push(n);r!=e;)r=this.getKey(t,r),i.push(r);return i.reverse(),i},n.hasKey=function(t,e){for(var n,i=t.keys();!(n=i.next()).done;)if(JSON.stringify(n.value)==JSON.stringify(e))return!0;return!1},n.getKey=function(t,e){for(var n,i,r=t.keys(),o=t.values();n=r.next(),i=o.next(),!n.done;)if(JSON.stringify(n.value)==JSON.stringify(e))return i.value;return null},n}();t.WeightedPathfinder=n}(es||(es={})),function(t){var e=function(){function e(){}return e.drawHollowRect=function(e,n,i){void 0===i&&(i=0),this._debugDrawItems.push(new t.DebugDrawItem(e,n,i))},e.render=function(){if(this._debugDrawItems.length>0){var e=new egret.Shape;t.Core.scene&&t.Core.scene.addChild(e);for(var n=this._debugDrawItems.length-1;n>=0;n--){this._debugDrawItems[n].draw(e)&&this._debugDrawItems.removeAt(n)}}},e._debugDrawItems=[],e}();t.Debug=e}(es||(es={})),function(t){var e=function(){function t(){}return t.verletParticle=14431326,t.verletConstraintEdge=4406838,t}();t.DebugDefaults=e}(es||(es={})),function(t){var e;!function(t){t[t.line=0]="line",t[t.hollowRectangle=1]="hollowRectangle",t[t.pixel=2]="pixel",t[t.text=3]="text"}(e=t.DebugDrawType||(t.DebugDrawType={}));var n=function(){function n(t,n,i){this.rectangle=t,this.color=n,this.duration=i,this.drawType=e.hollowRectangle}return n.prototype.draw=function(n){switch(this.drawType){case e.line:t.DrawUtils.drawLine(n,this.start,this.end,this.color);break;case e.hollowRectangle:t.DrawUtils.drawHollowRect(n,this.rectangle,this.color);break;case e.pixel:t.DrawUtils.drawPixel(n,new t.Vector2(this.x,this.y),this.color,this.size);break;case e.text:}return this.duration-=t.Time.deltaTime,this.duration<0},n}();t.DebugDrawItem=n}(es||(es={})),function(t){var e=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.updateInterval=1,e._enabled=!0,e._updateOrder=0,e}return __extends(e,t),Object.defineProperty(e.prototype,"transform",{get:function(){return this.entity.transform},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"enabled",{get:function(){return this.entity?this.entity.enabled&&this._enabled:this._enabled},set:function(t){this.setEnabled(t)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"updateOrder",{get:function(){return this._updateOrder},set:function(t){this.setUpdateOrder(t)},enumerable:!0,configurable:!0}),e.prototype.initialize=function(){},e.prototype.onAddedToEntity=function(){},e.prototype.onRemovedFromEntity=function(){},e.prototype.onEntityTransformChanged=function(t){},e.prototype.debugRender=function(){},e.prototype.onEnabled=function(){},e.prototype.onDisabled=function(){},e.prototype.update=function(){},e.prototype.setEnabled=function(t){return this._enabled!=t&&(this._enabled=t,this._enabled?this.onEnabled():this.onDisabled()),this},e.prototype.setUpdateOrder=function(t){return this._updateOrder!=t&&(this._updateOrder=t),this},e.prototype.clone=function(){var t=ObjectUtils.clone(this);return t.entity=null,t},e}(egret.HashObject);t.Component=e}(es||(es={})),function(t){var e=function(e){function n(){var i=e.call(this)||this;return i._globalManagers=[],n._instance=i,n.emitter=new t.Emitter,n.content=new t.ContentManager,i.addEventListener(egret.Event.ADDED_TO_STAGE,i.onAddToStage,i),i}return __extends(n,e),Object.defineProperty(n,"Instance",{get:function(){return this._instance},enumerable:!0,configurable:!0}),Object.defineProperty(n,"scene",{get:function(){return this._instance?this._instance._scene:null},set:function(t){t?null==this._instance._scene?(this._instance._scene=t,this._instance.addChild(t),this._instance._scene.begin(),n.Instance.onSceneChanged()):this._instance._nextScene=t:console.error("场景不能为空")},enumerable:!0,configurable:!0}),n.startSceneTransition=function(t){if(!this._instance._sceneTransition)return this._instance._sceneTransition=t,t;console.warn("在前一个场景完成之前,不能开始一个新的场景转换。")},n.registerGlobalManager=function(t){this._instance._globalManagers.push(t),t.enabled=!0},n.unregisterGlobalManager=function(t){this._instance._globalManagers.remove(t),t.enabled=!1},n.getGlobalManager=function(t){for(var e=0;e=0;e--)this._globalManagers[e].enabled&&this._globalManagers[e].update();return this._sceneTransition&&(!this._sceneTransition||this._sceneTransition.loadsNewScene&&!this._sceneTransition.isNewSceneLoaded)||this._scene.update(),this._nextScene?(this.removeChild(this._scene),this._scene.end(),this._scene=this._nextScene,this._nextScene=null,this.onSceneChanged(),this.addChild(this._scene),[4,this._scene.begin()]):[3,2];case 1:n.sent(),n.label=2;case 2:return[4,this.draw()];case 3:return n.sent(),[2]}})})},n.prototype.onAddToStage=function(){n.graphicsDevice=new t.GraphicsDevice,this.addEventListener(egret.Event.RESIZE,this.onGraphicsDeviceReset,this),this.addEventListener(egret.StageOrientationEvent.ORIENTATION_CHANGE,this.onOrientationChanged,this),this.addEventListener(egret.Event.ENTER_FRAME,this.update,this),t.Input.initialize(),this.initialize()},n}(egret.DisplayObjectContainer);t.Core=e}(es||(es={})),function(t){!function(t){t[t.GraphicsDeviceReset=0]="GraphicsDeviceReset",t[t.SceneChanged=1]="SceneChanged",t[t.OrientationChanged=2]="OrientationChanged"}(t.CoreEvents||(t.CoreEvents={}))}(es||(es={})),function(t){var e=function(){function e(n){this.updateInterval=1,this._tag=0,this._enabled=!0,this._updateOrder=0,this.components=new t.ComponentList(this),this.transform=new t.Transform(this),this.name=n,this.id=e._idGenerator++,this.componentBits=new t.BitSet}return Object.defineProperty(e.prototype,"isDestroyed",{get:function(){return this._isDestroyed},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"tag",{get:function(){return this._tag},set:function(t){this.setTag(t)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"enabled",{get:function(){return this._enabled},set:function(t){this.setEnabled(t)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"updateOrder",{get:function(){return this._updateOrder},set:function(t){this.setUpdateOrder(t)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"parent",{get:function(){return this.transform.parent},set:function(t){this.transform.setParent(t)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"childCount",{get:function(){return this.transform.childCount},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"position",{get:function(){return this.transform.position},set:function(t){this.transform.setPosition(t.x,t.y)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"localPosition",{get:function(){return this.transform.localPosition},set:function(t){this.transform.setLocalPosition(t)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"rotation",{get:function(){return this.transform.rotation},set:function(t){this.transform.setRotation(t)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"rotationDegrees",{get:function(){return this.transform.rotationDegrees},set:function(t){this.transform.setRotationDegrees(t)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"localRotation",{get:function(){return this.transform.localRotation},set:function(t){this.transform.setLocalRotation(t)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"localRotationDegrees",{get:function(){return this.transform.localRotationDegrees},set:function(t){this.transform.setLocalRotationDegrees(t)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"scale",{get:function(){return this.transform.scale},set:function(t){this.transform.setScale(t)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"localScale",{get:function(){return this.transform.localScale},set:function(t){this.transform.setLocalScale(t)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"worldInverseTransform",{get:function(){return this.transform.worldInverseTransform},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"localToWorldTransform",{get:function(){return this.transform.localToWorldTransform},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"worldToLocalTransform",{get:function(){return this.transform.worldToLocalTransform},enumerable:!0,configurable:!0}),e.prototype.onTransformChanged=function(t){this.components.onEntityTransformChanged(t)},e.prototype.setTag=function(t){return this._tag!=t&&(this.scene&&this.scene.entities.removeFromTagList(this),this._tag=t,this.scene&&this.scene.entities.addToTagList(this)),this},e.prototype.setEnabled=function(t){return this._enabled!=t&&(this._enabled=t,this._enabled?this.components.onEntityEnabled():this.components.onEntityDisabled()),this},e.prototype.setUpdateOrder=function(t){if(this._updateOrder!=t)return this._updateOrder=t,this.scene&&(this.scene.entities.markEntityListUnsorted(),this.scene.entities.markTagUnsorted(this.tag)),this},e.prototype.destroy=function(){this._isDestroyed=!0,this.scene.entities.remove(this),this.transform.parent=null;for(var t=this.transform.childCount-1;t>=0;t--){this.transform.getChild(t).entity.destroy()}},e.prototype.detachFromScene=function(){this.scene.entities.remove(this),this.components.deregisterAllComponents();for(var t=0;te.x?-1:1,i=t.Vector2.normalize(t.Vector2.subtract(this.position,e));this.rotation=n*Math.acos(t.Vector2.dot(i,t.Vector2.unitY))},i.prototype.setLocalRotation=function(t){return this._localRotation=t,this._localDirty=this._positionDirty=this._localPositionDirty=this._localRotationDirty=this._localScaleDirty=!0,this.setDirty(e.rotationDirty),this},i.prototype.setLocalRotationDegrees=function(e){return this.setLocalRotation(t.MathHelper.toRadians(e))},i.prototype.setScale=function(e){return this._scale=e,this.parent?this.localScale=t.Vector2.divide(e,this.parent._scale):this.localScale=e,this},i.prototype.setLocalScale=function(t){return this._localScale=t,this._localDirty=this._positionDirty=this._localScaleDirty=!0,this.setDirty(e.scaleDirty),this},i.prototype.roundPosition=function(){this.position=this._position.round()},i.prototype.updateTransform=function(){this.hierarchyDirty!=e.clean&&(this.parent&&this.parent.updateTransform(),this._localDirty&&(this._localPositionDirty&&(this._translationMatrix=t.Matrix2D.create().translate(this._localPosition.x,this._localPosition.y),this._localPositionDirty=!1),this._localRotationDirty&&(this._rotationMatrix=t.Matrix2D.create().rotate(this._localRotation),this._localRotationDirty=!1),this._localScaleDirty&&(this._scaleMatrix=t.Matrix2D.create().scale(this._localScale.x,this._localScale.y),this._localScaleDirty=!1),this._localTransform=this._scaleMatrix.multiply(this._rotationMatrix),this._localTransform=this._localTransform.multiply(this._translationMatrix),this.parent||(this._worldTransform=this._localTransform,this._rotation=this._localRotation,this._scale=this._localScale,this._worldInverseDirty=!0),this._localDirty=!1),this.parent&&(this._worldTransform=this._localTransform.multiply(this.parent._worldTransform),this._rotation=this._localRotation+this.parent._rotation,this._scale=t.Vector2.multiply(this.parent._scale,this._localScale),this._worldInverseDirty=!0),this._worldToLocalDirty=!0,this._positionDirty=!0,this.hierarchyDirty=e.clean)},i.prototype.setDirty=function(e){if(0==(this.hierarchyDirty&e)){switch(this.hierarchyDirty|=e,e){case t.DirtyType.positionDirty:this.entity.onTransformChanged(transform.Component.position);break;case t.DirtyType.rotationDirty:this.entity.onTransformChanged(transform.Component.rotation);break;case t.DirtyType.scaleDirty:this.entity.onTransformChanged(transform.Component.scale)}this._children||(this._children=[]);for(var n=0;nt&&(this._zoom=t),this._maximumZoom=t,this;console.error("maximumZoom must be greater than zero")},r.prototype.onEntityTransformChanged=function(t){this._areMatrixedDirty=!0},r.prototype.zoomIn=function(t){this.zoom+=t},r.prototype.zoomOut=function(t){this.zoom-=t},r.prototype.worldToScreenPoint=function(e){return this.updateMatrixes(),e=t.Vector2.transform(e,this._transformMatrix)},r.prototype.screenToWorldPoint=function(e){return this.updateMatrixes(),e=t.Vector2.transform(e,this._inverseTransformMatrix)},r.prototype.mouseToWorldPoint=function(){return this.screenToWorldPoint(t.Input.touchPosition)},r.prototype.onAddedToEntity=function(){this.follow(this._targetEntity,this._cameraStyle)},r.prototype.update=function(){var e=t.Vector2.multiply(new t.Vector2(this.bounds.width,this.bounds.height),new t.Vector2(.5));this._worldSpaceDeadZone.x=this.position.x-e.x*t.Core.scene.scaleX+this.deadzone.x+this.focusOffset.x,this._worldSpaceDeadZone.y=this.position.y-e.y*t.Core.scene.scaleY+this.deadzone.y+this.focusOffset.y,this._worldSpaceDeadZone.width=this.deadzone.width,this._worldSpaceDeadZone.height=this.deadzone.height,this._targetEntity&&this.updateFollow(),this.position=t.Vector2.lerp(this.position,t.Vector2.add(this.position,this._desiredPositionDelta),this.followLerp),this.entity.transform.roundPosition(),this.mapLockEnabled&&(this.position=this.clampToMapSize(this.position),this.entity.transform.roundPosition())},r.prototype.clampToMapSize=function(e){var n=t.Vector2.multiply(new t.Vector2(this.bounds.width,this.bounds.height),new t.Vector2(.5)),i=new t.Vector2(this.mapSize.x-n.x,this.mapSize.y-n.y);return t.Vector2.clamp(e,n,i)},r.prototype.updateFollow=function(){if(this._desiredPositionDelta.x=this._desiredPositionDelta.y=0,this._cameraStyle==e.lockOn){var n=this._targetEntity.transform.position.x,i=this._targetEntity.transform.position.y;this._worldSpaceDeadZone.x>n?this._desiredPositionDelta.x=n-this._worldSpaceDeadZone.x:this._worldSpaceDeadZone.xi&&(this._desiredPositionDelta.y=i-this._worldSpaceDeadZone.y)}else{if(!this._targetCollider&&(this._targetCollider=this._targetEntity.getComponent(t.Collider),!this._targetCollider))return;var r=this._targetEntity.getComponent(t.Collider).bounds;this._worldSpaceDeadZone.containsRect(r)||(this._worldSpaceDeadZone.left>r.left?this._desiredPositionDelta.x=r.left-this._worldSpaceDeadZone.left:this._worldSpaceDeadZone.rightr.top&&(this._desiredPositionDelta.y=r.top-this._worldSpaceDeadZone.top))}},r.prototype.follow=function(n,i){switch(void 0===i&&(i=e.cameraWindow),this._targetEntity=n,this._cameraStyle=i,this._cameraStyle){case e.cameraWindow:var r=this.bounds.width/6,o=this.bounds.height/3;this.deadzone=new t.Rectangle((this.bounds.width-r)/2,(this.bounds.height-o)/2,r,o);break;case e.lockOn:this.deadzone=new t.Rectangle(this.bounds.width/2,this.bounds.height/2,10,10)}},r.prototype.setCenteredDeadzone=function(e,n){this.deadzone=new t.Rectangle((this.bounds.width-e)/2,(this.bounds.height-n)/2,e,n)},r.prototype.updateMatrixes=function(){var e;this._areMatrixedDirty&&(this._transformMatrix=t.Matrix2D.create().translate(-this.entity.transform.position.x,-this.entity.transform.position.y),1!=this._zoom&&(e=t.Matrix2D.create().scale(this._zoom,this._zoom),this._transformMatrix=this._transformMatrix.multiply(e)),0!=this.entity.transform.rotation&&(e=t.Matrix2D.create().rotate(this.entity.transform.rotation),this._transformMatrix=this._transformMatrix.multiply(e)),e=t.Matrix2D.create().translate(this._origin.x,this._origin.y),this._transformMatrix=this._transformMatrix.multiply(e),this._inverseTransformMatrix=this._transformMatrix.invert(),this._areBoundsDirty=!0,this._areMatrixedDirty=!1)},r}(t.Component);t.Camera=i}(es||(es={})),function(t){var e=function(){function t(t){this._type=t,this._cache=[]}return t.prototype.obtain=function(){try{return this._cache.length>0?this._cache.shift():new this._type}catch(t){throw new Error(this._type+t)}},t.prototype.free=function(t){t.reset(),this._cache.push(t)},t}();t.ComponentPool=e}(es||(es={})),function(t){var e=function(){function t(){}return t.prototype.compare=function(t,e){return t.updateOrder-e.updateOrder},t}();t.IUpdatableComparer=e}(es||(es={})),function(t){var e=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return __extends(e,t),e}(t.Component);t.PooledComponent=e}(es||(es={})),function(t){var e=function(e){function n(){var n=null!==e&&e.apply(this,arguments)||this;return n.displayObject=new egret.DisplayObject,n.color=0,n._areBoundsDirty=!0,n._localOffset=t.Vector2.zero,n._renderLayer=0,n._bounds=new t.Rectangle,n}return __extends(n,e),Object.defineProperty(n.prototype,"width",{get:function(){return this.bounds.width},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"height",{get:function(){return this.bounds.height},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"localOffset",{get:function(){return this._localOffset},set:function(t){this.setLocalOffset(t)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"renderLayer",{get:function(){return this._renderLayer},set:function(t){},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"bounds",{get:function(){return this._areBoundsDirty&&(this._bounds.calculateBounds(this.entity.transform.position,this._localOffset,t.Vector2.zero,this.entity.transform.scale,this.entity.transform.rotation,this.width,this.height),this._areBoundsDirty=!1),this._bounds},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"isVisible",{get:function(){return this._isVisible},set:function(t){this._isVisible!=t&&(this._isVisible=t,this._isVisible?this.onBecameVisible():this.onBecameInvisible())},enumerable:!0,configurable:!0}),n.prototype.onEntityTransformChanged=function(t){this._areBoundsDirty=!0},n.prototype.isVisibleFromCamera=function(t){return this.isVisible=t.bounds.intersects(this.bounds),this.isVisible},n.prototype.setRenderLayer=function(t){if(t!=this._renderLayer){var e=this._renderLayer;this._renderLayer=t,this.entity&&this.entity.scene&&this.entity.scene.renderableComponents.updateRenderableRenderLayer(this,e,this._renderLayer)}return this},n.prototype.setColor=function(t){return this.color=t,this},n.prototype.setLocalOffset=function(t){return this._localOffset!=t&&(this._localOffset=t),this},n.prototype.sync=function(t){this.displayObject.x=this.entity.position.x+this.localOffset.x-t.position.x+t.origin.x,this.displayObject.y=this.entity.position.y+this.localOffset.y-t.position.y+t.origin.y,this.displayObject.scaleX=this.entity.scale.x,this.displayObject.scaleY=this.entity.scale.y,this.displayObject.rotation=this.entity.rotation},n.prototype.toString=function(){return"[RenderableComponent] renderLayer: "+this.renderLayer},n.prototype.onBecameVisible=function(){this.displayObject.visible=this.isVisible},n.prototype.onBecameInvisible=function(){this.displayObject.visible=this.isVisible},n}(t.Component);t.RenderableComponent=e}(es||(es={})),function(t){var e=function(t){function e(){var e=t.call(this)||this;return e._mesh=new egret.Mesh,e}return __extends(e,t),e.prototype.setTexture=function(t){return this._mesh.texture=t,this._mesh.$renderNode=new egret.sys.RenderNode,this},e.prototype.reset=function(){},e.prototype.render=function(t){},e}(t.RenderableComponent);t.Mesh=e}(es||(es={})),function(t){var e=egret.Bitmap,n=function(n){function i(e){void 0===e&&(e=null);var i=n.call(this)||this;return e instanceof t.Sprite?i.setSprite(e):e instanceof egret.Texture&&i.setSprite(new t.Sprite(e)),i}return __extends(i,n),Object.defineProperty(i.prototype,"bounds",{get:function(){return this._areBoundsDirty&&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=!1),this._bounds},enumerable:!0,configurable:!0}),Object.defineProperty(i.prototype,"originNormalized",{get:function(){return new t.Vector2(this._origin.x/this.width*this.entity.transform.scale.x,this._origin.y/this.height*this.entity.transform.scale.y)},set:function(e){this.setOrigin(new t.Vector2(e.x*this.width/this.entity.transform.scale.x,e.y*this.height/this.entity.transform.scale.y))},enumerable:!0,configurable:!0}),Object.defineProperty(i.prototype,"origin",{get:function(){return this._origin},set:function(t){this.setOrigin(t)},enumerable:!0,configurable:!0}),Object.defineProperty(i.prototype,"sprite",{get:function(){return this._sprite},set:function(t){this.setSprite(t)},enumerable:!0,configurable:!0}),i.prototype.setSprite=function(t){return this._sprite=t,this._sprite&&(this._origin=this._sprite.origin,this.displayObject.anchorOffsetX=this._origin.x,this.displayObject.anchorOffsetY=this._origin.y),this.displayObject=new e(t.texture2D),this},i.prototype.setOrigin=function(t){return this._origin!=t&&(this._origin=t,this.displayObject.anchorOffsetX=this._origin.x,this.displayObject.anchorOffsetY=this._origin.y,this._areBoundsDirty=!0),this},i.prototype.setOriginNormalized=function(e){return this.setOrigin(new t.Vector2(e.x*this.width/this.entity.transform.scale.x,e.y*this.height/this.entity.transform.scale.y)),this},i.prototype.render=function(t){this.sync(t),this.displayObject.x=this.entity.position.x-this.origin.x+this.localOffset.x-t.position.x+t.origin.x,this.displayObject.y=this.entity.position.y-this.origin.y+this.localOffset.y-t.position.y+t.origin.y},i}(t.RenderableComponent);t.SpriteRenderer=n}(es||(es={})),function(t){var e=function(e){function n(n){var i=e.call(this,n)||this;return i._sourceRect=new t.Rectangle,i._textureScale=t.Vector2.one,i._inverseTexScale=t.Vector2.one,i._sourceRect=n.sourceRect,i.displayObject.$fillMode=egret.BitmapFillMode.REPEAT,i}return __extends(n,e),Object.defineProperty(n.prototype,"bounds",{get:function(){return this._areBoundsDirty&&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=!1),this._bounds},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"scrollX",{get:function(){return this._sourceRect.x},set:function(t){this._sourceRect.x=t},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"scrollY",{get:function(){return this._sourceRect.y},set:function(t){this._sourceRect.y=t},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"textureScale",{get:function(){return this._textureScale},set:function(e){this._textureScale=e,this._inverseTexScale=new t.Vector2(1/this._textureScale.x,1/this._textureScale.y),this._sourceRect.width=this._sprite.sourceRect.width*this._inverseTexScale.x,this._sourceRect.height=this._sprite.sourceRect.height*this._inverseTexScale.y},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"width",{get:function(){return this._sourceRect.width},set:function(t){this._areBoundsDirty=!0,this._sourceRect.width=t},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"height",{get:function(){return this._sourceRect.height},set:function(t){this._areBoundsDirty=!0,this._sourceRect.height=t},enumerable:!0,configurable:!0}),n.prototype.render=function(t){var n=this.displayObject;n.width=this.width,n.height=this.height,e.prototype.render.call(this,t)},n}(t.SpriteRenderer);t.TiledSpriteRenderer=e}(es||(es={})),function(t){var e=function(e){function n(t){var n=e.call(this,t)||this;return n.scrollSpeedX=15,n.scroolSpeedY=0,n._scrollX=0,n._scrollY=0,n}return __extends(n,e),Object.defineProperty(n.prototype,"textureScale",{get:function(){return this._textureScale},set:function(e){this._textureScale=e,this._inverseTexScale=new t.Vector2(1/this._textureScale.x,1/this._textureScale.y)},enumerable:!0,configurable:!0}),n.prototype.update=function(){this._scrollX+=this.scrollSpeedX*t.Time.deltaTime,this._scrollY+=this.scroolSpeedY*t.Time.deltaTime,this._sourceRect.x=this._scrollX,this._sourceRect.y=this._scrollY},n}(t.TiledSpriteRenderer);t.ScrollingSpriteRenderer=e}(es||(es={})),function(t){var e=function(){return function(e,n,i){void 0===n&&(n=new t.Rectangle(0,0,e.textureWidth,e.textureHeight)),void 0===i&&(i=n.getHalfSize()),this.uvs=new t.Rectangle,this.texture2D=e,this.sourceRect=n,this.center=new t.Vector2(.5*n.width,.5*n.height),this.origin=i;var r=1/e.textureWidth,o=1/e.textureHeight;this.uvs.x=n.x*r,this.uvs.y=n.y*o,this.uvs.width=n.width*r,this.uvs.height=n.height*o}}();t.Sprite=e}(es||(es={})),function(t){var e=function(){return function(t,e){this.sprites=t,this.frameRate=e}}();t.SpriteAnimation=e}(es||(es={})),function(t){var e,n;!function(t){t[t.loop=0]="loop",t[t.once=1]="once",t[t.clampForever=2]="clampForever",t[t.pingPong=3]="pingPong",t[t.pingPongOnce=4]="pingPongOnce"}(e=t.LoopMode||(t.LoopMode={})),function(t){t[t.none=0]="none",t[t.running=1]="running",t[t.paused=2]="paused",t[t.completed=3]="completed"}(n=t.State||(t.State={}));var i=function(i){function r(t){var e=i.call(this,t)||this;return e.speed=1,e.animationState=n.none,e._elapsedTime=0,e._animations=new Map,e}return __extends(r,i),Object.defineProperty(r.prototype,"isRunning",{get:function(){return this.animationState==n.running},enumerable:!0,configurable:!0}),Object.defineProperty(r.prototype,"animations",{get:function(){return this._animations},enumerable:!0,configurable:!0}),r.prototype.update=function(){if(this.animationState==n.running&&this.currentAnimation){var i=this.currentAnimation,r=1/(i.frameRate*this.speed),o=r*i.sprites.length;this._elapsedTime+=t.Time.deltaTime;var s=Math.abs(this._elapsedTime);if(this._loopMode==e.once&&s>o||this._loopMode==e.pingPongOnce&&s>2*o)return this.animationState=n.completed,this._elapsedTime=0,this.currentFrame=0,void(this.sprite=i.sprites[this.currentFrame]);var a=Math.floor(s/r),c=i.sprites.length;if(c>2&&(this._loopMode==e.pingPong||this._loopMode==e.pingPongOnce)){var h=c-1;this.currentFrame=h-Math.abs(h-a%(2*h))}else this.currentFrame=a%c;this.sprite=i.sprites[this.currentFrame]}},r.prototype.addAnimation=function(t,e){return!this.sprite&&e.sprites.length>0&&this.setSprite(e.sprites[0]),this._animations[t]=e,this},r.prototype.play=function(t,i){void 0===i&&(i=null),this.currentAnimation=this._animations[t],this.currentAnimationName=t,this.currentFrame=0,this.animationState=n.running,this.sprite=this.currentAnimation.sprites[0],this._elapsedTime=0,this._loopMode=i||e.loop},r.prototype.isAnimationActive=function(t){return this.currentAnimation&&this.currentAnimationName==t},r.prototype.pause=function(){this.animationState=n.paused},r.prototype.unPause=function(){this.animationState=n.running},r.prototype.stop=function(){this.currentAnimation=null,this.currentAnimationName=null,this.currentFrame=0,this.animationState=n.none},r}(t.SpriteRenderer);t.SpriteAnimator=i}(es||(es={})),function(t){var e=function(e){function n(){return null!==e&&e.apply(this,arguments)||this}return __extends(n,e),n.prototype.onAddedToEntity=function(){this._triggerHelper=new t.ColliderTriggerHelper(this.entity)},n.prototype.calculateMovement=function(e,n){if(!this.entity.getComponent(t.Collider)||!this._triggerHelper)return!1;for(var i=this.entity.getComponents(t.Collider),r=0;r>6;0!=(e&t.LONG_MASK)&&n++,this._bits=new Array(n)}return t.prototype.and=function(t){for(var e,n=Math.min(this._bits.length,t._bits.length),i=0;i=0;)this._bits[e]&=~t._bits[e]},t.prototype.cardinality=function(){for(var t=0,e=this._bits.length-1;e>=0;e--){var n=this._bits[e];if(0!=n)if(-1!=n){var i=((n=((n=(n>>1&0x5555555555555400)+(0x5555555555555400&n))>>2&0x3333333333333400)+(0x3333333333333400&n))>>32)+n;t+=((i=((i=(i>>4&252645135)+(252645135&i))>>8&16711935)+(16711935&i))>>16&65535)+(65535&i)}else t+=64}return t},t.prototype.clear=function(t){if(null!=t){var e=t>>6;this.ensure(e),this._bits[e]&=~(1<>6;return!(e>=this._bits.length)&&0!=(this._bits[e]&1<=0;)if(0!=(this._bits[e]&t._bits[e]))return!0;return!1},t.prototype.isEmpty=function(){for(var t=this._bits.length-1;t>=0;t--)if(this._bits[t])return!1;return!0},t.prototype.nextSetBit=function(t){for(var e=t>>6,n=1<>6;this.ensure(n),this._bits[n]|=1<=this._bits.length){var e=new Number[t+1];e=this._bits.copyWithin(0,0,this._bits.length),this._bits=e}},t.LONG_MASK=63,t}();t.BitSet=e}(es||(es={})),function(t){var e=function(){function e(t){this._components=[],this._componentsToAdd=[],this._componentsToRemove=[],this._tempBufferList=[],this._entity=t}return Object.defineProperty(e.prototype,"count",{get:function(){return this._components.length},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"buffer",{get:function(){return this._components},enumerable:!0,configurable:!0}),e.prototype.markEntityListUnsorted=function(){this._isComponentListUnsorted=!0},e.prototype.add=function(t){this._componentsToAdd.push(t)},e.prototype.remove=function(t){this._componentsToRemove.contains(t)&&console.warn("You are trying to remove a Component ("+t+") that you already removed"),this._componentsToAdd.contains(t)?this._componentsToAdd.remove(t):this._componentsToRemove.push(t)},e.prototype.removeAllComponents=function(){for(var t=0;t0){for(var n=0;n0){n=0;for(var i=this._componentsToAdd.length;n0){var e=this._entitiesToRemove;this._entitiesToRemove=this._tempEntityList,this._tempEntityList=e,this._tempEntityList.forEach(function(e){t.removeFromTagList(e),t._entities.remove(e),e.onRemovedFromScene(),e.scene=null,t.scene.entityProcessors.onEntityRemoved(e)}),this._tempEntityList.length=0}if(this._entitiesToAdded.length>0){e=this._entitiesToAdded;this._entitiesToAdded=this._tempEntityList,this._tempEntityList=e,this._tempEntityList.forEach(function(e){t._entities.contains(e)||(t._entities.push(e),e.scene=t.scene,t.addToTagList(e),t.scene.entityProcessors.onEntityAdded(e))}),this._tempEntityList.forEach(function(t){return t.onAddedToScene()}),this._tempEntityList.length=0,this._isEntityListUnsorted=!0}this._isEntityListUnsorted&&(this._entities.sort(),this._isEntityListUnsorted=!1),this._unsortedTags.length>0&&(this._unsortedTags.forEach(function(e){t._entityDict.get(e).sort()}),this._unsortedTags.length=0)},e.prototype.findEntity=function(t){for(var e=0;e=0;e=this.allSet.nextSetBit(e+1))if(!t.componentBits.get(e))return!1;return!(!this.exclusionSet.isEmpty()&&this.exclusionSet.intersects(t.componentBits))&&!(!this.oneSet.isEmpty()&&!this.oneSet.intersects(t.componentBits))},e.prototype.all=function(){for(var e=this,n=[],i=0;i0){for(var t=0,n=this._unsortedRenderLayers.length;t=e)return t;var i=!1;"-"==t.substr(0,1)&&(i=!0,t=t.substr(1));for(var r=e-n,o=0;o1?this.reverse(t.substring(1))+t.substring(0,1):t},t.cutOff=function(t,e,n,i){void 0===i&&(i=!0),e=Math.floor(e),n=Math.floor(n);var r=t.length;e>r&&(e=r);var o,s=e,a=e+n;return i?o=t.substring(0,s)+t.substr(a,r):(a=(s=r-1-e-n)+n,o=t.substring(0,s+1)+t.substr(a+1,r)),o},t.strReplace=function(t,e){for(var n=0,i=e.length;n",">",'"',""","'","'","®","®","©","©","™","™"],t}();!function(t){var e=function(){function e(){}return e.convertImageToCanvas=function(e,n){this.sharedCanvas||(this.sharedCanvas=egret.sys.createCanvas(),this.sharedContext=this.sharedCanvas.getContext("2d"));var i=e.$getTextureWidth(),r=e.$getTextureHeight();n||((n=egret.$TempRectangle).x=0,n.y=0,n.width=i,n.height=r),n.x=Math.min(n.x,i-1),n.y=Math.min(n.y,r-1),n.width=Math.min(n.width,i-n.x),n.height=Math.min(n.height,r-n.y);var o=Math.floor(n.width),s=Math.floor(n.height),a=this.sharedCanvas;if(a.style.width=o+"px",a.style.height=s+"px",this.sharedCanvas.width=o,this.sharedCanvas.height=s,"webgl"==egret.Capabilities.renderMode){var c=void 0;e.$renderBuffer?c=e:(egret.sys.systemRenderer.renderClear&&egret.sys.systemRenderer.renderClear(),(c=new egret.RenderTexture).drawToTexture(new egret.Bitmap(e)));for(var h=c.$renderBuffer.getPixels(n.x,n.y,o,s),u=0,l=0,p=0;p=0?"png":"jpg"});return wx.getFileSystemManager().saveFile({tempFilePath:o,filePath:wx.env.USER_DATA_PATH+"/"+n,success:function(t){}}),o},e.getPixel32=function(t,e,n){return egret.$warn(1041,"getPixel32","getPixels"),t.getPixels(e,n)},e.getPixels=function(t,e,n,i,r){if(void 0===i&&(i=1),void 0===r&&(r=1),"webgl"==egret.Capabilities.renderMode){var o=void 0;return t.$renderBuffer?o=t:(o=new egret.RenderTexture).drawToTexture(new egret.Bitmap(t)),o.$renderBuffer.getPixels(e,n,i,r)}try{this.convertImageToCanvas(t);return this.sharedContext.getImageData(e,n,i,r).data}catch(t){egret.$error(1039)}},e}();t.TextureUtils=e}(es||(es={})),function(t){var e=function(){function t(){}return t.update=function(t){var e=(t-this._lastTime)/1e3;this.deltaTime=e*this.timeScale,this.unscaledDeltaTime=e,this._timeSinceSceneLoad+=e,this.frameCount++,this._lastTime=t},t.sceneChanged=function(){this._timeSinceSceneLoad=0},t.checkEvery=function(t){return this._timeSinceSceneLoad/t>(this._timeSinceSceneLoad-this.deltaTime)/t},t.deltaTime=0,t.timeScale=1,t.frameCount=0,t._lastTime=0,t}();t.Time=e}(es||(es={}));var TimeUtils=function(){function t(){}return t.monthId=function(t){void 0===t&&(t=null);var e=(t=t||new Date).getFullYear(),n=t.getMonth()+1;return parseInt(e+(n<10?"0":"")+n)},t.dateId=function(t){void 0===t&&(t=null);var e=(t=t||new Date).getMonth()+1,n=e<10?"0":"",i=t.getDate(),r=i<10?"0":"";return parseInt(t.getFullYear()+n+e+r+i)},t.weekId=function(t,e){void 0===t&&(t=null),void 0===e&&(e=!0),t=t||new Date;var n=new Date;n.setTime(t.getTime()),n.setDate(1),n.setMonth(0);var i=n.getFullYear(),r=n.getDay();0==r&&(r=7);var o=!1;r<=4?(o=r>1,n.setDate(n.getDate()-(r-1))):n.setDate(n.getDate()+7-r+1);var s=this.diffDay(t,n,!1);if(s<0)return n.setDate(1),n.setMonth(0),n.setDate(n.getDate()-1),this.weekId(n,!1);var a=s/7,c=Math.floor(a)+1;if(53==c){n.setTime(t.getTime()),n.setDate(n.getDate()-1);var h=n.getDay();if(0==h&&(h=7),e&&(!o||h<4))return n.setFullYear(n.getFullYear()+1),n.setDate(1),n.setMonth(0),this.weekId(n,!1)}return parseInt(i+"00"+(c>9?"":"0")+c)},t.diffDay=function(t,e,n){void 0===n&&(n=!1);var i=(t.getTime()-e.getTime())/864e5;return n?Math.ceil(i):Math.floor(i)},t.getFirstDayOfWeek=function(t){var e=(t=t||new Date).getDay()||7;return new Date(t.getFullYear(),t.getMonth(),t.getDate()+1-e,0,0,0,0)},t.getFirstOfDay=function(t){return(t=t||new Date).setHours(0,0,0,0),t},t.getNextFirstOfDay=function(t){return new Date(this.getFirstOfDay(t).getTime()+864e5)},t.formatDate=function(t){var e=t.getFullYear(),n=t.getMonth()+1;n=n<10?"0"+n:n;var i=t.getDate();return e+"-"+n+"-"+(i=i<10?"0"+i:i)},t.formatDateTime=function(t){var e=t.getFullYear(),n=t.getMonth()+1;n=n<10?"0"+n:n;var i=t.getDate();i=i<10?"0"+i:i;var r=t.getHours(),o=t.getMinutes();o=o<10?"0"+o:o;var s=t.getSeconds();return e+"-"+n+"-"+i+" "+r+":"+o+":"+(s=s<10?"0"+s:s)},t.parseDate=function(t){var e=Date.parse(t);return isNaN(e)?new Date:new Date(Date.parse(t.replace(/-/g,"/")))},t.secondToTime=function(t,e,n){void 0===t&&(t=0),void 0===e&&(e=":"),void 0===n&&(n=!0);var i=Math.floor(t/3600),r=Math.floor(t%3600/60),o=Math.floor(t%3600%60),s=i.toString(),a=r.toString(),c=o.toString();return i<10&&(s="0"+s),r<10&&(a="0"+a),o<10&&(c="0"+c),n?s+e+a+e+c:a+e+c},t.timeToMillisecond=function(t,e){void 0===e&&(e=":");for(var n=t.split(e),i=0,r=n.length,o=0;o-1?this.os="iOS":i.indexOf("android")>-1&&(this.os="Android");var r=n.language;r=r.indexOf("zh")>-1?"zh-CN":"en-US",this.language=r}},e}(egret.Capabilities);t.GraphicsCapabilities=e}(es||(es={})),function(t){var e=function(){function e(){this.setup(),this.graphicsCapabilities=new t.GraphicsCapabilities,this.graphicsCapabilities.initialize(this)}return Object.defineProperty(e.prototype,"viewport",{get:function(){return this._viewport},enumerable:!0,configurable:!0}),e.prototype.setup=function(){this._viewport=new t.Viewport(0,0,t.Core._instance.stage.stageWidth,t.Core._instance.stage.stageHeight)},e}();t.GraphicsDevice=e}(es||(es={})),function(t){var e=function(){function e(t,e,n,i){this._x=t,this._y=e,this._width=n,this._height=i,this._minDepth=0,this._maxDepth=1}return Object.defineProperty(e.prototype,"width",{get:function(){return this._width},set:function(t){this._width=t},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"height",{get:function(){return this._height},set:function(t){this._height=t},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"aspectRatio",{get:function(){return 0!=this._height&&0!=this._width?this._width/this._height:0},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"bounds",{get:function(){return new t.Rectangle(this._x,this._y,this._width,this._height)},set:function(t){this._x=t.x,this._y=t.y,this._width=t.width,this._height=t.height},enumerable:!0,configurable:!0}),e}();t.Viewport=e}(es||(es={})),function(t){var e=function(e){function n(){return e.call(this,t.PostProcessor.default_vert,n.blur_frag,{screenWidth:t.Core.graphicsDevice.viewport.width,screenHeight:t.Core.graphicsDevice.viewport.height})||this}return __extends(n,e),n.blur_frag="precision mediump float;\nuniform sampler2D uSampler;\nuniform float screenWidth;\nuniform float screenHeight;\nfloat normpdf(in float x, in float sigma)\n{\nreturn 0.39894*exp(-0.5*x*x/(sigma*sigma))/sigma;\n}\nvoid main()\n{\nvec3 c = texture2D(uSampler, gl_FragCoord.xy / vec2(screenWidth, screenHeight).xy).rgb;\nconst int mSize = 11;\nconst int kSize = (mSize - 1)/2;\nfloat kernel[mSize];\nvec3 final_colour = vec3(0.0);\nfloat sigma = 7.0;\nfloat z = 0.0;\nfor (int j = 0; j <= kSize; ++j)\n{\nkernel[kSize+j] = kernel[kSize-j] = normpdf(float(j),sigma);\n}\nfor (int j = 0; j < mSize; ++j)\n{\nz += kernel[j];\n}\nfor (int i = -kSize; i <= kSize; ++i)\n{\nfor (int j = -kSize; j <= kSize; ++j)\n{\nfinal_colour += kernel[kSize+j]*kernel[kSize+i]*texture2D(uSampler, (gl_FragCoord.xy+vec2(float(i),float(j))) / vec2(screenWidth, screenHeight).xy).rgb;\n}\n}\ngl_FragColor = vec4(final_colour/(z*z), 1.0);\n}",n}(egret.CustomFilter);t.GaussianBlurEffect=e}(es||(es={})),function(t){var e=function(t){function e(){return t.call(this,e.vertSrc,e.fragmentSrc)||this}return __extends(e,t),e.vertSrc="attribute vec2 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform vec2 projectionVector;\nvarying vec2 vTextureCoord;\nconst vec2 center = vec2(-1.0, 1.0);\nvoid main(void) {\n gl_Position = vec4( (aVertexPosition / projectionVector) + center , 0.0, 1.0);\n vTextureCoord = aTextureCoord;\n}",e.fragmentSrc="precision lowp float;\nvarying vec2 vTextureCoord;\nuniform sampler2D uSampler;\n#define SAMPLE_COUNT 15\nuniform vec2 _sampleOffsets[SAMPLE_COUNT];\nuniform float _sampleWeights[SAMPLE_COUNT];\nvoid main(void) {\nvec4 c = vec4(0, 0, 0, 0);\nfor( int i = 0; i < SAMPLE_COUNT; i++ )\n c += texture2D( uSampler, vTextureCoord + _sampleOffsets[i] ) * _sampleWeights[i];\ngl_FragColor = c;\n}",e}(egret.CustomFilter);t.PolygonLightEffect=e}(es||(es={})),function(t){var e=function(){function e(t){void 0===t&&(t=null),this.enabled=!0,this.effect=t}return e.prototype.onAddedToScene=function(e){this.scene=e,this.shape=new egret.Shape,this.shape.graphics.beginFill(16777215,1),this.shape.graphics.drawRect(0,0,t.Core.graphicsDevice.viewport.width,t.Core.graphicsDevice.viewport.height),this.shape.graphics.endFill(),e.addChild(this.shape)},e.prototype.process=function(){this.drawFullscreenQuad()},e.prototype.onSceneBackBufferSizeChanged=function(t,e){},e.prototype.unload=function(){this.effect&&(this.effect=null),this.scene.removeChild(this.shape),this.scene=null},e.prototype.drawFullscreenQuad=function(){this.scene.filters=[this.effect]},e.default_vert="attribute vec2 aVertexPosition;\nattribute vec2 aTextureCoord;\nattribute vec2 aColor;\nuniform vec2 projectionVector;\nvarying vec2 vTextureCoord;\nvarying vec4 vColor;\nconst vec2 center = vec2(-1.0, 1.0);\nvoid main(void) {\ngl_Position = vec4( (aVertexPosition / projectionVector) + center , 0.0, 1.0);\nvTextureCoord = aTextureCoord;\nvColor = vec4(aColor.x, aColor.x, aColor.x, aColor.x);\n}",e}();t.PostProcessor=e}(es||(es={})),function(t){var e=function(e){function n(){return null!==e&&e.apply(this,arguments)||this}return __extends(n,e),n.prototype.onAddedToScene=function(n){e.prototype.onAddedToScene.call(this,n),this.effect=new t.GaussianBlurEffect},n}(t.PostProcessor);t.GaussianBlurPostProcessor=e}(es||(es={})),function(t){var e=function(){function t(t,e){void 0===e&&(e=null),this.renderOrder=0,this.camera=e,this.renderOrder=t}return t.prototype.onAddedToScene=function(t){},t.prototype.unload=function(){},t.prototype.onSceneBackBufferSizeChanged=function(t,e){},t.prototype.compareTo=function(t){return this.renderOrder-t.renderOrder},t.prototype.beginRender=function(t){},t.prototype.renderAfterStateCheck=function(t,e){t.render(e)},t}();t.Renderer=e}(es||(es={})),function(t){var e=function(t){function e(){return t.call(this,0,null)||this}return __extends(e,t),e.prototype.render=function(t){var e=this.camera?this.camera:t.camera;this.beginRender(e);for(var n=0;nn?n:t},e.pointOnCirlce=function(n,i,r){var o=e.toRadians(r);return new t.Vector2(Math.cos(o)*o+n.x,Math.sin(o)*o+n.y)},e.isEven=function(t){return t%2==0},e.clamp01=function(t){return t<0?0:t>1?1:t},e.angleBetweenVectors=function(t,e){return Math.atan2(e.y-t.y,e.x-t.x)},e.Epsilon=1e-5,e.Rad2Deg=57.29578,e.Deg2Rad=.0174532924,e}();t.MathHelper=e}(es||(es={})),function(t){t.matrixPool=[];var e=function(e){function n(){return null!==e&&e.apply(this,arguments)||this}return __extends(n,e),Object.defineProperty(n.prototype,"m11",{get:function(){return this.a},set:function(t){this.a=t},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"m12",{get:function(){return this.b},set:function(t){this.b=t},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"m21",{get:function(){return this.c},set:function(t){this.c=t},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"m22",{get:function(){return this.d},set:function(t){this.d=t},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"m31",{get:function(){return this.tx},set:function(t){this.tx=t},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"m32",{get:function(){return this.ty},set:function(t){this.ty=t},enumerable:!0,configurable:!0}),n.create=function(){var e=t.matrixPool.pop();return e||(e=new n),e},n.prototype.identity=function(){return this.a=this.d=1,this.b=this.c=this.tx=this.ty=0,this},n.prototype.translate=function(t,e){return this.tx+=t,this.ty+=e,this},n.prototype.scale=function(t,e){return 1!==t&&(this.a*=t,this.c*=t,this.tx*=t),1!==e&&(this.b*=e,this.d*=e,this.ty*=e),this},n.prototype.rotate=function(t){if(0!==(t=+t)){t/=DEG_TO_RAD;var e=Math.cos(t),n=Math.sin(t),i=this.a,r=this.b,o=this.c,s=this.d,a=this.tx,c=this.ty;this.a=i*e-r*n,this.b=i*n+r*e,this.c=o*e-s*n,this.d=o*n+s*e,this.tx=a*e-c*n,this.ty=a*n+c*e}return this},n.prototype.invert=function(){return this.$invertInto(this),this},n.prototype.add=function(t){return this.m11+=t.m11,this.m12+=t.m12,this.m21+=t.m21,this.m22+=t.m22,this.m31+=t.m31,this.m32+=t.m32,this},n.prototype.substract=function(t){return this.m11-=t.m11,this.m12-=t.m12,this.m21-=t.m21,this.m22-=t.m22,this.m31-=t.m31,this.m32-=t.m32,this},n.prototype.divide=function(t){return this.m11/=t.m11,this.m12/=t.m12,this.m21/=t.m21,this.m22/=t.m22,this.m31/=t.m31,this.m32/=t.m32,this},n.prototype.multiply=function(t){var e=this.m11*t.m11+this.m12*t.m21,n=this.m11*t.m12+this.m12*t.m22,i=this.m21*t.m11+this.m22*t.m21,r=this.m21*t.m12+this.m22*t.m22,o=this.m31*t.m11+this.m32*t.m21+t.m31,s=this.m31*t.m12+this.m32*t.m22+t.m32;return this.m11=e,this.m12=n,this.m21=i,this.m22=r,this.m31=o,this.m32=s,this},n.prototype.determinant=function(){return this.m11*this.m22-this.m12*this.m21},n.prototype.release=function(e){e&&t.matrixPool.push(e)},n}(egret.Matrix);t.Matrix2D=e}(es||(es={})),function(t){var e=function(e){function n(){return null!==e&&e.apply(this,arguments)||this}return __extends(n,e),Object.defineProperty(n.prototype,"max",{get:function(){return new t.Vector2(this.right,this.bottom)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"center",{get:function(){return new t.Vector2(this.x+this.width/2,this.y+this.height/2)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"location",{get:function(){return new t.Vector2(this.x,this.y)},set:function(t){this.x=t.x,this.y=t.y},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"size",{get:function(){return new t.Vector2(this.width,this.height)},set:function(t){this.width=t.x,this.height=t.y},enumerable:!0,configurable:!0}),n.fromMinMax=function(t,e,i,r){return new n(t,e,i-t,r-e)},n.rectEncompassingPoints=function(t){for(var e=Number.POSITIVE_INFINITY,n=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY,r=Number.NEGATIVE_INFINITY,o=0;oi&&(i=s.x),s.yr&&(r=s.y)}return this.fromMinMax(e,n,i,r)},n.prototype.intersects=function(t){return t.leftthis.x+this.width)return e}else{var i=1/t.direction.x,r=(this.x-t.start.x)*i,o=(this.x+this.width-t.start.x)*i;if(r>o){var s=r;r=o,o=s}if((e=Math.max(r,e))>(n=Math.min(o,n)))return e}if(Math.abs(t.direction.y)<1e-6){if(t.start.ythis.y+this.height)return e}else{var a=1/t.direction.y,c=(this.y-t.start.y)*a,h=(this.y+this.height-t.start.y)*a;if(c>h){var u=c;c=h,h=u}if((e=Math.max(c,e))>(n=Math.max(h,n)))return e}return e},n.prototype.containsRect=function(t){return this.x<=t.x&&t.x1)return!1;var u=(c.x*o.y-c.y*o.x)/a;return!(u<0||u>1)},n.lineToLineIntersection=function(e,n,i,r){var o=new t.Vector2(0,0),s=t.Vector2.subtract(n,e),a=t.Vector2.subtract(r,i),c=s.x*a.y-s.y*a.x;if(0==c)return o;var h=t.Vector2.subtract(i,e),u=(h.x*a.y-h.y*a.x)/c;if(u<0||u>1)return o;var l=(h.x*s.y-h.y*s.x)/c;return l<0||l>1?o:o=t.Vector2.add(e,new t.Vector2(u*s.x,u*s.y))},n.closestPointOnLine=function(e,n,i){var r=t.Vector2.subtract(n,e),o=t.Vector2.subtract(i,e),s=t.Vector2.dot(o,r)/t.Vector2.dot(r,r);return s=t.MathHelper.clamp(s,0,1),t.Vector2.add(e,new t.Vector2(r.x*s,r.y*s))},n.isCircleToCircle=function(e,n,i,r){return t.Vector2.distanceSquared(e,i)<(n+r)*(n+r)},n.isCircleToLine=function(e,n,i,r){return t.Vector2.distanceSquared(e,this.closestPointOnLine(i,r,e))=t&&r.y>=e&&r.x=t+i&&(s|=e.right),o.y=n+r&&(s|=e.bottom),s},n}();t.Collisions=n}(es||(es={})),function(t){var e=function(){function e(){}return e.reset=function(){this._spatialHash=new t.SpatialHash(this.spatialHashCellSize)},e.clear=function(){this._spatialHash.clear()},e.overlapCircleAll=function(t,e,n,i){if(void 0===i&&(i=-1),0!=n.length)return this._spatialHash.overlapCircle(t,e,n,i);console.error("An empty results array was passed in. No results will ever be returned.")},e.boxcastBroadphase=function(t,e){return void 0===e&&(e=this.allLayers),this._spatialHash.aabbBroadphase(t,null,e)},e.boxcastBroadphaseExcludingSelf=function(t,e,n){return void 0===n&&(n=this.allLayers),this._spatialHash.aabbBroadphase(e,t,n)},e.addCollider=function(t){e._spatialHash.register(t)},e.removeCollider=function(t){e._spatialHash.remove(t)},e.updateCollider=function(t){this._spatialHash.remove(t),this._spatialHash.register(t)},e.debugDraw=function(t){this._spatialHash.debugDraw(t,2)},e.spatialHashCellSize=100,e.allLayers=-1,e.raycastsHitTriggers=!1,e.raycastsStartInColliders=!1,e}();t.Physics=e}(es||(es={})),function(t){var e=function(){return function(e,n){this.start=e,this.end=n,this.direction=t.Vector2.subtract(this.end,this.start)}}();t.Ray2D=e}(es||(es={})),function(t){var e=function(){function e(e,n,i,r,o){this.fraction=0,this.distance=0,this.point=t.Vector2.zero,this.normal=t.Vector2.zero,this.collider=e,this.fraction=n,this.distance=i,this.point=r,this.centroid=t.Vector2.zero}return e.prototype.setValues=function(t,e,n,i){this.collider=t,this.fraction=e,this.distance=n,this.point=i},e.prototype.setValuesNonCollider=function(t,e,n,i){this.fraction=t,this.distance=e,this.point=n,this.normal=i},e.prototype.reset=function(){this.collider=null,this.fraction=this.distance=0},e.prototype.toString=function(){return"[RaycastHit] fraction: "+this.fraction+", distance: "+this.distance+", normal: "+this.normal+", centroid: "+this.centroid+", point: "+this.point},e}();t.RaycastHit=e}(es||(es={})),function(t){var e=function(){function t(){}return t.prototype.clone=function(){return ObjectUtils.clone(this)},t}();t.Shape=e}(es||(es={})),function(t){var e=function(e){function n(t,n){var i=e.call(this)||this;return i._areEdgeNormalsDirty=!0,i.isUnrotated=!0,i.setPoints(t),i.isBox=n,i}return __extends(n,e),Object.defineProperty(n.prototype,"edgeNormals",{get:function(){return this._areEdgeNormalsDirty&&this.buildEdgeNormals(),this._edgeNormals},enumerable:!0,configurable:!0}),n.prototype.setPoints=function(t){this.points=t,this.recalculateCenterAndEdgeNormals(),this._originalPoints=[];for(var e=0;e=this.points.length?this.points[0]:this.points[i+1];var o=t.Vector2Ext.perpendicular(r,e);o=t.Vector2.normalize(o),this._edgeNormals[i]=o}},n.buildSymmetricalPolygon=function(e,n){for(var i=new Array(e),r=0;rr&&(r=s,i=o)}return e[i]},n.getClosestPointOnPolygonToPoint=function(e,n,i,r){i=Number.MAX_VALUE,r=new t.Vector2(0,0);for(var o,s=new t.Vector2(0,0),a=0;ae.y!=this.points[r].y>e.y&&e.x<(this.points[r].x-this.points[i].x)*(e.y-this.points[i].y)/(this.points[r].y-this.points[i].y)+this.points[i].x&&(n=!n);return n},n.prototype.pointCollidesWithShape=function(e,n){return t.ShapeCollisions.pointToPoly(e,this,n)},n}(t.Shape);t.Polygon=e}(es||(es={})),function(t){var e=function(e){function n(t,i){var r=e.call(this,n.buildBox(t,i),!0)||this;return r.width=t,r.height=i,r}return __extends(n,e),n.buildBox=function(e,n){var i=e/2,r=n/2,o=new Array(4);return o[0]=new t.Vector2(-i,-r),o[1]=new t.Vector2(i,-r),o[2]=new t.Vector2(i,r),o[3]=new t.Vector2(-i,r),o},n.prototype.updateBox=function(e,n){this.width=e,this.height=n;var i=e/2,r=n/2;this.points[0]=new t.Vector2(-i,-r),this.points[1]=new t.Vector2(i,-r),this.points[2]=new t.Vector2(i,r),this.points[3]=new t.Vector2(-i,r);for(var o=0;o1)return s;var a,c=t.Vector2.add(o.start,t.Vector2.add(o.direction,new t.Vector2(s))),h=0;c.xn.bounds.right&&(h|=1),c.yn.bounds.bottom&&(h|=2);var u=a+h;return 3==u&&console.log("m == 3. corner "+t.Time.frameCount),s},e}();t.RealtimeCollisions=e}(es||(es={})),function(t){var e=function(){function e(){}return e.polygonToPolygon=function(e,n,i){for(var r,o=!0,s=e.edgeNormals,a=n.edgeNormals,c=Number.POSITIVE_INFINITY,h=new t.Vector2,u=t.Vector2.subtract(e.position,n.position),l=0;l0&&(o=!1),!o)return!1;(m=Math.abs(m))r&&(r=o);return{min:i,max:r}},e.circleToPolygon=function(e,n,i){var r,o=t.Vector2.subtract(e.position,n.position),s=t.Polygon.getClosestPointOnPolygonToPoint(n.points,o,0,i.normal),a=n.containsPoint(e.position);if(0>e.radius*e.radius&&!a)return!1;a?r=t.Vector2.multiply(i.normal,new t.Vector2(Math.sqrt(0)-e.radius)):r=t.Vector2.multiply(i.normal,new t.Vector2(e.radius));return i.minimumTranslationVector=r,i.point=t.Vector2.add(s,n.position),!0},e.circleToBox=function(e,n,i){var r=n.bounds.getClosestPointOnRectangleBorderToPoint(e.position,i.normal);if(n.containsPoint(e.position)){i.point=r;var o=t.Vector2.add(r,t.Vector2.multiply(i.normal,new t.Vector2(e.radius)));return i.minimumTranslationVector=t.Vector2.subtract(e.position,o),!0}var s=t.Vector2.distanceSquared(r,e.position);if(0==s)i.minimumTranslationVector=t.Vector2.multiply(i.normal,new t.Vector2(e.radius));else if(s<=e.radius*e.radius){i.normal=t.Vector2.subtract(e.position,r);var a=i.normal.length()-e.radius;return i.point=r,i.normal=t.Vector2Ext.normalize(i.normal),i.minimumTranslationVector=t.Vector2.multiply(new t.Vector2(a),i.normal),!0}return!1},e.pointToCircle=function(e,n,i){var r=t.Vector2.distanceSquared(e,n.position),o=1+n.radius;if(r1)return!1;var l=(h.x*s.y-h.y*s.x)/c;return!(l<0||l>1)&&(o=o.add(e).add(t.Vector2.multiply(new t.Vector2(u),s)),!0)},e.lineToCircle=function(e,n,i,r){var o=t.Vector2.distance(e,n),s=t.Vector2.divide(t.Vector2.subtract(n,e),new t.Vector2(o)),a=t.Vector2.subtract(e,i.position),c=t.Vector2.dot(a,s),h=t.Vector2.dot(a,a)-i.radius*i.radius;if(h>0&&c>0)return!1;var u=c*c-h;return!(u<0)&&(r.fraction=-c-Math.sqrt(u),r.fraction<0&&(r.fraction=0),r.point=t.Vector2.add(e,t.Vector2.multiply(new t.Vector2(r.fraction),s)),r.distance=t.Vector2.distance(e,r.point),r.normal=t.Vector2.normalize(t.Vector2.subtract(r.point,i.position)),r.fraction=r.distance/o,!0)},e.boxToBoxCast=function(e,n,i,r){var o=this.minkowskiDifference(e,n);if(o.contains(0,0)){var s=o.getClosestPointOnBoundsToOrigin();return!s.equals(t.Vector2.zero)&&(r.normal=new t.Vector2(-s.x),r.normal=r.normal.normalize(),r.distance=0,r.fraction=0,!0)}var a=new t.Ray2D(t.Vector2.zero,new t.Vector2(-i.x)),c=o.rayIntersects(a);return c<=1&&(r.fraction=c,r.distance=i.length()*c,r.normal=new t.Vector2(-i.x),r.normal=r.normal.normalize(),r.centroid=t.Vector2.add(e.bounds.center,t.Vector2.multiply(i,new t.Vector2(c))),!0)},e}();t.ShapeCollisions=e}(es||(es={})),function(t){var e=function(){function e(e){void 0===e&&(e=100),this.gridBounds=new t.Rectangle,this._overlapTestCircle=new t.Circle(0),this._cellDict=new n,this._tempHashSet=[],this._cellSize=e,this._inverseCellSize=1/this._cellSize,this._raycastParser=new i}return e.prototype.register=function(e){var n=e.bounds;e.registeredPhysicsBounds=n;var i=this.cellCoords(n.x,n.y),r=this.cellCoords(n.right,n.bottom);this.gridBounds.contains(i.x,i.y)||(this.gridBounds=t.RectangleExt.union(this.gridBounds,i)),this.gridBounds.contains(r.x,r.y)||(this.gridBounds=t.RectangleExt.union(this.gridBounds,r));for(var o=i.x;o<=r.x;o++)for(var s=i.y;s<=r.y;s++){var a=this.cellAtPosition(o,s,!0);a.firstOrDefault(function(t){return t.hashCode==e.hashCode})||a.push(e)}},e.prototype.remove=function(t){for(var e=t.registeredPhysicsBounds,n=this.cellCoords(e.x,e.y),i=this.cellCoords(e.right,e.bottom),r=n.x;r<=i.x;r++)for(var o=n.y;o<=i.y;o++){var s=this.cellAtPosition(r,o);s?s.remove(t):console.error("removing Collider ["+t+"] from a cell that it is not present in")}},e.prototype.removeWithBruteForce=function(t){this._cellDict.remove(t)},e.prototype.clear=function(){this._cellDict.clear()},e.prototype.debugDraw=function(t,e){void 0===e&&(e=1);for(var n=this.gridBounds.x;n<=this.gridBounds.right;n++)for(var i=this.gridBounds.y;i<=this.gridBounds.bottom;i++){var r=this.cellAtPosition(n,i);r&&r.length>0&&this.debugDrawCellDetails(n,i,r.length,t,e)}},e.prototype.aabbBroadphase=function(e,n,i){this._tempHashSet.length=0;for(var r=this.cellCoords(e.x,e.y),o=this.cellCoords(e.right,e.bottom),s=r.x;s<=o.x;s++)for(var a=r.y;a<=o.y;a++){var c=this.cellAtPosition(s,a);if(c)for(var h=function(r){var o=c[r];if(o==n||!t.Flags.isFlagSet(i,o.physicsLayer))return"continue";e.intersects(o.bounds)&&(u._tempHashSet.firstOrDefault(function(t){return t.hashCode==o.hashCode})||u._tempHashSet.push(o))},u=this,l=0;ln;i--)if(t[i]0&&t[r-1]>i;r--)t[r]=t[r-1];t[r]=i}},t.binarySearch=function(t,e){for(var n=0,i=t.length,r=n+i>>1;n=t[r]&&(n=r+1),r=n+i>>1;return t[n]==e?n:-1},t.findElementIndex=function(t,e){for(var n=t.length,i=0;it[e]&&(e=i);return e},t.getMinElementIndex=function(t){for(var e=0,n=t.length,i=1;i=0;--r)n.unshift(e[r]);return n},t.getDifferAry=function(t,e){t=this.getUniqueAry(t),e=this.getUniqueAry(e);for(var n=t.concat(e),i={},r=[],o=n.length,s=0;s=0;e-=1)t.splice(e,1)},t.cloneList=function(t){return t?t.slice(0,t.length):null},t.equals=function(t,e){if(t==e)return!0;var n=t.length;if(n!=e.length)return!1;for(;n--;)if(t[n]!=e[n])return!1;return!0},t.insert=function(t,e,n){if(!t)return null;var i=t.length;if(e>i&&(e=i),e<0&&(e=0),e==i)t.push(n);else if(0==e)t.unshift(n);else{for(var r=i-1;r>=e;r-=1)t[r+1]=t[r];t[e]=n}return n},t}(),Base64Utils=function(){function t(){}return t.decode=function(t,e){void 0===e&&(e=!0);var n,i,r,o,s,a,c="",h=0;for(t=(t=this.getConfKey(t)).replace(/[^A-Za-z0-9\+\/\=]/g,"");h>4,i=(15&o)<<4|(s=this._keyAll.indexOf(t.charAt(h++)))>>2,r=(3&s)<<6|(a=this._keyAll.indexOf(t.charAt(h++))),c+=String.fromCharCode(n),64!=s&&(0==i?e&&(c+=String.fromCharCode(i)):c+=String.fromCharCode(i)),64!=a&&(0==r?e&&(c+=String.fromCharCode(r)):c+=String.fromCharCode(r));return c=this._utf8_decode(c)},t._utf8_encode=function(t){t=t.replace(/\r\n/g,"\n");for(var e="",n=0;n127&&i<2048?(e+=String.fromCharCode(i>>6|192),e+=String.fromCharCode(63&i|128)):(e+=String.fromCharCode(i>>12|224),e+=String.fromCharCode(i>>6&63|128),e+=String.fromCharCode(63&i|128))}return e},t._utf8_decode=function(t){for(var e="",n=0,i=0,r=0,o=0;n191&&i<224?(r=t.charCodeAt(n+1),e+=String.fromCharCode((31&i)<<6|63&r),n+=2):(r=t.charCodeAt(n+1),o=t.charCodeAt(n+2),e+=String.fromCharCode((15&i)<<12|(63&r)<<6|63&o),n+=3);return e},t.getConfKey=function(t){return t.slice(1,t.length)},t._keyNum="0123456789+/",t._keyStr="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",t._keyAll=t._keyNum+t._keyStr,t.encode=function(t){var e,n,i,r,o,s,a,c="",h=0;for(t=this._utf8_encode(t);h>2,o=(3&e)<<4|(n=t.charCodeAt(h++))>>4,s=(15&n)<<2|(i=t.charCodeAt(h++))>>6,a=63&i,isNaN(n)?s=a=64:isNaN(i)&&(a=64),c=c+this._keyAll.charAt(r)+this._keyAll.charAt(o)+this._keyAll.charAt(s)+this._keyAll.charAt(a);return this._keyStr.charAt(Math.floor(Math.random()*this._keyStr.length))+c},t}();!function(t){var e=function(){function t(){this.loadedAssets=new Map}return t.prototype.loadRes=function(t,e){var n=this;return void 0===e&&(e=!0),new Promise(function(i,r){var o=n.loadedAssets.get(t);o?i(o):e?RES.getResAsync(t).then(function(e){n.loadedAssets.set(t,e),i(e)}).catch(function(e){console.error("资源加载错误:",t,e),r(e)}):RES.getResByUrl(t).then(function(e){n.loadedAssets.set(t,e),i(e)}).catch(function(e){console.error("资源加载错误:",t,e),r(e)})})},t.prototype.dispose=function(){this.loadedAssets.forEach(function(t){t.dispose()}),this.loadedAssets.clear()},t}();t.ContentManager=e}(es||(es={})),function(t){var e=function(){function e(){}return e.drawLine=function(e,n,i,r,o){void 0===o&&(o=1),this.drawLineAngle(e,n,t.MathHelper.angleBetweenVectors(n,i),t.Vector2.distance(n,i),r,o)},e.drawLineAngle=function(t,e,n,i,r,o){void 0===o&&(o=1),t.graphics.beginFill(r),t.graphics.drawRect(e.x,e.y,1,1),t.graphics.endFill(),t.scaleX=i,t.scaleY=o,t.$anchorOffsetX=0,t.$anchorOffsetY=0,t.rotation=n},e.drawHollowRect=function(t,e,n,i){void 0===i&&(i=1),this.drawHollowRectR(t,e.x,e.y,e.width,e.height,n,i)},e.drawHollowRectR=function(e,n,i,r,o,s,a){void 0===a&&(a=1);var c=new t.Vector2(n,i).round(),h=new t.Vector2(n+r,i).round(),u=new t.Vector2(n+r,i+o).round(),l=new t.Vector2(n,i+o).round();this.drawLine(e,c,h,s,a),this.drawLine(e,h,u,s,a),this.drawLine(e,u,l,s,a),this.drawLine(e,l,c,s,a)},e.drawPixel=function(e,n,i,r){void 0===r&&(r=1);var o=new t.Rectangle(n.x,n.y,r,r);1!=r&&(o.x-=.5*r,o.y-=.5*r),e.graphics.beginFill(i),e.graphics.drawRect(o.x,o.y,o.width,o.height),e.graphics.endFill()},e.getColorMatrix=function(t){var e=[1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0];return e[0]=Math.floor(t/256/256)/255,e[6]=Math.floor(t/256%256)/255,e[12]=t%256/255,new egret.ColorMatrixFilter(e)},e}();t.DrawUtils=e}(es||(es={})),function(t){var e=function(){return function(t,e){this.func=t,this.context=e}}();t.FuncPack=e;var n=function(){function t(){this._messageTable=new Map}return t.prototype.addObserver=function(t,n,i){var r=this._messageTable.get(t);r||(r=[],this._messageTable.set(t,r)),-1!=r.findIndex(function(t){return t.func==n})&&console.warn("您试图添加相同的观察者两次"),r.push(new e(n,i))},t.prototype.removeObserver=function(t,e){var n=this._messageTable.get(t),i=n.findIndex(function(t){return t.func==e});-1!=i&&n.removeAt(i)},t.prototype.emit=function(t,e){var n=this._messageTable.get(t);if(n)for(var i=n.length-1;i>=0;i--)n[i].func.call(n[i].context,e)},t}();t.Emitter=n}(es||(es={})),function(t){var e=function(){function t(){}return Object.defineProperty(t.prototype,"enabled",{get:function(){return this._enabled},set:function(t){this.setEnabled(t)},enumerable:!0,configurable:!0}),t.prototype.setEnabled=function(t){this._enabled!=t&&(this._enabled=t,this._enabled?this.onEnabled():this.onDisabled())},t.prototype.onEnabled=function(){},t.prototype.onDisabled=function(){},t.prototype.update=function(){},t}();t.GlobalManager=e}(es||(es={})),function(t){var e=function(){function e(){this.x=0,this.y=0,this.touchPoint=-1,this.touchDown=!1}return Object.defineProperty(e.prototype,"position",{get:function(){return new t.Vector2(this.x,this.y)},enumerable:!0,configurable:!0}),e.prototype.reset=function(){this.x=0,this.y=0,this.touchDown=!1,this.touchPoint=-1},e}();t.TouchState=e;var n=function(){function n(){}return Object.defineProperty(n,"gameTouchs",{get:function(){return this._gameTouchs},enumerable:!0,configurable:!0}),Object.defineProperty(n,"resolutionScale",{get:function(){return this._resolutionScale},enumerable:!0,configurable:!0}),Object.defineProperty(n,"totalTouchCount",{get:function(){return this._totalTouchCount},enumerable:!0,configurable:!0}),Object.defineProperty(n,"touchPosition",{get:function(){return this._gameTouchs[0]?this._gameTouchs[0].position:t.Vector2.zero},enumerable:!0,configurable:!0}),Object.defineProperty(n,"maxSupportedTouch",{get:function(){return t.Core._instance.stage.maxTouches},set:function(e){t.Core._instance.stage.maxTouches=e,this.initTouchCache()},enumerable:!0,configurable:!0}),Object.defineProperty(n,"touchPositionDelta",{get:function(){var e=t.Vector2.subtract(this.touchPosition,this._previousTouchState.position);return e.length()>0&&this.setpreviousTouchState(this._gameTouchs[0]),e},enumerable:!0,configurable:!0}),n.initialize=function(){this._init||(this._init=!0,t.Core._instance.stage.addEventListener(egret.TouchEvent.TOUCH_BEGIN,this.touchBegin,this),t.Core._instance.stage.addEventListener(egret.TouchEvent.TOUCH_MOVE,this.touchMove,this),t.Core._instance.stage.addEventListener(egret.TouchEvent.TOUCH_END,this.touchEnd,this),t.Core._instance.stage.addEventListener(egret.TouchEvent.TOUCH_CANCEL,this.touchEnd,this),t.Core._instance.stage.addEventListener(egret.TouchEvent.TOUCH_RELEASE_OUTSIDE,this.touchEnd,this),this.initTouchCache())},n.scaledPosition=function(e){var n=new t.Vector2(e.x-this._resolutionOffset.x,e.y-this._resolutionOffset.y);return t.Vector2.multiply(n,this.resolutionScale)},n.initTouchCache=function(){this._totalTouchCount=0,this._touchIndex=0,this._gameTouchs.length=0;for(var t=0;t0)for(var e=0;ethis._objectQueue.length;)this._objectQueue.shift()},t.clearCache=function(){this._objectQueue.length=0},t.obtain=function(){return this._objectQueue.length>0?this._objectQueue.shift():[]},t.free=function(t){this._objectQueue.unshift(t),t.length=0},t._objectQueue=[],t}();t.ListPool=e}(es||(es={}));var THREAD_ID=Math.floor(1e3*Math.random())+"-"+Date.now(),nextTick=function(t){setTimeout(t,0)},LockUtils=function(){function t(t){this._keyX="mutex_key_"+t+"_X",this._keyY="mutex_key_"+t+"_Y",this.setItem=egret.localStorage.setItem.bind(localStorage),this.getItem=egret.localStorage.getItem.bind(localStorage),this.removeItem=egret.localStorage.removeItem.bind(localStorage)}return t.prototype.lock=function(){var t=this;return new Promise(function(e,n){var i=function(){t.setItem(t._keyX,THREAD_ID),null===!t.getItem(t._keyY)&&nextTick(i),t.setItem(t._keyY,THREAD_ID),t.getItem(t._keyX)!==THREAD_ID?setTimeout(function(){t.getItem(t._keyY)===THREAD_ID?(e(),t.removeItem(t._keyY)):nextTick(i)},10):(e(),t.removeItem(t._keyY))};i()})},t}();!function(t){var e=function(){function t(t,e){this.first=t,this.second=e}return t.prototype.clear=function(){this.first=this.second=null},t.prototype.equals=function(t){return this.first==t.first&&this.second==t.second},t}();t.Pair=e}(es||(es={}));var RandomUtils=function(){function t(){}return t.randrange=function(t,e,n){if(void 0===n&&(n=1),0==n)throw new Error("step 不能为 0");var i=e-t;if(0==i)throw new Error("没有可用的范围("+t+","+e+")");i<0&&(i=t-e);var r=Math.floor((i+n-1)/n);return Math.floor(this.random()*r)*n+Math.min(t,e)},t.randint=function(t,e){return(t=Math.floor(t))>(e=Math.floor(e))?t++:e++,this.randrange(t,e)},t.randnum=function(t,e){return this.random()*(e-t)+t},t.shuffle=function(t){return t.sort(this._randomCompare),t},t.choice=function(t){if(!t.hasOwnProperty("length"))throw new Error("无法对此对象执行此操作");var e=Math.floor(this.random()*t.length);return t instanceof String?String(t).charAt(e):t[e]},t.sample=function(t,e){var n=t.length;if(e<=0||n=0;)s=Math.floor(this.random()*n);i.push(t[s]),r.push(s)}return i},t.random=function(){return Math.random()},t.boolean=function(t){return void 0===t&&(t=.5),this.random().5?1:-1},t}();!function(t){var e=function(){function e(){}return e.union=function(e,n){var i=new t.Rectangle(n.x,n.y,0,0),r=new t.Rectangle;return r.x=Math.min(e.x,i.x),r.y=Math.min(e.y,i.y),r.width=Math.max(e.right,i.right)-r.x,r.height=Math.max(e.bottom,r.bottom)-r.y,r},e}();t.RectangleExt=e}(es||(es={})),function(t){var e=function(){function e(){this.triangleIndices=[],this._triPrev=new Array(12),this._triNext=new Array(12)}return e.testPointTriangle=function(e,n,i,r){return!(t.Vector2Ext.cross(t.Vector2.subtract(e,n),t.Vector2.subtract(i,n))<0)&&(!(t.Vector2Ext.cross(t.Vector2.subtract(e,i),t.Vector2.subtract(r,i))<0)&&!(t.Vector2Ext.cross(t.Vector2.subtract(e,r),t.Vector2.subtract(n,r))<0))},e.prototype.triangulate=function(n,i){void 0===i&&(i=!0);var r=n.length;this.initialize(r);for(var o=0,s=0;r>3&&o<500;){o++;var a=!0,c=n[this._triPrev[s]],h=n[s],u=n[this._triNext[s]];if(t.Vector2Ext.isTriangleCCW(c,h,u)){var l=this._triNext[this._triNext[s]];do{if(e.testPointTriangle(n[l],c,h,u)){a=!1;break}l=this._triNext[l]}while(l!=this._triPrev[s])}else a=!1;a?(this.triangleIndices.push(this._triPrev[s]),this.triangleIndices.push(s),this.triangleIndices.push(this._triNext[s]),this._triNext[this._triPrev[s]]=this._triNext[s],this._triPrev[this._triNext[s]]=this._triPrev[s],r--,s=this._triPrev[s]):s=this._triNext[s]}this.triangleIndices.push(this._triPrev[s]),this.triangleIndices.push(s),this.triangleIndices.push(this._triNext[s]),i||this.triangleIndices.reverse()},e.prototype.initialize=function(t){this.triangleIndices.length=0,this._triNext.lengtht.MathHelper.Epsilon?e=t.Vector2.divide(e,new t.Vector2(n)):e.x=e.y=0,e},e.transformA=function(t,e,n,i,r,o){for(var s=0;sthis.safeArea.right&&(s.x=this.safeArea.right-s.width),s.topthis.safeArea.bottom&&(s.y=this.safeArea.bottom-s.height),s},n}();t.Layout=n,function(t){t[t.none=0]="none",t[t.left=1]="left",t[t.right=2]="right",t[t.horizontalCenter=4]="horizontalCenter",t[t.top=8]="top",t[t.bottom=16]="bottom",t[t.verticalCenter=32]="verticalCenter",t[t.topLeft=9]="topLeft",t[t.topRight=10]="topRight",t[t.topCenter=12]="topCenter",t[t.bottomLeft=17]="bottomLeft",t[t.bottomRight=18]="bottomRight",t[t.bottomCenter=20]="bottomCenter",t[t.centerLeft=33]="centerLeft",t[t.centerRight=34]="centerRight",t[t.center=36]="center"}(e=t.Alignment||(t.Alignment={}))}(es||(es={})),function(t){var e,n=function(){function t(t){void 0===t&&(t=i),this.getSystemTime=t,this._stopDuration=0,this._completeSlices=[]}return t.prototype.getState=function(){return void 0===this._startSystemTime?e.IDLE:void 0===this._stopSystemTime?e.RUNNING:e.STOPPED},t.prototype.isIdle=function(){return this.getState()===e.IDLE},t.prototype.isRunning=function(){return this.getState()===e.RUNNING},t.prototype.isStopped=function(){return this.getState()===e.STOPPED},t.prototype.slice=function(){return this.recordPendingSlice()},t.prototype.getCompletedSlices=function(){return Array.from(this._completeSlices)},t.prototype.getCompletedAndPendingSlices=function(){return this._completeSlices.concat([this.getPendingSlice()])},t.prototype.getPendingSlice=function(){return this.calculatePendingSlice()},t.prototype.getTime=function(){return this.caculateStopwatchTime()},t.prototype.reset=function(){this._startSystemTime=this._pendingSliceStartStopwatchTime=this._stopSystemTime=void 0,this._stopDuration=0,this._completeSlices=[]},t.prototype.start=function(t){if(void 0===t&&(t=!1),t&&this.reset(),void 0!==this._stopSystemTime){var e=(n=this.getSystemTime())-this._stopSystemTime;this._stopDuration+=e,this._stopSystemTime=void 0}else if(void 0===this._startSystemTime){var n=this.getSystemTime();this._startSystemTime=n,this._pendingSliceStartStopwatchTime=0}},t.prototype.stop=function(t){if(void 0===t&&(t=!1),void 0===this._startSystemTime)return 0;var e=this.getSystemTimeOfCurrentStopwatchTime();return t&&this.recordPendingSlice(this.caculateStopwatchTime(e)),this._stopSystemTime=e,this.getTime()},t.prototype.calculatePendingSlice=function(t){return void 0===this._pendingSliceStartStopwatchTime?Object.freeze({startTime:0,endTime:0,duration:0}):(void 0===t&&(t=this.getTime()),Object.freeze({startTime:this._pendingSliceStartStopwatchTime,endTime:t,duration:t-this._pendingSliceStartStopwatchTime}))},t.prototype.caculateStopwatchTime=function(t){return void 0===this._startSystemTime?0:(void 0===t&&(t=this.getSystemTimeOfCurrentStopwatchTime()),t-this._startSystemTime-this._stopDuration)},t.prototype.getSystemTimeOfCurrentStopwatchTime=function(){return void 0===this._stopSystemTime?this.getSystemTime():this._stopSystemTime},t.prototype.recordPendingSlice=function(t){if(void 0!==this._pendingSliceStartStopwatchTime){void 0===t&&(t=this.getTime());var e=this.calculatePendingSlice(t);return this._pendingSliceStartStopwatchTime=e.endTime,this._completeSlices.push(e),e}return this.calculatePendingSlice()},t}();t.Stopwatch=n,function(t){t.IDLE="IDLE",t.RUNNING="RUNNING",t.STOPPED="STOPPED"}(e||(e={})),t.setDefaultSystemTimeGetter=function(t){void 0===t&&(t=Date.now),i=t};var i=Date.now}(stopwatch||(stopwatch={})),function(t){var e=function(){function e(){this.showLog=!1,this._frameKey="frame",this._logKey="log",this.markers=[],this.stopwacth=new stopwatch.Stopwatch,this._markerNameToIdMap=new Map,this._logs=new Array(2);for(var e=0;e=e.logSnapDuration&&(l.logs[r].snapMin=l.logs[r].min,l.logs[r].snapMax=l.logs[r].max,l.logs[r].snapAvg=l.logs[r].avg,l.logs[r].samples=0)):(l.logs[r].min=h,l.logs[r].max=h,l.logs[r].avg=h,l.logs[r].initialized=!0)}s.markCount=o.nestCount,s.nestCount=o.nestCount}t.stopwacth.reset(),t.stopwacth.start()}})},e.prototype.beginMark=function(t,n,i){var r=this;void 0===i&&(i=0),new LockUtils(this._frameKey).lock().then(function(){if(i<0||i>=e.maxBars)throw new Error("barIndex argument out of range");var o=r._curLog.bars[i];if(o.markCount>=e.maxSamples)throw new Error("exceeded sample count. either set larger number to timeruler.maxsaple or lower sample count");if(o.nestCount>=e.maxNestCall)throw new Error("exceeded nest count. either set larger number to timeruler.maxnestcall or lower nest calls");var s=r._markerNameToIdMap.get(t);isNaN(s)&&(s=r.markers.length,r._markerNameToIdMap.set(t,s)),o.markerNests[o.nestCount++]=o.markCount,o.markers[o.markCount].markerId=s,o.markers[o.markCount].color=n,o.markers[o.markCount].beginTime=r.stopwacth.getTime(),o.markers[o.markCount].endTime=-1})},e.prototype.endMark=function(t,n){var i=this;void 0===n&&(n=0),new LockUtils(this._frameKey).lock().then(function(){if(n<0||n>=e.maxBars)throw new Error("barIndex argument out of range");var r=i._curLog.bars[n];if(r.nestCount<=0)throw new Error("call beginMark method before calling endMark method");var o=i._markerNameToIdMap.get(t);if(isNaN(o))throw new Error("Marker "+t+" is not registered. Make sure you specifed same name as you used for beginMark method");var s=r.markerNests[--r.nestCount];if(r.markers[s].markerId!=o)throw new Error("Incorrect call order of beginMark/endMark method. beginMark(A), beginMark(B), endMark(B), endMark(A) But you can't called it like beginMark(A), beginMark(B), endMark(A), endMark(B).");r.markers[s].endTime=i.stopwacth.getTime()})},e.prototype.getAverageTime=function(t,n){if(t<0||t>=e.maxBars)throw new Error("barIndex argument out of range");var i=0,r=this._markerNameToIdMap.get(n);return r&&(i=this.markers[r].logs[t].avg),i},e.prototype.resetLog=function(){var t=this;new LockUtils(this._logKey).lock().then(function(){var e=parseInt(egret.localStorage.getItem(t._logKey),10);e+=1,egret.localStorage.setItem(t._logKey,e.toString()),t.markers.forEach(function(t){for(var e=0;e0&&(i+=e.barHeight+2*e.barPadding,r=Math.max(r,t.markers[t.markCount-1].endTime))});var o=this.sampleFrames*(1/60*1e3);this._frameAdjust=r>o?Math.max(0,this._frameAdjust)+1:Math.min(0,this._frameAdjust)-1,Math.max(this._frameAdjust)>e.autoAdjustDelay&&(this.sampleFrames=Math.min(e.maxSampleFrames,this.sampleFrames),this.sampleFrames=Math.max(this.targetSampleFrames,r/(1/60*1e3)+1),this._frameAdjust=0);t.y,e.barHeight}},e.prototype.onGraphicsDeviceReset=function(){var n=new t.Layout;this._position=n.place(new t.Vector2(this.width,e.barHeight),0,.01,t.Alignment.bottomCenter).location},e.maxBars=8,e.maxSamples=256,e.maxNestCall=32,e.barHeight=8,e.maxSampleFrames=4,e.logSnapDuration=120,e.barPadding=2,e.autoAdjustDelay=30,e}();t.TimeRuler=e;var n=function(){return function(){this.bars=new Array(e.maxBars),this.bars.fill(new i,0,e.maxBars)}}();t.FrameLog=n;var i=function(){return function(){this.markers=new Array(e.maxSamples),this.markCount=0,this.markerNests=new Array(e.maxNestCall),this.nestCount=0,this.markers.fill(new r,0,e.maxSamples),this.markerNests.fill(0,0,e.maxNestCall)}}();t.MarkerCollection=i;var r=function(){return function(){this.markerId=0,this.beginTime=0,this.endTime=0,this.color=0}}();t.Marker=r;var o=function(){return function(t){this.logs=new Array(e.maxBars),this.name=t,this.logs.fill(new s,0,e.maxBars)}}();t.MarkerInfo=o;var s=function(){return function(){this.snapMin=0,this.snapMax=0,this.snapAvg=0,this.min=0,this.max=0,this.avg=0,this.samples=0,this.color=0,this.initialized=!1}}();t.MarkerLog=s}(es||(es={})); \ No newline at end of file diff --git a/demo/manifest.json b/demo/manifest.json index 2d454643..522c8eec 100644 --- a/demo/manifest.json +++ b/demo/manifest.json @@ -11,12 +11,11 @@ "libs/long/long.js" ], "game": [ - "bin-debug/game/CoreEmitterType.js", "bin-debug/AssetAdapter.js", + "bin-debug/LoadingUI.js", "bin-debug/Main.js", "bin-debug/Platform.js", "bin-debug/ThemeAdapter.js", - "bin-debug/LoadingUI.js", "bin-debug/game/MainScene.js", "bin-debug/game/PlayerController.js", "bin-debug/game/SimplePooled.js", diff --git a/demo/scripts/wxgame/wxgame.ts b/demo/scripts/wxgame/wxgame.ts index be865602..13943ce1 100644 --- a/demo/scripts/wxgame/wxgame.ts +++ b/demo/scripts/wxgame/wxgame.ts @@ -44,6 +44,9 @@ export class WxgamePlugin implements plugins.Command { if (filename == 'main.js') { content += "\n;window.Main = Main;" } + if (filename == 'libs/long/long.js' || filename == 'libs/long/long.min.js'){ + content += "window.Long = long;" + } this.md5Obj[path.basename(filename)] = this.md5(content) file.contents = new Buffer(content); } diff --git a/demo/src/Main.ts b/demo/src/Main.ts index 2233ec36..0ac8bbb8 100644 --- a/demo/src/Main.ts +++ b/demo/src/Main.ts @@ -27,71 +27,29 @@ // ////////////////////////////////////////////////////////////////////////////////////// - -class Main extends eui.UILayer { - public static emitter: Emitter; - public static manager: SceneManager; - - protected createChildren(): void { - super.createChildren(); - - egret.lifecycle.addLifecycleListener((context) => { - // custom lifecycle plugin - }) - - egret.lifecycle.onPause = () => { - egret.ticker.pause(); - } - - egret.lifecycle.onResume = () => { - egret.ticker.resume(); - } - - //inject the custom material parser - //注入自定义的素材解析器 - let assetAdapter = new AssetAdapter(); - egret.registerImplementation("eui.IAssetAdapter", assetAdapter); - egret.registerImplementation("eui.IThemeAdapter", new ThemeAdapter()); - - Main.manager = new SceneManager(this.stage); - Main.emitter = new Emitter(); - this.addEventListener(egret.Event.ENTER_FRAME, this.updateFrame, this); +class Main extends es.Core { + protected initialize() { this.runGame(); } - private updateFrame(evt: egret.Event){ - Main.emitter.emit(CoreEmitterType.Update, evt); + private runGame() { + this.loadResource(); } - private async runGame() { - await this.loadResource(); - this.createGameScene(); - } - private async loadResource() { - try { - const loadingView = new LoadingUI(); - this.stage.addChild(loadingView); - await RES.loadConfig("resource/default.res.json", "resource/"); - await this.loadTheme(); - await RES.loadGroup("preload", 0, loadingView); - this.stage.removeChild(loadingView); - } - catch (e) { - console.error(e); - } - } - - private loadTheme() { - return new Promise((resolve, reject) => { - // load skin theme configuration file, you can manually modify the file. And replace the default skin. - //加载皮肤主题配置文件,可以手动修改这个文件。替换默认皮肤。 - let theme = new eui.Theme("resource/default.thm.json", this.stage); - theme.addEventListener(eui.UIEvent.COMPLETE, () => { - resolve(); - }, this); - - }) + private loadResource() { + const loadingView = new LoadingUI(); + this.stage.addChild(loadingView); + RES.loadConfig("resource/default.res.json", "resource/").then(()=>{ + RES.loadGroup("preload", 0, loadingView).then(()=>{ + this.stage.removeChild(loadingView); + this.createGameScene(); + }).catch(err => { + console.error(err); + }); + }).catch(err =>{ + console.error(err); + }); } /** @@ -99,10 +57,6 @@ class Main extends eui.UILayer { * Create scene interface */ protected createGameScene(): void { - SceneManager.scene = new MainScene(); - - // Main.emitter.addObserver(CoreEmitterType.Update, ()=>{ - // console.log("update emitter"); - // }); + es.Core.scene = new scene.MainScene(); } } diff --git a/demo/src/game/CoreEmitterType.ts b/demo/src/game/CoreEmitterType.ts deleted file mode 100644 index 6f845ce5..00000000 --- a/demo/src/game/CoreEmitterType.ts +++ /dev/null @@ -1,3 +0,0 @@ -enum CoreEmitterType { - Update, -} \ No newline at end of file diff --git a/demo/src/game/MainScene.ts b/demo/src/game/MainScene.ts index 94edd363..6a5b5550 100644 --- a/demo/src/game/MainScene.ts +++ b/demo/src/game/MainScene.ts @@ -1,86 +1,90 @@ -class MainScene extends Scene { - constructor() { - super(); +module scene { + export class MainScene extends es.Scene { + constructor() { + super(); - // this.addEntityProcessor(new SpawnerSystem(new Matcher())); - this.astarTest(); - this.dijkstraTest(); - this.breadthfirstTest(); - } - - public async onStart() { - let sprite = new Sprite(RES.getRes("checkbox_select_disabled_png")); - let bg = this.createEntity("bg"); - bg.addComponent(new SpriteRenderer()).setSprite(sprite).setColor(0xff0000); - bg.addComponent(new PlayerController()); - bg.addComponent(new Mover()); - bg.addComponent(new BoxCollider()); - bg.position = new Vector2(300, 300); - - for (let i = 0; i < 1; i++) { - let sprite = new Sprite(RES.getRes("checkbox_select_disabled_png")); - let player2 = this.createEntity("player2"); - player2.addComponent(new SpriteRenderer()).setSprite(sprite); - player2.position = new Vector2(200, 200); - player2.addComponent(new BoxCollider()); + // this.addEntityProcessor(new SpawnerSystem(new Matcher())); + this.astarTest(); + this.dijkstraTest(); + this.breadthfirstTest(); } - this.camera.follow(bg, CameraStyle.lockOn); + public async onStart() { + let sprite = new es.Sprite(RES.getRes("checkbox_select_disabled_png")); + let bg = this.createEntity("bg"); + bg.addComponent(new es.SpriteRenderer()).setSprite(sprite).setColor(0xff0000); + bg.addComponent(new component.PlayerController()); + bg.addComponent(new es.Mover()); + bg.addComponent(new es.ScrollingSpriteRenderer(sprite)); + bg.addComponent(new es.BoxCollider()); + bg.position = new es.Vector2(Math.random() * 200, Math.random() * 200); - let pool = new ComponentPool(SimplePooled); - let c1 = pool.obtain(); - let c2 = pool.obtain(); - pool.free(c1); - let c1b = pool.obtain(); + for (let i = 0; i < 20; i++) { + let sprite = new es.Sprite(RES.getRes("checkbox_select_disabled_png")); + let player2 = this.createEntity("player2"); + player2.addComponent(new es.SpriteRenderer()).setSprite(sprite); + player2.position = new es.Vector2(Math.random() * 1000, Math.random() * 1000); + player2.addComponent(new es.BoxCollider()); + } - console.log(c1 != c2); - console.log(c1 == c1b); + this.camera.follow(bg, es.CameraStyle.lockOn); - let button = new eui.Button(); - button.label = "切换场景"; - this.addChild(button); - button.addEventListener(egret.TouchEvent.TOUCH_TAP, () => { - SceneManager.startSceneTransition(new FadeTransition(() => { - return new MainScene(); - })); - }, this); + let pool = new es.ComponentPool(component.SimplePooled); + let c1 = pool.obtain(); + let c2 = pool.obtain(); + pool.free(c1); + let c1b = pool.obtain(); + + console.log(c1 != c2); + console.log(c1 == c1b); + + let button = new eui.Button(); + button.label = "切换场景"; + this.addChild(button); + button.addEventListener(egret.TouchEvent.TOUCH_TAP, () => { + es.Core.startSceneTransition(new es.FadeTransition(() => { + return new MainScene(); + })); + }, this); + } + + public breadthfirstTest() { + let graph = new es.UnweightedGraph(); + + graph.addEdgesForNode("a", ["b"]); // a->b + graph.addEdgesForNode("b", ["a", "c", "d"]); // b->a b->c b->d + graph.addEdgesForNode("c", ["a"]); // c->a + graph.addEdgesForNode("d", ["e", "a"]); // d->e d->a + graph.addEdgesForNode("e", ["b"]); // e->b + + // 计算从c到e的路径 + let path = es.BreadthFirstPathfinder.search(graph, "c", "e"); + console.log(path); + } + + public dijkstraTest() { + let graph = new es.WeightedGridGraph(20, 20); + + graph.weightedNodes.push(new es.Vector2(3, 3)); + graph.weightedNodes.push(new es.Vector2(3, 4)); + graph.weightedNodes.push(new es.Vector2(4, 3)); + graph.weightedNodes.push(new es.Vector2(4, 4)); + + let path = graph.search(new es.Vector2(3, 4), new es.Vector2(15, 17)); + console.log(path); + } + + public astarTest() { + let graph = new es.AstarGridGraph(30, 30); + + // graph.weightedNodes.push(new Vector2(3, 3)); + // graph.weightedNodes.push(new Vector2(3, 4)); + // graph.weightedNodes.push(new Vector2(4, 3)); + // graph.weightedNodes.push(new Vector2(4, 4)); + + let startTime = egret.getTimer(); + let path = graph.search(new es.Vector2(1, 1), new es.Vector2(29, 29)); + console.log(egret.getTimer() - startTime); + } } - - public breadthfirstTest() { - let graph = new UnweightedGraph(); - - graph.addEdgesForNode("a", ["b"]); // a->b - graph.addEdgesForNode("b", ["a", "c", "d"]); // b->a b->c b->d - graph.addEdgesForNode("c", ["a"]); // c->a - graph.addEdgesForNode("d", ["e", "a"]); // d->e d->a - graph.addEdgesForNode("e", ["b"]); // e->b - - // 计算从c到e的路径 - let path = BreadthFirstPathfinder.search(graph, "c", "e"); - console.log(path); - } - - public dijkstraTest() { - let graph = new WeightedGridGraph(20, 20); - - graph.weightedNodes.push(new Vector2(3, 3)); - graph.weightedNodes.push(new Vector2(3, 4)); - graph.weightedNodes.push(new Vector2(4, 3)); - graph.weightedNodes.push(new Vector2(4, 4)); - - let path = graph.search(new Vector2(3, 4), new Vector2(15, 17)); - console.log(path); - } - - public astarTest() { - let graph = new AstarGridGraph(20, 20); - - graph.weightedNodes.push(new Vector2(3, 3)); - graph.weightedNodes.push(new Vector2(3, 4)); - graph.weightedNodes.push(new Vector2(4, 3)); - graph.weightedNodes.push(new Vector2(4, 4)); - - let path = graph.search(new Vector2(3, 4), new Vector2(15, 17)); - console.log(path); - } -} \ No newline at end of file +} diff --git a/demo/src/game/PlayerController.ts b/demo/src/game/PlayerController.ts index 60d4bcf2..332fb945 100644 --- a/demo/src/game/PlayerController.ts +++ b/demo/src/game/PlayerController.ts @@ -1,56 +1,66 @@ -class PlayerController extends Component { - private down: boolean = false; - private touchPoint: Vector2 = Vector2.zero; - private mover: Mover; - private spriteRenderer: SpriteRenderer; +module component { + import Component = es.Component; + import Vector2 = es.Vector2; + import Mover = es.Mover; + import SpriteRenderer = es.SpriteRenderer; + import Time = es.Time; + import Input = es.Input; + import CollisionResult = es.CollisionResult; - public onAddedToEntity(){ - this.entity.scene.stage.addEventListener(egret.TouchEvent.TOUCH_BEGIN, this.touchBegin, this); - this.entity.scene.stage.addEventListener(egret.TouchEvent.TOUCH_MOVE, this.touchBegin, this); - this.entity.scene.stage.addEventListener(egret.TouchEvent.TOUCH_END, this.touchEnd, this); - } + export class PlayerController extends Component { + private down: boolean = false; + private touchPoint: Vector2 = Vector2.zero; + private mover: Mover; + private spriteRenderer: SpriteRenderer; - private touchBegin(evt: egret.TouchEvent){ - this.down = true; - this.touchPoint = new Vector2(evt.stageX, evt.stageY); - } + public onAddedToEntity(){ + this.entity.scene.stage.addEventListener(egret.TouchEvent.TOUCH_BEGIN, this.touchBegin, this); + this.entity.scene.stage.addEventListener(egret.TouchEvent.TOUCH_MOVE, this.touchBegin, this); + this.entity.scene.stage.addEventListener(egret.TouchEvent.TOUCH_END, this.touchEnd, this); + } - private touchEnd(evt: egret.TouchEvent){ - this.down = false; - this.touchPoint = new Vector2(evt.stageX, evt.stageY); - } + private touchBegin(evt: egret.TouchEvent){ + this.down = true; + this.touchPoint = new Vector2(evt.stageX, evt.stageY); + } - public update(){ - if (!this.mover) - this.mover = this.entity.getComponent(Mover); + private touchEnd(evt: egret.TouchEvent){ + this.down = false; + this.touchPoint = new Vector2(evt.stageX, evt.stageY); + } - if (!this.spriteRenderer) - this.spriteRenderer = this.entity.getComponent(SpriteRenderer); + public update(){ + if (!this.mover) + this.mover = this.entity.getComponent(Mover); - if (!this.mover) - return; + if (!this.spriteRenderer) + this.spriteRenderer = this.entity.getComponent(SpriteRenderer); - if (!SpriteRenderer) - return; + if (!this.mover) + return; - if (this.down){ - // let camera = SceneManager.scene.camera; - // let moveLeft: number = 0; - // let moveRight: number = 0; - // let speed = 100; - // let worldPos = Input.touchPosition; - // if (worldPos.x < this.spriteRenderer.x){ - // moveLeft = -1; - // } else if(worldPos.x > this.spriteRenderer.x){ - // moveLeft = 1; - // } + if (!SpriteRenderer) + return; - // if (worldPos.y < this.spriteRenderer.y){ - // moveRight = -1; - // } else if(worldPos.y > this.spriteRenderer.y){ - // moveRight = 1; - // } - this.mover.move(new Vector2(-1, -1)); + if (this.down){ + let moveLeft: number = 0; + let moveRight: number = 0; + let speed = 100; + let worldPos = this.entity.scene.camera.mouseToWorldPoint(); + if (worldPos.x < this.spriteRenderer.transform.position.x){ + moveLeft = -1; + } else if(worldPos.x > this.spriteRenderer.transform.position.x){ + moveLeft = 1; + } + + if (worldPos.y < this.spriteRenderer.transform.position.y){ + moveRight = -1; + } else if(worldPos.y > this.spriteRenderer.transform.position.y){ + moveRight = 1; + } + let collisionResult = new CollisionResult(); + this.mover.move(new Vector2(moveLeft * speed * Time.deltaTime, moveRight * speed * Time.deltaTime), collisionResult); + } } } -} \ No newline at end of file +} diff --git a/demo/src/game/SimplePooled.ts b/demo/src/game/SimplePooled.ts index c9345b4c..c455db33 100644 --- a/demo/src/game/SimplePooled.ts +++ b/demo/src/game/SimplePooled.ts @@ -1,5 +1,9 @@ -class SimplePooled extends PooledComponent { - public reset(){ - +module component { + import PooledComponent = es.PooledComponent; + + export class SimplePooled extends PooledComponent { + public reset(){ + + } } -} \ No newline at end of file +} diff --git a/demo/src/game/SpawnerComponent.ts b/demo/src/game/SpawnerComponent.ts index 381b8b14..fb50ee0e 100644 --- a/demo/src/game/SpawnerComponent.ts +++ b/demo/src/game/SpawnerComponent.ts @@ -1,35 +1,37 @@ -class SpawnComponent extends Component implements ITriggerListener { - public cooldown = -1; - public minInterval = 2; - public maxInterval = 60; - public enemyType = EnemyType.worm; - public numSpawned = 0; - public numAlive = 0; +module component { + export class SpawnComponent extends es.Component implements es.ITriggerListener { + public cooldown = -1; + public minInterval = 2; + public maxInterval = 60; + public enemyType = EnemyType.worm; + public numSpawned = 0; + public numAlive = 0; - constructor(enemyType: EnemyType) { - super(); - this.enemyType = enemyType; + constructor(enemyType: EnemyType) { + super(); + this.enemyType = enemyType; + } + + public initialize() { + // console.log("initialize"); + } + + public update() { + // console.log("update"); + } + + public onTriggerEnter(other: es.Collider, local: es.Collider){ + if (other == local) + console.log("repeat collider"); + console.log("enter collider"); + } + + public onTriggerExit(other: es.Collider, local: es.Collider){ + console.log("exit collider"); + } } - public initialize() { - // console.log("initialize"); - } - - public update() { - // console.log("update"); - } - - public onTriggerEnter(other: Collider, local: Collider){ - if (other == local) - console.log("repeat collider") - console.log("enter collider"); - } - - public onTriggerExit(other: Collider, local: Collider){ - console.log("exit collider"); + export enum EnemyType { + worm } } - -enum EnemyType { - worm -} \ No newline at end of file diff --git a/demo/src/game/SpawnerSystem.ts b/demo/src/game/SpawnerSystem.ts index 019cbef2..fa3a418a 100644 --- a/demo/src/game/SpawnerSystem.ts +++ b/demo/src/game/SpawnerSystem.ts @@ -1,34 +1,36 @@ -class SpawnerSystem extends EntityProcessingSystem { - constructor(matcher: Matcher){ - super(matcher); - } - - public processEntity(entity: Entity){ - let spawner = entity.getComponent(SpawnComponent); - if (!spawner) - return; - - if (spawner.numAlive <= 0) - spawner.enabled = true; - - if (!spawner.enabled) - return; - - console.log("cooldown", spawner.cooldown); - if (spawner.cooldown == -1){ - spawner.cooldown = Math.random() * 60; - spawner.cooldown /= 4; +module system { + export class SpawnerSystem extends es.EntityProcessingSystem { + constructor(matcher: es.Matcher){ + super(matcher); } - spawner.cooldown -= Time.deltaTime; - if (spawner.cooldown <= 0){ - spawner.cooldown = Math.random() * 60; - // CreateEnemy - spawner.numSpawned ++; - spawner.numAlive ++; + public processEntity(entity: es.Entity){ + let spawner = entity.getComponent(component.SpawnComponent); + if (!spawner) + return; - if (spawner.numAlive > 0) - spawner.enabled = false; + if (spawner.numAlive <= 0) + spawner.enabled = true; + + if (!spawner.enabled) + return; + + console.log("cooldown", spawner.cooldown); + if (spawner.cooldown == -1){ + spawner.cooldown = Math.random() * 60; + spawner.cooldown /= 4; + } + + spawner.cooldown -= es.Time.deltaTime; + if (spawner.cooldown <= 0){ + spawner.cooldown = Math.random() * 60; + // CreateEnemy + spawner.numSpawned ++; + spawner.numAlive ++; + + if (spawner.numAlive > 0) + spawner.enabled = false; + } } } -} \ No newline at end of file +} diff --git a/demo/template/runtime/native_require.js b/demo/template/runtime/native_require.js index 62d691bf..3df96bc9 100644 --- a/demo/template/runtime/native_require.js +++ b/demo/template/runtime/native_require.js @@ -32,7 +32,7 @@ egret_native.egretStart = function () { //The following is automatically modified, please do not modify //----auto option start---- entryClassName: "Main", - frameRate: 30, + frameRate: 60, scaleMode: "fixedWidth", contentWidth: 640, contentHeight: 1136, diff --git a/demo/tsconfig.json b/demo/tsconfig.json index 5737e5ba..23bf9dbf 100644 --- a/demo/tsconfig.json +++ b/demo/tsconfig.json @@ -2,6 +2,7 @@ "compilerOptions": { "target": "es5", "outDir": "bin-debug", + "sourceMap": true, "experimentalDecorators": true, "emitDecoratorMetadata": true, "lib": [ diff --git a/source/.vscode/tasks.json b/source/.vscode/tasks.json index aba11758..8d24ee93 100644 --- a/source/.vscode/tasks.json +++ b/source/.vscode/tasks.json @@ -1,13 +1,13 @@ { - // See https://go.microsoft.com/fwlink/?LinkId=733558 - // for the documentation about the tasks.json format - "version": "2.0.0", - "tasks": [ - { - "type": "gulp", - "task": "build", - "group": "build", - "problemMatcher": [] - } - ] + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "type": "gulp", + "task": "build", + "group": "build", + "problemMatcher": [] + } + ] } \ No newline at end of file diff --git a/source/.wing/settings.json b/source/.wing/settings.json new file mode 100644 index 00000000..c3fcd996 --- /dev/null +++ b/source/.wing/settings.json @@ -0,0 +1,3 @@ +{ + "typescript.tsdk": "./node_modules/typescript/lib" +} \ No newline at end of file diff --git a/source/bin/framework.d.ts b/source/bin/framework.d.ts index a8d146ad..f8cf463e 100644 --- a/source/bin/framework.d.ts +++ b/source/bin/framework.d.ts @@ -1,1058 +1,1848 @@ declare interface Array { - findIndex(predicate: Function): number; - any(predicate: Function): boolean; - firstOrDefault(predicate: Function): T; - find(predicate: Function): T; - where(predicate: Function): Array; - count(predicate: Function): number; - findAll(predicate: Function): Array; - contains(value: any): boolean; - removeAll(predicate: Function): void; - remove(element: any): boolean; - removeAt(index: any): void; - removeRange(index: any, count: any): void; + findIndex(predicate: (c: T) => boolean): number; + any(predicate: (c: T) => boolean): boolean; + firstOrDefault(predicate: (c: T) => boolean): T; + find(predicate: (c: T) => boolean): T; + where(predicate: (c: T) => boolean): Array; + count(predicate: (c: T) => boolean): number; + findAll(predicate: (c: T) => boolean): Array; + contains(value: T): boolean; + removeAll(predicate: (c: T) => boolean): void; + remove(element: T): boolean; + removeAt(index: number): void; + removeRange(index: number, count: number): void; select(selector: Function): Array; orderBy(keySelector: Function, comparer: Function): Array; orderByDescending(keySelector: Function, comparer: Function): Array; groupBy(keySelector: Function): Array; - sum(selector: any): any; -} -declare class PriorityQueueNode { - priority: number; - insertionIndex: number; - queueIndex: number; -} -declare class AStarPathfinder { - static search(graph: IAstarGraph, start: T, goal: T): T[]; - private static hasKey; - private static getKey; - static recontructPath(cameFrom: Map, start: T, goal: T): T[]; -} -declare class AStarNode extends PriorityQueueNode { - data: T; - constructor(data: T); -} -declare class AstarGridGraph implements IAstarGraph { - dirs: Vector2[]; - walls: Vector2[]; - weightedNodes: Vector2[]; - defaultWeight: number; - weightedNodeWeight: number; - private _width; - private _height; - private _neighbors; - constructor(width: number, height: number); - isNodeInBounds(node: Vector2): boolean; - isNodePassable(node: Vector2): boolean; - search(start: Vector2, goal: Vector2): Vector2[]; - getNeighbors(node: Vector2): Vector2[]; - cost(from: Vector2, to: Vector2): number; - heuristic(node: Vector2, goal: Vector2): number; -} -interface IAstarGraph { - getNeighbors(node: T): Array; - cost(from: T, to: T): number; - heuristic(node: T, goal: T): any; -} -declare class PriorityQueue { - private _numNodes; - private _nodes; - private _numNodesEverEnqueued; - constructor(maxNodes: number); - clear(): void; - readonly count: number; - contains(node: T): boolean; - enqueue(node: T, priority: number): void; - dequeue(): T; - remove(node: T): void; - isValidQueue(): boolean; - private onNodeUpdated; - private cascadeDown; - private cascadeUp; - private swap; - private hasHigherPriority; -} -declare class BreadthFirstPathfinder { - static search(graph: IUnweightedGraph, start: T, goal: T): T[]; - private static hasKey; -} -interface IUnweightedGraph { - getNeighbors(node: T): T[]; -} -declare class UnweightedGraph implements IUnweightedGraph { - edges: Map; - addEdgesForNode(node: T, edges: T[]): this; - getNeighbors(node: T): T[]; -} -declare class Vector2 { - x: number; - y: number; - private static readonly unitYVector; - private static readonly unitXVector; - private static readonly unitVector2; - private static readonly zeroVector2; - static readonly zero: Vector2; - static readonly one: Vector2; - static readonly unitX: Vector2; - static readonly unitY: Vector2; - constructor(x?: number, y?: number); - static add(value1: Vector2, value2: Vector2): Vector2; - static divide(value1: Vector2, value2: Vector2): Vector2; - static multiply(value1: Vector2, value2: Vector2): Vector2; - static subtract(value1: Vector2, value2: Vector2): Vector2; - normalize(): void; - length(): number; - round(): Vector2; - static normalize(value: Vector2): Vector2; - static dot(value1: Vector2, value2: Vector2): number; - static distanceSquared(value1: Vector2, value2: Vector2): number; - static clamp(value1: Vector2, min: Vector2, max: Vector2): Vector2; - static lerp(value1: Vector2, value2: Vector2, amount: number): Vector2; - static transform(position: Vector2, matrix: Matrix2D): Vector2; - static distance(value1: Vector2, value2: Vector2): number; - static negate(value: Vector2): Vector2; -} -declare class UnweightedGridGraph implements IUnweightedGraph { - private static readonly CARDINAL_DIRS; - private static readonly COMPASS_DIRS; - walls: Vector2[]; - private _width; - private _hegiht; - private _dirs; - private _neighbors; - constructor(width: number, height: number, allowDiagonalSearch?: boolean); - isNodeInBounds(node: Vector2): boolean; - isNodePassable(node: Vector2): boolean; - getNeighbors(node: Vector2): Vector2[]; - search(start: Vector2, goal: Vector2): Vector2[]; -} -interface IWeightedGraph { - getNeighbors(node: T): T[]; - cost(from: T, to: T): number; -} -declare class WeightedGridGraph implements IWeightedGraph { - static readonly CARDINAL_DIRS: Vector2[]; - private static readonly COMPASS_DIRS; - walls: Vector2[]; - weightedNodes: Vector2[]; - defaultWeight: number; - weightedNodeWeight: number; - private _width; - private _height; - private _dirs; - private _neighbors; - constructor(width: number, height: number, allowDiagonalSearch?: boolean); - isNodeInBounds(node: Vector2): boolean; - isNodePassable(node: Vector2): boolean; - search(start: Vector2, goal: Vector2): Vector2[]; - getNeighbors(node: Vector2): Vector2[]; - cost(from: Vector2, to: Vector2): number; -} -declare class WeightedNode extends PriorityQueueNode { - data: T; - constructor(data: T); -} -declare class WeightedPathfinder { - static search(graph: IWeightedGraph, start: T, goal: T): T[]; - private static hasKey; - private static getKey; - static recontructPath(cameFrom: Map, start: T, goal: T): T[]; -} -declare class DebugDefaults { - static verletParticle: number; - static verletConstraintEdge: number; -} -declare abstract class Component extends egret.DisplayObjectContainer { - entity: Entity; - private _enabled; - updateInterval: number; - userData: any; - enabled: boolean; - setEnabled(isEnabled: boolean): this; - initialize(): void; - onAddedToEntity(): void; - onRemovedFromEntity(): void; - onEnabled(): void; - onDisabled(): void; - update(): void; - debugRender(): void; - onEntityTransformChanged(comp: TransformComponent): void; - registerComponent(): void; - deregisterComponent(): void; -} -declare class Entity extends egret.DisplayObjectContainer { - private static _idGenerator; - name: string; - readonly id: number; - scene: Scene; - readonly components: ComponentList; - private _updateOrder; - private _enabled; - _isDestoryed: boolean; - private _tag; - componentBits: BitSet; - readonly isDestoryed: boolean; - position: Vector2; - scale: Vector2; - rotation: number; - enabled: boolean; - setEnabled(isEnabled: boolean): this; - tag: number; - readonly stage: egret.Stage; - constructor(name: string); - updateOrder: number; - roundPosition(): void; - setUpdateOrder(updateOrder: number): this; - setTag(tag: number): Entity; - attachToScene(newScene: Scene): void; - detachFromScene(): void; - addComponent(component: T): T; - hasComponent(type: any): boolean; - getOrCreateComponent(type: T): T; - getComponent(type: any): T; - getComponents(typeName: string | any, componentList?: any): any; - private onEntityTransformChanged; - removeComponentForType(type: any): boolean; - removeComponent(component: Component): void; - removeAllComponents(): void; - update(): void; - onAddedToScene(): void; - onRemovedFromScene(): void; - destroy(): void; -} -declare enum TransformComponent { - rotation = 0, - scale = 1, - position = 2 -} -declare class Scene extends egret.DisplayObjectContainer { - camera: Camera; - readonly entities: EntityList; - readonly renderableComponents: RenderableComponentList; - readonly content: ContentManager; - enablePostProcessing: boolean; - private _renderers; - private _postProcessors; - private _didSceneBegin; - readonly entityProcessors: EntityProcessorList; - constructor(); - createEntity(name: string): Entity; - addEntity(entity: Entity): Entity; - destroyAllEntities(): void; - findEntity(name: string): Entity; - addEntityProcessor(processor: EntitySystem): EntitySystem; - removeEntityProcessor(processor: EntitySystem): void; - getEntityProcessor(): T; - addRenderer(renderer: T): T; - getRenderer(type: any): T; - removeRenderer(renderer: Renderer): void; - begin(): void; - end(): void; - protected onStart(): Promise; - protected onActive(): void; - protected onDeactive(): void; - protected unload(): void; - update(): void; - postRender(): void; - render(): void; - addPostProcessor(postProcessor: T): T; -} -declare class SceneManager { - private static _scene; - private static _nextScene; - static sceneTransition: SceneTransition; - static stage: egret.Stage; - constructor(stage: egret.Stage); - static scene: Scene; - static initialize(stage: egret.Stage): void; - static update(): void; - static render(): void; - static startSceneTransition(sceneTransition: T): T; -} -declare class Camera extends Component { - private _zoom; - private _origin; - private _minimumZoom; - private _maximumZoom; - private _position; - followLerp: number; - deadzone: Rectangle; - focusOffset: Vector2; - mapLockEnabled: boolean; - mapSize: Vector2; - targetEntity: Entity; - private _worldSpaceDeadZone; - private _desiredPositionDelta; - private _targetCollider; - cameraStyle: CameraStyle; - zoom: number; - minimumZoom: number; - maximumZoom: number; - origin: Vector2; - position: Vector2; - x: number; - y: number; - constructor(); - onSceneSizeChanged(newWidth: number, newHeight: number): void; - setMinimumZoom(minZoom: number): Camera; - setMaximumZoom(maxZoom: number): Camera; - setZoom(zoom: number): Camera; - setRotation(rotation: number): Camera; - setPosition(position: Vector2): this; - follow(targetEntity: Entity, cameraStyle?: CameraStyle): void; - update(): void; - private clampToMapSize; - private updateFollow; -} -declare enum CameraStyle { - lockOn = 0, - cameraWindow = 1 -} -declare class ComponentPool { - private _cache; - private _type; - constructor(typeClass: any); - obtain(): T; - free(component: T): void; -} -declare abstract class PooledComponent extends Component { - abstract reset(): any; -} -declare abstract class RenderableComponent extends PooledComponent implements IRenderable { - private _isVisible; - protected _areBoundsDirty: boolean; - protected _bounds: Rectangle; - protected _localOffset: Vector2; - color: number; - readonly width: number; - readonly height: number; - isVisible: boolean; - readonly bounds: Rectangle; - protected getWidth(): number; - protected getHeight(): number; - protected onBecameVisible(): void; - protected onBecameInvisible(): void; - abstract render(camera: Camera): any; - isVisibleFromCamera(camera: Camera): boolean; -} -declare class Mesh extends RenderableComponent { - private _mesh; - constructor(); - setTexture(texture: egret.Texture): Mesh; - onAddedToEntity(): void; - onRemovedFromEntity(): void; - render(camera: Camera): void; - reset(): void; -} -declare class SpriteRenderer extends RenderableComponent { - private _sprite; - protected bitmap: egret.Bitmap; - sprite: Sprite; - setSprite(sprite: Sprite): SpriteRenderer; - setColor(color: number): SpriteRenderer; - isVisibleFromCamera(camera: Camera): boolean; - render(camera: Camera): void; - onRemovedFromEntity(): void; - reset(): void; -} -declare class TiledSpriteRenderer extends SpriteRenderer { - protected sourceRect: Rectangle; - protected leftTexture: egret.Bitmap; - protected rightTexture: egret.Bitmap; - scrollX: number; - scrollY: number; - constructor(sprite: Sprite); - render(camera: Camera): void; -} -declare class ScrollingSpriteRenderer extends TiledSpriteRenderer { - scrollSpeedX: number; - scroolSpeedY: number; - private _scrollX; - private _scrollY; - update(): void; -} -declare class Sprite { - texture2D: egret.Texture; - readonly sourceRect: Rectangle; - readonly center: Vector2; - origin: Vector2; - readonly uvs: Rectangle; - constructor(texture: egret.Texture, sourceRect?: Rectangle, origin?: Vector2); -} -declare class SpriteAnimation { - readonly sprites: Sprite[]; - readonly frameRate: number; - constructor(sprites: Sprite[], frameRate: number); -} -declare class SpriteAnimator extends SpriteRenderer { - onAnimationCompletedEvent: Function; - speed: number; - animationState: State; - currentAnimation: SpriteAnimation; - currentAnimationName: string; - currentFrame: number; - readonly isRunning: boolean; - private _animations; - private _elapsedTime; - private _loopMode; - constructor(sprite?: Sprite); - addAnimation(name: string, animation: SpriteAnimation): SpriteAnimator; - play(name: string, loopMode?: LoopMode): void; - isAnimationActive(name: string): boolean; - pause(): void; - unPause(): void; - stop(): void; - update(): void; -} -declare enum LoopMode { - loop = 0, - once = 1, - clampForever = 2, - pingPong = 3, - pingPongOnce = 4 -} -declare enum State { - none = 0, - running = 1, - paused = 2, - completed = 3 -} -interface ITriggerListener { - onTriggerEnter(other: Collider, local: Collider): any; - onTriggerExit(other: Collider, local: Collider): any; -} -declare class Mover extends Component { - private _triggerHelper; - onAddedToEntity(): void; - calculateMovement(motion: Vector2): { - collisionResult: CollisionResult; - motion: Vector2; - }; - applyMovement(motion: Vector2): void; - move(motion: Vector2): CollisionResult; -} -declare abstract class Collider extends Component { - shape: Shape; - physicsLayer: number; - isTrigger: boolean; - registeredPhysicsBounds: Rectangle; - shouldColliderScaleAndRotateWithTransform: boolean; - collidesWithLayers: number; - _localOffsetLength: number; - protected _isParentEntityAddedToScene: any; - protected _colliderRequiresAutoSizing: any; - protected _localOffset: Vector2; - protected _isColliderRegistered: any; - readonly bounds: Rectangle; - localOffset: Vector2; - setLocalOffset(offset: Vector2): void; - registerColliderWithPhysicsSystem(): void; - unregisterColliderWithPhysicsSystem(): void; - overlaps(other: Collider): any; - collidesWith(collider: Collider, motion: Vector2): CollisionResult; - onAddedToEntity(): void; - onRemovedFromEntity(): void; - onEnabled(): void; - onDisabled(): void; - onEntityTransformChanged(comp: TransformComponent): void; -} -declare class BoxCollider extends Collider { - width: number; - setWidth(width: number): BoxCollider; - height: number; - setHeight(height: number): void; - constructor(); - setSize(width: number, height: number): this; -} -declare class EntitySystem { - private _scene; - private _entities; - private _matcher; - readonly matcher: Matcher; - scene: Scene; - constructor(matcher?: Matcher); - initialize(): void; - onChanged(entity: Entity): void; - add(entity: Entity): void; - onAdded(entity: Entity): void; - remove(entity: Entity): void; - onRemoved(entity: Entity): void; - update(): void; - lateUpdate(): void; - protected begin(): void; - protected process(entities: Entity[]): void; - protected lateProcess(entities: Entity[]): void; - protected end(): void; -} -declare abstract class EntityProcessingSystem extends EntitySystem { - constructor(matcher: Matcher); - abstract processEntity(entity: Entity): any; - lateProcessEntity(entity: Entity): void; - protected process(entities: Entity[]): void; - protected lateProcess(entities: Entity[]): void; -} -declare abstract class PassiveSystem extends EntitySystem { - onChanged(entity: Entity): void; - protected process(entities: Entity[]): void; -} -declare abstract class ProcessingSystem extends EntitySystem { - onChanged(entity: Entity): void; - protected process(entities: Entity[]): void; - abstract processSystem(): any; -} -declare class BitSet { - private static LONG_MASK; - private _bits; - constructor(nbits?: number); - and(bs: BitSet): void; - andNot(bs: BitSet): void; - cardinality(): number; - clear(pos?: number): void; - private ensure; - get(pos: number): boolean; - intersects(set: BitSet): boolean; - isEmpty(): boolean; - nextSetBit(from: number): number; - set(pos: number, value?: boolean): void; -} -declare class ComponentList { - private _entity; - private _components; - private _componentsToAdd; - private _componentsToRemove; - private _tempBufferList; - constructor(entity: Entity); - readonly count: number; - readonly buffer: Component[]; - add(component: Component): void; - remove(component: Component): void; - removeAllComponents(): void; - deregisterAllComponents(): void; - registerAllComponents(): void; - updateLists(): void; - onEntityTransformChanged(comp: TransformComponent): void; - private handleRemove; - getComponent(type: any, onlyReturnInitializedComponents: boolean): T; - getComponents(typeName: string | any, components?: any): any; - update(): void; -} -declare class ComponentTypeManager { - private static _componentTypesMask; - static add(type: any): void; - static getIndexFor(type: any): number; -} -declare class EntityList { - scene: Scene; - private _entitiesToRemove; - private _entitiesToAdded; - private _tempEntityList; - private _entities; - private _entityDict; - private _unsortedTags; - constructor(scene: Scene); - readonly count: number; - readonly buffer: Entity[]; - add(entity: Entity): void; - remove(entity: Entity): void; - findEntity(name: string): Entity; - getTagList(tag: number): Entity[]; - addToTagList(entity: Entity): void; - removeFromTagList(entity: Entity): void; - update(): void; - removeAllEntities(): void; - updateLists(): void; -} -declare class EntityProcessorList { - private _processors; - add(processor: EntitySystem): void; - remove(processor: EntitySystem): void; - onComponentAdded(entity: Entity): void; - onComponentRemoved(entity: Entity): void; - onEntityAdded(entity: Entity): void; - onEntityRemoved(entity: Entity): void; - protected notifyEntityChanged(entity: Entity): void; - protected removeFromProcessors(entity: Entity): void; - begin(): void; - update(): void; - lateUpdate(): void; - end(): void; - getProcessor(): T; -} -declare class Matcher { - protected allSet: BitSet; - protected exclusionSet: BitSet; - protected oneSet: BitSet; - static empty(): Matcher; - getAllSet(): BitSet; - getExclusionSet(): BitSet; - getOneSet(): BitSet; - IsIntersted(e: Entity): boolean; - all(...types: any[]): Matcher; - exclude(...types: any[]): this; - one(...types: any[]): this; -} -declare class RenderableComponentList { - private _components; - readonly count: number; - readonly buffer: IRenderable[]; - add(component: IRenderable): void; - remove(component: IRenderable): void; - updateList(): void; -} -declare class Time { - static unscaledDeltaTime: any; - static deltaTime: number; - static timeScale: number; - static frameCount: number; - private static _lastTime; - static update(currentTime: number): void; -} -declare class GraphicsCapabilities { - supportsTextureFilterAnisotropic: boolean; - supportsNonPowerOfTwo: boolean; - supportsDepth24: boolean; - supportsPackedDepthStencil: boolean; - supportsDepthNonLinear: boolean; - supportsTextureMaxLevel: boolean; - supportsS3tc: boolean; - supportsDxt1: boolean; - supportsPvrtc: boolean; - supportsAtitc: boolean; - supportsFramebufferObjectARB: boolean; - initialize(device: GraphicsDevice): void; - private platformInitialize; -} -declare class GraphicsDevice { - private viewport; - graphicsCapabilities: GraphicsCapabilities; - constructor(); -} -declare class Viewport { - private _x; - private _y; - private _width; - private _height; - private _minDepth; - private _maxDepth; - readonly aspectRatio: number; - bounds: Rectangle; - constructor(x: number, y: number, width: number, height: number); -} -declare class GaussianBlurEffect extends egret.CustomFilter { - private static blur_frag; - constructor(); -} -declare class PolygonLightEffect extends egret.CustomFilter { - private static vertSrc; - private static fragmentSrc; - constructor(); -} -declare class PostProcessor { - enable: boolean; - effect: egret.Filter; - scene: Scene; - shape: egret.Shape; - static default_vert: string; - constructor(effect?: egret.Filter); - onAddedToScene(scene: Scene): void; - process(): void; - onSceneBackBufferSizeChanged(newWidth: number, newHeight: number): void; - protected drawFullscreenQuad(): void; - unload(): void; -} -declare class GaussianBlurPostProcessor extends PostProcessor { - onAddedToScene(scene: Scene): void; -} -declare abstract class Renderer { - camera: Camera; - onAddedToScene(scene: Scene): void; - protected beginRender(cam: Camera): void; - abstract render(scene: Scene): any; - unload(): void; - protected renderAfterStateCheck(renderable: IRenderable, cam: Camera): void; -} -declare class DefaultRenderer extends Renderer { - render(scene: Scene): void; -} -interface IRenderable { - bounds: Rectangle; - enabled: boolean; - isVisible: boolean; - isVisibleFromCamera(camera: Camera): any; - render(camera: Camera): any; -} -declare class ScreenSpaceRenderer extends Renderer { - render(scene: Scene): void; -} -declare class PolyLight extends RenderableComponent { - power: number; - protected _radius: number; - private _lightEffect; - private _indices; - radius: number; - constructor(radius: number, color: number, power: number); - private computeTriangleIndices; - setRadius(radius: number): void; - render(camera: Camera): void; - reset(): void; -} -declare abstract class SceneTransition { - private _hasPreviousSceneRender; - loadsNewScene: boolean; - isNewSceneLoaded: boolean; - protected sceneLoadAction: Function; - onScreenObscured: Function; - onTransitionCompleted: Function; - readonly hasPreviousSceneRender: boolean; - constructor(sceneLoadAction: Function); - preRender(): void; - render(): void; - onBeginTransition(): Promise; - protected transitionComplete(): void; - protected loadNextScene(): Promise; - tickEffectProgressProperty(filter: egret.CustomFilter, duration: number, easeType: Function, reverseDirection?: boolean): Promise<{}>; -} -declare class FadeTransition extends SceneTransition { - fadeToColor: number; - fadeOutDuration: number; - fadeEaseType: Function; - delayBeforeFadeInDuration: number; - private _mask; - private _alpha; - constructor(sceneLoadAction: Function); - onBeginTransition(): Promise; - render(): void; -} -declare class WindTransition extends SceneTransition { - private _mask; - private _windEffect; - duration: number; - windSegments: number; - size: number; - easeType: (t: number) => number; - constructor(sceneLoadAction: Function); - onBeginTransition(): Promise; -} -declare class Flags { - static isFlagSet(self: number, flag: number): boolean; - static isUnshiftedFlagSet(self: number, flag: number): boolean; - static setFlagExclusive(self: number, flag: number): number; - static setFlag(self: number, flag: number): number; - static unsetFlag(self: number, flag: number): number; - static invertFlags(self: number): number; -} -declare class MathHelper { - static readonly Epsilon: number; - static readonly Rad2Deg: number; - static readonly Deg2Rad: number; - static toDegrees(radians: number): number; - static toRadians(degrees: number): number; - static map(value: number, leftMin: number, leftMax: number, rightMin: number, rightMax: number): number; - static lerp(value1: number, value2: number, amount: number): number; - static clamp(value: number, min: number, max: number): number; - static pointOnCirlce(circleCenter: Vector2, radius: number, angleInDegrees: number): Vector2; - static isEven(value: number): boolean; -} -declare class Matrix2D { - m11: number; - m12: number; - m21: number; - m22: number; - m31: number; - m32: number; - private static _identity; - static readonly identity: Matrix2D; - constructor(m11?: number, m12?: number, m21?: number, m22?: number, m31?: number, m32?: number); - translation: Vector2; - rotation: number; - rotationDegrees: number; - scale: Vector2; - static add(matrix1: Matrix2D, matrix2: Matrix2D): Matrix2D; - static divide(matrix1: Matrix2D, matrix2: Matrix2D): Matrix2D; - static multiply(matrix1: Matrix2D, matrix2: Matrix2D): Matrix2D; - static multiplyTranslation(matrix: Matrix2D, x: number, y: number): Matrix2D; - determinant(): number; - static invert(matrix: Matrix2D, result?: Matrix2D): Matrix2D; - static createTranslation(xPosition: number, yPosition: number): Matrix2D; - static createTranslationVector(position: Vector2): Matrix2D; - static createRotation(radians: number, result?: Matrix2D): Matrix2D; - static createScale(xScale: number, yScale: number, result?: Matrix2D): Matrix2D; - toEgretMatrix(): egret.Matrix; -} -declare class Rectangle extends egret.Rectangle { - readonly max: Vector2; - readonly center: Vector2; - location: Vector2; - size: Vector2; - intersects(value: egret.Rectangle): boolean; - containsInVec(value: Vector2): boolean; - containsRect(value: Rectangle): boolean; - getHalfSize(): Vector2; - static fromMinMax(minX: number, minY: number, maxX: number, maxY: number): Rectangle; - getClosestPointOnRectangleBorderToPoint(point: Vector2): { - res: Vector2; - edgeNormal: Vector2; - }; - getClosestPointOnBoundsToOrigin(): Vector2; - static rectEncompassingPoints(points: Vector2[]): Rectangle; -} -declare class Vector3 { - x: number; - y: number; - z: number; - constructor(x: number, y: number, z: number); -} -declare class ColliderTriggerHelper { - private _entity; - private _activeTriggerIntersections; - private _previousTriggerIntersections; - private _tempTriggerList; - constructor(entity: Entity); - update(): void; - private checkForExitedColliders; - private notifyTriggerListeners; -} -declare enum PointSectors { - center = 0, - top = 1, - bottom = 2, - topLeft = 9, - topRight = 5, - left = 8, - right = 4, - bottomLeft = 10, - bottomRight = 6 -} -declare class Collisions { - static isLineToLine(a1: Vector2, a2: Vector2, b1: Vector2, b2: Vector2): boolean; - static lineToLineIntersection(a1: Vector2, a2: Vector2, b1: Vector2, b2: Vector2): Vector2; - static closestPointOnLine(lineA: Vector2, lineB: Vector2, closestTo: Vector2): Vector2; - static isCircleToCircle(circleCenter1: Vector2, circleRadius1: number, circleCenter2: Vector2, circleRadius2: number): boolean; - static isCircleToLine(circleCenter: Vector2, radius: number, lineFrom: Vector2, lineTo: Vector2): boolean; - static isCircleToPoint(circleCenter: Vector2, radius: number, point: Vector2): boolean; - static isRectToCircle(rect: Rectangle, cPosition: Vector2, cRadius: number): boolean; - static isRectToLine(rect: Rectangle, lineFrom: Vector2, lineTo: Vector2): boolean; - static isRectToPoint(rX: number, rY: number, rW: number, rH: number, point: Vector2): boolean; - static getSector(rX: number, rY: number, rW: number, rH: number, point: Vector2): PointSectors; -} -declare class Physics { - private static _spatialHash; - static spatialHashCellSize: number; - static readonly allLayers: number; - static reset(): void; - static clear(): void; - static overlapCircleAll(center: Vector2, randius: number, results: any[], layerMask?: number): number; - static boxcastBroadphase(rect: Rectangle, layerMask?: number): { - colliders: Collider[]; - rect: Rectangle; - }; - static boxcastBroadphaseExcludingSelf(collider: Collider, rect: Rectangle, layerMask?: number): { - tempHashSet: Collider[]; + sum(selector: Function): number; +} +declare module es { + class PriorityQueueNode { + priority: number; + insertionIndex: number; + queueIndex: number; + } +} +declare module es { + class AStarPathfinder { + static search(graph: IAstarGraph, start: T, goal: T): T[]; + static recontructPath(cameFrom: Map, start: T, goal: T): T[]; + private static hasKey; + private static getKey; + } + class AStarNode extends PriorityQueueNode { + data: T; + constructor(data: T); + } +} +declare module es { + class AstarGridGraph implements IAstarGraph { + dirs: Vector2[]; + walls: Vector2[]; + weightedNodes: Vector2[]; + defaultWeight: number; + weightedNodeWeight: number; + private _width; + private _height; + private _neighbors; + constructor(width: number, height: number); + isNodeInBounds(node: Vector2): boolean; + isNodePassable(node: Vector2): boolean; + search(start: Vector2, goal: Vector2): Vector2[]; + getNeighbors(node: Vector2): Vector2[]; + cost(from: Vector2, to: Vector2): number; + heuristic(node: Vector2, goal: Vector2): number; + } +} +declare module es { + interface IAstarGraph { + getNeighbors(node: T): Array; + cost(from: T, to: T): number; + heuristic(node: T, goal: T): any; + } +} +declare module es { + class PriorityQueue { + private _numNodes; + private _nodes; + private _numNodesEverEnqueued; + constructor(maxNodes: number); + readonly count: number; + readonly maxSize: number; + clear(): void; + contains(node: T): boolean; + enqueue(node: T, priority: number): void; + dequeue(): T; + remove(node: T): void; + isValidQueue(): boolean; + private onNodeUpdated; + private cascadeDown; + private cascadeUp; + private swap; + private hasHigherPriority; + } +} +declare module es { + class BreadthFirstPathfinder { + static search(graph: IUnweightedGraph, start: T, goal: T): T[]; + private static hasKey; + } +} +declare module es { + interface IUnweightedGraph { + getNeighbors(node: T): T[]; + } +} +declare module es { + class UnweightedGraph implements IUnweightedGraph { + edges: Map; + addEdgesForNode(node: T, edges: T[]): this; + getNeighbors(node: T): T[]; + } +} +declare module es { + class Vector2 { + private static readonly unitYVector; + private static readonly unitXVector; + private static readonly unitVector2; + private static readonly zeroVector2; + x: number; + y: number; + constructor(x?: number, y?: number); + static readonly zero: Vector2; + static readonly one: Vector2; + static readonly unitX: Vector2; + static readonly unitY: Vector2; + static add(value1: Vector2, value2: Vector2): Vector2; + static divide(value1: Vector2, value2: Vector2): Vector2; + static multiply(value1: Vector2, value2: Vector2): Vector2; + static subtract(value1: Vector2, value2: Vector2): Vector2; + static normalize(value: Vector2): Vector2; + static dot(value1: Vector2, value2: Vector2): number; + static distanceSquared(value1: Vector2, value2: Vector2): number; + static clamp(value1: Vector2, min: Vector2, max: Vector2): Vector2; + static lerp(value1: Vector2, value2: Vector2, amount: number): Vector2; + static transform(position: Vector2, matrix: Matrix2D): Vector2; + static distance(value1: Vector2, value2: Vector2): number; + static negate(value: Vector2): Vector2; + add(value: Vector2): Vector2; + divide(value: Vector2): Vector2; + multiply(value: Vector2): Vector2; + subtract(value: Vector2): this; + normalize(): this; + length(): number; + lengthSquared(): number; + round(): Vector2; + equals(other: Vector2): boolean; + } +} +declare module es { + class UnweightedGridGraph implements IUnweightedGraph { + private static readonly CARDINAL_DIRS; + private static readonly COMPASS_DIRS; + walls: Vector2[]; + private _width; + private _hegiht; + private _dirs; + private _neighbors; + constructor(width: number, height: number, allowDiagonalSearch?: boolean); + isNodeInBounds(node: Vector2): boolean; + isNodePassable(node: Vector2): boolean; + getNeighbors(node: Vector2): Vector2[]; + search(start: Vector2, goal: Vector2): Vector2[]; + } +} +declare module es { + interface IWeightedGraph { + getNeighbors(node: T): T[]; + cost(from: T, to: T): number; + } +} +declare module es { + class WeightedGridGraph implements IWeightedGraph { + static readonly CARDINAL_DIRS: Vector2[]; + private static readonly COMPASS_DIRS; + walls: Vector2[]; + weightedNodes: Vector2[]; + defaultWeight: number; + weightedNodeWeight: number; + private _width; + private _height; + private _dirs; + private _neighbors; + constructor(width: number, height: number, allowDiagonalSearch?: boolean); + isNodeInBounds(node: Vector2): boolean; + isNodePassable(node: Vector2): boolean; + search(start: Vector2, goal: Vector2): Vector2[]; + getNeighbors(node: Vector2): Vector2[]; + cost(from: Vector2, to: Vector2): number; + } +} +declare module es { + class WeightedNode extends PriorityQueueNode { + data: T; + constructor(data: T); + } + class WeightedPathfinder { + static search(graph: IWeightedGraph, start: T, goal: T): T[]; + static recontructPath(cameFrom: Map, start: T, goal: T): T[]; + private static hasKey; + private static getKey; + } +} +declare module es { + class Debug { + private static _debugDrawItems; + static drawHollowRect(rectanle: Rectangle, color: number, duration?: number): void; + static render(): void; + } +} +declare module es { + class DebugDefaults { + static verletParticle: number; + static verletConstraintEdge: number; + } +} +declare module es { + enum DebugDrawType { + line = 0, + hollowRectangle = 1, + pixel = 2, + text = 3 + } + class DebugDrawItem { + rectangle: Rectangle; + color: number; + duration: number; + drawType: DebugDrawType; + text: string; + start: Vector2; + end: Vector2; + x: number; + y: number; + size: number; + constructor(rectangle: Rectangle, color: number, duration: number); + draw(shape: egret.Shape): boolean; + } +} +declare module es { + abstract class Component extends egret.HashObject { + entity: Entity; + updateInterval: number; + readonly transform: Transform; + private _enabled; + enabled: boolean; + private _updateOrder; + updateOrder: number; + initialize(): void; + onAddedToEntity(): void; + onRemovedFromEntity(): void; + onEntityTransformChanged(comp: transform.Component): void; + debugRender(): void; + onEnabled(): void; + onDisabled(): void; + update(): void; + setEnabled(isEnabled: boolean): this; + setUpdateOrder(updateOrder: number): this; + clone(): Component; + } +} +declare module es { + class Core extends egret.DisplayObjectContainer { + static emitter: Emitter; + static graphicsDevice: GraphicsDevice; + static content: ContentManager; + static _instance: Core; + _nextScene: Scene; + _sceneTransition: SceneTransition; + _globalManagers: GlobalManager[]; + constructor(); + static readonly Instance: Core; + _scene: Scene; + static scene: Scene; + static startSceneTransition(sceneTransition: T): T; + static registerGlobalManager(manager: es.GlobalManager): void; + static unregisterGlobalManager(manager: es.GlobalManager): void; + static getGlobalManager(type: any): T; + onOrientationChanged(): void; + draw(): Promise; + startDebugUpdate(): void; + endDebugUpdate(): void; + onSceneChanged(): void; + protected onGraphicsDeviceReset(): void; + protected initialize(): void; + protected update(): Promise; + private onAddToStage; + } +} +declare module es { + enum CoreEvents { + GraphicsDeviceReset = 0, + SceneChanged = 1, + OrientationChanged = 2 + } +} +declare module es { + class Entity { + static _idGenerator: number; + scene: Scene; + name: string; + readonly id: number; + readonly transform: Transform; + readonly components: ComponentList; + updateInterval: number; + componentBits: BitSet; + constructor(name: string); + _isDestroyed: boolean; + readonly isDestroyed: boolean; + private _tag; + tag: number; + private _enabled; + enabled: boolean; + private _updateOrder; + updateOrder: number; + parent: Transform; + readonly childCount: number; + position: Vector2; + localPosition: Vector2; + rotation: number; + rotationDegrees: number; + localRotation: number; + localRotationDegrees: number; + scale: Vector2; + localScale: Vector2; + readonly worldInverseTransform: Matrix2D; + readonly localToWorldTransform: Matrix2D; + readonly worldToLocalTransform: Matrix2D; + onTransformChanged(comp: transform.Component): void; + setTag(tag: number): Entity; + setEnabled(isEnabled: boolean): this; + setUpdateOrder(updateOrder: number): this; + destroy(): void; + detachFromScene(): void; + attachToScene(newScene: Scene): void; + clone(position?: Vector2): Entity; + onAddedToScene(): void; + onRemovedFromScene(): void; + update(): void; + addComponent(component: T): T; + getComponent(type: any): T; + hasComponent(type: any): boolean; + getOrCreateComponent(type: T): T; + getComponents(typeName: string | any, componentList?: any): any; + removeComponent(component: Component): void; + removeComponentForType(type: any): boolean; + removeAllComponents(): void; + compareTo(other: Entity): number; + toString(): string; + protected copyFrom(entity: Entity): void; + } +} +declare module es { + class Scene extends egret.DisplayObjectContainer { + camera: Camera; + readonly content: ContentManager; + enablePostProcessing: boolean; + readonly entities: EntityList; + readonly renderableComponents: RenderableComponentList; + readonly entityProcessors: EntityProcessorList; + _renderers: Renderer[]; + readonly _postProcessors: PostProcessor[]; + _didSceneBegin: any; + constructor(); + static createWithDefaultRenderer(): Scene; + initialize(): void; + onStart(): Promise; + unload(): void; + onActive(): void; + onDeactive(): void; + begin(): Promise; + end(): void; + update(): void; + render(): void; + postRender(): void; + addRenderer(renderer: T): T; + getRenderer(type: any): T; + removeRenderer(renderer: Renderer): void; + addPostProcessor(postProcessor: T): T; + getPostProcessor(type: any): T; + removePostProcessor(postProcessor: PostProcessor): void; + createEntity(name: string): Entity; + addEntity(entity: Entity): Entity; + destroyAllEntities(): void; + findEntity(name: string): Entity; + findEntitiesWithTag(tag: number): Entity[]; + entitiesOfType(type: any): T[]; + findComponentOfType(type: any): T; + findComponentsOfType(type: any): T[]; + addEntityProcessor(processor: EntitySystem): EntitySystem; + removeEntityProcessor(processor: EntitySystem): void; + getEntityProcessor(): T; + } +} +declare module transform { + enum Component { + position = 0, + scale = 1, + rotation = 2 + } +} +declare module es { + import HashObject = egret.HashObject; + enum DirtyType { + clean = 0, + positionDirty = 1, + scaleDirty = 2, + rotationDirty = 3 + } + class Transform extends HashObject { + readonly entity: Entity; + hierarchyDirty: DirtyType; + _localDirty: boolean; + _localPositionDirty: boolean; + _localScaleDirty: boolean; + _localRotationDirty: boolean; + _positionDirty: boolean; + _worldToLocalDirty: boolean; + _worldInverseDirty: boolean; + _localTransform: Matrix2D; + _worldTransform: Matrix2D; + _rotationMatrix: Matrix2D; + _translationMatrix: Matrix2D; + _scaleMatrix: Matrix2D; + _children: Transform[]; + constructor(entity: Entity); + readonly childCount: number; + rotationDegrees: number; + localRotationDegrees: number; + readonly localToWorldTransform: Matrix2D; + _parent: Transform; + parent: Transform; + _worldToLocalTransform: Matrix2D; + readonly worldToLocalTransform: Matrix2D; + _worldInverseTransform: Matrix2D; + readonly worldInverseTransform: Matrix2D; + _position: Vector2; + position: Vector2; + _scale: Vector2; + scale: Vector2; + _rotation: number; + rotation: number; + _localPosition: Vector2; + localPosition: Vector2; + _localScale: Vector2; + localScale: Vector2; + _localRotation: number; + localRotation: number; + getChild(index: number): Transform; + setParent(parent: Transform): Transform; + setPosition(x: number, y: number): Transform; + setLocalPosition(localPosition: Vector2): Transform; + setRotation(radians: number): Transform; + setRotationDegrees(degrees: number): Transform; + lookAt(pos: Vector2): void; + setLocalRotation(radians: number): this; + setLocalRotationDegrees(degrees: number): Transform; + setScale(scale: Vector2): Transform; + setLocalScale(scale: Vector2): Transform; + roundPosition(): void; + updateTransform(): void; + setDirty(dirtyFlagType: DirtyType): void; + copyFrom(transform: Transform): void; + toString(): string; + equals(other: Transform): boolean; + } +} +declare module es { + enum CameraStyle { + lockOn = 0, + cameraWindow = 1 + } + class CameraInset { + left: number; + right: number; + top: number; + bottom: number; + } + class Camera extends Component { + _inset: CameraInset; + _areMatrixedDirty: boolean; + _areBoundsDirty: boolean; + _isProjectionMatrixDirty: boolean; + followLerp: number; + deadzone: Rectangle; + focusOffset: Vector2; + mapLockEnabled: boolean; + mapSize: Vector2; + _targetEntity: Entity; + _targetCollider: Collider; + _desiredPositionDelta: Vector2; + _cameraStyle: CameraStyle; + _worldSpaceDeadZone: Rectangle; + constructor(targetEntity?: Entity, cameraStyle?: CameraStyle); + position: Vector2; + rotation: number; + _zoom: any; + zoom: number; + _minimumZoom: number; + minimumZoom: number; + _maximumZoom: number; + maximumZoom: number; + _bounds: Rectangle; + readonly bounds: Rectangle; + _transformMatrix: Matrix2D; + readonly transformMatrix: Matrix2D; + _inverseTransformMatrix: Matrix2D; + readonly inverseTransformMatrix: Matrix2D; + _origin: Vector2; + origin: Vector2; + onSceneSizeChanged(newWidth: number, newHeight: number): void; + setInset(left: number, right: number, top: number, bottom: number): Camera; + setPosition(position: Vector2): this; + setRotation(rotation: number): Camera; + setZoom(zoom: number): Camera; + setMinimumZoom(minZoom: number): Camera; + setMaximumZoom(maxZoom: number): Camera; + onEntityTransformChanged(comp: transform.Component): void; + zoomIn(deltaZoom: number): void; + zoomOut(deltaZoom: number): void; + worldToScreenPoint(worldPosition: Vector2): Vector2; + screenToWorldPoint(screenPosition: Vector2): Vector2; + mouseToWorldPoint(): Vector2; + onAddedToEntity(): void; + update(): void; + clampToMapSize(position: Vector2): Vector2; + updateFollow(): void; + follow(targetEntity: Entity, cameraStyle?: CameraStyle): void; + setCenteredDeadzone(width: number, height: number): void; + protected updateMatrixes(): void; + } +} +declare module es { + class ComponentPool { + private _cache; + private _type; + constructor(typeClass: any); + obtain(): T; + free(component: T): void; + } +} +declare module es { + class IUpdatableComparer { + compare(a: Component, b: Component): number; + } +} +declare module es { + abstract class PooledComponent extends Component { + abstract reset(): any; + } +} +declare module es { + abstract class RenderableComponent extends Component implements IRenderable { + displayObject: egret.DisplayObject; + color: number; + protected _areBoundsDirty: boolean; + readonly width: number; + readonly height: number; + protected _localOffset: Vector2; + localOffset: Vector2; + protected _renderLayer: number; + renderLayer: number; + protected _bounds: Rectangle; + readonly bounds: Rectangle; + private _isVisible; + isVisible: boolean; + onEntityTransformChanged(comp: transform.Component): void; + abstract render(camera: Camera): any; + isVisibleFromCamera(camera: Camera): boolean; + setRenderLayer(renderLayer: number): RenderableComponent; + setColor(color: number): RenderableComponent; + setLocalOffset(offset: Vector2): RenderableComponent; + sync(camera: Camera): void; + toString(): string; + protected onBecameVisible(): void; + protected onBecameInvisible(): void; + } +} +declare module es { + class Mesh extends RenderableComponent { + private _mesh; + constructor(); + setTexture(texture: egret.Texture): Mesh; + reset(): void; + render(camera: es.Camera): void; + } +} +declare module es { + class SpriteRenderer extends RenderableComponent { + constructor(sprite?: Sprite | egret.Texture); + readonly bounds: Rectangle; + originNormalized: Vector2; + protected _origin: Vector2; + origin: Vector2; + protected _sprite: Sprite; + sprite: Sprite; + setSprite(sprite: Sprite): SpriteRenderer; + setOrigin(origin: Vector2): SpriteRenderer; + setOriginNormalized(value: Vector2): SpriteRenderer; + render(camera: Camera): void; + } +} +declare module es { + class TiledSpriteRenderer extends SpriteRenderer { + readonly bounds: Rectangle; + scrollX: number; + scrollY: number; + textureScale: Vector2; + width: number; + height: number; + protected _sourceRect: Rectangle; + protected _textureScale: Vector2; + protected _inverseTexScale: Vector2; + constructor(sprite: Sprite); + render(camera: es.Camera): void; + } +} +declare module es { + class ScrollingSpriteRenderer extends TiledSpriteRenderer { + scrollSpeedX: number; + scroolSpeedY: number; + textureScale: Vector2; + private _scrollX; + private _scrollY; + constructor(sprite: Sprite); + update(): void; + } +} +declare module es { + class Sprite { + texture2D: egret.Texture; + readonly sourceRect: Rectangle; + readonly center: Vector2; + origin: Vector2; + readonly uvs: Rectangle; + constructor(texture: egret.Texture, sourceRect?: Rectangle, origin?: Vector2); + } +} +declare module es { + class SpriteAnimation { + readonly sprites: Sprite[]; + readonly frameRate: number; + constructor(sprites: Sprite[], frameRate: number); + } +} +declare module es { + enum LoopMode { + loop = 0, + once = 1, + clampForever = 2, + pingPong = 3, + pingPongOnce = 4 + } + enum State { + none = 0, + running = 1, + paused = 2, + completed = 3 + } + class SpriteAnimator extends SpriteRenderer { + onAnimationCompletedEvent: (string: any) => {}; + speed: number; + animationState: State; + currentAnimation: SpriteAnimation; + currentAnimationName: string; + currentFrame: number; + _elapsedTime: number; + _loopMode: LoopMode; + constructor(sprite?: Sprite); + readonly isRunning: boolean; + private _animations; + readonly animations: Map; + update(): void; + addAnimation(name: string, animation: SpriteAnimation): SpriteAnimator; + play(name: string, loopMode?: LoopMode): void; + isAnimationActive(name: string): boolean; + pause(): void; + unPause(): void; + stop(): void; + } +} +declare module es { + interface ITriggerListener { + onTriggerEnter(other: Collider, local: Collider): any; + onTriggerExit(other: Collider, local: Collider): any; + } +} +declare module es { + class Mover extends Component { + private _triggerHelper; + onAddedToEntity(): void; + calculateMovement(motion: Vector2, collisionResult: CollisionResult): boolean; + applyMovement(motion: Vector2): void; + move(motion: Vector2, collisionResult: CollisionResult): boolean; + } +} +declare module es { + class ProjectileMover extends Component { + private _tempTriggerList; + private _collider; + onAddedToEntity(): void; + move(motion: Vector2): boolean; + private notifyTriggerListeners; + } +} +declare module es { + abstract class Collider extends Component { + shape: Shape; + isTrigger: boolean; + physicsLayer: number; + collidesWithLayers: number; + shouldColliderScaleAndRotateWithTransform: boolean; + registeredPhysicsBounds: Rectangle; + _localOffsetLength: number; + _isPositionDirty: boolean; + _isRotationDirty: boolean; + protected _colliderRequiresAutoSizing: any; + protected _isParentEntityAddedToScene: any; + protected _isColliderRegistered: any; + readonly absolutePosition: Vector2; + readonly rotation: number; + readonly bounds: Rectangle; + protected _localOffset: Vector2; + localOffset: Vector2; + setLocalOffset(offset: Vector2): Collider; + setShouldColliderScaleAndRotateWithTransform(shouldColliderScaleAndRotationWithTransform: boolean): Collider; + onAddedToEntity(): void; + onRemovedFromEntity(): void; + onEntityTransformChanged(comp: transform.Component): void; + onEnabled(): void; + onDisabled(): void; + registerColliderWithPhysicsSystem(): void; + unregisterColliderWithPhysicsSystem(): void; + overlaps(other: Collider): boolean; + collidesWith(collider: Collider, motion: Vector2, result: CollisionResult): boolean; + clone(): Component; + } +} +declare module es { + class BoxCollider extends Collider { + constructor(); + width: number; + height: number; + setSize(width: number, height: number): this; + setWidth(width: number): BoxCollider; + setHeight(height: number): void; + toString(): string; + } +} +declare module es { + class CircleCollider extends Collider { + constructor(radius?: number); + radius: number; + setRadius(radius: number): CircleCollider; + toString(): string; + } +} +declare module es { + class PolygonCollider extends Collider { + constructor(points: Vector2[]); + } +} +declare module es { + class EntitySystem { + private _entities; + constructor(matcher?: Matcher); + private _scene; + scene: Scene; + private _matcher; + readonly matcher: Matcher; + initialize(): void; + onChanged(entity: Entity): void; + add(entity: Entity): void; + onAdded(entity: Entity): void; + remove(entity: Entity): void; + onRemoved(entity: Entity): void; + update(): void; + lateUpdate(): void; + protected begin(): void; + protected process(entities: Entity[]): void; + protected lateProcess(entities: Entity[]): void; + protected end(): void; + } +} +declare module es { + abstract class EntityProcessingSystem extends EntitySystem { + constructor(matcher: Matcher); + abstract processEntity(entity: Entity): any; + lateProcessEntity(entity: Entity): void; + protected process(entities: Entity[]): void; + protected lateProcess(entities: Entity[]): void; + } +} +declare module es { + abstract class PassiveSystem extends EntitySystem { + onChanged(entity: Entity): void; + protected process(entities: Entity[]): void; + } +} +declare module es { + abstract class ProcessingSystem extends EntitySystem { + onChanged(entity: Entity): void; + abstract processSystem(): any; + protected process(entities: Entity[]): void; + } +} +declare module es { + class BitSet { + private static LONG_MASK; + private _bits; + constructor(nbits?: number); + and(bs: BitSet): void; + andNot(bs: BitSet): void; + cardinality(): number; + clear(pos?: number): void; + get(pos: number): boolean; + intersects(set: BitSet): boolean; + isEmpty(): boolean; + nextSetBit(from: number): number; + set(pos: number, value?: boolean): void; + private ensure; + } +} +declare module es { + class ComponentList { + static compareUpdatableOrder: IUpdatableComparer; + _entity: Entity; + _components: Component[]; + _componentsToAdd: Component[]; + _componentsToRemove: Component[]; + _tempBufferList: Component[]; + _isComponentListUnsorted: boolean; + constructor(entity: Entity); + readonly count: number; + readonly buffer: Component[]; + markEntityListUnsorted(): void; + add(component: Component): void; + remove(component: Component): void; + removeAllComponents(): void; + deregisterAllComponents(): void; + registerAllComponents(): void; + updateLists(): void; + handleRemove(component: Component): void; + getComponent(type: any, onlyReturnInitializedComponents: boolean): T; + getComponents(typeName: string | any, components?: any): any; + update(): void; + onEntityTransformChanged(comp: transform.Component): void; + onEntityEnabled(): void; + onEntityDisabled(): void; + } +} +declare module es { + class ComponentTypeManager { + private static _componentTypesMask; + static add(type: any): void; + static getIndexFor(type: any): number; + } +} +declare module es { + class EntityList { + scene: Scene; + _entities: Entity[]; + _entitiesToAdded: Entity[]; + _entitiesToRemove: Entity[]; + _isEntityListUnsorted: boolean; + _entityDict: Map; + _unsortedTags: number[]; + _tempEntityList: Entity[]; + constructor(scene: Scene); + readonly count: number; + readonly buffer: Entity[]; + markEntityListUnsorted(): void; + markTagUnsorted(tag: number): void; + add(entity: Entity): void; + remove(entity: Entity): void; + removeAllEntities(): void; + contains(entity: Entity): boolean; + getTagList(tag: number): Entity[]; + addToTagList(entity: Entity): void; + removeFromTagList(entity: Entity): void; + update(): void; + updateLists(): void; + findEntity(name: string): Entity; + entitiesWithTag(tag: number): Entity[]; + entitiesOfType(type: any): T[]; + findComponentOfType(type: any): T; + findComponentsOfType(type: any): T[]; + } +} +declare module es { + class EntityProcessorList { + private _processors; + add(processor: EntitySystem): void; + remove(processor: EntitySystem): void; + onComponentAdded(entity: Entity): void; + onComponentRemoved(entity: Entity): void; + onEntityAdded(entity: Entity): void; + onEntityRemoved(entity: Entity): void; + begin(): void; + update(): void; + lateUpdate(): void; + end(): void; + getProcessor(): T; + protected notifyEntityChanged(entity: Entity): void; + protected removeFromProcessors(entity: Entity): void; + } +} +declare module es { + class Matcher { + protected allSet: BitSet; + protected exclusionSet: BitSet; + protected oneSet: BitSet; + static empty(): Matcher; + getAllSet(): BitSet; + getExclusionSet(): BitSet; + getOneSet(): BitSet; + IsIntersted(e: Entity): boolean; + all(...types: any[]): Matcher; + exclude(...types: any[]): this; + one(...types: any[]): this; + } +} +declare class ObjectUtils { + static clone(p: any, c?: T): T; +} +declare module es { + interface IRenderable { bounds: Rectangle; - }; - static addCollider(collider: Collider): void; - static removeCollider(collider: Collider): void; - static updateCollider(collider: Collider): void; + enabled: boolean; + renderLayer: number; + isVisible: boolean; + isVisibleFromCamera(camera: Camera): any; + render(camera: Camera): any; + } + class RenderableComparer { + compare(self: IRenderable, other: IRenderable): number; + } } -declare abstract class Shape { - bounds: Rectangle; - position: Vector2; - center: Vector2; - abstract recalculateBounds(collider: Collider): any; - abstract pointCollidesWithShape(point: Vector2): CollisionResult; - abstract overlaps(other: Shape): any; - abstract collidesWithShape(other: Shape): CollisionResult; +declare module es { + class RenderableComponentList { + static compareUpdatableOrder: RenderableComparer; + _components: IRenderable[]; + _componentsByRenderLayer: Map; + _unsortedRenderLayers: number[]; + _componentsNeedSort: boolean; + readonly count: number; + readonly buffer: IRenderable[]; + add(component: IRenderable): void; + remove(component: IRenderable): void; + updateRenderableRenderLayer(component: IRenderable, oldRenderLayer: number, newRenderLayer: number): void; + setRenderLayerNeedsComponentSort(renderLayer: number): void; + setNeedsComponentSort(): void; + addToRenderLayerList(component: IRenderable, renderLayer: number): void; + componentsWithRenderLayer(renderLayer: number): IRenderable[]; + updateList(): void; + } } -declare class Polygon extends Shape { - points: Vector2[]; - isUnrotated: boolean; - private _polygonCenter; - private _areEdgeNormalsDirty; - protected _originalPoints: Vector2[]; - _edgeNormals: Vector2[]; - readonly edgeNormals: Vector2[]; - isBox: boolean; - constructor(points: Vector2[], isBox?: boolean); - private buildEdgeNormals; - setPoints(points: Vector2[]): void; - collidesWithShape(other: Shape): any; - recalculateCenterAndEdgeNormals(): void; - overlaps(other: Shape): any; - static findPolygonCenter(points: Vector2[]): Vector2; - static getClosestPointOnPolygonToPoint(points: Vector2[], point: Vector2): { - closestPoint: any; - distanceSquared: any; - edgeNormal: any; - }; - pointCollidesWithShape(point: Vector2): CollisionResult; - containsPoint(point: Vector2): boolean; - static buildSymmertricalPolygon(vertCount: number, radius: number): any[]; - recalculateBounds(collider: Collider): void; +declare class StringUtils { + private static specialSigns; + static matchChineseWord(str: string): string[]; + static lTrim(target: string): string; + static rTrim(target: string): string; + static trim(target: string): string; + static isWhiteSpace(str: string): boolean; + static replaceMatch(mainStr: string, targetStr: string, replaceStr: string, caseMark?: boolean): string; + static htmlSpecialChars(str: string, reversion?: boolean): string; + static zfill(str: string, width?: number): string; + static reverse(str: string): string; + static cutOff(str: string, start: number, len: number, order?: boolean): string; + static strReplace(str: string, rStr: string[]): string; } -declare class Box extends Polygon { - width: number; - height: number; - constructor(width: number, height: number); - private static buildBox; - overlaps(other: Shape): any; - collidesWithShape(other: Shape): any; - updateBox(width: number, height: number): void; - containsPoint(point: Vector2): boolean; +declare module es { + class TextureUtils { + static sharedCanvas: HTMLCanvasElement; + static sharedContext: CanvasRenderingContext2D; + static convertImageToCanvas(texture: egret.Texture, rect?: egret.Rectangle): HTMLCanvasElement; + static toDataURL(type: string, texture: egret.Texture, rect?: egret.Rectangle, encoderOptions?: any): string; + static eliFoTevas(type: string, texture: egret.Texture, filePath: string, rect?: egret.Rectangle, encoderOptions?: any): void; + static getPixel32(texture: egret.Texture, x: number, y: number): number[]; + static getPixels(texture: egret.Texture, x: number, y: number, width?: number, height?: number): number[]; + } } -declare class Circle extends Shape { - radius: number; - private _originalRadius; - constructor(radius: number); - pointCollidesWithShape(point: Vector2): CollisionResult; - collidesWithShape(other: Shape): CollisionResult; - recalculateBounds(collider: Collider): void; - overlaps(other: Shape): any; +declare module es { + class Time { + static unscaledDeltaTime: any; + static deltaTime: number; + static timeScale: number; + static frameCount: number; + static _timeSinceSceneLoad: any; + private static _lastTime; + static update(currentTime: number): void; + static sceneChanged(): void; + static checkEvery(interval: number): boolean; + } } -declare class CollisionResult { - collider: Collider; - minimumTranslationVector: Vector2; - normal: Vector2; - point: Vector2; - invertResult(): void; +declare class TimeUtils { + static monthId(d?: Date): number; + static dateId(t?: Date): number; + static weekId(d?: Date, first?: boolean): number; + static diffDay(a: Date, b: Date, fixOne?: boolean): number; + static getFirstDayOfWeek(d?: Date): Date; + static getFirstOfDay(d?: Date): Date; + static getNextFirstOfDay(d?: Date): Date; + static formatDate(date: Date): string; + static formatDateTime(date: Date): string; + static parseDate(s: string): Date; + static secondToTime(time?: number, partition?: string, showHour?: boolean): string; + static timeToMillisecond(time: string, partition?: string): string; } -declare class ShapeCollisions { - static polygonToPolygon(first: Polygon, second: Polygon): CollisionResult; - static intervalDistance(minA: number, maxA: number, minB: number, maxB: any): number; - static getInterval(axis: Vector2, polygon: Polygon, min: number, max: number): { +declare module es { + class GraphicsCapabilities extends egret.Capabilities { + initialize(device: GraphicsDevice): void; + private platformInitialize; + } +} +declare module es { + class GraphicsDevice { + graphicsCapabilities: GraphicsCapabilities; + constructor(); + private _viewport; + readonly viewport: Viewport; + private setup; + } +} +declare module es { + class Viewport { + private _x; + private _y; + private _minDepth; + private _maxDepth; + constructor(x: number, y: number, width: number, height: number); + private _width; + width: number; + private _height; + height: number; + readonly aspectRatio: number; + bounds: Rectangle; + } +} +declare module es { + class GaussianBlurEffect extends egret.CustomFilter { + private static blur_frag; + constructor(); + } +} +declare module es { + class PolygonLightEffect extends egret.CustomFilter { + private static vertSrc; + private static fragmentSrc; + constructor(); + } +} +declare module es { + class PostProcessor { + static default_vert: string; + enabled: boolean; + effect: egret.Filter; + scene: Scene; + shape: egret.Shape; + constructor(effect?: egret.Filter); + onAddedToScene(scene: Scene): void; + process(): void; + onSceneBackBufferSizeChanged(newWidth: number, newHeight: number): void; + unload(): void; + protected drawFullscreenQuad(): void; + } +} +declare module es { + class GaussianBlurPostProcessor extends PostProcessor { + onAddedToScene(scene: Scene): void; + } +} +declare module es { + abstract class Renderer { + camera: Camera; + readonly renderOrder: number; + protected constructor(renderOrder: number, camera?: Camera); + onAddedToScene(scene: Scene): void; + unload(): void; + abstract render(scene: Scene): any; + onSceneBackBufferSizeChanged(newWidth: number, newHeight: number): void; + compareTo(other: Renderer): number; + protected beginRender(cam: Camera): void; + protected renderAfterStateCheck(renderable: IRenderable, cam: Camera): void; + } +} +declare module es { + class DefaultRenderer extends Renderer { + constructor(); + render(scene: Scene): void; + } +} +declare module es { + class ScreenSpaceRenderer extends Renderer { + render(scene: Scene): void; + } +} +declare module es { + class PolyLight extends RenderableComponent { + power: number; + private _lightEffect; + private _indices; + constructor(radius: number, color: number, power: number); + protected _radius: number; + radius: number; + setRadius(radius: number): void; + render(camera: Camera): void; + reset(): void; + private computeTriangleIndices; + } +} +declare module es { + abstract class SceneTransition { + loadsNewScene: boolean; + isNewSceneLoaded: boolean; + onScreenObscured: Function; + onTransitionCompleted: Function; + protected sceneLoadAction: Function; + constructor(sceneLoadAction: Function); + private _hasPreviousSceneRender; + readonly hasPreviousSceneRender: boolean; + preRender(): void; + render(): void; + onBeginTransition(): Promise; + tickEffectProgressProperty(filter: egret.CustomFilter, duration: number, easeType: Function, reverseDirection?: boolean): Promise; + protected transitionComplete(): void; + protected loadNextScene(): Promise; + } +} +declare module es { + class FadeTransition extends SceneTransition { + fadeToColor: number; + fadeOutDuration: number; + fadeEaseType: Function; + delayBeforeFadeInDuration: number; + private _mask; + private _alpha; + constructor(sceneLoadAction: Function); + onBeginTransition(): Promise; + render(): void; + } +} +declare module es { + class WindTransition extends SceneTransition { + duration: number; + easeType: (t: number) => number; + private _mask; + private _windEffect; + constructor(sceneLoadAction: Function); + windSegments: number; + size: number; + onBeginTransition(): Promise; + } +} +declare module es { + class Bezier { + static getPoint(p0: Vector2, p1: Vector2, p2: Vector2, t: number): Vector2; + static getFirstDerivative(p0: Vector2, p1: Vector2, p2: Vector2, t: number): Vector2; + static getFirstDerivativeThree(start: Vector2, firstControlPoint: Vector2, secondControlPoint: Vector2, end: Vector2, t: number): Vector2; + static getPointThree(start: Vector2, firstControlPoint: Vector2, secondControlPoint: Vector2, end: Vector2, t: number): Vector2; + static getOptimizedDrawingPoints(start: Vector2, firstCtrlPoint: Vector2, secondCtrlPoint: Vector2, end: Vector2, distanceTolerance?: number): Vector2[]; + private static recursiveGetOptimizedDrawingPoints; + } +} +declare module es { + class Flags { + static isFlagSet(self: number, flag: number): boolean; + static isUnshiftedFlagSet(self: number, flag: number): boolean; + static setFlagExclusive(self: number, flag: number): number; + static setFlag(self: number, flag: number): number; + static unsetFlag(self: number, flag: number): number; + static invertFlags(self: number): number; + } +} +declare module es { + class MathHelper { + static readonly Epsilon: number; + static readonly Rad2Deg: number; + static readonly Deg2Rad: number; + static toDegrees(radians: number): number; + static toRadians(degrees: number): number; + static map(value: number, leftMin: number, leftMax: number, rightMin: number, rightMax: number): number; + static lerp(value1: number, value2: number, amount: number): number; + static clamp(value: number, min: number, max: number): number; + static pointOnCirlce(circleCenter: Vector2, radius: number, angleInDegrees: number): Vector2; + static isEven(value: number): boolean; + static clamp01(value: number): number; + static angleBetweenVectors(from: Vector2, to: Vector2): number; + } +} +declare module es { + var matrixPool: any[]; + class Matrix2D extends egret.Matrix { + m11: number; + m12: number; + m21: number; + m22: number; + m31: number; + m32: number; + static create(): Matrix2D; + identity(): Matrix2D; + translate(dx: number, dy: number): Matrix2D; + scale(sx: number, sy: number): Matrix2D; + rotate(angle: number): Matrix2D; + invert(): Matrix2D; + add(matrix: Matrix2D): Matrix2D; + substract(matrix: Matrix2D): Matrix2D; + divide(matrix: Matrix2D): Matrix2D; + multiply(matrix: Matrix2D): Matrix2D; + determinant(): number; + release(matrix: Matrix2D): void; + } +} +declare module es { + class Rectangle extends egret.Rectangle { + _tempMat: Matrix2D; + _transformMat: Matrix2D; + readonly max: Vector2; + readonly center: Vector2; + location: Vector2; + size: Vector2; + static fromMinMax(minX: number, minY: number, maxX: number, maxY: number): Rectangle; + static rectEncompassingPoints(points: Vector2[]): Rectangle; + intersects(value: egret.Rectangle): boolean; + rayIntersects(ray: Ray2D): number; + containsRect(value: Rectangle): boolean; + contains(x: number, y: number): boolean; + getHalfSize(): Vector2; + getClosestPointOnRectangleBorderToPoint(point: Vector2, edgeNormal: Vector2): Vector2; + getClosestPointOnBoundsToOrigin(): Vector2; + calculateBounds(parentPosition: Vector2, position: Vector2, origin: Vector2, scale: Vector2, rotation: number, width: number, height: number): void; + } +} +declare module es { + class Vector3 { + x: number; + y: number; + z: number; + constructor(x: number, y: number, z: number); + } +} +declare module es { + class ColliderTriggerHelper { + private _entity; + private _activeTriggerIntersections; + private _previousTriggerIntersections; + private _tempTriggerList; + constructor(entity: Entity); + update(): void; + private checkForExitedColliders; + private notifyTriggerListeners; + } +} +declare module es { + enum PointSectors { + center = 0, + top = 1, + bottom = 2, + topLeft = 9, + topRight = 5, + left = 8, + right = 4, + bottomLeft = 10, + bottomRight = 6 + } + class Collisions { + static isLineToLine(a1: Vector2, a2: Vector2, b1: Vector2, b2: Vector2): boolean; + static lineToLineIntersection(a1: Vector2, a2: Vector2, b1: Vector2, b2: Vector2): Vector2; + static closestPointOnLine(lineA: Vector2, lineB: Vector2, closestTo: Vector2): Vector2; + static isCircleToCircle(circleCenter1: Vector2, circleRadius1: number, circleCenter2: Vector2, circleRadius2: number): boolean; + static isCircleToLine(circleCenter: Vector2, radius: number, lineFrom: Vector2, lineTo: Vector2): boolean; + static isCircleToPoint(circleCenter: Vector2, radius: number, point: Vector2): boolean; + static isRectToCircle(rect: egret.Rectangle, cPosition: Vector2, cRadius: number): boolean; + static isRectToLine(rect: Rectangle, lineFrom: Vector2, lineTo: Vector2): boolean; + static isRectToPoint(rX: number, rY: number, rW: number, rH: number, point: Vector2): boolean; + static getSector(rX: number, rY: number, rW: number, rH: number, point: Vector2): PointSectors; + } +} +declare module es { + class Physics { + static spatialHashCellSize: number; + static readonly allLayers: number; + private static _spatialHash; + static raycastsHitTriggers: boolean; + static raycastsStartInColliders: boolean; + static reset(): void; + static clear(): void; + static overlapCircleAll(center: Vector2, randius: number, results: any[], layerMask?: number): number; + static boxcastBroadphase(rect: Rectangle, layerMask?: number): Collider[]; + static boxcastBroadphaseExcludingSelf(collider: Collider, rect: Rectangle, layerMask?: number): Collider[]; + static addCollider(collider: Collider): void; + static removeCollider(collider: Collider): void; + static updateCollider(collider: Collider): void; + static debugDraw(secondsToDisplay: any): void; + } +} +declare module es { + class Ray2D { + start: Vector2; + end: Vector2; + direction: Vector2; + constructor(position: Vector2, end: Vector2); + } +} +declare module es { + class RaycastHit { + collider: Collider; + fraction: number; + distance: number; + point: Vector2; + normal: Vector2; + centroid: Vector2; + constructor(collider: Collider, fraction: number, distance: number, point: Vector2, normal: Vector2); + setValues(collider: Collider, fraction: number, distance: number, point: Vector2): void; + setValuesNonCollider(fraction: number, distance: number, point: Vector2, normal: Vector2): void; + reset(): void; + toString(): string; + } +} +declare module es { + abstract class Shape { + position: Vector2; + center: Vector2; + bounds: Rectangle; + abstract recalculateBounds(collider: Collider): any; + abstract overlaps(other: Shape): boolean; + abstract collidesWithShape(other: Shape, collisionResult: CollisionResult): boolean; + abstract collidesWithLine(start: Vector2, end: Vector2, hit: RaycastHit): boolean; + abstract containsPoint(point: Vector2): any; + abstract pointCollidesWithShape(point: Vector2, result: CollisionResult): boolean; + clone(): Shape; + } +} +declare module es { + class Polygon extends Shape { + points: Vector2[]; + _areEdgeNormalsDirty: boolean; + _originalPoints: Vector2[]; + _polygonCenter: Vector2; + isBox: boolean; + isUnrotated: boolean; + constructor(points: Vector2[], isBox?: boolean); + _edgeNormals: Vector2[]; + readonly edgeNormals: Vector2[]; + setPoints(points: Vector2[]): void; + recalculateCenterAndEdgeNormals(): void; + buildEdgeNormals(): void; + static buildSymmetricalPolygon(vertCount: number, radius: number): any[]; + static recenterPolygonVerts(points: Vector2[]): void; + static findPolygonCenter(points: Vector2[]): Vector2; + static getFarthestPointInDirection(points: Vector2[], direction: Vector2): Vector2; + static getClosestPointOnPolygonToPoint(points: Vector2[], point: Vector2, distanceSquared: number, edgeNormal: Vector2): Vector2; + static rotatePolygonVerts(radians: number, originalPoints: Vector2[], rotatedPoints: any): void; + recalculateBounds(collider: Collider): void; + overlaps(other: Shape): any; + collidesWithShape(other: Shape, result: CollisionResult): boolean; + collidesWithLine(start: es.Vector2, end: es.Vector2, hit: es.RaycastHit): boolean; + containsPoint(point: Vector2): boolean; + pointCollidesWithShape(point: Vector2, result: CollisionResult): boolean; + } +} +declare module es { + class Box extends Polygon { + width: number; + height: number; + constructor(width: number, height: number); + private static buildBox; + updateBox(width: number, height: number): void; + overlaps(other: Shape): any; + collidesWithShape(other: Shape, result: CollisionResult): boolean; + containsPoint(point: Vector2): boolean; + pointCollidesWithShape(point: es.Vector2, result: es.CollisionResult): boolean; + } +} +declare module es { + class Circle extends Shape { + radius: number; + _originalRadius: number; + constructor(radius: number); + recalculateBounds(collider: es.Collider): void; + overlaps(other: Shape): any; + collidesWithShape(other: Shape, result: CollisionResult): boolean; + collidesWithLine(start: es.Vector2, end: es.Vector2, hit: es.RaycastHit): boolean; + containsPoint(point: es.Vector2): boolean; + pointCollidesWithShape(point: Vector2, result: CollisionResult): boolean; + } +} +declare module es { + class CollisionResult { + collider: Collider; + normal: Vector2; + minimumTranslationVector: Vector2; + point: Vector2; + removeHorizontal(deltaMovement: Vector2): void; + invertResult(): this; + toString(): string; + } +} +declare module es { + class RealtimeCollisions { + static intersectMovingCircleToBox(s: Circle, b: Box, movement: Vector2): number; + } +} +declare module es { + class ShapeCollisions { + static polygonToPolygon(first: Polygon, second: Polygon, result: CollisionResult): boolean; + static intervalDistance(minA: number, maxA: number, minB: number, maxB: any): number; + static getInterval(axis: Vector2, polygon: Polygon, min: number, max: number): { + min: number; + max: number; + }; + static circleToPolygon(circle: Circle, polygon: Polygon, result: CollisionResult): boolean; + static circleToBox(circle: Circle, box: Box, result: CollisionResult): boolean; + static pointToCircle(point: Vector2, circle: Circle, result: CollisionResult): boolean; + static pointToBox(point: Vector2, box: Box, result: CollisionResult): boolean; + static closestPointOnLine(lineA: Vector2, lineB: Vector2, closestTo: Vector2): Vector2; + static pointToPoly(point: Vector2, poly: Polygon, result: CollisionResult): boolean; + static circleToCircle(first: Circle, second: Circle, result: CollisionResult): boolean; + static boxToBox(first: Box, second: Box, result: CollisionResult): boolean; + private static minkowskiDifference; + static lineToPoly(start: Vector2, end: Vector2, polygon: Polygon, hit: RaycastHit): boolean; + static lineToLine(a1: Vector2, a2: Vector2, b1: Vector2, b2: Vector2, intersection: Vector2): boolean; + static lineToCircle(start: Vector2, end: Vector2, s: Circle, hit: RaycastHit): boolean; + static boxToBoxCast(first: Box, second: Box, movement: Vector2, hit: RaycastHit): boolean; + } +} +declare module es { + class SpatialHash { + gridBounds: Rectangle; + _raycastParser: RaycastResultParser; + _cellSize: number; + _inverseCellSize: number; + _overlapTestCircle: Circle; + _cellDict: NumberDictionary; + _tempHashSet: Collider[]; + constructor(cellSize?: number); + register(collider: Collider): void; + remove(collider: Collider): void; + removeWithBruteForce(obj: Collider): void; + clear(): void; + debugDraw(secondsToDisplay: number, textScale?: number): void; + aabbBroadphase(bounds: Rectangle, excludeCollider: Collider, layerMask: number): Collider[]; + overlapCircle(circleCenter: Vector2, radius: number, results: Collider[], layerMask: any): number; + private cellCoords; + private cellAtPosition; + private debugDrawCellDetails; + } + class NumberDictionary { + _store: Map; + add(x: number, y: number, list: Collider[]): void; + remove(obj: Collider): void; + tryGetValue(x: number, y: number): Collider[]; + clear(): void; + private getKey; + } + class RaycastResultParser { + hitCounter: number; + static compareRaycastHits: (a: RaycastHit, b: RaycastHit) => number; + _hits: RaycastHit[]; + _tempHit: RaycastHit; + _checkedColliders: Collider[]; + _cellHits: RaycastHit[]; + _ray: Ray2D; + _layerMask: number; + start(ray: Ray2D, hits: RaycastHit[], layerMask: number): void; + checkRayIntersection(cellX: number, cellY: number, cell: Collider[]): boolean; + reset(): void; + } +} +declare class ArrayUtils { + static bubbleSort(ary: number[]): void; + static insertionSort(ary: number[]): void; + static binarySearch(ary: number[], value: number): number; + static findElementIndex(ary: any[], num: any): any; + static getMaxElementIndex(ary: number[]): number; + static getMinElementIndex(ary: number[]): number; + static getUniqueAry(ary: number[]): number[]; + static getDifferAry(aryA: number[], aryB: number[]): number[]; + static swap(array: any[], index1: number, index2: number): void; + static clearList(ary: any[]): void; + static cloneList(ary: any[]): any[]; + static equals(ary1: number[], ary2: number[]): Boolean; + static insert(ary: any[], index: number, value: any): any; +} +declare class Base64Utils { + private static _keyNum; + private static _keyStr; + private static _keyAll; + static encode: (input: any) => string; + static decode(input: any, isNotStr?: boolean): string; + private static _utf8_encode; + private static _utf8_decode; + private static getConfKey; +} +declare module es { + class ContentManager { + protected loadedAssets: Map; + loadRes(name: string, local?: boolean): Promise; + dispose(): void; + } +} +declare module es { + class DrawUtils { + static drawLine(shape: egret.Shape, start: Vector2, end: Vector2, color: number, thickness?: number): void; + static drawLineAngle(shape: egret.Shape, start: Vector2, radians: number, length: number, color: number, thickness?: number): void; + static drawHollowRect(shape: egret.Shape, rect: Rectangle, color: number, thickness?: number): void; + static drawHollowRectR(shape: egret.Shape, x: number, y: number, width: number, height: number, color: number, thickness?: number): void; + static drawPixel(shape: egret.Shape, position: Vector2, color: number, size?: number): void; + static getColorMatrix(color: number): egret.ColorMatrixFilter; + } +} +declare module es { + class FuncPack { + func: Function; + context: any; + constructor(func: Function, context: any); + } + class Emitter { + private _messageTable; + constructor(); + addObserver(eventType: T, handler: Function, context: any): void; + removeObserver(eventType: T, handler: Function): void; + emit(eventType: T, data?: any): void; + } +} +declare module es { + class GlobalManager { + _enabled: boolean; + enabled: boolean; + setEnabled(isEnabled: boolean): void; + onEnabled(): void; + onDisabled(): void; + update(): void; + } +} +declare module es { + class TouchState { + x: number; + y: number; + touchPoint: number; + touchDown: boolean; + readonly position: Vector2; + reset(): void; + } + class Input { + private static _init; + private static _previousTouchState; + private static _resolutionOffset; + private static _touchIndex; + private static _gameTouchs; + static readonly gameTouchs: TouchState[]; + private static _resolutionScale; + static readonly resolutionScale: Vector2; + private static _totalTouchCount; + static readonly totalTouchCount: number; + static readonly touchPosition: Vector2; + static maxSupportedTouch: number; + static readonly touchPositionDelta: Vector2; + static initialize(): void; + static scaledPosition(position: Vector2): Vector2; + private static initTouchCache; + private static touchBegin; + private static touchMove; + private static touchEnd; + private static setpreviousTouchState; + } +} +declare class KeyboardUtils { + static TYPE_KEY_DOWN: number; + static TYPE_KEY_UP: number; + static A: string; + static B: string; + static C: string; + static D: string; + static E: string; + static F: string; + static G: string; + static H: string; + static I: string; + static J: string; + static K: string; + static L: string; + static M: string; + static N: string; + static O: string; + static P: string; + static Q: string; + static R: string; + static S: string; + static T: string; + static U: string; + static V: string; + static W: string; + static X: string; + static Y: string; + static Z: string; + static ESC: string; + static F1: string; + static F2: string; + static F3: string; + static F4: string; + static F5: string; + static F6: string; + static F7: string; + static F8: string; + static F9: string; + static F10: string; + static F11: string; + static F12: string; + static NUM_1: string; + static NUM_2: string; + static NUM_3: string; + static NUM_4: string; + static NUM_5: string; + static NUM_6: string; + static NUM_7: string; + static NUM_8: string; + static NUM_9: string; + static NUM_0: string; + static TAB: string; + static CTRL: string; + static ALT: string; + static SHIFT: string; + static CAPS_LOCK: string; + static ENTER: string; + static SPACE: string; + static BACK_SPACE: string; + static INSERT: string; + static DELETE: string; + static HOME: string; + static END: string; + static PAGE_UP: string; + static PAGE_DOWN: string; + static LEFT: string; + static RIGHT: string; + static UP: string; + static DOWN: string; + static PAUSE_BREAK: string; + static NUM_LOCK: string; + static SCROLL_LOCK: string; + static WINDOWS: string; + private static keyDownDict; + private static keyUpDict; + static init(): void; + static registerKey(key: string, fun: Function, thisObj: any, type?: number, ...args: any[]): void; + static unregisterKey(key: string, type?: number): void; + static destroy(): void; + private static onKeyDonwHander; + private static onKeyUpHander; + private static keyCodeToString; +} +declare module es { + class ListPool { + private static readonly _objectQueue; + static warmCache(cacheCount: number): void; + static trimCache(cacheCount: any): void; + static clearCache(): void; + static obtain(): T[]; + static free(obj: Array): void; + } +} +declare const THREAD_ID: string; +declare const nextTick: (fn: any) => void; +declare class LockUtils { + private _keyX; + private _keyY; + private setItem; + private getItem; + private removeItem; + constructor(key: any); + lock(): Promise<{}>; +} +declare module es { + class Pair { + first: T; + second: T; + constructor(first: T, second: T); + clear(): void; + equals(other: Pair): boolean; + } +} +declare class RandomUtils { + static randrange(start: number, stop: number, step?: number): number; + static randint(a: number, b: number): number; + static randnum(a: number, b: number): number; + static shuffle(array: any[]): any[]; + static choice(sequence: any): any; + static sample(sequence: any[], num: number): any[]; + static random(): number; + static boolean(chance?: number): boolean; + private static _randomCompare; +} +declare module es { + class RectangleExt { + static union(first: Rectangle, point: Vector2): Rectangle; + } +} +declare module es { + class Triangulator { + triangleIndices: number[]; + private _triPrev; + private _triNext; + static testPointTriangle(point: Vector2, a: Vector2, b: Vector2, c: Vector2): boolean; + triangulate(points: Vector2[], arePointsCCW?: boolean): void; + private initialize; + } +} +declare module es { + class Vector2Ext { + static isTriangleCCW(a: Vector2, center: Vector2, c: Vector2): boolean; + static cross(u: Vector2, v: Vector2): number; + static perpendicular(first: Vector2, second: Vector2): Vector2; + static normalize(vec: Vector2): Vector2; + static transformA(sourceArray: Vector2[], sourceIndex: number, matrix: Matrix2D, destinationArray: Vector2[], destinationIndex: number, length: number): void; + static transformR(position: Vector2, matrix: Matrix2D): Vector2; + static transform(sourceArray: Vector2[], matrix: Matrix2D, destinationArray: Vector2[]): void; + static round(vec: Vector2): Vector2; + } +} +declare class WebGLUtils { + static getContext(): CanvasRenderingContext2D; +} +declare module es { + class Layout { + clientArea: Rectangle; + safeArea: Rectangle; + constructor(); + place(size: Vector2, horizontalMargin: number, verticalMargine: number, alignment: Alignment): Rectangle; + } + enum Alignment { + none = 0, + left = 1, + right = 2, + horizontalCenter = 4, + top = 8, + bottom = 16, + verticalCenter = 32, + topLeft = 9, + topRight = 10, + topCenter = 12, + bottomLeft = 17, + bottomRight = 18, + bottomCenter = 20, + centerLeft = 33, + centerRight = 34, + center = 36 + } +} +declare namespace stopwatch { + class Stopwatch { + private readonly getSystemTime; + private _startSystemTime; + private _stopSystemTime; + private _stopDuration; + private _pendingSliceStartStopwatchTime; + private _completeSlices; + constructor(getSystemTime?: GetTimeFunc); + getState(): State; + isIdle(): boolean; + isRunning(): boolean; + isStopped(): boolean; + slice(): Slice; + getCompletedSlices(): Slice[]; + getCompletedAndPendingSlices(): Slice[]; + getPendingSlice(): Slice; + getTime(): number; + reset(): void; + start(forceReset?: boolean): void; + stop(recordPendingSlice?: boolean): number; + private calculatePendingSlice; + private caculateStopwatchTime; + private getSystemTimeOfCurrentStopwatchTime; + private recordPendingSlice; + } + type GetTimeFunc = () => number; + enum State { + IDLE = "IDLE", + RUNNING = "RUNNING", + STOPPED = "STOPPED" + } + function setDefaultSystemTimeGetter(systemTimeGetter?: GetTimeFunc): void; + interface Slice { + readonly startTime: number; + readonly endTime: number; + readonly duration: number; + } +} +declare module es { + class TimeRuler { + static readonly maxBars: number; + static readonly maxSamples: number; + static readonly maxNestCall: number; + static readonly barHeight: number; + static readonly maxSampleFrames: number; + static readonly logSnapDuration: number; + static readonly barPadding: number; + static readonly autoAdjustDelay: number; + private static _instance; + targetSampleFrames: number; + width: number; + enabled: true; + showLog: boolean; + private _frameKey; + private _logKey; + private _logs; + private sampleFrames; + private _position; + private _prevLog; + private _curLog; + private frameCount; + private markers; + private stopwacth; + private _markerNameToIdMap; + private _updateCount; + private _frameAdjust; + constructor(); + static readonly Instance: TimeRuler; + startFrame(): void; + beginMark(markerName: string, color: number, barIndex?: number): void; + endMark(markerName: string, barIndex?: number): void; + getAverageTime(barIndex: number, markerName: string): number; + resetLog(): void; + render(position?: Vector2, width?: number): void; + private onGraphicsDeviceReset; + } + class FrameLog { + bars: MarkerCollection[]; + constructor(); + } + class MarkerCollection { + markers: Marker[]; + markCount: number; + markerNests: number[]; + nestCount: number; + constructor(); + } + class Marker { + markerId: number; + beginTime: number; + endTime: number; + color: number; + } + class MarkerInfo { + name: string; + logs: MarkerLog[]; + constructor(name: any); + } + class MarkerLog { + snapMin: number; + snapMax: number; + snapAvg: number; min: number; max: number; - }; - static circleToPolygon(circle: Circle, polygon: Polygon): CollisionResult; - static circleToBox(circle: Circle, box: Box): CollisionResult; - static pointToCircle(point: Vector2, circle: Circle): CollisionResult; - static closestPointOnLine(lineA: Vector2, lineB: Vector2, closestTo: Vector2): Vector2; - static pointToPoly(point: Vector2, poly: Polygon): CollisionResult; - static circleToCircle(first: Circle, second: Circle): CollisionResult; - static boxToBox(first: Box, second: Box): CollisionResult; - private static minkowskiDifference; -} -declare class SpatialHash { - gridBounds: Rectangle; - private _raycastParser; - private _cellSize; - private _inverseCellSize; - private _overlapTestCircle; - private _tempHashSet; - private _cellDict; - constructor(cellSize?: number); - remove(collider: Collider): void; - register(collider: Collider): void; - clear(): void; - overlapCircle(circleCenter: Vector2, radius: number, results: Collider[], layerMask: any): number; - aabbBroadphase(bounds: Rectangle, excludeCollider: Collider, layerMask: number): { - tempHashSet: Collider[]; - bounds: Rectangle; - }; - private cellAtPosition; - private cellCoords; -} -declare class RaycastResultParser { -} -declare class NumberDictionary { - private _store; - private getKey; - private intToUint; - add(x: number, y: number, list: Collider[]): void; - remove(obj: Collider): void; - tryGetValue(x: number, y: number): Collider[]; - clear(): void; -} -declare class fui { -} -declare class ContentManager { - protected loadedAssets: Map; - loadRes(name: string, local?: boolean): Promise; - dispose(): void; -} -declare class Emitter { - private _messageTable; - constructor(); - addObserver(eventType: T, handler: Function): void; - removeObserver(eventType: T, handler: Function): void; - emit(eventType: T, data: any): void; -} -declare class GlobalManager { - static globalManagers: GlobalManager[]; - private _enabled; - enabled: boolean; - setEnabled(isEnabled: boolean): void; - onEnabled(): void; - onDisabled(): void; - update(): void; - static registerGlobalManager(manager: GlobalManager): void; - static unregisterGlobalManager(manager: GlobalManager): void; - static getGlobalManager(type: any): T; -} -declare class TouchState { - x: number; - y: number; - touchPoint: number; - touchDown: boolean; - readonly position: Vector2; - reset(): void; -} -declare class Input { - private static _init; - private static _stage; - private static _previousTouchState; - private static _gameTouchs; - private static _resolutionOffset; - private static _resolutionScale; - private static _touchIndex; - private static _totalTouchCount; - static readonly touchPosition: Vector2; - static maxSupportedTouch: number; - static readonly resolutionScale: Vector2; - static readonly totalTouchCount: number; - static readonly gameTouchs: TouchState[]; - static readonly touchPositionDelta: Vector2; - static initialize(stage: egret.Stage): void; - private static initTouchCache; - private static touchBegin; - private static touchMove; - private static touchEnd; - private static setpreviousTouchState; - static scaledPosition(position: Vector2): Vector2; -} -declare class ListPool { - private static readonly _objectQueue; - static warmCache(cacheCount: number): void; - static trimCache(cacheCount: any): void; - static clearCache(): void; - static obtain(): Array; - static free(obj: Array): void; -} -declare class Pair { - first: T; - second: T; - constructor(first: T, second: T); - clear(): void; - equals(other: Pair): boolean; -} -declare class RectangleExt { - static union(first: Rectangle, point: Vector2): Rectangle; - static unionR(value1: Rectangle, value2: Rectangle): Rectangle; -} -declare class Triangulator { - triangleIndices: number[]; - private _triPrev; - private _triNext; - triangulate(points: Vector2[], arePointsCCW?: boolean): void; - private initialize; - static testPointTriangle(point: Vector2, a: Vector2, b: Vector2, c: Vector2): boolean; -} -declare class Vector2Ext { - static isTriangleCCW(a: Vector2, center: Vector2, c: Vector2): boolean; - static cross(u: Vector2, v: Vector2): number; - static perpendicular(first: Vector2, second: Vector2): Vector2; - static normalize(vec: Vector2): Vector2; - static transformA(sourceArray: Vector2[], sourceIndex: number, matrix: Matrix2D, destinationArray: Vector2[], destinationIndex: number, length: number): void; - static transformR(position: Vector2, matrix: Matrix2D): Vector2; - static transform(sourceArray: Vector2[], matrix: Matrix2D, destinationArray: Vector2[]): void; - static round(vec: Vector2): Vector2; + avg: number; + samples: number; + color: number; + initialized: boolean; + } } diff --git a/source/bin/framework.js b/source/bin/framework.js index b8d3301d..a1ee37aa 100644 --- a/source/bin/framework.js +++ b/source/bin/framework.js @@ -111,6 +111,10 @@ Array.prototype.findAll = function (predicate) { Array.prototype.contains = function (value) { function contains(array, value) { for (var i = 0, len = array.length; i < len; i++) { + if (array[i] instanceof egret.HashObject && value instanceof egret.HashObject) { + if (array[i].hashCode == value.hashCode) + return true; + } if (array[i] == value) { return true; } @@ -214,7 +218,9 @@ Array.prototype.groupBy = function (keySelector) { var keys_1 = []; return array.reduce(function (groups, element, index) { var key = JSON.stringify(keySelector.call(arguments[1], element, index, array)); - var index2 = keys_1.findIndex(function (x) { return x === key; }); + var index2 = keys_1.findIndex(function (x) { + return x === key; + }); if (index2 < 0) { index2 = keys_1.push(key) - 1; } @@ -230,7 +236,9 @@ Array.prototype.groupBy = function (keySelector) { var keys = []; var _loop_1 = function (i, len) { var key = JSON.stringify(keySelector.call(arguments_1[1], array[i], i, array)); - var index = keys.findIndex(function (x) { return x === key; }); + var index = keys.findIndex(function (x) { + return x === key; + }); if (index < 0) { index = keys.push(key) - 1; } @@ -273,2961 +281,4635 @@ Array.prototype.sum = function (selector) { } return sum(this, selector); }; -var PriorityQueueNode = (function () { - function PriorityQueueNode() { - this.priority = 0; - this.insertionIndex = 0; - this.queueIndex = 0; - } - return PriorityQueueNode; -}()); -var AStarPathfinder = (function () { - function AStarPathfinder() { - } - AStarPathfinder.search = function (graph, start, goal) { - var _this = this; - var foundPath = false; - var cameFrom = new Map(); - cameFrom.set(start, start); - var costSoFar = new Map(); - var frontier = new PriorityQueue(1000); - frontier.enqueue(new AStarNode(start), 0); - costSoFar.set(start, 0); - var _loop_2 = function () { - var current = frontier.dequeue(); - if (JSON.stringify(current.data) == JSON.stringify(goal)) { - foundPath = true; - return "break"; - } - graph.getNeighbors(current.data).forEach(function (next) { - var newCost = costSoFar.get(current.data) + graph.cost(current.data, next); - if (!_this.hasKey(costSoFar, next) || newCost < costSoFar.get(next)) { - costSoFar.set(next, newCost); - var priority = newCost + graph.heuristic(next, goal); - frontier.enqueue(new AStarNode(next), priority); - cameFrom.set(next, current.data); +var es; +(function (es) { + var PriorityQueueNode = (function () { + function PriorityQueueNode() { + this.priority = 0; + this.insertionIndex = 0; + this.queueIndex = 0; + } + return PriorityQueueNode; + }()); + es.PriorityQueueNode = PriorityQueueNode; +})(es || (es = {})); +var es; +(function (es) { + var AStarPathfinder = (function () { + function AStarPathfinder() { + } + AStarPathfinder.search = function (graph, start, goal) { + var _this = this; + var foundPath = false; + var cameFrom = new Map(); + cameFrom.set(start, start); + var costSoFar = new Map(); + var frontier = new es.PriorityQueue(1000); + frontier.enqueue(new AStarNode(start), 0); + costSoFar.set(start, 0); + var _loop_2 = function () { + var current = frontier.dequeue(); + if (JSON.stringify(current.data) == JSON.stringify(goal)) { + foundPath = true; + return "break"; } - }); + graph.getNeighbors(current.data).forEach(function (next) { + var newCost = costSoFar.get(current.data) + graph.cost(current.data, next); + if (!_this.hasKey(costSoFar, next) || newCost < costSoFar.get(next)) { + costSoFar.set(next, newCost); + var priority = newCost + graph.heuristic(next, goal); + frontier.enqueue(new AStarNode(next), priority); + cameFrom.set(next, current.data); + } + }); + }; + while (frontier.count > 0) { + var state_1 = _loop_2(); + if (state_1 === "break") + break; + } + return foundPath ? this.recontructPath(cameFrom, start, goal) : null; }; - while (frontier.count > 0) { - var state_1 = _loop_2(); - if (state_1 === "break") - break; + AStarPathfinder.recontructPath = function (cameFrom, start, goal) { + var path = []; + var current = goal; + path.push(goal); + while (current != start) { + current = this.getKey(cameFrom, current); + path.push(current); + } + path.reverse(); + return path; + }; + AStarPathfinder.hasKey = function (map, compareKey) { + var iterator = map.keys(); + var r; + while (r = iterator.next(), !r.done) { + if (JSON.stringify(r.value) == JSON.stringify(compareKey)) + return true; + } + return false; + }; + AStarPathfinder.getKey = function (map, compareKey) { + var iterator = map.keys(); + var valueIterator = map.values(); + var r; + var v; + while (r = iterator.next(), v = valueIterator.next(), !r.done) { + if (JSON.stringify(r.value) == JSON.stringify(compareKey)) + return v.value; + } + return null; + }; + return AStarPathfinder; + }()); + es.AStarPathfinder = AStarPathfinder; + var AStarNode = (function (_super) { + __extends(AStarNode, _super); + function AStarNode(data) { + var _this = _super.call(this) || this; + _this.data = data; + return _this; } - return foundPath ? this.recontructPath(cameFrom, start, goal) : null; - }; - AStarPathfinder.hasKey = function (map, compareKey) { - var iterator = map.keys(); - var r; - while (r = iterator.next(), !r.done) { - if (JSON.stringify(r.value) == JSON.stringify(compareKey)) - return true; + return AStarNode; + }(es.PriorityQueueNode)); + es.AStarNode = AStarNode; +})(es || (es = {})); +var es; +(function (es) { + var AstarGridGraph = (function () { + function AstarGridGraph(width, height) { + this.dirs = [ + new es.Vector2(1, 0), + new es.Vector2(0, -1), + new es.Vector2(-1, 0), + new es.Vector2(0, 1) + ]; + this.walls = []; + this.weightedNodes = []; + this.defaultWeight = 1; + this.weightedNodeWeight = 5; + this._neighbors = new Array(4); + this._width = width; + this._height = height; } - return false; - }; - AStarPathfinder.getKey = function (map, compareKey) { - var iterator = map.keys(); - var valueIterator = map.values(); - var r; - var v; - while (r = iterator.next(), v = valueIterator.next(), !r.done) { - if (JSON.stringify(r.value) == JSON.stringify(compareKey)) - return v.value; + AstarGridGraph.prototype.isNodeInBounds = function (node) { + return 0 <= node.x && node.x < this._width && 0 <= node.y && node.y < this._height; + }; + AstarGridGraph.prototype.isNodePassable = function (node) { + return !this.walls.firstOrDefault(function (wall) { return JSON.stringify(wall) == JSON.stringify(node); }); + }; + AstarGridGraph.prototype.search = function (start, goal) { + return es.AStarPathfinder.search(this, start, goal); + }; + AstarGridGraph.prototype.getNeighbors = function (node) { + var _this = this; + this._neighbors.length = 0; + this.dirs.forEach(function (dir) { + var next = new es.Vector2(node.x + dir.x, node.y + dir.y); + if (_this.isNodeInBounds(next) && _this.isNodePassable(next)) + _this._neighbors.push(next); + }); + return this._neighbors; + }; + AstarGridGraph.prototype.cost = function (from, to) { + return this.weightedNodes.find(function (p) { return JSON.stringify(p) == JSON.stringify(to); }) ? this.weightedNodeWeight : this.defaultWeight; + }; + AstarGridGraph.prototype.heuristic = function (node, goal) { + return Math.abs(node.x - goal.x) + Math.abs(node.y - goal.y); + }; + return AstarGridGraph; + }()); + es.AstarGridGraph = AstarGridGraph; +})(es || (es = {})); +var es; +(function (es) { + var PriorityQueue = (function () { + function PriorityQueue(maxNodes) { + this._numNodes = 0; + this._nodes = new Array(maxNodes + 1); + this._numNodesEverEnqueued = 0; } - return null; - }; - AStarPathfinder.recontructPath = function (cameFrom, start, goal) { - var path = []; - var current = goal; - path.push(goal); - while (current != start) { - current = this.getKey(cameFrom, current); - path.push(current); - } - path.reverse(); - return path; - }; - return AStarPathfinder; -}()); -var AStarNode = (function (_super) { - __extends(AStarNode, _super); - function AStarNode(data) { - var _this = _super.call(this) || this; - _this.data = data; - return _this; - } - return AStarNode; -}(PriorityQueueNode)); -var AstarGridGraph = (function () { - function AstarGridGraph(width, height) { - this.dirs = [ - new Vector2(1, 0), - new Vector2(0, -1), - new Vector2(-1, 0), - new Vector2(0, 1) - ]; - this.walls = []; - this.weightedNodes = []; - this.defaultWeight = 1; - this.weightedNodeWeight = 5; - this._neighbors = new Array(4); - this._width = width; - this._height = height; - } - AstarGridGraph.prototype.isNodeInBounds = function (node) { - return 0 <= node.x && node.x < this._width && 0 <= node.y && node.y < this._height; - }; - AstarGridGraph.prototype.isNodePassable = function (node) { - return !this.walls.firstOrDefault(function (wall) { return JSON.stringify(wall) == JSON.stringify(node); }); - }; - AstarGridGraph.prototype.search = function (start, goal) { - return AStarPathfinder.search(this, start, goal); - }; - AstarGridGraph.prototype.getNeighbors = function (node) { - var _this = this; - this._neighbors.length = 0; - this.dirs.forEach(function (dir) { - var next = new Vector2(node.x + dir.x, node.y + dir.y); - if (_this.isNodeInBounds(next) && _this.isNodePassable(next)) - _this._neighbors.push(next); + Object.defineProperty(PriorityQueue.prototype, "count", { + get: function () { + return this._numNodes; + }, + enumerable: true, + configurable: true }); - return this._neighbors; - }; - AstarGridGraph.prototype.cost = function (from, to) { - return this.weightedNodes.find(function (p) { return JSON.stringify(p) == JSON.stringify(to); }) ? this.weightedNodeWeight : this.defaultWeight; - }; - AstarGridGraph.prototype.heuristic = function (node, goal) { - return Math.abs(node.x - goal.x) + Math.abs(node.y - goal.y); - }; - return AstarGridGraph; -}()); -var PriorityQueue = (function () { - function PriorityQueue(maxNodes) { - this._numNodes = 0; - this._nodes = new Array(maxNodes + 1); - this._numNodesEverEnqueued = 0; - } - PriorityQueue.prototype.clear = function () { - this._nodes.splice(1, this._numNodes); - this._numNodes = 0; - }; - Object.defineProperty(PriorityQueue.prototype, "count", { - get: function () { - return this._numNodes; - }, - enumerable: true, - configurable: true - }); - PriorityQueue.prototype.contains = function (node) { - return (this._nodes[node.queueIndex] == node); - }; - PriorityQueue.prototype.enqueue = function (node, priority) { - node.priority = priority; - this._numNodes++; - this._nodes[this._numNodes] = node; - node.queueIndex = this._numNodes; - node.insertionIndex = this._numNodesEverEnqueued++; - this.cascadeUp(this._nodes[this._numNodes]); - }; - PriorityQueue.prototype.dequeue = function () { - var returnMe = this._nodes[1]; - this.remove(returnMe); - return returnMe; - }; - PriorityQueue.prototype.remove = function (node) { - if (node.queueIndex == this._numNodes) { - this._nodes[this._numNodes] = null; + Object.defineProperty(PriorityQueue.prototype, "maxSize", { + get: function () { + return this._nodes.length - 1; + }, + enumerable: true, + configurable: true + }); + PriorityQueue.prototype.clear = function () { + this._nodes.splice(1, this._numNodes); + this._numNodes = 0; + }; + PriorityQueue.prototype.contains = function (node) { + if (!node) { + console.error("node cannot be null"); + return false; + } + if (node.queueIndex < 0 || node.queueIndex >= this._nodes.length) { + console.error("node.QueueIndex has been corrupted. Did you change it manually? Or add this node to another queue?"); + return false; + } + return (this._nodes[node.queueIndex] == node); + }; + PriorityQueue.prototype.enqueue = function (node, priority) { + node.priority = priority; + this._numNodes++; + this._nodes[this._numNodes] = node; + node.queueIndex = this._numNodes; + node.insertionIndex = this._numNodesEverEnqueued++; + this.cascadeUp(this._nodes[this._numNodes]); + }; + PriorityQueue.prototype.dequeue = function () { + var returnMe = this._nodes[1]; + this.remove(returnMe); + return returnMe; + }; + PriorityQueue.prototype.remove = function (node) { + if (node.queueIndex == this._numNodes) { + this._nodes[this._numNodes] = null; + this._numNodes--; + return; + } + var formerLastNode = this._nodes[this._numNodes]; + this.swap(node, formerLastNode); + delete this._nodes[this._numNodes]; this._numNodes--; - return; - } - var formerLastNode = this._nodes[this._numNodes]; - this.swap(node, formerLastNode); - delete this._nodes[this._numNodes]; - this._numNodes--; - this.onNodeUpdated(formerLastNode); - }; - PriorityQueue.prototype.isValidQueue = function () { - for (var i = 1; i < this._nodes.length; i++) { - if (this._nodes[i]) { - var childLeftIndex = 2 * i; - if (childLeftIndex < this._nodes.length && this._nodes[childLeftIndex] && - this.hasHigherPriority(this._nodes[childLeftIndex], this._nodes[i])) - return false; + this.onNodeUpdated(formerLastNode); + }; + PriorityQueue.prototype.isValidQueue = function () { + for (var i = 1; i < this._nodes.length; i++) { + if (this._nodes[i]) { + var childLeftIndex = 2 * i; + if (childLeftIndex < this._nodes.length && this._nodes[childLeftIndex] && + this.hasHigherPriority(this._nodes[childLeftIndex], this._nodes[i])) + return false; + var childRightIndex = childLeftIndex + 1; + if (childRightIndex < this._nodes.length && this._nodes[childRightIndex] && + this.hasHigherPriority(this._nodes[childRightIndex], this._nodes[i])) + return false; + } + } + return true; + }; + PriorityQueue.prototype.onNodeUpdated = function (node) { + var parentIndex = Math.floor(node.queueIndex / 2); + var parentNode = this._nodes[parentIndex]; + if (parentIndex > 0 && this.hasHigherPriority(node, parentNode)) { + this.cascadeUp(node); + } + else { + this.cascadeDown(node); + } + }; + PriorityQueue.prototype.cascadeDown = function (node) { + var newParent; + var finalQueueIndex = node.queueIndex; + while (true) { + newParent = node; + var childLeftIndex = 2 * finalQueueIndex; + if (childLeftIndex > this._numNodes) { + node.queueIndex = finalQueueIndex; + this._nodes[finalQueueIndex] = node; + break; + } + var childLeft = this._nodes[childLeftIndex]; + if (this.hasHigherPriority(childLeft, newParent)) { + newParent = childLeft; + } var childRightIndex = childLeftIndex + 1; - if (childRightIndex < this._nodes.length && this._nodes[childRightIndex] && - this.hasHigherPriority(this._nodes[childRightIndex], this._nodes[i])) - return false; - } - } - return true; - }; - PriorityQueue.prototype.onNodeUpdated = function (node) { - var parentIndex = Math.floor(node.queueIndex / 2); - var parentNode = this._nodes[parentIndex]; - if (parentIndex > 0 && this.hasHigherPriority(node, parentNode)) { - this.cascadeUp(node); - } - else { - this.cascadeDown(node); - } - }; - PriorityQueue.prototype.cascadeDown = function (node) { - var newParent; - var finalQueueIndex = node.queueIndex; - while (true) { - newParent = node; - var childLeftIndex = 2 * finalQueueIndex; - if (childLeftIndex > this._numNodes) { - node.queueIndex = finalQueueIndex; - this._nodes[finalQueueIndex] = node; - break; - } - var childLeft = this._nodes[childLeftIndex]; - if (this.hasHigherPriority(childLeft, newParent)) { - newParent = childLeft; - } - var childRightIndex = childLeftIndex + 1; - if (childRightIndex <= this._numNodes) { - var childRight = this._nodes[childRightIndex]; - if (this.hasHigherPriority(childRight, newParent)) { - newParent = childRight; + if (childRightIndex <= this._numNodes) { + var childRight = this._nodes[childRightIndex]; + if (this.hasHigherPriority(childRight, newParent)) { + newParent = childRight; + } + } + if (newParent != node) { + this._nodes[finalQueueIndex] = newParent; + var temp = newParent.queueIndex; + newParent.queueIndex = finalQueueIndex; + finalQueueIndex = temp; + } + else { + node.queueIndex = finalQueueIndex; + this._nodes[finalQueueIndex] = node; + break; } } - if (newParent != node) { - this._nodes[finalQueueIndex] = newParent; - var temp = newParent.queueIndex; - newParent.queueIndex = finalQueueIndex; - finalQueueIndex = temp; - } - else { - node.queueIndex = finalQueueIndex; - this._nodes[finalQueueIndex] = node; - break; - } - } - }; - PriorityQueue.prototype.cascadeUp = function (node) { - var parent = Math.floor(node.queueIndex / 2); - while (parent >= 1) { - var parentNode = this._nodes[parent]; - if (this.hasHigherPriority(parentNode, node)) - break; - this.swap(node, parentNode); - parent = Math.floor(node.queueIndex / 2); - } - }; - PriorityQueue.prototype.swap = function (node1, node2) { - this._nodes[node1.queueIndex] = node2; - this._nodes[node2.queueIndex] = node1; - var temp = node1.queueIndex; - node1.queueIndex = node2.queueIndex; - node2.queueIndex = temp; - }; - PriorityQueue.prototype.hasHigherPriority = function (higher, lower) { - return (higher.priority < lower.priority || - (higher.priority == lower.priority && higher.insertionIndex < lower.insertionIndex)); - }; - return PriorityQueue; -}()); -var BreadthFirstPathfinder = (function () { - function BreadthFirstPathfinder() { - } - BreadthFirstPathfinder.search = function (graph, start, goal) { - var _this = this; - var foundPath = false; - var frontier = []; - frontier.unshift(start); - var cameFrom = new Map(); - cameFrom.set(start, start); - var _loop_3 = function () { - var current = frontier.shift(); - if (JSON.stringify(current) == JSON.stringify(goal)) { - foundPath = true; - return "break"; - } - graph.getNeighbors(current).forEach(function (next) { - if (!_this.hasKey(cameFrom, next)) { - frontier.unshift(next); - cameFrom.set(next, current); - } - }); }; - while (frontier.length > 0) { - var state_2 = _loop_3(); - if (state_2 === "break") - break; - } - return foundPath ? AStarPathfinder.recontructPath(cameFrom, start, goal) : null; - }; - BreadthFirstPathfinder.hasKey = function (map, compareKey) { - var iterator = map.keys(); - var r; - while (r = iterator.next(), !r.done) { - if (JSON.stringify(r.value) == JSON.stringify(compareKey)) - return true; - } - return false; - }; - return BreadthFirstPathfinder; -}()); -var UnweightedGraph = (function () { - function UnweightedGraph() { - this.edges = new Map(); - } - UnweightedGraph.prototype.addEdgesForNode = function (node, edges) { - this.edges.set(node, edges); - return this; - }; - UnweightedGraph.prototype.getNeighbors = function (node) { - return this.edges.get(node); - }; - return UnweightedGraph; -}()); -var Vector2 = (function () { - function Vector2(x, y) { - this.x = 0; - this.y = 0; - this.x = x ? x : 0; - this.y = y ? y : this.x; - } - Object.defineProperty(Vector2, "zero", { - get: function () { - return Vector2.zeroVector2; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Vector2, "one", { - get: function () { - return Vector2.unitVector2; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Vector2, "unitX", { - get: function () { - return Vector2.unitXVector; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Vector2, "unitY", { - get: function () { - return Vector2.unitYVector; - }, - enumerable: true, - configurable: true - }); - Vector2.add = function (value1, value2) { - var result = new Vector2(0, 0); - result.x = value1.x + value2.x; - result.y = value1.y + value2.y; - return result; - }; - Vector2.divide = function (value1, value2) { - var result = new Vector2(0, 0); - result.x = value1.x / value2.x; - result.y = value1.y / value2.y; - return result; - }; - Vector2.multiply = function (value1, value2) { - var result = new Vector2(0, 0); - result.x = value1.x * value2.x; - result.y = value1.y * value2.y; - return result; - }; - Vector2.subtract = function (value1, value2) { - var result = new Vector2(0, 0); - result.x = value1.x - value2.x; - result.y = value1.y - value2.y; - return result; - }; - Vector2.prototype.normalize = function () { - var val = 1 / Math.sqrt((this.x * this.x) + (this.y * this.y)); - this.x *= val; - this.y *= val; - }; - Vector2.prototype.length = function () { - return Math.sqrt((this.x * this.x) + (this.y * this.y)); - }; - Vector2.prototype.round = function () { - return new Vector2(Math.round(this.x), Math.round(this.y)); - }; - Vector2.normalize = function (value) { - var val = 1 / Math.sqrt((value.x * value.x) + (value.y * value.y)); - value.x *= val; - value.y *= val; - return value; - }; - Vector2.dot = function (value1, value2) { - return (value1.x * value2.x) + (value1.y * value2.y); - }; - Vector2.distanceSquared = function (value1, value2) { - var v1 = value1.x - value2.x, v2 = value1.y - value2.y; - return (v1 * v1) + (v2 * v2); - }; - Vector2.clamp = function (value1, min, max) { - return new Vector2(MathHelper.clamp(value1.x, min.x, max.x), MathHelper.clamp(value1.y, min.y, max.y)); - }; - Vector2.lerp = function (value1, value2, amount) { - return new Vector2(MathHelper.lerp(value1.x, value2.x, amount), MathHelper.lerp(value1.y, value2.y, amount)); - }; - Vector2.transform = function (position, matrix) { - return new Vector2((position.x * matrix.m11) + (position.y * matrix.m21), (position.x * matrix.m12) + (position.y * matrix.m22)); - }; - Vector2.distance = function (value1, value2) { - var v1 = value1.x - value2.x, v2 = value1.y - value2.y; - return Math.sqrt((v1 * v1) + (v2 * v2)); - }; - Vector2.negate = function (value) { - var result = new Vector2(); - result.x = -value.x; - result.y = -value.y; - return result; - }; - Vector2.unitYVector = new Vector2(0, 1); - Vector2.unitXVector = new Vector2(1, 0); - Vector2.unitVector2 = new Vector2(1, 1); - Vector2.zeroVector2 = new Vector2(0, 0); - return Vector2; -}()); -var UnweightedGridGraph = (function () { - function UnweightedGridGraph(width, height, allowDiagonalSearch) { - if (allowDiagonalSearch === void 0) { allowDiagonalSearch = false; } - this.walls = []; - this._neighbors = new Array(4); - this._width = width; - this._hegiht = height; - this._dirs = allowDiagonalSearch ? UnweightedGridGraph.COMPASS_DIRS : UnweightedGridGraph.CARDINAL_DIRS; - } - UnweightedGridGraph.prototype.isNodeInBounds = function (node) { - return 0 <= node.x && node.x < this._width && 0 <= node.y && node.y < this._hegiht; - }; - UnweightedGridGraph.prototype.isNodePassable = function (node) { - return !this.walls.firstOrDefault(function (wall) { return JSON.stringify(wall) == JSON.stringify(node); }); - }; - UnweightedGridGraph.prototype.getNeighbors = function (node) { - var _this = this; - this._neighbors.length = 0; - this._dirs.forEach(function (dir) { - var next = new Vector2(node.x + dir.x, node.y + dir.y); - if (_this.isNodeInBounds(next) && _this.isNodePassable(next)) - _this._neighbors.push(next); - }); - return this._neighbors; - }; - UnweightedGridGraph.prototype.search = function (start, goal) { - return BreadthFirstPathfinder.search(this, start, goal); - }; - UnweightedGridGraph.CARDINAL_DIRS = [ - new Vector2(1, 0), - new Vector2(0, -1), - new Vector2(-1, 0), - new Vector2(0, -1) - ]; - UnweightedGridGraph.COMPASS_DIRS = [ - new Vector2(1, 0), - new Vector2(1, -1), - new Vector2(0, -1), - new Vector2(-1, -1), - new Vector2(-1, 0), - new Vector2(-1, 1), - new Vector2(0, 1), - new Vector2(1, 1), - ]; - return UnweightedGridGraph; -}()); -var WeightedGridGraph = (function () { - function WeightedGridGraph(width, height, allowDiagonalSearch) { - if (allowDiagonalSearch === void 0) { allowDiagonalSearch = false; } - this.walls = []; - this.weightedNodes = []; - this.defaultWeight = 1; - this.weightedNodeWeight = 5; - this._neighbors = new Array(4); - this._width = width; - this._height = height; - this._dirs = allowDiagonalSearch ? WeightedGridGraph.COMPASS_DIRS : WeightedGridGraph.CARDINAL_DIRS; - } - WeightedGridGraph.prototype.isNodeInBounds = function (node) { - return 0 <= node.x && node.x < this._width && 0 <= node.y && node.y < this._height; - }; - WeightedGridGraph.prototype.isNodePassable = function (node) { - return !this.walls.firstOrDefault(function (wall) { return JSON.stringify(wall) == JSON.stringify(node); }); - }; - WeightedGridGraph.prototype.search = function (start, goal) { - return WeightedPathfinder.search(this, start, goal); - }; - WeightedGridGraph.prototype.getNeighbors = function (node) { - var _this = this; - this._neighbors.length = 0; - this._dirs.forEach(function (dir) { - var next = new Vector2(node.x + dir.x, node.y + dir.y); - if (_this.isNodeInBounds(next) && _this.isNodePassable(next)) - _this._neighbors.push(next); - }); - return this._neighbors; - }; - WeightedGridGraph.prototype.cost = function (from, to) { - return this.weightedNodes.find(function (t) { return JSON.stringify(t) == JSON.stringify(to); }) ? this.weightedNodeWeight : this.defaultWeight; - }; - WeightedGridGraph.CARDINAL_DIRS = [ - new Vector2(1, 0), - new Vector2(0, -1), - new Vector2(-1, 0), - new Vector2(0, 1) - ]; - WeightedGridGraph.COMPASS_DIRS = [ - new Vector2(1, 0), - new Vector2(1, -1), - new Vector2(0, -1), - new Vector2(-1, -1), - new Vector2(-1, 0), - new Vector2(-1, 1), - new Vector2(0, 1), - new Vector2(1, 1), - ]; - return WeightedGridGraph; -}()); -var WeightedNode = (function (_super) { - __extends(WeightedNode, _super); - function WeightedNode(data) { - var _this = _super.call(this) || this; - _this.data = data; - return _this; - } - return WeightedNode; -}(PriorityQueueNode)); -var WeightedPathfinder = (function () { - function WeightedPathfinder() { - } - WeightedPathfinder.search = function (graph, start, goal) { - var _this = this; - var foundPath = false; - var cameFrom = new Map(); - cameFrom.set(start, start); - var costSoFar = new Map(); - var frontier = new PriorityQueue(1000); - frontier.enqueue(new WeightedNode(start), 0); - costSoFar.set(start, 0); - var _loop_4 = function () { - var current = frontier.dequeue(); - if (JSON.stringify(current.data) == JSON.stringify(goal)) { - foundPath = true; - return "break"; + PriorityQueue.prototype.cascadeUp = function (node) { + var parent = Math.floor(node.queueIndex / 2); + while (parent >= 1) { + var parentNode = this._nodes[parent]; + if (this.hasHigherPriority(parentNode, node)) + break; + this.swap(node, parentNode); + parent = Math.floor(node.queueIndex / 2); } - graph.getNeighbors(current.data).forEach(function (next) { - var newCost = costSoFar.get(current.data) + graph.cost(current.data, next); - if (!_this.hasKey(costSoFar, next) || newCost < costSoFar.get(next)) { - costSoFar.set(next, newCost); - var priprity = newCost; - frontier.enqueue(new WeightedNode(next), priprity); - cameFrom.set(next, current.data); - } - }); }; - while (frontier.count > 0) { - var state_3 = _loop_4(); - if (state_3 === "break") - break; + PriorityQueue.prototype.swap = function (node1, node2) { + this._nodes[node1.queueIndex] = node2; + this._nodes[node2.queueIndex] = node1; + var temp = node1.queueIndex; + node1.queueIndex = node2.queueIndex; + node2.queueIndex = temp; + }; + PriorityQueue.prototype.hasHigherPriority = function (higher, lower) { + return (higher.priority < lower.priority || + (higher.priority == lower.priority && higher.insertionIndex < lower.insertionIndex)); + }; + return PriorityQueue; + }()); + es.PriorityQueue = PriorityQueue; +})(es || (es = {})); +var es; +(function (es) { + var BreadthFirstPathfinder = (function () { + function BreadthFirstPathfinder() { } - return foundPath ? this.recontructPath(cameFrom, start, goal) : null; - }; - WeightedPathfinder.hasKey = function (map, compareKey) { - var iterator = map.keys(); - var r; - while (r = iterator.next(), !r.done) { - if (JSON.stringify(r.value) == JSON.stringify(compareKey)) - return true; - } - return false; - }; - WeightedPathfinder.getKey = function (map, compareKey) { - var iterator = map.keys(); - var valueIterator = map.values(); - var r; - var v; - while (r = iterator.next(), v = valueIterator.next(), !r.done) { - if (JSON.stringify(r.value) == JSON.stringify(compareKey)) - return v.value; - } - return null; - }; - WeightedPathfinder.recontructPath = function (cameFrom, start, goal) { - var path = []; - var current = goal; - path.push(goal); - while (current != start) { - current = this.getKey(cameFrom, current); - path.push(current); - } - path.reverse(); - return path; - }; - return WeightedPathfinder; -}()); -var DebugDefaults = (function () { - function DebugDefaults() { - } - DebugDefaults.verletParticle = 0xDC345E; - DebugDefaults.verletConstraintEdge = 0x433E36; - return DebugDefaults; -}()); -var Component = (function (_super) { - __extends(Component, _super); - function Component() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this._enabled = true; - _this.updateInterval = 1; - return _this; - } - Object.defineProperty(Component.prototype, "enabled", { - get: function () { - return this.entity ? this.entity.enabled && this._enabled : this._enabled; - }, - set: function (value) { - this.setEnabled(value); - }, - enumerable: true, - configurable: true - }); - Component.prototype.setEnabled = function (isEnabled) { - if (this._enabled != isEnabled) { - this._enabled = isEnabled; - if (this._enabled) { - this.onEnabled(); + BreadthFirstPathfinder.search = function (graph, start, goal) { + var _this = this; + var foundPath = false; + var frontier = []; + frontier.unshift(start); + var cameFrom = new Map(); + cameFrom.set(start, start); + var _loop_3 = function () { + var current = frontier.shift(); + if (JSON.stringify(current) == JSON.stringify(goal)) { + foundPath = true; + return "break"; + } + graph.getNeighbors(current).forEach(function (next) { + if (!_this.hasKey(cameFrom, next)) { + frontier.unshift(next); + cameFrom.set(next, current); + } + }); + }; + while (frontier.length > 0) { + var state_2 = _loop_3(); + if (state_2 === "break") + break; } - else { - this.onDisabled(); + return foundPath ? es.AStarPathfinder.recontructPath(cameFrom, start, goal) : null; + }; + BreadthFirstPathfinder.hasKey = function (map, compareKey) { + var iterator = map.keys(); + var r; + while (r = iterator.next(), !r.done) { + if (JSON.stringify(r.value) == JSON.stringify(compareKey)) + return true; } + return false; + }; + return BreadthFirstPathfinder; + }()); + es.BreadthFirstPathfinder = BreadthFirstPathfinder; +})(es || (es = {})); +var es; +(function (es) { + var UnweightedGraph = (function () { + function UnweightedGraph() { + this.edges = new Map(); } - return this; - }; - Component.prototype.initialize = function () { - }; - Component.prototype.onAddedToEntity = function () { - }; - Component.prototype.onRemovedFromEntity = function () { - }; - Component.prototype.onEnabled = function () { - }; - Component.prototype.onDisabled = function () { - }; - Component.prototype.update = function () { - }; - Component.prototype.debugRender = function () { - }; - Component.prototype.onEntityTransformChanged = function (comp) { - }; - Component.prototype.registerComponent = function () { - this.entity.componentBits.set(ComponentTypeManager.getIndexFor(this), false); - this.entity.scene.entityProcessors.onComponentAdded(this.entity); - }; - Component.prototype.deregisterComponent = function () { - this.entity.componentBits.set(ComponentTypeManager.getIndexFor(this)); - this.entity.scene.entityProcessors.onComponentRemoved(this.entity); - }; - return Component; -}(egret.DisplayObjectContainer)); -var Entity = (function (_super) { - __extends(Entity, _super); - function Entity(name) { - var _this = _super.call(this) || this; - _this._updateOrder = 0; - _this._enabled = true; - _this._tag = 0; - _this.name = name; - _this.components = new ComponentList(_this); - _this.id = Entity._idGenerator++; - _this.componentBits = new BitSet(); - return _this; - } - Object.defineProperty(Entity.prototype, "isDestoryed", { - get: function () { - return this._isDestoryed; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Entity.prototype, "position", { - get: function () { - return new Vector2(this.x, this.y); - }, - set: function (value) { - this.$setX(value.x); - this.$setY(value.y); - this.onEntityTransformChanged(TransformComponent.position); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Entity.prototype, "scale", { - get: function () { - return new Vector2(this.scaleX, this.scaleY); - }, - set: function (value) { - this.$setScaleX(value.x); - this.$setScaleY(value.y); - this.onEntityTransformChanged(TransformComponent.scale); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Entity.prototype, "rotation", { - set: function (value) { - this.$setRotation(value); - this.onEntityTransformChanged(TransformComponent.rotation); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Entity.prototype, "enabled", { - get: function () { - return this._enabled; - }, - set: function (value) { - this.setEnabled(value); - }, - enumerable: true, - configurable: true - }); - Entity.prototype.setEnabled = function (isEnabled) { - if (this._enabled != isEnabled) { - this._enabled = isEnabled; + UnweightedGraph.prototype.addEdgesForNode = function (node, edges) { + this.edges.set(node, edges); + return this; + }; + UnweightedGraph.prototype.getNeighbors = function (node) { + return this.edges.get(node); + }; + return UnweightedGraph; + }()); + es.UnweightedGraph = UnweightedGraph; +})(es || (es = {})); +var es; +(function (es) { + var Vector2 = (function () { + function Vector2(x, y) { + this.x = 0; + this.y = 0; + this.x = x ? x : 0; + this.y = y != undefined ? y : this.x; } - return this; - }; - Object.defineProperty(Entity.prototype, "tag", { - get: function () { - return this._tag; - }, - set: function (value) { - this.setTag(value); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Entity.prototype, "stage", { - get: function () { - if (!this.scene) - return null; - return this.scene.stage; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Entity.prototype, "updateOrder", { - get: function () { - return this._updateOrder; - }, - set: function (value) { - this.setUpdateOrder(value); - }, - enumerable: true, - configurable: true - }); - Entity.prototype.roundPosition = function () { - this.position = Vector2Ext.round(this.position); - }; - Entity.prototype.setUpdateOrder = function (updateOrder) { - if (this._updateOrder != updateOrder) { - this._updateOrder = updateOrder; - if (this.scene) { + Object.defineProperty(Vector2, "zero", { + get: function () { + return Vector2.zeroVector2; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Vector2, "one", { + get: function () { + return Vector2.unitVector2; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Vector2, "unitX", { + get: function () { + return Vector2.unitXVector; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Vector2, "unitY", { + get: function () { + return Vector2.unitYVector; + }, + enumerable: true, + configurable: true + }); + Vector2.add = function (value1, value2) { + var result = new Vector2(0, 0); + result.x = value1.x + value2.x; + result.y = value1.y + value2.y; + return result; + }; + Vector2.divide = function (value1, value2) { + var result = new Vector2(0, 0); + result.x = value1.x / value2.x; + result.y = value1.y / value2.y; + return result; + }; + Vector2.multiply = function (value1, value2) { + var result = new Vector2(0, 0); + result.x = value1.x * value2.x; + result.y = value1.y * value2.y; + return result; + }; + Vector2.subtract = function (value1, value2) { + var result = new Vector2(0, 0); + result.x = value1.x - value2.x; + result.y = value1.y - value2.y; + return result; + }; + Vector2.normalize = function (value) { + var val = 1 / Math.sqrt((value.x * value.x) + (value.y * value.y)); + value.x *= val; + value.y *= val; + return value; + }; + Vector2.dot = function (value1, value2) { + return (value1.x * value2.x) + (value1.y * value2.y); + }; + Vector2.distanceSquared = function (value1, value2) { + var v1 = value1.x - value2.x, v2 = value1.y - value2.y; + return (v1 * v1) + (v2 * v2); + }; + Vector2.clamp = function (value1, min, max) { + return new Vector2(es.MathHelper.clamp(value1.x, min.x, max.x), es.MathHelper.clamp(value1.y, min.y, max.y)); + }; + Vector2.lerp = function (value1, value2, amount) { + return new Vector2(es.MathHelper.lerp(value1.x, value2.x, amount), es.MathHelper.lerp(value1.y, value2.y, amount)); + }; + Vector2.transform = function (position, matrix) { + return new Vector2((position.x * matrix.m11) + (position.y * matrix.m21) + matrix.m31, (position.x * matrix.m12) + (position.y * matrix.m22) + matrix.m32); + }; + Vector2.distance = function (value1, value2) { + var v1 = value1.x - value2.x, v2 = value1.y - value2.y; + return Math.sqrt((v1 * v1) + (v2 * v2)); + }; + Vector2.negate = function (value) { + var result = new Vector2(); + result.x = -value.x; + result.y = -value.y; + return result; + }; + Vector2.prototype.add = function (value) { + this.x += value.x; + this.y += value.y; + return this; + }; + Vector2.prototype.divide = function (value) { + this.x /= value.x; + this.y /= value.y; + return this; + }; + Vector2.prototype.multiply = function (value) { + this.x *= value.x; + this.y *= value.y; + return this; + }; + Vector2.prototype.subtract = function (value) { + this.x -= value.x; + this.y -= value.y; + return this; + }; + Vector2.prototype.normalize = function () { + var val = 1 / Math.sqrt((this.x * this.x) + (this.y * this.y)); + this.x *= val; + this.y *= val; + return this; + }; + Vector2.prototype.length = function () { + return Math.sqrt((this.x * this.x) + (this.y * this.y)); + }; + Vector2.prototype.lengthSquared = function () { + return (this.x * this.x) + (this.y * this.y); + }; + Vector2.prototype.round = function () { + return new Vector2(Math.round(this.x), Math.round(this.y)); + }; + Vector2.prototype.equals = function (other) { + return other.x == this.x && other.y == this.y; + }; + Vector2.unitYVector = new Vector2(0, 1); + Vector2.unitXVector = new Vector2(1, 0); + Vector2.unitVector2 = new Vector2(1, 1); + Vector2.zeroVector2 = new Vector2(0, 0); + return Vector2; + }()); + es.Vector2 = Vector2; +})(es || (es = {})); +var es; +(function (es) { + var UnweightedGridGraph = (function () { + function UnweightedGridGraph(width, height, allowDiagonalSearch) { + if (allowDiagonalSearch === void 0) { allowDiagonalSearch = false; } + this.walls = []; + this._neighbors = new Array(4); + this._width = width; + this._hegiht = height; + this._dirs = allowDiagonalSearch ? UnweightedGridGraph.COMPASS_DIRS : UnweightedGridGraph.CARDINAL_DIRS; + } + UnweightedGridGraph.prototype.isNodeInBounds = function (node) { + return 0 <= node.x && node.x < this._width && 0 <= node.y && node.y < this._hegiht; + }; + UnweightedGridGraph.prototype.isNodePassable = function (node) { + return !this.walls.firstOrDefault(function (wall) { return JSON.stringify(wall) == JSON.stringify(node); }); + }; + UnweightedGridGraph.prototype.getNeighbors = function (node) { + var _this = this; + this._neighbors.length = 0; + this._dirs.forEach(function (dir) { + var next = new es.Vector2(node.x + dir.x, node.y + dir.y); + if (_this.isNodeInBounds(next) && _this.isNodePassable(next)) + _this._neighbors.push(next); + }); + return this._neighbors; + }; + UnweightedGridGraph.prototype.search = function (start, goal) { + return es.BreadthFirstPathfinder.search(this, start, goal); + }; + UnweightedGridGraph.CARDINAL_DIRS = [ + new es.Vector2(1, 0), + new es.Vector2(0, -1), + new es.Vector2(-1, 0), + new es.Vector2(0, -1) + ]; + UnweightedGridGraph.COMPASS_DIRS = [ + new es.Vector2(1, 0), + new es.Vector2(1, -1), + new es.Vector2(0, -1), + new es.Vector2(-1, -1), + new es.Vector2(-1, 0), + new es.Vector2(-1, 1), + new es.Vector2(0, 1), + new es.Vector2(1, 1), + ]; + return UnweightedGridGraph; + }()); + es.UnweightedGridGraph = UnweightedGridGraph; +})(es || (es = {})); +var es; +(function (es) { + var WeightedGridGraph = (function () { + function WeightedGridGraph(width, height, allowDiagonalSearch) { + if (allowDiagonalSearch === void 0) { allowDiagonalSearch = false; } + this.walls = []; + this.weightedNodes = []; + this.defaultWeight = 1; + this.weightedNodeWeight = 5; + this._neighbors = new Array(4); + this._width = width; + this._height = height; + this._dirs = allowDiagonalSearch ? WeightedGridGraph.COMPASS_DIRS : WeightedGridGraph.CARDINAL_DIRS; + } + WeightedGridGraph.prototype.isNodeInBounds = function (node) { + return 0 <= node.x && node.x < this._width && 0 <= node.y && node.y < this._height; + }; + WeightedGridGraph.prototype.isNodePassable = function (node) { + return !this.walls.firstOrDefault(function (wall) { return JSON.stringify(wall) == JSON.stringify(node); }); + }; + WeightedGridGraph.prototype.search = function (start, goal) { + return es.WeightedPathfinder.search(this, start, goal); + }; + WeightedGridGraph.prototype.getNeighbors = function (node) { + var _this = this; + this._neighbors.length = 0; + this._dirs.forEach(function (dir) { + var next = new es.Vector2(node.x + dir.x, node.y + dir.y); + if (_this.isNodeInBounds(next) && _this.isNodePassable(next)) + _this._neighbors.push(next); + }); + return this._neighbors; + }; + WeightedGridGraph.prototype.cost = function (from, to) { + return this.weightedNodes.find(function (t) { return JSON.stringify(t) == JSON.stringify(to); }) ? this.weightedNodeWeight : this.defaultWeight; + }; + WeightedGridGraph.CARDINAL_DIRS = [ + new es.Vector2(1, 0), + new es.Vector2(0, -1), + new es.Vector2(-1, 0), + new es.Vector2(0, 1) + ]; + WeightedGridGraph.COMPASS_DIRS = [ + new es.Vector2(1, 0), + new es.Vector2(1, -1), + new es.Vector2(0, -1), + new es.Vector2(-1, -1), + new es.Vector2(-1, 0), + new es.Vector2(-1, 1), + new es.Vector2(0, 1), + new es.Vector2(1, 1), + ]; + return WeightedGridGraph; + }()); + es.WeightedGridGraph = WeightedGridGraph; +})(es || (es = {})); +var es; +(function (es) { + var WeightedNode = (function (_super) { + __extends(WeightedNode, _super); + function WeightedNode(data) { + var _this = _super.call(this) || this; + _this.data = data; + return _this; + } + return WeightedNode; + }(es.PriorityQueueNode)); + es.WeightedNode = WeightedNode; + var WeightedPathfinder = (function () { + function WeightedPathfinder() { + } + WeightedPathfinder.search = function (graph, start, goal) { + var _this = this; + var foundPath = false; + var cameFrom = new Map(); + cameFrom.set(start, start); + var costSoFar = new Map(); + var frontier = new es.PriorityQueue(1000); + frontier.enqueue(new WeightedNode(start), 0); + costSoFar.set(start, 0); + var _loop_4 = function () { + var current = frontier.dequeue(); + if (JSON.stringify(current.data) == JSON.stringify(goal)) { + foundPath = true; + return "break"; + } + graph.getNeighbors(current.data).forEach(function (next) { + var newCost = costSoFar.get(current.data) + graph.cost(current.data, next); + if (!_this.hasKey(costSoFar, next) || newCost < costSoFar.get(next)) { + costSoFar.set(next, newCost); + var priprity = newCost; + frontier.enqueue(new WeightedNode(next), priprity); + cameFrom.set(next, current.data); + } + }); + }; + while (frontier.count > 0) { + var state_3 = _loop_4(); + if (state_3 === "break") + break; + } + return foundPath ? this.recontructPath(cameFrom, start, goal) : null; + }; + WeightedPathfinder.recontructPath = function (cameFrom, start, goal) { + var path = []; + var current = goal; + path.push(goal); + while (current != start) { + current = this.getKey(cameFrom, current); + path.push(current); + } + path.reverse(); + return path; + }; + WeightedPathfinder.hasKey = function (map, compareKey) { + var iterator = map.keys(); + var r; + while (r = iterator.next(), !r.done) { + if (JSON.stringify(r.value) == JSON.stringify(compareKey)) + return true; + } + return false; + }; + WeightedPathfinder.getKey = function (map, compareKey) { + var iterator = map.keys(); + var valueIterator = map.values(); + var r; + var v; + while (r = iterator.next(), v = valueIterator.next(), !r.done) { + if (JSON.stringify(r.value) == JSON.stringify(compareKey)) + return v.value; + } + return null; + }; + return WeightedPathfinder; + }()); + es.WeightedPathfinder = WeightedPathfinder; +})(es || (es = {})); +var es; +(function (es) { + var Debug = (function () { + function Debug() { + } + Debug.drawHollowRect = function (rectanle, color, duration) { + if (duration === void 0) { duration = 0; } + this._debugDrawItems.push(new es.DebugDrawItem(rectanle, color, duration)); + }; + Debug.render = function () { + if (this._debugDrawItems.length > 0) { + var debugShape = new egret.Shape(); + if (es.Core.scene) { + es.Core.scene.addChild(debugShape); + } + for (var i = this._debugDrawItems.length - 1; i >= 0; i--) { + var item = this._debugDrawItems[i]; + if (item.draw(debugShape)) + this._debugDrawItems.removeAt(i); + } + } + }; + Debug._debugDrawItems = []; + return Debug; + }()); + es.Debug = Debug; +})(es || (es = {})); +var es; +(function (es) { + var DebugDefaults = (function () { + function DebugDefaults() { + } + DebugDefaults.verletParticle = 0xDC345E; + DebugDefaults.verletConstraintEdge = 0x433E36; + return DebugDefaults; + }()); + es.DebugDefaults = DebugDefaults; +})(es || (es = {})); +var es; +(function (es) { + var DebugDrawType; + (function (DebugDrawType) { + DebugDrawType[DebugDrawType["line"] = 0] = "line"; + DebugDrawType[DebugDrawType["hollowRectangle"] = 1] = "hollowRectangle"; + DebugDrawType[DebugDrawType["pixel"] = 2] = "pixel"; + DebugDrawType[DebugDrawType["text"] = 3] = "text"; + })(DebugDrawType = es.DebugDrawType || (es.DebugDrawType = {})); + var DebugDrawItem = (function () { + function DebugDrawItem(rectangle, color, duration) { + this.rectangle = rectangle; + this.color = color; + this.duration = duration; + this.drawType = DebugDrawType.hollowRectangle; + } + DebugDrawItem.prototype.draw = function (shape) { + switch (this.drawType) { + case DebugDrawType.line: + es.DrawUtils.drawLine(shape, this.start, this.end, this.color); + break; + case DebugDrawType.hollowRectangle: + es.DrawUtils.drawHollowRect(shape, this.rectangle, this.color); + break; + case DebugDrawType.pixel: + es.DrawUtils.drawPixel(shape, new es.Vector2(this.x, this.y), this.color, this.size); + break; + case DebugDrawType.text: + break; + } + this.duration -= es.Time.deltaTime; + return this.duration < 0; + }; + return DebugDrawItem; + }()); + es.DebugDrawItem = DebugDrawItem; +})(es || (es = {})); +var es; +(function (es) { + var Component = (function (_super) { + __extends(Component, _super); + function Component() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.updateInterval = 1; + _this._enabled = true; + _this._updateOrder = 0; + return _this; + } + Object.defineProperty(Component.prototype, "transform", { + get: function () { + return this.entity.transform; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Component.prototype, "enabled", { + get: function () { + return this.entity ? this.entity.enabled && this._enabled : this._enabled; + }, + set: function (value) { + this.setEnabled(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Component.prototype, "updateOrder", { + get: function () { + return this._updateOrder; + }, + set: function (value) { + this.setUpdateOrder(value); + }, + enumerable: true, + configurable: true + }); + Component.prototype.initialize = function () { + }; + Component.prototype.onAddedToEntity = function () { + }; + Component.prototype.onRemovedFromEntity = function () { + }; + Component.prototype.onEntityTransformChanged = function (comp) { + }; + Component.prototype.debugRender = function () { + }; + Component.prototype.onEnabled = function () { + }; + Component.prototype.onDisabled = function () { + }; + Component.prototype.update = function () { + }; + Component.prototype.setEnabled = function (isEnabled) { + if (this._enabled != isEnabled) { + this._enabled = isEnabled; + if (this._enabled) { + this.onEnabled(); + } + else { + this.onDisabled(); + } } return this; - } - }; - Entity.prototype.setTag = function (tag) { - if (this._tag != tag) { - if (this.scene) { - this.scene.entities.removeFromTagList(this); - } - this._tag = tag; - if (this.scene) { - this.scene.entities.addToTagList(this); + }; + Component.prototype.setUpdateOrder = function (updateOrder) { + if (this._updateOrder != updateOrder) { + this._updateOrder = updateOrder; } + return this; + }; + Component.prototype.clone = function () { + var component = ObjectUtils.clone(this); + component.entity = null; + return component; + }; + return Component; + }(egret.HashObject)); + es.Component = Component; +})(es || (es = {})); +var es; +(function (es) { + var Core = (function (_super) { + __extends(Core, _super); + function Core() { + var _this = _super.call(this) || this; + _this._globalManagers = []; + Core._instance = _this; + Core.emitter = new es.Emitter(); + Core.content = new es.ContentManager(); + _this.addEventListener(egret.Event.ADDED_TO_STAGE, _this.onAddToStage, _this); + return _this; } - return this; - }; - Entity.prototype.attachToScene = function (newScene) { - this.scene = newScene; - newScene.entities.add(this); - this.components.registerAllComponents(); - for (var i = 0; i < this.numChildren; i++) { - this.getChildAt(i).entity.attachToScene(newScene); - } - }; - Entity.prototype.detachFromScene = function () { - this.scene.entities.remove(this); - this.components.deregisterAllComponents(); - for (var i = 0; i < this.numChildren; i++) - this.getChildAt(i).entity.detachFromScene(); - }; - Entity.prototype.addComponent = function (component) { - component.entity = this; - this.components.add(component); - this.addChild(component); - component.initialize(); - return component; - }; - Entity.prototype.hasComponent = function (type) { - return this.components.getComponent(type, false) != null; - }; - Entity.prototype.getOrCreateComponent = function (type) { - var comp = this.components.getComponent(type, true); - if (!comp) { - comp = this.addComponent(type); - } - return comp; - }; - Entity.prototype.getComponent = function (type) { - return this.components.getComponent(type, false); - }; - Entity.prototype.getComponents = function (typeName, componentList) { - return this.components.getComponents(typeName, componentList); - }; - Entity.prototype.onEntityTransformChanged = function (comp) { - this.components.onEntityTransformChanged(comp); - }; - Entity.prototype.removeComponentForType = function (type) { - var comp = this.getComponent(type); - if (comp) { - this.removeComponent(comp); - return true; - } - return false; - }; - Entity.prototype.removeComponent = function (component) { - this.components.remove(component); - }; - Entity.prototype.removeAllComponents = function () { - for (var i = 0; i < this.components.count; i++) { - this.removeComponent(this.components.buffer[i]); - } - }; - Entity.prototype.update = function () { - this.components.update(); - }; - Entity.prototype.onAddedToScene = function () { - }; - Entity.prototype.onRemovedFromScene = function () { - if (this._isDestoryed) - this.components.removeAllComponents(); - }; - Entity.prototype.destroy = function () { - this._isDestoryed = true; - this.scene.entities.remove(this); - this.removeChildren(); - for (var i = this.numChildren - 1; i >= 0; i--) { - var child = this.getChildAt(i); - child.entity.destroy(); - } - }; - return Entity; -}(egret.DisplayObjectContainer)); -var TransformComponent; -(function (TransformComponent) { - TransformComponent[TransformComponent["rotation"] = 0] = "rotation"; - TransformComponent[TransformComponent["scale"] = 1] = "scale"; - TransformComponent[TransformComponent["position"] = 2] = "position"; -})(TransformComponent || (TransformComponent = {})); -var Scene = (function (_super) { - __extends(Scene, _super); - function Scene() { - var _this = _super.call(this) || this; - _this.enablePostProcessing = true; - _this._renderers = []; - _this._postProcessors = []; - _this.entityProcessors = new EntityProcessorList(); - _this.renderableComponents = new RenderableComponentList(); - _this.entities = new EntityList(_this); - _this.content = new ContentManager(); - _this.width = SceneManager.stage.stageWidth; - _this.height = SceneManager.stage.stageHeight; - _this.addEventListener(egret.Event.ACTIVATE, _this.onActive, _this); - _this.addEventListener(egret.Event.DEACTIVATE, _this.onDeactive, _this); - return _this; - } - Scene.prototype.createEntity = function (name) { - var entity = new Entity(name); - entity.position = new Vector2(0, 0); - return this.addEntity(entity); - }; - Scene.prototype.addEntity = function (entity) { - this.entities.add(entity); - entity.scene = this; - this.addChild(entity); - for (var i = 0; i < entity.numChildren; i++) - this.addEntity(entity.getChildAt(i).entity); - return entity; - }; - Scene.prototype.destroyAllEntities = function () { - for (var i = 0; i < this.entities.count; i++) { - this.entities.buffer[i].destroy(); - } - }; - Scene.prototype.findEntity = function (name) { - return this.entities.findEntity(name); - }; - Scene.prototype.addEntityProcessor = function (processor) { - processor.scene = this; - this.entityProcessors.add(processor); - return processor; - }; - Scene.prototype.removeEntityProcessor = function (processor) { - this.entityProcessors.remove(processor); - }; - Scene.prototype.getEntityProcessor = function () { - return this.entityProcessors.getProcessor(); - }; - Scene.prototype.addRenderer = function (renderer) { - this._renderers.push(renderer); - this._renderers.sort(); - renderer.onAddedToScene(this); - return renderer; - }; - Scene.prototype.getRenderer = function (type) { - for (var i = 0; i < this._renderers.length; i++) { - if (this._renderers[i] instanceof type) - return this._renderers[i]; - } - return null; - }; - Scene.prototype.removeRenderer = function (renderer) { - this._renderers.remove(renderer); - renderer.unload(); - }; - Scene.prototype.begin = function () { - if (SceneManager.sceneTransition) { - SceneManager.stage.addChildAt(this, SceneManager.stage.numChildren - 1); - } - else { - SceneManager.stage.addChild(this); - } - if (this._renderers.length == 0) { - this.addRenderer(new DefaultRenderer()); - console.warn("场景开始时没有渲染器 自动添加DefaultRenderer以保证能够正常渲染"); - } - this.camera = this.createEntity("camera").getOrCreateComponent(new Camera()); - Physics.reset(); - if (this.entityProcessors) - this.entityProcessors.begin(); - this.camera.onSceneSizeChanged(this.stage.stageWidth, this.stage.stageHeight); - this._didSceneBegin = true; - this.onStart(); - }; - Scene.prototype.end = function () { - this._didSceneBegin = false; - this.removeEventListener(egret.Event.DEACTIVATE, this.onDeactive, this); - this.removeEventListener(egret.Event.ACTIVATE, this.onActive, this); - for (var i = 0; i < this._renderers.length; i++) { - this._renderers[i].unload(); - } - for (var i = 0; i < this._postProcessors.length; i++) { - this._postProcessors[i].unload(); - } - this.entities.removeAllEntities(); - this.removeChildren(); - Physics.clear(); - this.camera = null; - this.content.dispose(); - if (this.entityProcessors) - this.entityProcessors.end(); - this.unload(); - if (this.parent) - this.parent.removeChild(this); - }; - Scene.prototype.onStart = function () { - return __awaiter(this, void 0, void 0, function () { - return __generator(this, function (_a) { - return [2]; - }); + Object.defineProperty(Core, "Instance", { + get: function () { + return this._instance; + }, + enumerable: true, + configurable: true }); - }; - Scene.prototype.onActive = function () { - }; - Scene.prototype.onDeactive = function () { - }; - Scene.prototype.unload = function () { }; - Scene.prototype.update = function () { - this.entities.updateLists(); - if (this.entityProcessors) - this.entityProcessors.update(); - this.entities.update(); - if (this.entityProcessors) - this.entityProcessors.lateUpdate(); - this.renderableComponents.updateList(); - }; - Scene.prototype.postRender = function () { - var enabledCounter = 0; - if (this.enablePostProcessing) { - for (var i = 0; i < this._postProcessors.length; i++) { - if (this._postProcessors[i].enable) { - var isEven = MathHelper.isEven(enabledCounter); - enabledCounter++; - this._postProcessors[i].process(); - } - } - } - }; - Scene.prototype.render = function () { - for (var i = 0; i < this._renderers.length; i++) { - this._renderers[i].render(this); - } - }; - Scene.prototype.addPostProcessor = function (postProcessor) { - this._postProcessors.push(postProcessor); - this._postProcessors.sort(); - postProcessor.onAddedToScene(this); - if (this._didSceneBegin) { - postProcessor.onSceneBackBufferSizeChanged(this.stage.stageWidth, this.stage.stageHeight); - } - return postProcessor; - }; - return Scene; -}(egret.DisplayObjectContainer)); -var SceneManager = (function () { - function SceneManager(stage) { - stage.addEventListener(egret.Event.ENTER_FRAME, SceneManager.update, this); - SceneManager.stage = stage; - SceneManager.initialize(stage); - } - Object.defineProperty(SceneManager, "scene", { - get: function () { - return this._scene; - }, - set: function (value) { - if (!value) - throw new Error("场景不能为空"); - if (this._scene == null) { - this._scene = value; - this._scene.begin(); - } - else { - this._nextScene = value; - } - }, - enumerable: true, - configurable: true - }); - SceneManager.initialize = function (stage) { - Input.initialize(stage); - }; - SceneManager.update = function () { - Time.update(egret.getTimer()); - if (SceneManager._scene) { - for (var i = GlobalManager.globalManagers.length - 1; i >= 0; i--) { - if (GlobalManager.globalManagers[i].enabled) - GlobalManager.globalManagers[i].update(); - } - if (!SceneManager.sceneTransition || - (SceneManager.sceneTransition && (!SceneManager.sceneTransition.loadsNewScene || SceneManager.sceneTransition.isNewSceneLoaded))) { - SceneManager._scene.update(); - } - if (SceneManager._nextScene) { - SceneManager._scene.end(); - for (var i = 0; i < SceneManager._scene.entities.buffer.length; i++) { - var entity = SceneManager._scene.entities.buffer[i]; - entity.destroy(); - } - SceneManager._scene = SceneManager._nextScene; - SceneManager._nextScene = null; - SceneManager._scene.begin(); - } - } - SceneManager.render(); - }; - SceneManager.render = function () { - if (this.sceneTransition) { - this.sceneTransition.preRender(); - if (this._scene && !this.sceneTransition.hasPreviousSceneRender) { - this._scene.render(); - this._scene.postRender(); - this.sceneTransition.onBeginTransition(); - } - else if (this.sceneTransition) { - if (this._scene && this.sceneTransition.isNewSceneLoaded) { - this._scene.render(); - this._scene.postRender(); - } - this.sceneTransition.render(); - } - } - else if (this._scene) { - this._scene.render(); - this._scene.postRender(); - } - }; - SceneManager.startSceneTransition = function (sceneTransition) { - if (this.sceneTransition) { - console.warn("在前一个场景完成之前,不能开始一个新的场景转换。"); - return; - } - this.sceneTransition = sceneTransition; - return sceneTransition; - }; - return SceneManager; -}()); -var Camera = (function (_super) { - __extends(Camera, _super); - function Camera() { - var _this = _super.call(this) || this; - _this._origin = Vector2.zero; - _this._minimumZoom = 0.3; - _this._maximumZoom = 3; - _this._position = Vector2.zero; - _this.followLerp = 0.1; - _this.deadzone = new Rectangle(); - _this.focusOffset = new Vector2(); - _this.mapLockEnabled = false; - _this.mapSize = new Vector2(); - _this._worldSpaceDeadZone = new Rectangle(); - _this._desiredPositionDelta = new Vector2(); - _this.cameraStyle = CameraStyle.lockOn; - _this.width = SceneManager.stage.stageWidth; - _this.height = SceneManager.stage.stageHeight; - _this.setZoom(0); - return _this; - } - Object.defineProperty(Camera.prototype, "zoom", { - get: function () { - if (this._zoom == 0) - return 1; - if (this._zoom < 1) - return MathHelper.map(this._zoom, this._minimumZoom, 1, -1, 0); - return MathHelper.map(this._zoom, 1, this._maximumZoom, 0, 1); - }, - set: function (value) { - this.setZoom(value); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Camera.prototype, "minimumZoom", { - get: function () { - return this._minimumZoom; - }, - set: function (value) { - this.setMinimumZoom(value); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Camera.prototype, "maximumZoom", { - get: function () { - return this._maximumZoom; - }, - set: function (value) { - this.setMaximumZoom(value); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Camera.prototype, "origin", { - get: function () { - return this._origin; - }, - set: function (value) { - if (this._origin != value) { - this._origin = value; - } - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Camera.prototype, "position", { - get: function () { - return this._position; - }, - set: function (value) { - this._position = value; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Camera.prototype, "x", { - get: function () { - return this._position.x; - }, - set: function (value) { - this._position.x = value; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Camera.prototype, "y", { - get: function () { - return this._position.y; - }, - set: function (value) { - this._position.y = value; - }, - enumerable: true, - configurable: true - }); - Camera.prototype.onSceneSizeChanged = function (newWidth, newHeight) { - var oldOrigin = this._origin; - this.origin = new Vector2(newWidth / 2, newHeight / 2); - this.entity.position = Vector2.add(this.entity.position, Vector2.subtract(this._origin, oldOrigin)); - }; - Camera.prototype.setMinimumZoom = function (minZoom) { - if (this._zoom < minZoom) - this._zoom = this.minimumZoom; - this._minimumZoom = minZoom; - return this; - }; - Camera.prototype.setMaximumZoom = function (maxZoom) { - if (this._zoom > maxZoom) - this._zoom = maxZoom; - this._maximumZoom = maxZoom; - return this; - }; - Camera.prototype.setZoom = function (zoom) { - var newZoom = MathHelper.clamp(zoom, -1, 1); - if (newZoom == 0) { - this._zoom = 1; - } - else if (newZoom < 0) { - this._zoom = MathHelper.map(newZoom, -1, 0, this._minimumZoom, 1); - } - else { - this._zoom = MathHelper.map(newZoom, 0, 1, 1, this._maximumZoom); - } - SceneManager.scene.scaleX = this._zoom; - SceneManager.scene.scaleY = this._zoom; - return this; - }; - Camera.prototype.setRotation = function (rotation) { - SceneManager.scene.rotation = rotation; - return this; - }; - Camera.prototype.setPosition = function (position) { - this.entity.position = position; - return this; - }; - Camera.prototype.follow = function (targetEntity, cameraStyle) { - if (cameraStyle === void 0) { cameraStyle = CameraStyle.cameraWindow; } - this.targetEntity = targetEntity; - this.cameraStyle = cameraStyle; - var cameraBounds = new Rectangle(0, 0, SceneManager.stage.stageWidth, SceneManager.stage.stageHeight); - switch (this.cameraStyle) { - case CameraStyle.cameraWindow: - var w = cameraBounds.width / 6; - var h = cameraBounds.height / 3; - this.deadzone = new Rectangle((cameraBounds.width - w) / 2, (cameraBounds.height - h) / 2, w, h); - break; - case CameraStyle.lockOn: - this.deadzone = new Rectangle(cameraBounds.width / 2, cameraBounds.height / 2, 10, 10); - break; - } - }; - Camera.prototype.update = function () { - var cameraBounds = new Rectangle(0, 0, SceneManager.stage.stageWidth, SceneManager.stage.stageHeight); - var halfScreen = Vector2.multiply(new Vector2(cameraBounds.width, cameraBounds.height), new Vector2(0.5)); - this._worldSpaceDeadZone.x = this.position.x - halfScreen.x + this.deadzone.x + this.focusOffset.x; - this._worldSpaceDeadZone.y = this.position.y - halfScreen.y + this.deadzone.y + this.focusOffset.y; - this._worldSpaceDeadZone.width = this.deadzone.width; - this._worldSpaceDeadZone.height = this.deadzone.height; - if (this.targetEntity) - this.updateFollow(); - this.position = Vector2.lerp(this.position, Vector2.add(this.position, this._desiredPositionDelta), this.followLerp); - this.entity.roundPosition(); - if (this.mapLockEnabled) { - this.position = this.clampToMapSize(this.position); - this.entity.roundPosition(); - } - }; - Camera.prototype.clampToMapSize = function (position) { - var cameraBounds = new Rectangle(0, 0, SceneManager.stage.stageWidth, SceneManager.stage.stageHeight); - var halfScreen = Vector2.multiply(new Vector2(cameraBounds.width, cameraBounds.height), new Vector2(0.5)); - var cameraMax = new Vector2(this.mapSize.x - halfScreen.x, this.mapSize.y - halfScreen.y); - return Vector2.clamp(position, halfScreen, cameraMax); - }; - Camera.prototype.updateFollow = function () { - this._desiredPositionDelta.x = this._desiredPositionDelta.y = 0; - if (this.cameraStyle == CameraStyle.lockOn) { - var targetX = this.targetEntity.position.x; - var targetY = this.targetEntity.position.y; - if (this._worldSpaceDeadZone.x > targetX) - this._desiredPositionDelta.x = targetX - this._worldSpaceDeadZone.x; - else if (this._worldSpaceDeadZone.x < targetX) - this._desiredPositionDelta.x = targetX - this._worldSpaceDeadZone.x; - if (this._worldSpaceDeadZone.y < targetY) - this._desiredPositionDelta.y = targetY - this._worldSpaceDeadZone.y; - else if (this._worldSpaceDeadZone.y > targetY) - this._desiredPositionDelta.y = targetY - this._worldSpaceDeadZone.y; - } - else { - if (!this._targetCollider) { - this._targetCollider = this.targetEntity.getComponent(Collider); - if (!this._targetCollider) + Object.defineProperty(Core, "scene", { + get: function () { + if (!this._instance) + return null; + return this._instance._scene; + }, + set: function (value) { + if (!value) { + console.error("场景不能为空"); return; + } + if (this._instance._scene == null) { + this._instance._scene = value; + this._instance.addChild(value); + this._instance._scene.begin(); + Core.Instance.onSceneChanged(); + } + else { + this._instance._nextScene = value; + } + }, + enumerable: true, + configurable: true + }); + Core.startSceneTransition = function (sceneTransition) { + if (this._instance._sceneTransition) { + console.warn("在前一个场景完成之前,不能开始一个新的场景转换。"); + return; } - var targetBounds = this.targetEntity.getComponent(Collider).bounds; - if (!this._worldSpaceDeadZone.containsRect(targetBounds)) { - if (this._worldSpaceDeadZone.left > targetBounds.left) - this._desiredPositionDelta.x = targetBounds.left - this._worldSpaceDeadZone.left; - else if (this._worldSpaceDeadZone.right < targetBounds.right) - this._desiredPositionDelta.x = targetBounds.right - this._worldSpaceDeadZone.right; - if (this._worldSpaceDeadZone.bottom < targetBounds.bottom) - this._desiredPositionDelta.y = targetBounds.bottom - this._worldSpaceDeadZone.bottom; - else if (this._worldSpaceDeadZone.top > targetBounds.top) - this._desiredPositionDelta.y = targetBounds.top - this._worldSpaceDeadZone.top; + this._instance._sceneTransition = sceneTransition; + return sceneTransition; + }; + Core.registerGlobalManager = function (manager) { + this._instance._globalManagers.push(manager); + manager.enabled = true; + }; + Core.unregisterGlobalManager = function (manager) { + this._instance._globalManagers.remove(manager); + manager.enabled = false; + }; + Core.getGlobalManager = function (type) { + for (var i = 0; i < this._instance._globalManagers.length; i++) { + if (this._instance._globalManagers[i] instanceof type) + return this._instance._globalManagers[i]; } - } - }; - return Camera; -}(Component)); -var CameraStyle; -(function (CameraStyle) { - CameraStyle[CameraStyle["lockOn"] = 0] = "lockOn"; - CameraStyle[CameraStyle["cameraWindow"] = 1] = "cameraWindow"; -})(CameraStyle || (CameraStyle = {})); -var ComponentPool = (function () { - function ComponentPool(typeClass) { - this._type = typeClass; - this._cache = []; - } - ComponentPool.prototype.obtain = function () { - try { - return this._cache.length > 0 ? this._cache.shift() : new this._type(); - } - catch (err) { - throw new Error(this._type + err); - } - }; - ComponentPool.prototype.free = function (component) { - component.reset(); - this._cache.push(component); - }; - return ComponentPool; -}()); -var PooledComponent = (function (_super) { - __extends(PooledComponent, _super); - function PooledComponent() { - return _super !== null && _super.apply(this, arguments) || this; - } - return PooledComponent; -}(Component)); -var RenderableComponent = (function (_super) { - __extends(RenderableComponent, _super); - function RenderableComponent() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this._areBoundsDirty = true; - _this._bounds = new Rectangle(); - _this._localOffset = Vector2.zero; - _this.color = 0x000000; - return _this; - } - Object.defineProperty(RenderableComponent.prototype, "width", { - get: function () { - return this.getWidth(); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(RenderableComponent.prototype, "height", { - get: function () { - return this.getHeight(); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(RenderableComponent.prototype, "isVisible", { - get: function () { - return this._isVisible; - }, - set: function (value) { - this._isVisible = value; - if (this._isVisible) - this.onBecameVisible(); - else - this.onBecameInvisible(); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(RenderableComponent.prototype, "bounds", { - get: function () { - return new Rectangle(this.getBounds().x, this.getBounds().y, this.getBounds().width, this.getBounds().height); - }, - enumerable: true, - configurable: true - }); - RenderableComponent.prototype.getWidth = function () { - return this.bounds.width; - }; - RenderableComponent.prototype.getHeight = function () { - return this.bounds.height; - }; - RenderableComponent.prototype.onBecameVisible = function () { }; - RenderableComponent.prototype.onBecameInvisible = function () { }; - RenderableComponent.prototype.isVisibleFromCamera = function (camera) { - this.isVisible = camera.getBounds().intersects(this.getBounds()); - return this.isVisible; - }; - return RenderableComponent; -}(PooledComponent)); -var Mesh = (function (_super) { - __extends(Mesh, _super); - function Mesh() { - var _this = _super.call(this) || this; - _this._mesh = new egret.Mesh(); - return _this; - } - Mesh.prototype.setTexture = function (texture) { - this._mesh.texture = texture; - return this; - }; - Mesh.prototype.onAddedToEntity = function () { - this.addChild(this._mesh); - }; - Mesh.prototype.onRemovedFromEntity = function () { - this.removeChild(this._mesh); - }; - Mesh.prototype.render = function (camera) { - this.x = this.entity.position.x - camera.position.x + camera.origin.x; - this.y = this.entity.position.y - camera.position.y + camera.origin.y; - }; - Mesh.prototype.reset = function () { - }; - return Mesh; -}(RenderableComponent)); -var SpriteRenderer = (function (_super) { - __extends(SpriteRenderer, _super); - function SpriteRenderer() { - return _super !== null && _super.apply(this, arguments) || this; - } - Object.defineProperty(SpriteRenderer.prototype, "sprite", { - get: function () { - return this._sprite; - }, - set: function (value) { - this.setSprite(value); - }, - enumerable: true, - configurable: true - }); - SpriteRenderer.prototype.setSprite = function (sprite) { - this.removeChildren(); - this._sprite = sprite; - if (this._sprite) { - this.anchorOffsetX = this._sprite.origin.x / this._sprite.sourceRect.width; - this.anchorOffsetY = this._sprite.origin.y / this._sprite.sourceRect.height; - } - this.bitmap = new egret.Bitmap(sprite.texture2D); - this.addChild(this.bitmap); - return this; - }; - SpriteRenderer.prototype.setColor = function (color) { - var colorMatrix = [ - 1, 0, 0, 0, 0, - 0, 1, 0, 0, 0, - 0, 0, 1, 0, 0, - 0, 0, 0, 1, 0 - ]; - colorMatrix[0] = Math.floor(color / 256 / 256) / 255; - colorMatrix[6] = Math.floor(color / 256 % 256) / 255; - colorMatrix[12] = color % 256 / 255; - var colorFilter = new egret.ColorMatrixFilter(colorMatrix); - this.filters = [colorFilter]; - return this; - }; - SpriteRenderer.prototype.isVisibleFromCamera = function (camera) { - this.isVisible = new Rectangle(0, 0, this.stage.stageWidth, this.stage.stageHeight).intersects(this.bounds); - this.visible = this.isVisible; - return this.isVisible; - }; - SpriteRenderer.prototype.render = function (camera) { - this.x = -camera.position.x + camera.origin.x; - this.y = -camera.position.y + camera.origin.y; - }; - SpriteRenderer.prototype.onRemovedFromEntity = function () { - if (this.parent) - this.parent.removeChild(this); - }; - SpriteRenderer.prototype.reset = function () { - }; - return SpriteRenderer; -}(RenderableComponent)); -var TiledSpriteRenderer = (function (_super) { - __extends(TiledSpriteRenderer, _super); - function TiledSpriteRenderer(sprite) { - var _this = _super.call(this) || this; - _this.leftTexture = new egret.Bitmap(); - _this.rightTexture = new egret.Bitmap(); - _this.leftTexture.texture = sprite.texture2D; - _this.rightTexture.texture = sprite.texture2D; - _this.setSprite(sprite); - _this.sourceRect = sprite.sourceRect; - return _this; - } - Object.defineProperty(TiledSpriteRenderer.prototype, "scrollX", { - get: function () { - return this.sourceRect.x; - }, - set: function (value) { - this.sourceRect.x = value; - if (this.sourceRect.x < -this.sourceRect.width) - this.sourceRect.x = this.sourceRect.width; - else if (this.sourceRect.x > this.sourceRect.width) - this.sourceRect.x = -this.sourceRect.width; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(TiledSpriteRenderer.prototype, "scrollY", { - get: function () { - return this.sourceRect.y; - }, - set: function (value) { - this.sourceRect.y = value; - if (this.sourceRect.y < -this.sourceRect.height) - this.sourceRect.y = this.sourceRect.height; - else if (this.sourceRect.y > this.sourceRect.height) - this.sourceRect.y = -this.sourceRect.height; - }, - enumerable: true, - configurable: true - }); - TiledSpriteRenderer.prototype.render = function (camera) { - if (!this.sprite) - return; - _super.prototype.render.call(this, camera); - var renderTexture = new egret.RenderTexture(); - var cacheBitmap = new egret.DisplayObjectContainer(); - cacheBitmap.removeChildren(); - cacheBitmap.addChild(this.leftTexture); - cacheBitmap.addChild(this.rightTexture); - this.leftTexture.x = this.sourceRect.x; - this.rightTexture.x = this.sourceRect.x - this.sourceRect.width; - this.leftTexture.y = this.sourceRect.y; - this.rightTexture.y = this.sourceRect.y; - cacheBitmap.cacheAsBitmap = true; - renderTexture.drawToTexture(cacheBitmap, new egret.Rectangle(0, 0, this.sourceRect.width, this.sourceRect.height)); - this.bitmap.texture = renderTexture; - }; - return TiledSpriteRenderer; -}(SpriteRenderer)); -var ScrollingSpriteRenderer = (function (_super) { - __extends(ScrollingSpriteRenderer, _super); - function ScrollingSpriteRenderer() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this.scrollSpeedX = 15; - _this.scroolSpeedY = 0; - _this._scrollX = 0; - _this._scrollY = 0; - return _this; - } - ScrollingSpriteRenderer.prototype.update = function () { - this.scrollX += this.scrollSpeedX * Time.deltaTime; - this.scrollY += this.scroolSpeedY * Time.deltaTime; - this.sourceRect.x = this._scrollX; - this.sourceRect.y = this._scrollY; - }; - return ScrollingSpriteRenderer; -}(TiledSpriteRenderer)); -var Sprite = (function () { - function Sprite(texture, sourceRect, origin) { - if (sourceRect === void 0) { sourceRect = new Rectangle(0, 0, texture.textureWidth, texture.textureHeight); } - if (origin === void 0) { origin = sourceRect.getHalfSize(); } - this.uvs = new Rectangle(); - this.texture2D = texture; - this.sourceRect = sourceRect; - this.center = new Vector2(sourceRect.width * 0.5, sourceRect.height * 0.5); - this.origin = origin; - var inverseTexW = 1 / texture.textureWidth; - var 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; - } - return Sprite; -}()); -var SpriteAnimation = (function () { - function SpriteAnimation(sprites, frameRate) { - this.sprites = sprites; - this.frameRate = frameRate; - } - return SpriteAnimation; -}()); -var SpriteAnimator = (function (_super) { - __extends(SpriteAnimator, _super); - function SpriteAnimator(sprite) { - var _this = _super.call(this) || this; - _this.speed = 1; - _this.animationState = State.none; - _this._animations = new Map(); - _this._elapsedTime = 0; - if (sprite) - _this.setSprite(sprite); - return _this; - } - Object.defineProperty(SpriteAnimator.prototype, "isRunning", { - get: function () { - return this.animationState == State.running; - }, - enumerable: true, - configurable: true - }); - SpriteAnimator.prototype.addAnimation = function (name, animation) { - if (!this.sprite && animation.sprites.length > 0) - this.setSprite(animation.sprites[0]); - this._animations[name] = animation; - return this; - }; - SpriteAnimator.prototype.play = function (name, loopMode) { - if (loopMode === void 0) { 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; - }; - SpriteAnimator.prototype.isAnimationActive = function (name) { - return this.currentAnimation && this.currentAnimationName == name; - }; - SpriteAnimator.prototype.pause = function () { - this.animationState = State.paused; - }; - SpriteAnimator.prototype.unPause = function () { - this.animationState = State.running; - }; - SpriteAnimator.prototype.stop = function () { - this.currentAnimation = null; - this.currentAnimationName = null; - this.currentFrame = 0; - this.animationState = State.none; - }; - SpriteAnimator.prototype.update = function () { - if (this.animationState != State.running || !this.currentAnimation) - return; - var animation = this.currentAnimation; - var secondsPerFrame = 1 / (animation.frameRate * this.speed); - var iterationDuration = secondsPerFrame * animation.sprites.length; - this._elapsedTime += Time.deltaTime; - var 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; - } - var i = Math.floor(time / secondsPerFrame); - var n = animation.sprites.length; - if (n > 2 && (this._loopMode == LoopMode.pingPong || this._loopMode == LoopMode.pingPongOnce)) { - var maxIndex = n - 1; - this.currentFrame = maxIndex - Math.abs(maxIndex - i % (maxIndex * 2)); - } - else { - this.currentFrame = i % n; - } - this.sprite = animation.sprites[this.currentFrame]; - }; - return SpriteAnimator; -}(SpriteRenderer)); -var LoopMode; -(function (LoopMode) { - LoopMode[LoopMode["loop"] = 0] = "loop"; - LoopMode[LoopMode["once"] = 1] = "once"; - LoopMode[LoopMode["clampForever"] = 2] = "clampForever"; - LoopMode[LoopMode["pingPong"] = 3] = "pingPong"; - LoopMode[LoopMode["pingPongOnce"] = 4] = "pingPongOnce"; -})(LoopMode || (LoopMode = {})); -var State; -(function (State) { - State[State["none"] = 0] = "none"; - State[State["running"] = 1] = "running"; - State[State["paused"] = 2] = "paused"; - State[State["completed"] = 3] = "completed"; -})(State || (State = {})); -var Mover = (function (_super) { - __extends(Mover, _super); - function Mover() { - return _super !== null && _super.apply(this, arguments) || this; - } - Mover.prototype.onAddedToEntity = function () { - this._triggerHelper = new ColliderTriggerHelper(this.entity); - }; - Mover.prototype.calculateMovement = function (motion) { - var collisionResult = new CollisionResult(); - if (!this.entity.getComponent(Collider) || !this._triggerHelper) { return null; + }; + Core.prototype.onOrientationChanged = function () { + Core.emitter.emit(es.CoreEvents.OrientationChanged); + }; + Core.prototype.draw = function () { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + if (!this._sceneTransition) return [3, 4]; + this._sceneTransition.preRender(); + if (!(this._scene && !this._sceneTransition.hasPreviousSceneRender)) return [3, 2]; + this._scene.render(); + this._scene.postRender(); + return [4, this._sceneTransition.onBeginTransition()]; + case 1: + _a.sent(); + return [3, 3]; + case 2: + if (this._sceneTransition) { + if (this._scene && this._sceneTransition.isNewSceneLoaded) { + this._scene.render(); + this._scene.postRender(); + } + this._sceneTransition.render(); + } + _a.label = 3; + case 3: return [3, 5]; + case 4: + if (this._scene) { + this._scene.render(); + es.Debug.render(); + this._scene.postRender(); + } + _a.label = 5; + case 5: return [2]; + } + }); + }); + }; + Core.prototype.startDebugUpdate = function () { + es.TimeRuler.Instance.startFrame(); + es.TimeRuler.Instance.beginMark("update", 0x00FF00); + }; + Core.prototype.endDebugUpdate = function () { + es.TimeRuler.Instance.endMark("update"); + }; + Core.prototype.onSceneChanged = function () { + Core.emitter.emit(es.CoreEvents.SceneChanged); + es.Time.sceneChanged(); + }; + Core.prototype.onGraphicsDeviceReset = function () { + Core.emitter.emit(es.CoreEvents.GraphicsDeviceReset); + }; + Core.prototype.initialize = function () { + }; + Core.prototype.update = function () { + return __awaiter(this, void 0, void 0, function () { + var i; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + es.Time.update(egret.getTimer()); + if (!this._scene) return [3, 2]; + for (i = this._globalManagers.length - 1; i >= 0; i--) { + if (this._globalManagers[i].enabled) + this._globalManagers[i].update(); + } + if (!this._sceneTransition || + (this._sceneTransition && (!this._sceneTransition.loadsNewScene || this._sceneTransition.isNewSceneLoaded))) { + this._scene.update(); + } + if (!this._nextScene) return [3, 2]; + this.removeChild(this._scene); + this._scene.end(); + this._scene = this._nextScene; + this._nextScene = null; + this.onSceneChanged(); + this.addChild(this._scene); + return [4, this._scene.begin()]; + case 1: + _a.sent(); + _a.label = 2; + case 2: return [4, this.draw()]; + case 3: + _a.sent(); + return [2]; + } + }); + }); + }; + Core.prototype.onAddToStage = function () { + Core.graphicsDevice = new es.GraphicsDevice(); + this.addEventListener(egret.Event.RESIZE, this.onGraphicsDeviceReset, this); + this.addEventListener(egret.StageOrientationEvent.ORIENTATION_CHANGE, this.onOrientationChanged, this); + this.addEventListener(egret.Event.ENTER_FRAME, this.update, this); + es.Input.initialize(); + this.initialize(); + }; + return Core; + }(egret.DisplayObjectContainer)); + es.Core = Core; +})(es || (es = {})); +var es; +(function (es) { + var CoreEvents; + (function (CoreEvents) { + CoreEvents[CoreEvents["GraphicsDeviceReset"] = 0] = "GraphicsDeviceReset"; + CoreEvents[CoreEvents["SceneChanged"] = 1] = "SceneChanged"; + CoreEvents[CoreEvents["OrientationChanged"] = 2] = "OrientationChanged"; + })(CoreEvents = es.CoreEvents || (es.CoreEvents = {})); +})(es || (es = {})); +var es; +(function (es) { + var Entity = (function () { + function Entity(name) { + this.updateInterval = 1; + this._tag = 0; + this._enabled = true; + this._updateOrder = 0; + this.components = new es.ComponentList(this); + this.transform = new es.Transform(this); + this.name = name; + this.id = Entity._idGenerator++; + this.componentBits = new es.BitSet(); } - var colliders = this.entity.getComponents(Collider); - for (var i = 0; i < colliders.length; i++) { - var collider = colliders[i]; - if (collider.isTrigger) - continue; - var bounds = collider.bounds; - bounds.x += motion.x; - bounds.y += motion.y; - var boxcastResult = Physics.boxcastBroadphaseExcludingSelf(collider, bounds, collider.collidesWithLayers); - bounds = boxcastResult.bounds; - var neighbors = boxcastResult.tempHashSet; - for (var j = 0; j < neighbors.length; j++) { - var neighbor = neighbors[j]; - if (neighbor.isTrigger) - continue; - var _internalcollisionResult = collider.collidesWith(neighbor, motion); - if (_internalcollisionResult) { - motion = Vector2.subtract(motion, _internalcollisionResult.minimumTranslationVector); - if (_internalcollisionResult.collider) { - collisionResult = _internalcollisionResult; + Object.defineProperty(Entity.prototype, "isDestroyed", { + get: function () { + return this._isDestroyed; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Entity.prototype, "tag", { + get: function () { + return this._tag; + }, + set: function (value) { + this.setTag(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Entity.prototype, "enabled", { + get: function () { + return this._enabled; + }, + set: function (value) { + this.setEnabled(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Entity.prototype, "updateOrder", { + get: function () { + return this._updateOrder; + }, + set: function (value) { + this.setUpdateOrder(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Entity.prototype, "parent", { + get: function () { + return this.transform.parent; + }, + set: function (value) { + this.transform.setParent(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Entity.prototype, "childCount", { + get: function () { + return this.transform.childCount; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Entity.prototype, "position", { + get: function () { + return this.transform.position; + }, + set: function (value) { + this.transform.setPosition(value.x, value.y); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Entity.prototype, "localPosition", { + get: function () { + return this.transform.localPosition; + }, + set: function (value) { + this.transform.setLocalPosition(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Entity.prototype, "rotation", { + get: function () { + return this.transform.rotation; + }, + set: function (value) { + this.transform.setRotation(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Entity.prototype, "rotationDegrees", { + get: function () { + return this.transform.rotationDegrees; + }, + set: function (value) { + this.transform.setRotationDegrees(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Entity.prototype, "localRotation", { + get: function () { + return this.transform.localRotation; + }, + set: function (value) { + this.transform.setLocalRotation(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Entity.prototype, "localRotationDegrees", { + get: function () { + return this.transform.localRotationDegrees; + }, + set: function (value) { + this.transform.setLocalRotationDegrees(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Entity.prototype, "scale", { + get: function () { + return this.transform.scale; + }, + set: function (value) { + this.transform.setScale(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Entity.prototype, "localScale", { + get: function () { + return this.transform.localScale; + }, + set: function (value) { + this.transform.setLocalScale(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Entity.prototype, "worldInverseTransform", { + get: function () { + return this.transform.worldInverseTransform; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Entity.prototype, "localToWorldTransform", { + get: function () { + return this.transform.localToWorldTransform; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Entity.prototype, "worldToLocalTransform", { + get: function () { + return this.transform.worldToLocalTransform; + }, + enumerable: true, + configurable: true + }); + Entity.prototype.onTransformChanged = function (comp) { + this.components.onEntityTransformChanged(comp); + }; + Entity.prototype.setTag = function (tag) { + if (this._tag != tag) { + if (this.scene) + this.scene.entities.removeFromTagList(this); + this._tag = tag; + if (this.scene) + this.scene.entities.addToTagList(this); + } + return this; + }; + Entity.prototype.setEnabled = function (isEnabled) { + if (this._enabled != isEnabled) { + this._enabled = isEnabled; + if (this._enabled) + this.components.onEntityEnabled(); + else + this.components.onEntityDisabled(); + } + return this; + }; + Entity.prototype.setUpdateOrder = function (updateOrder) { + if (this._updateOrder != updateOrder) { + this._updateOrder = updateOrder; + if (this.scene) { + this.scene.entities.markEntityListUnsorted(); + this.scene.entities.markTagUnsorted(this.tag); + } + return this; + } + }; + Entity.prototype.destroy = function () { + this._isDestroyed = true; + this.scene.entities.remove(this); + this.transform.parent = null; + for (var i = this.transform.childCount - 1; i >= 0; i--) { + var child = this.transform.getChild(i); + child.entity.destroy(); + } + }; + Entity.prototype.detachFromScene = function () { + this.scene.entities.remove(this); + this.components.deregisterAllComponents(); + for (var i = 0; i < this.transform.childCount; i++) + this.transform.getChild(i).entity.detachFromScene(); + }; + Entity.prototype.attachToScene = function (newScene) { + this.scene = newScene; + newScene.entities.add(this); + this.components.registerAllComponents(); + for (var i = 0; i < this.transform.childCount; i++) { + this.transform.getChild(i).entity.attachToScene(newScene); + } + }; + Entity.prototype.clone = function (position) { + if (position === void 0) { position = new es.Vector2(); } + var entity = new Entity(this.name + "(clone)"); + entity.copyFrom(this); + entity.transform.position = position; + return entity; + }; + Entity.prototype.onAddedToScene = function () { + }; + Entity.prototype.onRemovedFromScene = function () { + if (this._isDestroyed) + this.components.removeAllComponents(); + }; + Entity.prototype.update = function () { + this.components.update(); + }; + Entity.prototype.addComponent = function (component) { + component.entity = this; + this.components.add(component); + component.initialize(); + return component; + }; + Entity.prototype.getComponent = function (type) { + return this.components.getComponent(type, false); + }; + Entity.prototype.hasComponent = function (type) { + return this.components.getComponent(type, false) != null; + }; + Entity.prototype.getOrCreateComponent = function (type) { + var comp = this.components.getComponent(type, true); + if (!comp) { + comp = this.addComponent(type); + } + return comp; + }; + Entity.prototype.getComponents = function (typeName, componentList) { + return this.components.getComponents(typeName, componentList); + }; + Entity.prototype.removeComponent = function (component) { + this.components.remove(component); + }; + Entity.prototype.removeComponentForType = function (type) { + var comp = this.getComponent(type); + if (comp) { + this.removeComponent(comp); + return true; + } + return false; + }; + Entity.prototype.removeAllComponents = function () { + for (var i = 0; i < this.components.count; i++) { + this.removeComponent(this.components.buffer[i]); + } + }; + Entity.prototype.compareTo = function (other) { + var compare = this._updateOrder - other._updateOrder; + if (compare == 0) + compare = this.id - other.id; + return compare; + }; + Entity.prototype.toString = function () { + return "[Entity: name: " + this.name + ", tag: " + this.tag + ", enabled: " + this.enabled + ", depth: " + this.updateOrder + "]"; + }; + Entity.prototype.copyFrom = function (entity) { + this.tag = entity.tag; + this.updateInterval = entity.updateInterval; + this.updateOrder = entity.updateOrder; + this.enabled = entity.enabled; + this.transform.scale = entity.transform.scale; + this.transform.rotation = entity.transform.rotation; + for (var i = 0; i < entity.components.count; i++) + this.addComponent(entity.components.buffer[i].clone()); + for (var i = 0; i < entity.components._componentsToAdd.length; i++) + this.addComponent(entity.components._componentsToAdd[i].clone()); + for (var i = 0; i < entity.transform.childCount; i++) { + var child = entity.transform.getChild(i).entity; + var childClone = child.clone(); + childClone.transform.copyFrom(child.transform); + childClone.transform.parent = this.transform; + } + }; + return Entity; + }()); + es.Entity = Entity; +})(es || (es = {})); +var es; +(function (es) { + var Scene = (function (_super) { + __extends(Scene, _super); + function Scene() { + var _this = _super.call(this) || this; + _this.enablePostProcessing = true; + _this._renderers = []; + _this._postProcessors = []; + _this.entities = new es.EntityList(_this); + _this.renderableComponents = new es.RenderableComponentList(); + _this.content = new es.ContentManager(); + _this.entityProcessors = new es.EntityProcessorList(); + _this.initialize(); + return _this; + } + Scene.createWithDefaultRenderer = function () { + var scene = new Scene(); + scene.addRenderer(new es.DefaultRenderer()); + return scene; + }; + Scene.prototype.initialize = function () { + }; + Scene.prototype.onStart = function () { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + return [2]; + }); + }); + }; + Scene.prototype.unload = function () { + }; + Scene.prototype.onActive = function () { + }; + Scene.prototype.onDeactive = function () { + }; + Scene.prototype.begin = function () { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + if (this._renderers.length == 0) { + this.addRenderer(new es.DefaultRenderer()); + console.warn("场景开始时没有渲染器 自动添加DefaultRenderer以保证能够正常渲染"); + } + this.camera = this.createEntity("camera").getOrCreateComponent(new es.Camera()); + es.Physics.reset(); + if (this.entityProcessors) + this.entityProcessors.begin(); + this.addEventListener(egret.Event.ACTIVATE, this.onActive, this); + this.addEventListener(egret.Event.DEACTIVATE, this.onDeactive, this); + this.camera.onSceneSizeChanged(this.stage.stageWidth, this.stage.stageHeight); + this._didSceneBegin = true; + this.onStart(); + return [2]; + }); + }); + }; + Scene.prototype.end = function () { + this._didSceneBegin = false; + this.removeEventListener(egret.Event.DEACTIVATE, this.onDeactive, this); + this.removeEventListener(egret.Event.ACTIVATE, this.onActive, this); + for (var i = 0; i < this._renderers.length; i++) { + this._renderers[i].unload(); + } + for (var i = 0; i < this._postProcessors.length; i++) { + this._postProcessors[i].unload(); + } + this.entities.removeAllEntities(); + this.removeChildren(); + this.camera = null; + this.content.dispose(); + if (this.entityProcessors) + this.entityProcessors.end(); + if (this.parent) + this.parent.removeChild(this); + this.unload(); + }; + Scene.prototype.update = function () { + this.entities.updateLists(); + if (this.entityProcessors) + this.entityProcessors.update(); + this.entities.update(); + if (this.entityProcessors) + this.entityProcessors.lateUpdate(); + this.renderableComponents.updateList(); + }; + Scene.prototype.render = function () { + if (this._renderers.length == 0) { + console.error("there are no renderers in the scene!"); + return; + } + for (var i = 0; i < this._renderers.length; i++) { + this._renderers[i].render(this); + } + }; + Scene.prototype.postRender = function () { + if (this.enablePostProcessing) { + for (var i = 0; i < this._postProcessors.length; i++) { + if (this._postProcessors[i].enabled) { + this._postProcessors[i].process(); } } } - } - ListPool.free(colliders); - return { collisionResult: collisionResult, motion: motion }; - }; - Mover.prototype.applyMovement = function (motion) { - this.entity.position = Vector2.add(this.entity.position, motion); - if (this._triggerHelper) - this._triggerHelper.update(); - }; - Mover.prototype.move = function (motion) { - var movementResult = this.calculateMovement(motion); - var collisionResult = movementResult.collisionResult; - motion = movementResult.motion; - this.applyMovement(motion); - return collisionResult; - }; - return Mover; -}(Component)); -var Collider = (function (_super) { - __extends(Collider, _super); - function Collider() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this.physicsLayer = 1 << 0; - _this.registeredPhysicsBounds = new Rectangle(); - _this.shouldColliderScaleAndRotateWithTransform = true; - _this.collidesWithLayers = Physics.allLayers; - _this._localOffset = new Vector2(0, 0); - return _this; - } - Object.defineProperty(Collider.prototype, "bounds", { - get: function () { - var bds = this.entity.getBounds(); - return new Rectangle(bds.x, bds.y, bds.width, bds.height); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Collider.prototype, "localOffset", { - get: function () { - return new Vector2(this.x, this.y); - }, - set: function (value) { - this.setLocalOffset(value); - }, - enumerable: true, - configurable: true - }); - Collider.prototype.setLocalOffset = function (offset) { - if (this._localOffset != offset) { - this.unregisterColliderWithPhysicsSystem(); - this.$setX(offset.x); - this.$setY(offset.y); - this._localOffsetLength = this._localOffset.length(); - this.registerColliderWithPhysicsSystem(); - } - }; - Collider.prototype.registerColliderWithPhysicsSystem = function () { - if (this._isParentEntityAddedToScene && !this._isColliderRegistered) { - Physics.addCollider(this); - this._isColliderRegistered = true; - } - }; - Collider.prototype.unregisterColliderWithPhysicsSystem = function () { - if (this._isParentEntityAddedToScene && this._isColliderRegistered) { - Physics.removeCollider(this); - } - this._isColliderRegistered = false; - }; - Collider.prototype.overlaps = function (other) { - return this.shape.overlaps(other.shape); - }; - Collider.prototype.collidesWith = function (collider, motion) { - var oldPosition = this.shape.position; - this.shape.position = Vector2.add(this.shape.position, motion); - var result = this.shape.collidesWithShape(collider.shape); - if (result) - result.collider = collider; - this.shape.position = oldPosition; - return result; - }; - Collider.prototype.onAddedToEntity = function () { - if (this._colliderRequiresAutoSizing) { - if (!(this instanceof BoxCollider)) { - console.error("Only box and circle colliders can be created automatically"); + }; + Scene.prototype.addRenderer = function (renderer) { + this._renderers.push(renderer); + this._renderers.sort(); + renderer.onAddedToScene(this); + return renderer; + }; + Scene.prototype.getRenderer = function (type) { + for (var i = 0; i < this._renderers.length; i++) { + if (this._renderers[i] instanceof type) + return this._renderers[i]; } - var bounds = this.entity.getBounds(); - var renderbaleBounds = new Rectangle(bounds.x, bounds.y, bounds.width, bounds.height); - var width = renderbaleBounds.width / this.entity.scale.x; - var height = renderbaleBounds.height / this.entity.scale.y; - if (this instanceof BoxCollider) { - var boxCollider = this; - boxCollider.width = width; - boxCollider.height = height; - this.localOffset = Vector2.subtract(renderbaleBounds.center, this.entity.position); + return null; + }; + Scene.prototype.removeRenderer = function (renderer) { + if (!this._renderers.contains(renderer)) + return; + this._renderers.remove(renderer); + renderer.unload(); + }; + Scene.prototype.addPostProcessor = function (postProcessor) { + this._postProcessors.push(postProcessor); + this._postProcessors.sort(); + postProcessor.onAddedToScene(this); + if (this._didSceneBegin) { + postProcessor.onSceneBackBufferSizeChanged(this.stage.stageWidth, this.stage.stageHeight); } - } - this._isParentEntityAddedToScene = true; - this.registerColliderWithPhysicsSystem(); - }; - Collider.prototype.onRemovedFromEntity = function () { - this.unregisterColliderWithPhysicsSystem(); - this._isParentEntityAddedToScene = false; - }; - Collider.prototype.onEnabled = function () { - this.registerColliderWithPhysicsSystem(); - }; - Collider.prototype.onDisabled = function () { - this.unregisterColliderWithPhysicsSystem(); - }; - Collider.prototype.onEntityTransformChanged = function (comp) { - if (this._isColliderRegistered) - Physics.updateCollider(this); - }; - return Collider; -}(Component)); -var BoxCollider = (function (_super) { - __extends(BoxCollider, _super); - function BoxCollider() { - var _this = _super.call(this) || this; - _this.shape = new Box(1, 1); - _this._colliderRequiresAutoSizing = true; - return _this; - } - Object.defineProperty(BoxCollider.prototype, "width", { - get: function () { - return this.shape.width; - }, - set: function (value) { - this.setWidth(value); - }, - enumerable: true, - configurable: true - }); - BoxCollider.prototype.setWidth = function (width) { - this._colliderRequiresAutoSizing = false; - var box = this.shape; - if (width != box.width) { - box.updateBox(width, box.height); - if (this.entity && this._isParentEntityAddedToScene) - Physics.updateCollider(this); - } - return this; - }; - Object.defineProperty(BoxCollider.prototype, "height", { - get: function () { - return this.shape.height; - }, - set: function (value) { - this.setHeight(value); - }, - enumerable: true, - configurable: true - }); - BoxCollider.prototype.setHeight = function (height) { - this._colliderRequiresAutoSizing = false; - var box = this.shape; - if (height != box.height) { - box.updateBox(box.width, height); - if (this.entity && this._isParentEntityAddedToScene) - Physics.updateCollider(this); - } - }; - BoxCollider.prototype.setSize = function (width, height) { - this._colliderRequiresAutoSizing = false; - var box = this.shape; - if (width != box.width || height != box.height) { - box.updateBox(width, height); - if (this.entity && this._isParentEntityAddedToScene) - Physics.updateCollider(this); - } - return this; - }; - return BoxCollider; -}(Collider)); -var EntitySystem = (function () { - function EntitySystem(matcher) { - this._entities = []; - this._matcher = matcher ? matcher : Matcher.empty(); - } - Object.defineProperty(EntitySystem.prototype, "matcher", { - get: function () { - return this._matcher; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(EntitySystem.prototype, "scene", { - get: function () { - return this._scene; - }, - set: function (value) { - this._scene = value; - this._entities = []; - }, - enumerable: true, - configurable: true - }); - EntitySystem.prototype.initialize = function () { - }; - EntitySystem.prototype.onChanged = function (entity) { - var contains = this._entities.contains(entity); - var interest = this._matcher.IsIntersted(entity); - if (interest && !contains) - this.add(entity); - else if (!interest && contains) - this.remove(entity); - }; - EntitySystem.prototype.add = function (entity) { - this._entities.push(entity); - this.onAdded(entity); - }; - EntitySystem.prototype.onAdded = function (entity) { - }; - EntitySystem.prototype.remove = function (entity) { - this._entities.remove(entity); - this.onRemoved(entity); - }; - EntitySystem.prototype.onRemoved = function (entity) { - }; - EntitySystem.prototype.update = function () { - this.begin(); - this.process(this._entities); - }; - EntitySystem.prototype.lateUpdate = function () { - this.lateProcess(this._entities); - this.end(); - }; - EntitySystem.prototype.begin = function () { - }; - EntitySystem.prototype.process = function (entities) { - }; - EntitySystem.prototype.lateProcess = function (entities) { - }; - EntitySystem.prototype.end = function () { - }; - return EntitySystem; -}()); -var EntityProcessingSystem = (function (_super) { - __extends(EntityProcessingSystem, _super); - function EntityProcessingSystem(matcher) { - return _super.call(this, matcher) || this; - } - EntityProcessingSystem.prototype.lateProcessEntity = function (entity) { - }; - EntityProcessingSystem.prototype.process = function (entities) { - var _this = this; - entities.forEach(function (entity) { return _this.processEntity(entity); }); - }; - EntityProcessingSystem.prototype.lateProcess = function (entities) { - var _this = this; - entities.forEach(function (entity) { return _this.lateProcessEntity(entity); }); - }; - return EntityProcessingSystem; -}(EntitySystem)); -var PassiveSystem = (function (_super) { - __extends(PassiveSystem, _super); - function PassiveSystem() { - return _super !== null && _super.apply(this, arguments) || this; - } - PassiveSystem.prototype.onChanged = function (entity) { - }; - PassiveSystem.prototype.process = function (entities) { - this.begin(); - this.end(); - }; - return PassiveSystem; -}(EntitySystem)); -var ProcessingSystem = (function (_super) { - __extends(ProcessingSystem, _super); - function ProcessingSystem() { - return _super !== null && _super.apply(this, arguments) || this; - } - ProcessingSystem.prototype.onChanged = function (entity) { - }; - ProcessingSystem.prototype.process = function (entities) { - this.begin(); - this.processSystem(); - this.end(); - }; - return ProcessingSystem; -}(EntitySystem)); -var BitSet = (function () { - function BitSet(nbits) { - if (nbits === void 0) { nbits = 64; } - var length = nbits >> 6; - if ((nbits & BitSet.LONG_MASK) != 0) - length++; - this._bits = new Array(length); - } - BitSet.prototype.and = function (bs) { - var max = Math.min(this._bits.length, bs._bits.length); - var i; - for (var i_1 = 0; i_1 < max; ++i_1) - this._bits[i_1] &= bs._bits[i_1]; - while (i < this._bits.length) - this._bits[i++] = 0; - }; - BitSet.prototype.andNot = function (bs) { - var i = Math.min(this._bits.length, bs._bits.length); - while (--i >= 0) - this._bits[i] &= ~bs._bits[i]; - }; - BitSet.prototype.cardinality = function () { - var card = 0; - for (var i = this._bits.length - 1; i >= 0; i--) { - var a = this._bits[i]; - if (a == 0) - continue; - if (a == -1) { - card += 64; - continue; + return postProcessor; + }; + Scene.prototype.getPostProcessor = function (type) { + for (var i = 0; i < this._postProcessors.length; i++) { + if (this._postProcessors[i] instanceof type) + return this._postProcessors[i]; } - a = ((a >> 1) & 0x5555555555555555) + (a & 0x5555555555555555); - a = ((a >> 2) & 0x3333333333333333) + (a & 0x3333333333333333); - var b = ((a >> 32) + a); - b = ((b >> 4) & 0x0f0f0f0f) + (b & 0x0f0f0f0f); - b = ((b >> 8) & 0x00ff00ff) + (b & 0x00ff00ff); - card += ((b >> 16) & 0x0000ffff) + (b & 0x0000ffff); - } - return card; - }; - BitSet.prototype.clear = function (pos) { - if (pos != undefined) { - var offset = pos >> 6; - this.ensure(offset); - this._bits[offset] &= ~(1 << pos); - } - else { - for (var i = 0; i < this._bits.length; i++) - this._bits[i] = 0; - } - }; - BitSet.prototype.ensure = function (lastElt) { - if (lastElt >= this._bits.length) { - var nd = new Number[lastElt + 1]; - nd = this._bits.copyWithin(0, 0, this._bits.length); - this._bits = nd; - } - }; - BitSet.prototype.get = function (pos) { - var offset = pos >> 6; - if (offset >= this._bits.length) - return false; - return (this._bits[offset] & (1 << pos)) != 0; - }; - BitSet.prototype.intersects = function (set) { - var i = Math.min(this._bits.length, set._bits.length); - while (--i >= 0) { - if ((this._bits[i] & set._bits[i]) != 0) - return true; - } - return false; - }; - BitSet.prototype.isEmpty = function () { - for (var i = this._bits.length - 1; i >= 0; i--) { - if (this._bits[i]) - return false; - } - return true; - }; - BitSet.prototype.nextSetBit = function (from) { - var offset = from >> 6; - var mask = 1 << from; - while (offset < this._bits.length) { - var h = this._bits[offset]; - do { - if ((h & mask) != 0) - return from; - mask <<= 1; - from++; - } while (mask != 0); - mask = 1; - offset++; - } - return -1; - }; - BitSet.prototype.set = function (pos, value) { - if (value === void 0) { value = true; } - if (value) { - var offset = pos >> 6; - this.ensure(offset); - this._bits[offset] |= 1 << pos; - } - else { - this.clear(pos); - } - }; - BitSet.LONG_MASK = 0x3f; - return BitSet; -}()); -var ComponentList = (function () { - function ComponentList(entity) { - this._components = []; - this._componentsToAdd = []; - this._componentsToRemove = []; - this._tempBufferList = []; - this._entity = entity; - } - Object.defineProperty(ComponentList.prototype, "count", { - get: function () { - return this._components.length; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(ComponentList.prototype, "buffer", { - get: function () { - return this._components; - }, - enumerable: true, - configurable: true - }); - ComponentList.prototype.add = function (component) { - this._componentsToAdd.push(component); - }; - ComponentList.prototype.remove = function (component) { - if (this._componentsToAdd.contains(component)) { - this._componentsToAdd.remove(component); - return; - } - this._componentsToRemove.push(component); - }; - ComponentList.prototype.removeAllComponents = function () { - for (var i = 0; i < this._components.length; i++) { - this.handleRemove(this._components[i]); - } - this._components.length = 0; - this._componentsToAdd.length = 0; - this._componentsToRemove.length = 0; - }; - ComponentList.prototype.deregisterAllComponents = function () { - for (var i = 0; i < this._components.length; i++) { - var component = this._components[i]; - if (component instanceof RenderableComponent) - this._entity.scene.renderableComponents.remove(component); - this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component), false); - this._entity.scene.entityProcessors.onComponentRemoved(this._entity); - } - }; - ComponentList.prototype.registerAllComponents = function () { - for (var i = 0; i < this._components.length; i++) { - var component = this._components[i]; - if (component instanceof RenderableComponent) - this._entity.scene.renderableComponents.add(component); - this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component)); - this._entity.scene.entityProcessors.onComponentAdded(this._entity); - } - }; - ComponentList.prototype.updateLists = function () { - if (this._componentsToRemove.length > 0) { - for (var i = 0; i < this._componentsToRemove.length; i++) { - this.handleRemove(this._componentsToRemove[i]); - this._components.remove(this._componentsToRemove[i]); + return null; + }; + Scene.prototype.removePostProcessor = function (postProcessor) { + if (!this._postProcessors.contains(postProcessor)) + return; + this._postProcessors.remove(postProcessor); + postProcessor.unload(); + }; + Scene.prototype.createEntity = function (name) { + var entity = new es.Entity(name); + return this.addEntity(entity); + }; + Scene.prototype.addEntity = function (entity) { + if (this.entities.buffer.contains(entity)) + console.warn("You are attempting to add the same entity to a scene twice: " + entity); + this.entities.add(entity); + entity.scene = this; + for (var i = 0; i < entity.transform.childCount; i++) + this.addEntity(entity.transform.getChild(i).entity); + return entity; + }; + Scene.prototype.destroyAllEntities = function () { + for (var i = 0; i < this.entities.count; i++) { + this.entities.buffer[i].destroy(); } - this._componentsToRemove.length = 0; + }; + Scene.prototype.findEntity = function (name) { + return this.entities.findEntity(name); + }; + Scene.prototype.findEntitiesWithTag = function (tag) { + return this.entities.entitiesWithTag(tag); + }; + Scene.prototype.entitiesOfType = function (type) { + return this.entities.entitiesOfType(type); + }; + Scene.prototype.findComponentOfType = function (type) { + return this.entities.findComponentOfType(type); + }; + Scene.prototype.findComponentsOfType = function (type) { + return this.entities.findComponentsOfType(type); + }; + Scene.prototype.addEntityProcessor = function (processor) { + processor.scene = this; + this.entityProcessors.add(processor); + return processor; + }; + Scene.prototype.removeEntityProcessor = function (processor) { + this.entityProcessors.remove(processor); + }; + Scene.prototype.getEntityProcessor = function () { + return this.entityProcessors.getProcessor(); + }; + return Scene; + }(egret.DisplayObjectContainer)); + es.Scene = Scene; +})(es || (es = {})); +var transform; +(function (transform) { + var Component; + (function (Component) { + Component[Component["position"] = 0] = "position"; + Component[Component["scale"] = 1] = "scale"; + Component[Component["rotation"] = 2] = "rotation"; + })(Component = transform.Component || (transform.Component = {})); +})(transform || (transform = {})); +var es; +(function (es) { + var HashObject = egret.HashObject; + var DirtyType; + (function (DirtyType) { + DirtyType[DirtyType["clean"] = 0] = "clean"; + DirtyType[DirtyType["positionDirty"] = 1] = "positionDirty"; + DirtyType[DirtyType["scaleDirty"] = 2] = "scaleDirty"; + DirtyType[DirtyType["rotationDirty"] = 3] = "rotationDirty"; + })(DirtyType = es.DirtyType || (es.DirtyType = {})); + var Transform = (function (_super) { + __extends(Transform, _super); + function Transform(entity) { + var _this = _super.call(this) || this; + _this._localTransform = es.Matrix2D.create(); + _this._worldTransform = es.Matrix2D.create().identity(); + _this._rotationMatrix = es.Matrix2D.create(); + _this._translationMatrix = es.Matrix2D.create(); + _this._scaleMatrix = es.Matrix2D.create(); + _this._worldToLocalTransform = es.Matrix2D.create().identity(); + _this._worldInverseTransform = es.Matrix2D.create().identity(); + _this._position = es.Vector2.zero; + _this._scale = es.Vector2.one; + _this._rotation = 0; + _this._localPosition = es.Vector2.zero; + _this._localScale = es.Vector2.one; + _this._localRotation = 0; + _this.entity = entity; + _this.scale = es.Vector2.one; + _this._children = []; + return _this; } - if (this._componentsToAdd.length > 0) { - for (var i = 0, count = this._componentsToAdd.length; i < count; i++) { - var component = this._componentsToAdd[i]; - if (component instanceof RenderableComponent) - this._entity.scene.renderableComponents.add(component); - this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component)); - this._entity.scene.entityProcessors.onComponentAdded(this._entity); - this._components.push(component); - this._tempBufferList.push(component); + Object.defineProperty(Transform.prototype, "childCount", { + get: function () { + return this._children.length; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Transform.prototype, "rotationDegrees", { + get: function () { + return es.MathHelper.toDegrees(this._rotation); + }, + set: function (value) { + this.setRotation(es.MathHelper.toRadians(value)); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Transform.prototype, "localRotationDegrees", { + get: function () { + return es.MathHelper.toDegrees(this._localRotation); + }, + set: function (value) { + this.localRotation = es.MathHelper.toRadians(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Transform.prototype, "localToWorldTransform", { + get: function () { + this.updateTransform(); + return this._worldTransform; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Transform.prototype, "parent", { + get: function () { + return this._parent; + }, + set: function (value) { + this.setParent(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Transform.prototype, "worldToLocalTransform", { + get: function () { + if (this._worldToLocalDirty) { + if (!this.parent) { + this._worldToLocalTransform = es.Matrix2D.create().identity(); + } + else { + this.parent.updateTransform(); + this._worldToLocalTransform = this.parent._worldTransform.invert(); + } + this._worldToLocalDirty = false; + } + return this._worldToLocalTransform; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Transform.prototype, "worldInverseTransform", { + get: function () { + this.updateTransform(); + if (this._worldInverseDirty) { + this._worldInverseTransform = this._worldTransform.invert(); + this._worldInverseDirty = false; + } + return this._worldInverseTransform; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Transform.prototype, "position", { + get: function () { + this.updateTransform(); + if (this._positionDirty) { + if (!this.parent) { + this._position = this._localPosition; + } + else { + this.parent.updateTransform(); + this._position = es.Vector2Ext.transformR(this._localPosition, this.parent._worldTransform); + } + this._positionDirty = false; + } + return this._position; + }, + set: function (value) { + this.setPosition(value.x, value.y); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Transform.prototype, "scale", { + get: function () { + this.updateTransform(); + return this._scale; + }, + set: function (value) { + this.setScale(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Transform.prototype, "rotation", { + get: function () { + this.updateTransform(); + return this._rotation; + }, + set: function (value) { + this.setRotation(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Transform.prototype, "localPosition", { + get: function () { + this.updateTransform(); + return this._localPosition; + }, + set: function (value) { + this.setLocalPosition(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Transform.prototype, "localScale", { + get: function () { + this.updateTransform(); + return this._localScale; + }, + set: function (value) { + this.setLocalScale(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Transform.prototype, "localRotation", { + get: function () { + this.updateTransform(); + return this._localRotation; + }, + set: function (value) { + this.setLocalRotation(value); + }, + enumerable: true, + configurable: true + }); + Transform.prototype.getChild = function (index) { + return this._children[index]; + }; + Transform.prototype.setParent = function (parent) { + if (this._parent.equals(parent)) + return this; + if (!this._parent) { + this._parent._children.remove(this); + this._parent._children.push(this); } - this._componentsToAdd.length = 0; - for (var i = 0; i < this._tempBufferList.length; i++) { - var component = this._tempBufferList[i]; - component.onAddedToEntity(); - if (component.enabled) { - component.onEnabled(); + this._parent = parent; + this.setDirty(DirtyType.positionDirty); + return this; + }; + Transform.prototype.setPosition = function (x, y) { + var position = new es.Vector2(x, y); + if (position.equals(this._position)) + return this; + this._position = position; + if (this.parent) { + this.localPosition = es.Vector2Ext.transformR(this._position, this._worldToLocalTransform); + } + else { + this.localPosition = position; + } + this._positionDirty = false; + return this; + }; + Transform.prototype.setLocalPosition = function (localPosition) { + if (localPosition.equals(this._localPosition)) + return this; + this._localPosition = localPosition; + this._localDirty = this._positionDirty = this._localPositionDirty = this._localRotationDirty = this._localScaleDirty = true; + this.setDirty(DirtyType.positionDirty); + return this; + }; + Transform.prototype.setRotation = function (radians) { + this._rotation = radians; + if (this.parent) { + this.localRotation = this.parent.rotation + radians; + } + else { + this.localRotation = radians; + } + return this; + }; + Transform.prototype.setRotationDegrees = function (degrees) { + return this.setRotation(es.MathHelper.toRadians(degrees)); + }; + Transform.prototype.lookAt = function (pos) { + var sign = this.position.x > pos.x ? -1 : 1; + var vectorToAlignTo = es.Vector2.normalize(es.Vector2.subtract(this.position, pos)); + this.rotation = sign * Math.acos(es.Vector2.dot(vectorToAlignTo, es.Vector2.unitY)); + }; + Transform.prototype.setLocalRotation = function (radians) { + this._localRotation = radians; + this._localDirty = this._positionDirty = this._localPositionDirty = this._localRotationDirty = this._localScaleDirty = true; + this.setDirty(DirtyType.rotationDirty); + return this; + }; + Transform.prototype.setLocalRotationDegrees = function (degrees) { + return this.setLocalRotation(es.MathHelper.toRadians(degrees)); + }; + Transform.prototype.setScale = function (scale) { + this._scale = scale; + if (this.parent) { + this.localScale = es.Vector2.divide(scale, this.parent._scale); + } + else { + this.localScale = scale; + } + return this; + }; + Transform.prototype.setLocalScale = function (scale) { + this._localScale = scale; + this._localDirty = this._positionDirty = this._localScaleDirty = true; + this.setDirty(DirtyType.scaleDirty); + return this; + }; + Transform.prototype.roundPosition = function () { + this.position = this._position.round(); + }; + Transform.prototype.updateTransform = function () { + if (this.hierarchyDirty != DirtyType.clean) { + if (this.parent) + this.parent.updateTransform(); + if (this._localDirty) { + if (this._localPositionDirty) { + this._translationMatrix = es.Matrix2D.create().translate(this._localPosition.x, this._localPosition.y); + this._localPositionDirty = false; + } + if (this._localRotationDirty) { + this._rotationMatrix = es.Matrix2D.create().rotate(this._localRotation); + this._localRotationDirty = false; + } + if (this._localScaleDirty) { + this._scaleMatrix = es.Matrix2D.create().scale(this._localScale.x, this._localScale.y); + this._localScaleDirty = false; + } + this._localTransform = this._scaleMatrix.multiply(this._rotationMatrix); + this._localTransform = this._localTransform.multiply(this._translationMatrix); + if (!this.parent) { + this._worldTransform = this._localTransform; + this._rotation = this._localRotation; + this._scale = this._localScale; + this._worldInverseDirty = true; + } + this._localDirty = false; + } + if (this.parent) { + this._worldTransform = this._localTransform.multiply(this.parent._worldTransform); + this._rotation = this._localRotation + this.parent._rotation; + this._scale = es.Vector2.multiply(this.parent._scale, this._localScale); + this._worldInverseDirty = true; + } + this._worldToLocalDirty = true; + this._positionDirty = true; + this.hierarchyDirty = DirtyType.clean; + } + }; + Transform.prototype.setDirty = function (dirtyFlagType) { + if ((this.hierarchyDirty & dirtyFlagType) == 0) { + this.hierarchyDirty |= dirtyFlagType; + switch (dirtyFlagType) { + case es.DirtyType.positionDirty: + this.entity.onTransformChanged(transform.Component.position); + break; + case es.DirtyType.rotationDirty: + this.entity.onTransformChanged(transform.Component.rotation); + break; + case es.DirtyType.scaleDirty: + this.entity.onTransformChanged(transform.Component.scale); + break; + } + if (!this._children) + this._children = []; + for (var i = 0; i < this._children.length; i++) + this._children[i].setDirty(dirtyFlagType); + } + }; + Transform.prototype.copyFrom = function (transform) { + this._position = transform.position; + this._localPosition = transform._localPosition; + this._rotation = transform._rotation; + this._localRotation = transform._localRotation; + this._scale = transform._scale; + this._localScale = transform._localScale; + this.setDirty(DirtyType.positionDirty); + this.setDirty(DirtyType.rotationDirty); + this.setDirty(DirtyType.scaleDirty); + }; + Transform.prototype.toString = function () { + return "[Transform: parent: " + this.parent + ", position: " + this.position + ", rotation: " + this.rotation + ",\n scale: " + this.scale + ", localPosition: " + this._localPosition + ", localRotation: " + this._localRotation + ",\n localScale: " + this._localScale + "]"; + }; + Transform.prototype.equals = function (other) { + return other.hashCode == this.hashCode; + }; + return Transform; + }(HashObject)); + es.Transform = Transform; +})(es || (es = {})); +var es; +(function (es) { + var CameraStyle; + (function (CameraStyle) { + CameraStyle[CameraStyle["lockOn"] = 0] = "lockOn"; + CameraStyle[CameraStyle["cameraWindow"] = 1] = "cameraWindow"; + })(CameraStyle = es.CameraStyle || (es.CameraStyle = {})); + var CameraInset = (function () { + function CameraInset() { + this.left = 0; + this.right = 0; + this.top = 0; + this.bottom = 0; + } + return CameraInset; + }()); + es.CameraInset = CameraInset; + var Camera = (function (_super) { + __extends(Camera, _super); + function Camera(targetEntity, cameraStyle) { + if (targetEntity === void 0) { targetEntity = null; } + if (cameraStyle === void 0) { cameraStyle = CameraStyle.lockOn; } + var _this = _super.call(this) || this; + _this._inset = new CameraInset(); + _this._areMatrixedDirty = true; + _this._areBoundsDirty = true; + _this._isProjectionMatrixDirty = true; + _this.followLerp = 0.1; + _this.deadzone = new es.Rectangle(); + _this.focusOffset = es.Vector2.zero; + _this.mapLockEnabled = false; + _this.mapSize = es.Vector2.zero; + _this._desiredPositionDelta = new es.Vector2(); + _this._worldSpaceDeadZone = new es.Rectangle(); + _this._minimumZoom = 0.3; + _this._maximumZoom = 3; + _this._bounds = new es.Rectangle(); + _this._transformMatrix = new es.Matrix2D().identity(); + _this._inverseTransformMatrix = new es.Matrix2D().identity(); + _this._origin = es.Vector2.zero; + _this._targetEntity = targetEntity; + _this._cameraStyle = cameraStyle; + _this.setZoom(0); + return _this; + } + Object.defineProperty(Camera.prototype, "position", { + get: function () { + return this.entity.transform.position; + }, + set: function (value) { + this.entity.transform.position = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Camera.prototype, "rotation", { + get: function () { + return this.entity.transform.rotation; + }, + set: function (value) { + this.entity.transform.rotation = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Camera.prototype, "zoom", { + get: function () { + if (this._zoom == 0) + return 1; + if (this._zoom < 1) + return es.MathHelper.map(this._zoom, this._minimumZoom, 1, -1, 0); + return es.MathHelper.map(this._zoom, 1, this._maximumZoom, 0, 1); + }, + set: function (value) { + this.setZoom(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Camera.prototype, "minimumZoom", { + get: function () { + return this._minimumZoom; + }, + set: function (value) { + this.setMinimumZoom(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Camera.prototype, "maximumZoom", { + get: function () { + return this._maximumZoom; + }, + set: function (value) { + this.setMaximumZoom(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Camera.prototype, "bounds", { + get: function () { + if (this._areMatrixedDirty) + this.updateMatrixes(); + if (this._areBoundsDirty) { + var topLeft = this.screenToWorldPoint(new es.Vector2(this._inset.left, this._inset.top)); + var bottomRight = this.screenToWorldPoint(new es.Vector2(es.Core.graphicsDevice.viewport.width - this._inset.right, es.Core.graphicsDevice.viewport.height - this._inset.bottom)); + if (this.entity.transform.rotation != 0) { + var topRight = this.screenToWorldPoint(new es.Vector2(es.Core.graphicsDevice.viewport.width - this._inset.right, this._inset.top)); + var bottomLeft = this.screenToWorldPoint(new es.Vector2(this._inset.left, es.Core.graphicsDevice.viewport.height - this._inset.bottom)); + var minX = Math.min(topLeft.x, bottomRight.x, topRight.x, bottomLeft.x); + var maxX = Math.max(topLeft.x, bottomRight.x, topRight.x, bottomLeft.x); + var minY = Math.min(topLeft.y, bottomRight.y, topRight.y, bottomLeft.y); + var maxY = Math.max(topLeft.y, bottomRight.y, topRight.y, bottomLeft.y); + this._bounds.location = new es.Vector2(minX, minY); + this._bounds.width = maxX - minX; + this._bounds.height = maxY - minY; + } + else { + this._bounds.location = topLeft; + this._bounds.width = bottomRight.x - topLeft.x; + this._bounds.height = bottomRight.y - topLeft.y; + } + this._areBoundsDirty = false; + } + return this._bounds; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Camera.prototype, "transformMatrix", { + get: function () { + if (this._areMatrixedDirty) + this.updateMatrixes(); + return this._transformMatrix; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Camera.prototype, "inverseTransformMatrix", { + get: function () { + if (this._areMatrixedDirty) + this.updateMatrixes(); + return this._inverseTransformMatrix; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Camera.prototype, "origin", { + get: function () { + return this._origin; + }, + set: function (value) { + if (this._origin != value) { + this._origin = value; + this._areMatrixedDirty = true; + } + }, + enumerable: true, + configurable: true + }); + Camera.prototype.onSceneSizeChanged = function (newWidth, newHeight) { + var oldOrigin = this._origin; + this.origin = new es.Vector2(newWidth / 2, newHeight / 2); + this.entity.transform.position = es.Vector2.add(this.entity.transform.position, es.Vector2.subtract(this._origin, oldOrigin)); + }; + Camera.prototype.setInset = function (left, right, top, bottom) { + this._inset = new CameraInset(); + this._inset.left = left; + this._inset.right = right; + this._inset.top = top; + this._inset.bottom = bottom; + this._areBoundsDirty = true; + return this; + }; + Camera.prototype.setPosition = function (position) { + this.entity.transform.setPosition(position.x, position.y); + return this; + }; + Camera.prototype.setRotation = function (rotation) { + this.entity.transform.setRotation(rotation); + return this; + }; + Camera.prototype.setZoom = function (zoom) { + var newZoom = es.MathHelper.clamp(zoom, -1, 1); + if (newZoom == 0) { + this._zoom = 1; + } + else if (newZoom < 0) { + this._zoom = es.MathHelper.map(newZoom, -1, 0, this._minimumZoom, 1); + } + else { + this._zoom = es.MathHelper.map(newZoom, 0, 1, 1, this._maximumZoom); + } + this._areMatrixedDirty = true; + return this; + }; + Camera.prototype.setMinimumZoom = function (minZoom) { + if (minZoom <= 0) { + console.error("minimumZoom must be greater than zero"); + return; + } + if (this._zoom < minZoom) + this._zoom = this.minimumZoom; + this._minimumZoom = minZoom; + return this; + }; + Camera.prototype.setMaximumZoom = function (maxZoom) { + if (maxZoom <= 0) { + console.error("maximumZoom must be greater than zero"); + return; + } + if (this._zoom > maxZoom) + this._zoom = maxZoom; + this._maximumZoom = maxZoom; + return this; + }; + Camera.prototype.onEntityTransformChanged = function (comp) { + this._areMatrixedDirty = true; + }; + Camera.prototype.zoomIn = function (deltaZoom) { + this.zoom += deltaZoom; + }; + Camera.prototype.zoomOut = function (deltaZoom) { + this.zoom -= deltaZoom; + }; + Camera.prototype.worldToScreenPoint = function (worldPosition) { + this.updateMatrixes(); + worldPosition = es.Vector2.transform(worldPosition, this._transformMatrix); + return worldPosition; + }; + Camera.prototype.screenToWorldPoint = function (screenPosition) { + this.updateMatrixes(); + screenPosition = es.Vector2.transform(screenPosition, this._inverseTransformMatrix); + return screenPosition; + }; + Camera.prototype.mouseToWorldPoint = function () { + return this.screenToWorldPoint(es.Input.touchPosition); + }; + Camera.prototype.onAddedToEntity = function () { + this.follow(this._targetEntity, this._cameraStyle); + }; + Camera.prototype.update = function () { + var halfScreen = es.Vector2.multiply(new es.Vector2(this.bounds.width, this.bounds.height), new es.Vector2(0.5)); + this._worldSpaceDeadZone.x = this.position.x - halfScreen.x * es.Core.scene.scaleX + this.deadzone.x + this.focusOffset.x; + this._worldSpaceDeadZone.y = this.position.y - halfScreen.y * es.Core.scene.scaleY + this.deadzone.y + this.focusOffset.y; + this._worldSpaceDeadZone.width = this.deadzone.width; + this._worldSpaceDeadZone.height = this.deadzone.height; + if (this._targetEntity) + this.updateFollow(); + this.position = es.Vector2.lerp(this.position, es.Vector2.add(this.position, this._desiredPositionDelta), this.followLerp); + this.entity.transform.roundPosition(); + if (this.mapLockEnabled) { + this.position = this.clampToMapSize(this.position); + this.entity.transform.roundPosition(); + } + }; + Camera.prototype.clampToMapSize = function (position) { + var halfScreen = es.Vector2.multiply(new es.Vector2(this.bounds.width, this.bounds.height), new es.Vector2(0.5)); + var cameraMax = new es.Vector2(this.mapSize.x - halfScreen.x, this.mapSize.y - halfScreen.y); + return es.Vector2.clamp(position, halfScreen, cameraMax); + }; + Camera.prototype.updateFollow = function () { + this._desiredPositionDelta.x = this._desiredPositionDelta.y = 0; + if (this._cameraStyle == CameraStyle.lockOn) { + var targetX = this._targetEntity.transform.position.x; + var targetY = this._targetEntity.transform.position.y; + if (this._worldSpaceDeadZone.x > targetX) + this._desiredPositionDelta.x = targetX - this._worldSpaceDeadZone.x; + else if (this._worldSpaceDeadZone.x < targetX) + this._desiredPositionDelta.x = targetX - this._worldSpaceDeadZone.x; + if (this._worldSpaceDeadZone.y < targetY) + this._desiredPositionDelta.y = targetY - this._worldSpaceDeadZone.y; + else if (this._worldSpaceDeadZone.y > targetY) + this._desiredPositionDelta.y = targetY - this._worldSpaceDeadZone.y; + } + else { + if (!this._targetCollider) { + this._targetCollider = this._targetEntity.getComponent(es.Collider); + if (!this._targetCollider) + return; + } + var targetBounds = this._targetEntity.getComponent(es.Collider).bounds; + if (!this._worldSpaceDeadZone.containsRect(targetBounds)) { + if (this._worldSpaceDeadZone.left > targetBounds.left) + this._desiredPositionDelta.x = targetBounds.left - this._worldSpaceDeadZone.left; + else if (this._worldSpaceDeadZone.right < targetBounds.right) + this._desiredPositionDelta.x = targetBounds.right - this._worldSpaceDeadZone.right; + if (this._worldSpaceDeadZone.bottom < targetBounds.bottom) + this._desiredPositionDelta.y = targetBounds.bottom - this._worldSpaceDeadZone.bottom; + else if (this._worldSpaceDeadZone.top > targetBounds.top) + this._desiredPositionDelta.y = targetBounds.top - this._worldSpaceDeadZone.top; } } - this._tempBufferList.length = 0; + }; + Camera.prototype.follow = function (targetEntity, cameraStyle) { + if (cameraStyle === void 0) { cameraStyle = CameraStyle.cameraWindow; } + this._targetEntity = targetEntity; + this._cameraStyle = cameraStyle; + switch (this._cameraStyle) { + case CameraStyle.cameraWindow: + var w = this.bounds.width / 6; + var h = this.bounds.height / 3; + this.deadzone = new es.Rectangle((this.bounds.width - w) / 2, (this.bounds.height - h) / 2, w, h); + break; + case CameraStyle.lockOn: + this.deadzone = new es.Rectangle(this.bounds.width / 2, this.bounds.height / 2, 10, 10); + break; + } + }; + Camera.prototype.setCenteredDeadzone = function (width, height) { + this.deadzone = new es.Rectangle((this.bounds.width - width) / 2, (this.bounds.height - height) / 2, width, height); + }; + Camera.prototype.updateMatrixes = function () { + if (!this._areMatrixedDirty) + return; + var tempMat; + this._transformMatrix = es.Matrix2D.create().translate(-this.entity.transform.position.x, -this.entity.transform.position.y); + if (this._zoom != 1) { + tempMat = es.Matrix2D.create().scale(this._zoom, this._zoom); + this._transformMatrix = this._transformMatrix.multiply(tempMat); + } + if (this.entity.transform.rotation != 0) { + tempMat = es.Matrix2D.create().rotate(this.entity.transform.rotation); + this._transformMatrix = this._transformMatrix.multiply(tempMat); + } + tempMat = es.Matrix2D.create().translate(this._origin.x, this._origin.y); + this._transformMatrix = this._transformMatrix.multiply(tempMat); + this._inverseTransformMatrix = this._transformMatrix.invert(); + this._areBoundsDirty = true; + this._areMatrixedDirty = false; + }; + return Camera; + }(es.Component)); + es.Camera = Camera; +})(es || (es = {})); +var es; +(function (es) { + var ComponentPool = (function () { + function ComponentPool(typeClass) { + this._type = typeClass; + this._cache = []; } - }; - ComponentList.prototype.onEntityTransformChanged = function (comp) { - for (var i = 0; i < this._components.length; i++) { - if (this._components[i].enabled) - this._components[i].onEntityTransformChanged(comp); + ComponentPool.prototype.obtain = function () { + try { + return this._cache.length > 0 ? this._cache.shift() : new this._type(); + } + catch (err) { + throw new Error(this._type + err); + } + }; + ComponentPool.prototype.free = function (component) { + component.reset(); + this._cache.push(component); + }; + return ComponentPool; + }()); + es.ComponentPool = ComponentPool; +})(es || (es = {})); +var es; +(function (es) { + var IUpdatableComparer = (function () { + function IUpdatableComparer() { } - for (var i = 0; i < this._componentsToAdd.length; i++) { - if (this._componentsToAdd[i].enabled) - this._componentsToAdd[i].onEntityTransformChanged(comp); + IUpdatableComparer.prototype.compare = function (a, b) { + return a.updateOrder - b.updateOrder; + }; + return IUpdatableComparer; + }()); + es.IUpdatableComparer = IUpdatableComparer; +})(es || (es = {})); +var es; +(function (es) { + var PooledComponent = (function (_super) { + __extends(PooledComponent, _super); + function PooledComponent() { + return _super !== null && _super.apply(this, arguments) || this; } - }; - ComponentList.prototype.handleRemove = function (component) { - if (component instanceof RenderableComponent) - this._entity.scene.renderableComponents.remove(component); - this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component), false); - this._entity.scene.entityProcessors.onComponentRemoved(this._entity); - component.onRemovedFromEntity(); - component.entity = null; - }; - ComponentList.prototype.getComponent = function (type, onlyReturnInitializedComponents) { - for (var i = 0; i < this._components.length; i++) { - var component = this._components[i]; - if (component instanceof type) - return component; + return PooledComponent; + }(es.Component)); + es.PooledComponent = PooledComponent; +})(es || (es = {})); +var es; +(function (es) { + var RenderableComponent = (function (_super) { + __extends(RenderableComponent, _super); + function RenderableComponent() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.displayObject = new egret.DisplayObject(); + _this.color = 0x000000; + _this._areBoundsDirty = true; + _this._localOffset = es.Vector2.zero; + _this._renderLayer = 0; + _this._bounds = new es.Rectangle(); + return _this; } - if (!onlyReturnInitializedComponents) { - for (var i = 0; i < this._componentsToAdd.length; i++) { - var component = this._componentsToAdd[i]; + Object.defineProperty(RenderableComponent.prototype, "width", { + get: function () { + return this.bounds.width; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(RenderableComponent.prototype, "height", { + get: function () { + return this.bounds.height; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(RenderableComponent.prototype, "localOffset", { + get: function () { + return this._localOffset; + }, + set: function (value) { + this.setLocalOffset(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(RenderableComponent.prototype, "renderLayer", { + get: function () { + return this._renderLayer; + }, + set: function (value) { + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(RenderableComponent.prototype, "bounds", { + get: function () { + if (this._areBoundsDirty) { + this._bounds.calculateBounds(this.entity.transform.position, this._localOffset, es.Vector2.zero, this.entity.transform.scale, this.entity.transform.rotation, this.width, this.height); + this._areBoundsDirty = false; + } + return this._bounds; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(RenderableComponent.prototype, "isVisible", { + get: function () { + return this._isVisible; + }, + set: function (value) { + if (this._isVisible != value) { + this._isVisible = value; + if (this._isVisible) + this.onBecameVisible(); + else + this.onBecameInvisible(); + } + }, + enumerable: true, + configurable: true + }); + RenderableComponent.prototype.onEntityTransformChanged = function (comp) { + this._areBoundsDirty = true; + }; + RenderableComponent.prototype.isVisibleFromCamera = function (camera) { + this.isVisible = camera.bounds.intersects(this.bounds); + return this.isVisible; + }; + RenderableComponent.prototype.setRenderLayer = function (renderLayer) { + if (renderLayer != this._renderLayer) { + var oldRenderLayer = this._renderLayer; + this._renderLayer = renderLayer; + if (this.entity && this.entity.scene) + this.entity.scene.renderableComponents.updateRenderableRenderLayer(this, oldRenderLayer, this._renderLayer); + } + return this; + }; + RenderableComponent.prototype.setColor = function (color) { + this.color = color; + return this; + }; + RenderableComponent.prototype.setLocalOffset = function (offset) { + if (this._localOffset != offset) { + this._localOffset = offset; + } + return this; + }; + RenderableComponent.prototype.sync = function (camera) { + this.displayObject.x = this.entity.position.x + this.localOffset.x - camera.position.x + camera.origin.x; + this.displayObject.y = this.entity.position.y + this.localOffset.y - camera.position.y + camera.origin.y; + this.displayObject.scaleX = this.entity.scale.x; + this.displayObject.scaleY = this.entity.scale.y; + this.displayObject.rotation = this.entity.rotation; + }; + RenderableComponent.prototype.toString = function () { + return "[RenderableComponent] renderLayer: " + this.renderLayer; + }; + RenderableComponent.prototype.onBecameVisible = function () { + this.displayObject.visible = this.isVisible; + }; + RenderableComponent.prototype.onBecameInvisible = function () { + this.displayObject.visible = this.isVisible; + }; + return RenderableComponent; + }(es.Component)); + es.RenderableComponent = RenderableComponent; +})(es || (es = {})); +var es; +(function (es) { + var Mesh = (function (_super) { + __extends(Mesh, _super); + function Mesh() { + var _this = _super.call(this) || this; + _this._mesh = new egret.Mesh(); + return _this; + } + Mesh.prototype.setTexture = function (texture) { + this._mesh.texture = texture; + this._mesh.$renderNode = new egret.sys.RenderNode(); + return this; + }; + Mesh.prototype.reset = function () { + }; + Mesh.prototype.render = function (camera) { + }; + return Mesh; + }(es.RenderableComponent)); + es.Mesh = Mesh; +})(es || (es = {})); +var es; +(function (es) { + var Bitmap = egret.Bitmap; + var SpriteRenderer = (function (_super) { + __extends(SpriteRenderer, _super); + function SpriteRenderer(sprite) { + if (sprite === void 0) { sprite = null; } + var _this = _super.call(this) || this; + if (sprite instanceof es.Sprite) + _this.setSprite(sprite); + else if (sprite instanceof egret.Texture) + _this.setSprite(new es.Sprite(sprite)); + return _this; + } + Object.defineProperty(SpriteRenderer.prototype, "bounds", { + get: function () { + 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; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(SpriteRenderer.prototype, "originNormalized", { + get: function () { + return new es.Vector2(this._origin.x / this.width * this.entity.transform.scale.x, this._origin.y / this.height * this.entity.transform.scale.y); + }, + set: function (value) { + this.setOrigin(new es.Vector2(value.x * this.width / this.entity.transform.scale.x, value.y * this.height / this.entity.transform.scale.y)); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(SpriteRenderer.prototype, "origin", { + get: function () { + return this._origin; + }, + set: function (value) { + this.setOrigin(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(SpriteRenderer.prototype, "sprite", { + get: function () { + return this._sprite; + }, + set: function (value) { + this.setSprite(value); + }, + enumerable: true, + configurable: true + }); + SpriteRenderer.prototype.setSprite = function (sprite) { + 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; + }; + SpriteRenderer.prototype.setOrigin = function (origin) { + if (this._origin != origin) { + this._origin = origin; + this.displayObject.anchorOffsetX = this._origin.x; + this.displayObject.anchorOffsetY = this._origin.y; + this._areBoundsDirty = true; + } + return this; + }; + SpriteRenderer.prototype.setOriginNormalized = function (value) { + this.setOrigin(new es.Vector2(value.x * this.width / this.entity.transform.scale.x, value.y * this.height / this.entity.transform.scale.y)); + return this; + }; + SpriteRenderer.prototype.render = function (camera) { + this.sync(camera); + this.displayObject.x = this.entity.position.x - this.origin.x + this.localOffset.x - camera.position.x + camera.origin.x; + this.displayObject.y = this.entity.position.y - this.origin.y + this.localOffset.y - camera.position.y + camera.origin.y; + }; + return SpriteRenderer; + }(es.RenderableComponent)); + es.SpriteRenderer = SpriteRenderer; +})(es || (es = {})); +var es; +(function (es) { + var TiledSpriteRenderer = (function (_super) { + __extends(TiledSpriteRenderer, _super); + function TiledSpriteRenderer(sprite) { + var _this = _super.call(this, sprite) || this; + _this._sourceRect = new es.Rectangle(); + _this._textureScale = es.Vector2.one; + _this._inverseTexScale = es.Vector2.one; + _this._sourceRect = sprite.sourceRect; + var bitmap = _this.displayObject; + bitmap.$fillMode = egret.BitmapFillMode.REPEAT; + return _this; + } + Object.defineProperty(TiledSpriteRenderer.prototype, "bounds", { + get: function () { + 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; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(TiledSpriteRenderer.prototype, "scrollX", { + get: function () { + return this._sourceRect.x; + }, + set: function (value) { + this._sourceRect.x = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(TiledSpriteRenderer.prototype, "scrollY", { + get: function () { + return this._sourceRect.y; + }, + set: function (value) { + this._sourceRect.y = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(TiledSpriteRenderer.prototype, "textureScale", { + get: function () { + return this._textureScale; + }, + set: function (value) { + this._textureScale = value; + this._inverseTexScale = new es.Vector2(1 / this._textureScale.x, 1 / this._textureScale.y); + this._sourceRect.width = this._sprite.sourceRect.width * this._inverseTexScale.x; + this._sourceRect.height = this._sprite.sourceRect.height * this._inverseTexScale.y; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(TiledSpriteRenderer.prototype, "width", { + get: function () { + return this._sourceRect.width; + }, + set: function (value) { + this._areBoundsDirty = true; + this._sourceRect.width = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(TiledSpriteRenderer.prototype, "height", { + get: function () { + return this._sourceRect.height; + }, + set: function (value) { + this._areBoundsDirty = true; + this._sourceRect.height = value; + }, + enumerable: true, + configurable: true + }); + TiledSpriteRenderer.prototype.render = function (camera) { + var bitmap = this.displayObject; + bitmap.width = this.width; + bitmap.height = this.height; + _super.prototype.render.call(this, camera); + }; + return TiledSpriteRenderer; + }(es.SpriteRenderer)); + es.TiledSpriteRenderer = TiledSpriteRenderer; +})(es || (es = {})); +var es; +(function (es) { + var ScrollingSpriteRenderer = (function (_super) { + __extends(ScrollingSpriteRenderer, _super); + function ScrollingSpriteRenderer(sprite) { + var _this = _super.call(this, sprite) || this; + _this.scrollSpeedX = 15; + _this.scroolSpeedY = 0; + _this._scrollX = 0; + _this._scrollY = 0; + return _this; + } + Object.defineProperty(ScrollingSpriteRenderer.prototype, "textureScale", { + get: function () { + return this._textureScale; + }, + set: function (value) { + this._textureScale = value; + this._inverseTexScale = new es.Vector2(1 / this._textureScale.x, 1 / this._textureScale.y); + }, + enumerable: true, + configurable: true + }); + ScrollingSpriteRenderer.prototype.update = function () { + this._scrollX += this.scrollSpeedX * es.Time.deltaTime; + this._scrollY += this.scroolSpeedY * es.Time.deltaTime; + this._sourceRect.x = this._scrollX; + this._sourceRect.y = this._scrollY; + }; + return ScrollingSpriteRenderer; + }(es.TiledSpriteRenderer)); + es.ScrollingSpriteRenderer = ScrollingSpriteRenderer; +})(es || (es = {})); +var es; +(function (es) { + var Sprite = (function () { + function Sprite(texture, sourceRect, origin) { + if (sourceRect === void 0) { sourceRect = new es.Rectangle(0, 0, texture.textureWidth, texture.textureHeight); } + if (origin === void 0) { origin = sourceRect.getHalfSize(); } + this.uvs = new es.Rectangle(); + this.texture2D = texture; + this.sourceRect = sourceRect; + this.center = new es.Vector2(sourceRect.width * 0.5, sourceRect.height * 0.5); + this.origin = origin; + var inverseTexW = 1 / texture.textureWidth; + var 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; + } + return Sprite; + }()); + es.Sprite = Sprite; +})(es || (es = {})); +var es; +(function (es) { + var SpriteAnimation = (function () { + function SpriteAnimation(sprites, frameRate) { + this.sprites = sprites; + this.frameRate = frameRate; + } + return SpriteAnimation; + }()); + es.SpriteAnimation = SpriteAnimation; +})(es || (es = {})); +var es; +(function (es) { + var LoopMode; + (function (LoopMode) { + LoopMode[LoopMode["loop"] = 0] = "loop"; + LoopMode[LoopMode["once"] = 1] = "once"; + LoopMode[LoopMode["clampForever"] = 2] = "clampForever"; + LoopMode[LoopMode["pingPong"] = 3] = "pingPong"; + LoopMode[LoopMode["pingPongOnce"] = 4] = "pingPongOnce"; + })(LoopMode = es.LoopMode || (es.LoopMode = {})); + var State; + (function (State) { + State[State["none"] = 0] = "none"; + State[State["running"] = 1] = "running"; + State[State["paused"] = 2] = "paused"; + State[State["completed"] = 3] = "completed"; + })(State = es.State || (es.State = {})); + var SpriteAnimator = (function (_super) { + __extends(SpriteAnimator, _super); + function SpriteAnimator(sprite) { + var _this = _super.call(this, sprite) || this; + _this.speed = 1; + _this.animationState = State.none; + _this._elapsedTime = 0; + _this._animations = new Map(); + return _this; + } + Object.defineProperty(SpriteAnimator.prototype, "isRunning", { + get: function () { + return this.animationState == State.running; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(SpriteAnimator.prototype, "animations", { + get: function () { + return this._animations; + }, + enumerable: true, + configurable: true + }); + SpriteAnimator.prototype.update = function () { + if (this.animationState != State.running || !this.currentAnimation) + return; + var animation = this.currentAnimation; + var secondsPerFrame = 1 / (animation.frameRate * this.speed); + var iterationDuration = secondsPerFrame * animation.sprites.length; + this._elapsedTime += es.Time.deltaTime; + var 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; + } + var i = Math.floor(time / secondsPerFrame); + var n = animation.sprites.length; + if (n > 2 && (this._loopMode == LoopMode.pingPong || this._loopMode == LoopMode.pingPongOnce)) { + var maxIndex = n - 1; + this.currentFrame = maxIndex - Math.abs(maxIndex - i % (maxIndex * 2)); + } + else { + this.currentFrame = i % n; + } + this.sprite = animation.sprites[this.currentFrame]; + }; + SpriteAnimator.prototype.addAnimation = function (name, animation) { + if (!this.sprite && animation.sprites.length > 0) + this.setSprite(animation.sprites[0]); + this._animations[name] = animation; + return this; + }; + SpriteAnimator.prototype.play = function (name, loopMode) { + if (loopMode === void 0) { 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; + }; + SpriteAnimator.prototype.isAnimationActive = function (name) { + return this.currentAnimation && this.currentAnimationName == name; + }; + SpriteAnimator.prototype.pause = function () { + this.animationState = State.paused; + }; + SpriteAnimator.prototype.unPause = function () { + this.animationState = State.running; + }; + SpriteAnimator.prototype.stop = function () { + this.currentAnimation = null; + this.currentAnimationName = null; + this.currentFrame = 0; + this.animationState = State.none; + }; + return SpriteAnimator; + }(es.SpriteRenderer)); + es.SpriteAnimator = SpriteAnimator; +})(es || (es = {})); +var es; +(function (es) { + var Mover = (function (_super) { + __extends(Mover, _super); + function Mover() { + return _super !== null && _super.apply(this, arguments) || this; + } + Mover.prototype.onAddedToEntity = function () { + this._triggerHelper = new es.ColliderTriggerHelper(this.entity); + }; + Mover.prototype.calculateMovement = function (motion, collisionResult) { + if (!this.entity.getComponent(es.Collider) || !this._triggerHelper) { + return false; + } + var colliders = this.entity.getComponents(es.Collider); + for (var i = 0; i < colliders.length; i++) { + var collider = colliders[i]; + if (collider.isTrigger) + continue; + var bounds = collider.bounds; + bounds.x += motion.x; + bounds.y += motion.y; + var neighbors = es.Physics.boxcastBroadphaseExcludingSelf(collider, bounds, collider.collidesWithLayers); + for (var j = 0; j < neighbors.length; j++) { + var neighbor = neighbors[j]; + if (neighbor.isTrigger) + continue; + var _internalcollisionResult = new es.CollisionResult(); + if (collider.collidesWith(neighbor, motion, _internalcollisionResult)) { + motion = motion.subtract(_internalcollisionResult.minimumTranslationVector); + if (_internalcollisionResult.collider != null) { + collisionResult = _internalcollisionResult; + } + } + } + } + es.ListPool.free(colliders); + return collisionResult.collider != null; + }; + Mover.prototype.applyMovement = function (motion) { + this.entity.position = es.Vector2.add(this.entity.position, motion); + if (this._triggerHelper) + this._triggerHelper.update(); + }; + Mover.prototype.move = function (motion, collisionResult) { + this.calculateMovement(motion, collisionResult); + this.applyMovement(motion); + return collisionResult.collider != null; + }; + return Mover; + }(es.Component)); + es.Mover = Mover; +})(es || (es = {})); +var es; +(function (es) { + var ProjectileMover = (function (_super) { + __extends(ProjectileMover, _super); + function ProjectileMover() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this._tempTriggerList = []; + return _this; + } + ProjectileMover.prototype.onAddedToEntity = function () { + this._collider = this.entity.getComponent(es.Collider); + if (!this._collider) + console.warn("ProjectileMover has no Collider. ProjectilMover requires a Collider!"); + }; + ProjectileMover.prototype.move = function (motion) { + if (!this._collider) + return false; + var didCollide = false; + this.entity.position = es.Vector2.add(this.entity.position, motion); + var neighbors = es.Physics.boxcastBroadphase(this._collider.bounds, this._collider.collidesWithLayers); + for (var i = 0; i < neighbors.length; i++) { + var neighbor = neighbors[i]; + if (this._collider.overlaps(neighbor) && neighbor.enabled) { + didCollide = true; + this.notifyTriggerListeners(this._collider, neighbor); + } + } + return didCollide; + }; + ProjectileMover.prototype.notifyTriggerListeners = function (self, other) { + other.entity.getComponents("ITriggerListener", this._tempTriggerList); + for (var i = 0; i < this._tempTriggerList.length; i++) { + this._tempTriggerList[i].onTriggerEnter(self, other); + } + this._tempTriggerList.length = 0; + this.entity.getComponents("ITriggerListener", this._tempTriggerList); + for (var i = 0; i < this._tempTriggerList.length; i++) { + this._tempTriggerList[i].onTriggerEnter(other, self); + } + this._tempTriggerList.length = 0; + }; + return ProjectileMover; + }(es.Component)); + es.ProjectileMover = ProjectileMover; +})(es || (es = {})); +var es; +(function (es) { + var Collider = (function (_super) { + __extends(Collider, _super); + function Collider() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.physicsLayer = 1 << 0; + _this.collidesWithLayers = es.Physics.allLayers; + _this.shouldColliderScaleAndRotateWithTransform = true; + _this.registeredPhysicsBounds = new es.Rectangle(); + _this._isPositionDirty = true; + _this._isRotationDirty = true; + _this._localOffset = es.Vector2.zero; + return _this; + } + Object.defineProperty(Collider.prototype, "absolutePosition", { + get: function () { + return es.Vector2.add(this.entity.transform.position, this._localOffset); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Collider.prototype, "rotation", { + get: function () { + if (this.shouldColliderScaleAndRotateWithTransform && this.entity) + return this.entity.transform.rotation; + return 0; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Collider.prototype, "bounds", { + get: function () { + if (this._isPositionDirty || this._isRotationDirty) { + this.shape.recalculateBounds(this); + this._isPositionDirty = this._isRotationDirty = false; + } + return this.shape.bounds; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Collider.prototype, "localOffset", { + get: function () { + return this._localOffset; + }, + set: function (value) { + this.setLocalOffset(value); + }, + enumerable: true, + configurable: true + }); + Collider.prototype.setLocalOffset = function (offset) { + if (this._localOffset != offset) { + this.unregisterColliderWithPhysicsSystem(); + this._localOffset = offset; + this._localOffsetLength = this._localOffset.length(); + this._isPositionDirty = true; + this.registerColliderWithPhysicsSystem(); + } + return this; + }; + Collider.prototype.setShouldColliderScaleAndRotateWithTransform = function (shouldColliderScaleAndRotationWithTransform) { + this.shouldColliderScaleAndRotateWithTransform = shouldColliderScaleAndRotationWithTransform; + this._isPositionDirty = this._isRotationDirty = true; + return this; + }; + Collider.prototype.onAddedToEntity = function () { + if (this._colliderRequiresAutoSizing) { + if (!(this instanceof es.BoxCollider || this instanceof es.CircleCollider)) { + console.error("Only box and circle colliders can be created automatically"); + return; + } + var renderable = this.entity.getComponent(es.RenderableComponent); + if (renderable) { + var renderableBounds = renderable.bounds; + var width = renderableBounds.width / this.entity.scale.x; + var height = renderableBounds.height / this.entity.scale.y; + if (this instanceof es.CircleCollider) { + this.radius = Math.max(width, height) * 0.5; + } + else { + this.width = width; + this.height = height; + } + this.localOffset = es.Vector2.subtract(renderableBounds.center, this.entity.transform.position); + } + else { + console.warn("Collider has no shape and no RenderableComponent. Can't figure out how to size it."); + } + } + this._isParentEntityAddedToScene = true; + this.registerColliderWithPhysicsSystem(); + }; + Collider.prototype.onRemovedFromEntity = function () { + this.unregisterColliderWithPhysicsSystem(); + this._isParentEntityAddedToScene = false; + }; + Collider.prototype.onEntityTransformChanged = function (comp) { + switch (comp) { + case transform.Component.position: + this._isPositionDirty = true; + break; + case transform.Component.scale: + this._isPositionDirty = true; + break; + case transform.Component.rotation: + this._isRotationDirty = true; + break; + } + if (this._isColliderRegistered) + es.Physics.updateCollider(this); + }; + Collider.prototype.onEnabled = function () { + this.registerColliderWithPhysicsSystem(); + this._isPositionDirty = this._isRotationDirty = true; + }; + Collider.prototype.onDisabled = function () { + this.unregisterColliderWithPhysicsSystem(); + }; + Collider.prototype.registerColliderWithPhysicsSystem = function () { + if (this._isParentEntityAddedToScene && !this._isColliderRegistered) { + es.Physics.addCollider(this); + this._isColliderRegistered = true; + } + }; + Collider.prototype.unregisterColliderWithPhysicsSystem = function () { + if (this._isParentEntityAddedToScene && this._isColliderRegistered) { + es.Physics.removeCollider(this); + } + this._isColliderRegistered = false; + }; + Collider.prototype.overlaps = function (other) { + return this.shape.overlaps(other.shape); + }; + Collider.prototype.collidesWith = function (collider, motion, result) { + var oldPosition = this.entity.position; + this.entity.position = this.entity.position.add(motion); + var didCollide = this.shape.collidesWithShape(collider.shape, result); + if (didCollide) + result.collider = collider; + this.entity.position = oldPosition; + return didCollide; + }; + Collider.prototype.clone = function () { + var collider = ObjectUtils.clone(this); + collider.entity = null; + if (this.shape) + collider.shape = this.shape.clone(); + return collider; + }; + return Collider; + }(es.Component)); + es.Collider = Collider; +})(es || (es = {})); +var es; +(function (es) { + var BoxCollider = (function (_super) { + __extends(BoxCollider, _super); + function BoxCollider() { + var _this = _super.call(this) || this; + _this.shape = new es.Box(1, 1); + _this._colliderRequiresAutoSizing = true; + return _this; + } + Object.defineProperty(BoxCollider.prototype, "width", { + get: function () { + return this.shape.width; + }, + set: function (value) { + this.setWidth(value); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(BoxCollider.prototype, "height", { + get: function () { + return this.shape.height; + }, + set: function (value) { + this.setHeight(value); + }, + enumerable: true, + configurable: true + }); + BoxCollider.prototype.setSize = function (width, height) { + this._colliderRequiresAutoSizing = false; + var box = this.shape; + if (width != box.width || height != box.height) { + box.updateBox(width, height); + if (this.entity && this._isParentEntityAddedToScene) + es.Physics.updateCollider(this); + } + return this; + }; + BoxCollider.prototype.setWidth = function (width) { + this._colliderRequiresAutoSizing = false; + var box = this.shape; + if (width != box.width) { + box.updateBox(width, box.height); + if (this.entity && this._isParentEntityAddedToScene) + es.Physics.updateCollider(this); + } + return this; + }; + BoxCollider.prototype.setHeight = function (height) { + this._colliderRequiresAutoSizing = false; + var box = this.shape; + if (height != box.height) { + box.updateBox(box.width, height); + if (this.entity && this._isParentEntityAddedToScene) + es.Physics.updateCollider(this); + } + }; + BoxCollider.prototype.toString = function () { + return "[BoxCollider: bounds: " + this.bounds + "]"; + }; + return BoxCollider; + }(es.Collider)); + es.BoxCollider = BoxCollider; +})(es || (es = {})); +var es; +(function (es) { + var CircleCollider = (function (_super) { + __extends(CircleCollider, _super); + function CircleCollider(radius) { + var _this = _super.call(this) || this; + if (radius) + _this._colliderRequiresAutoSizing = true; + _this.shape = new es.Circle(radius ? radius : 1); + return _this; + } + Object.defineProperty(CircleCollider.prototype, "radius", { + get: function () { + return this.shape.radius; + }, + set: function (value) { + this.setRadius(value); + }, + enumerable: true, + configurable: true + }); + CircleCollider.prototype.setRadius = function (radius) { + this._colliderRequiresAutoSizing = false; + var circle = this.shape; + if (radius != circle.radius) { + circle.radius = radius; + circle._originalRadius = radius; + if (this.entity && this._isParentEntityAddedToScene) + es.Physics.updateCollider(this); + } + return this; + }; + CircleCollider.prototype.toString = function () { + return "[CircleCollider: bounds: " + this.bounds + ", radius: " + this.shape.radius + "]"; + }; + return CircleCollider; + }(es.Collider)); + es.CircleCollider = CircleCollider; +})(es || (es = {})); +var es; +(function (es) { + var PolygonCollider = (function (_super) { + __extends(PolygonCollider, _super); + function PolygonCollider(points) { + var _this = _super.call(this) || this; + var isPolygonClosed = points[0] == points[points.length - 1]; + if (isPolygonClosed) + points.splice(points.length - 1, 1); + var center = es.Polygon.findPolygonCenter(points); + _this.setLocalOffset(center); + es.Polygon.recenterPolygonVerts(points); + _this.shape = new es.Polygon(points); + return _this; + } + return PolygonCollider; + }(es.Collider)); + es.PolygonCollider = PolygonCollider; +})(es || (es = {})); +var es; +(function (es) { + var EntitySystem = (function () { + function EntitySystem(matcher) { + this._entities = []; + this._matcher = matcher ? matcher : es.Matcher.empty(); + } + Object.defineProperty(EntitySystem.prototype, "scene", { + get: function () { + return this._scene; + }, + set: function (value) { + this._scene = value; + this._entities = []; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(EntitySystem.prototype, "matcher", { + get: function () { + return this._matcher; + }, + enumerable: true, + configurable: true + }); + EntitySystem.prototype.initialize = function () { + }; + EntitySystem.prototype.onChanged = function (entity) { + var contains = this._entities.contains(entity); + var interest = this._matcher.IsIntersted(entity); + if (interest && !contains) + this.add(entity); + else if (!interest && contains) + this.remove(entity); + }; + EntitySystem.prototype.add = function (entity) { + this._entities.push(entity); + this.onAdded(entity); + }; + EntitySystem.prototype.onAdded = function (entity) { + }; + EntitySystem.prototype.remove = function (entity) { + this._entities.remove(entity); + this.onRemoved(entity); + }; + EntitySystem.prototype.onRemoved = function (entity) { + }; + EntitySystem.prototype.update = function () { + this.begin(); + this.process(this._entities); + }; + EntitySystem.prototype.lateUpdate = function () { + this.lateProcess(this._entities); + this.end(); + }; + EntitySystem.prototype.begin = function () { + }; + EntitySystem.prototype.process = function (entities) { + }; + EntitySystem.prototype.lateProcess = function (entities) { + }; + EntitySystem.prototype.end = function () { + }; + return EntitySystem; + }()); + es.EntitySystem = EntitySystem; +})(es || (es = {})); +var es; +(function (es) { + var EntityProcessingSystem = (function (_super) { + __extends(EntityProcessingSystem, _super); + function EntityProcessingSystem(matcher) { + return _super.call(this, matcher) || this; + } + EntityProcessingSystem.prototype.lateProcessEntity = function (entity) { + }; + EntityProcessingSystem.prototype.process = function (entities) { + var _this = this; + entities.forEach(function (entity) { return _this.processEntity(entity); }); + }; + EntityProcessingSystem.prototype.lateProcess = function (entities) { + var _this = this; + entities.forEach(function (entity) { return _this.lateProcessEntity(entity); }); + }; + return EntityProcessingSystem; + }(es.EntitySystem)); + es.EntityProcessingSystem = EntityProcessingSystem; +})(es || (es = {})); +var es; +(function (es) { + var PassiveSystem = (function (_super) { + __extends(PassiveSystem, _super); + function PassiveSystem() { + return _super !== null && _super.apply(this, arguments) || this; + } + PassiveSystem.prototype.onChanged = function (entity) { + }; + PassiveSystem.prototype.process = function (entities) { + this.begin(); + this.end(); + }; + return PassiveSystem; + }(es.EntitySystem)); + es.PassiveSystem = PassiveSystem; +})(es || (es = {})); +var es; +(function (es) { + var ProcessingSystem = (function (_super) { + __extends(ProcessingSystem, _super); + function ProcessingSystem() { + return _super !== null && _super.apply(this, arguments) || this; + } + ProcessingSystem.prototype.onChanged = function (entity) { + }; + ProcessingSystem.prototype.process = function (entities) { + this.begin(); + this.processSystem(); + this.end(); + }; + return ProcessingSystem; + }(es.EntitySystem)); + es.ProcessingSystem = ProcessingSystem; +})(es || (es = {})); +var es; +(function (es) { + var BitSet = (function () { + function BitSet(nbits) { + if (nbits === void 0) { nbits = 64; } + var length = nbits >> 6; + if ((nbits & BitSet.LONG_MASK) != 0) + length++; + this._bits = new Array(length); + } + BitSet.prototype.and = function (bs) { + var max = Math.min(this._bits.length, bs._bits.length); + var i; + for (var i_1 = 0; i_1 < max; ++i_1) + this._bits[i_1] &= bs._bits[i_1]; + while (i < this._bits.length) + this._bits[i++] = 0; + }; + BitSet.prototype.andNot = function (bs) { + var i = Math.min(this._bits.length, bs._bits.length); + while (--i >= 0) + this._bits[i] &= ~bs._bits[i]; + }; + BitSet.prototype.cardinality = function () { + var card = 0; + for (var i = this._bits.length - 1; i >= 0; i--) { + var a = this._bits[i]; + if (a == 0) + continue; + if (a == -1) { + card += 64; + continue; + } + a = ((a >> 1) & 0x5555555555555555) + (a & 0x5555555555555555); + a = ((a >> 2) & 0x3333333333333333) + (a & 0x3333333333333333); + var b = ((a >> 32) + a); + b = ((b >> 4) & 0x0f0f0f0f) + (b & 0x0f0f0f0f); + b = ((b >> 8) & 0x00ff00ff) + (b & 0x00ff00ff); + card += ((b >> 16) & 0x0000ffff) + (b & 0x0000ffff); + } + return card; + }; + BitSet.prototype.clear = function (pos) { + if (pos != undefined) { + var offset = pos >> 6; + this.ensure(offset); + this._bits[offset] &= ~(1 << pos); + } + else { + for (var i = 0; i < this._bits.length; i++) + this._bits[i] = 0; + } + }; + BitSet.prototype.get = function (pos) { + var offset = pos >> 6; + if (offset >= this._bits.length) + return false; + return (this._bits[offset] & (1 << pos)) != 0; + }; + BitSet.prototype.intersects = function (set) { + var i = Math.min(this._bits.length, set._bits.length); + while (--i >= 0) { + if ((this._bits[i] & set._bits[i]) != 0) + return true; + } + return false; + }; + BitSet.prototype.isEmpty = function () { + for (var i = this._bits.length - 1; i >= 0; i--) { + if (this._bits[i]) + return false; + } + return true; + }; + BitSet.prototype.nextSetBit = function (from) { + var offset = from >> 6; + var mask = 1 << from; + while (offset < this._bits.length) { + var h = this._bits[offset]; + do { + if ((h & mask) != 0) + return from; + mask <<= 1; + from++; + } while (mask != 0); + mask = 1; + offset++; + } + return -1; + }; + BitSet.prototype.set = function (pos, value) { + if (value === void 0) { value = true; } + if (value) { + var offset = pos >> 6; + this.ensure(offset); + this._bits[offset] |= 1 << pos; + } + else { + this.clear(pos); + } + }; + BitSet.prototype.ensure = function (lastElt) { + if (lastElt >= this._bits.length) { + var nd = new Number[lastElt + 1]; + nd = this._bits.copyWithin(0, 0, this._bits.length); + this._bits = nd; + } + }; + BitSet.LONG_MASK = 0x3f; + return BitSet; + }()); + es.BitSet = BitSet; +})(es || (es = {})); +var es; +(function (es) { + var ComponentList = (function () { + function ComponentList(entity) { + this._components = []; + this._componentsToAdd = []; + this._componentsToRemove = []; + this._tempBufferList = []; + this._entity = entity; + } + Object.defineProperty(ComponentList.prototype, "count", { + get: function () { + return this._components.length; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(ComponentList.prototype, "buffer", { + get: function () { + return this._components; + }, + enumerable: true, + configurable: true + }); + ComponentList.prototype.markEntityListUnsorted = function () { + this._isComponentListUnsorted = true; + }; + ComponentList.prototype.add = function (component) { + this._componentsToAdd.push(component); + }; + ComponentList.prototype.remove = function (component) { + if (this._componentsToRemove.contains(component)) + console.warn("You are trying to remove a Component (" + component + ") that you already removed"); + if (this._componentsToAdd.contains(component)) { + this._componentsToAdd.remove(component); + return; + } + this._componentsToRemove.push(component); + }; + ComponentList.prototype.removeAllComponents = function () { + for (var i = 0; i < this._components.length; i++) { + this.handleRemove(this._components[i]); + } + this._components.length = 0; + this._componentsToAdd.length = 0; + this._componentsToRemove.length = 0; + }; + ComponentList.prototype.deregisterAllComponents = function () { + for (var i = 0; i < this._components.length; i++) { + var component = this._components[i]; + if (component instanceof es.RenderableComponent) { + this._entity.scene.removeChild(component.displayObject); + this._entity.scene.renderableComponents.remove(component); + } + this._entity.componentBits.set(es.ComponentTypeManager.getIndexFor(component), false); + this._entity.scene.entityProcessors.onComponentRemoved(this._entity); + } + }; + ComponentList.prototype.registerAllComponents = function () { + for (var i = 0; i < this._components.length; i++) { + var component = this._components[i]; + if (component instanceof es.RenderableComponent) { + this._entity.scene.addChild(component.displayObject); + this._entity.scene.renderableComponents.add(component); + } + this._entity.componentBits.set(es.ComponentTypeManager.getIndexFor(component)); + this._entity.scene.entityProcessors.onComponentAdded(this._entity); + } + }; + ComponentList.prototype.updateLists = function () { + if (this._componentsToRemove.length > 0) { + for (var i = 0; i < this._componentsToRemove.length; i++) { + this.handleRemove(this._componentsToRemove[i]); + this._components.remove(this._componentsToRemove[i]); + } + this._componentsToRemove.length = 0; + } + if (this._componentsToAdd.length > 0) { + for (var i = 0, count = this._componentsToAdd.length; i < count; i++) { + var component = this._componentsToAdd[i]; + if (component instanceof es.RenderableComponent) { + this._entity.scene.addChild(component.displayObject); + this._entity.scene.renderableComponents.add(component); + } + this._entity.componentBits.set(es.ComponentTypeManager.getIndexFor(component)); + this._entity.scene.entityProcessors.onComponentAdded(this._entity); + this._components.push(component); + this._tempBufferList.push(component); + } + this._componentsToAdd.length = 0; + this._isComponentListUnsorted = true; + for (var i = 0; i < this._tempBufferList.length; i++) { + var component = this._tempBufferList[i]; + component.onAddedToEntity(); + if (component.enabled) { + component.onEnabled(); + } + } + this._tempBufferList.length = 0; + } + if (this._isComponentListUnsorted) { + this._components.sort(ComponentList.compareUpdatableOrder.compare); + this._isComponentListUnsorted = false; + } + }; + ComponentList.prototype.handleRemove = function (component) { + if (component instanceof es.RenderableComponent) { + this._entity.scene.removeChild(component.displayObject); + this._entity.scene.renderableComponents.remove(component); + } + this._entity.componentBits.set(es.ComponentTypeManager.getIndexFor(component), false); + this._entity.scene.entityProcessors.onComponentRemoved(this._entity); + component.onRemovedFromEntity(); + component.entity = null; + }; + ComponentList.prototype.getComponent = function (type, onlyReturnInitializedComponents) { + for (var i = 0; i < this._components.length; i++) { + var component = this._components[i]; if (component instanceof type) return component; } - } - return null; - }; - ComponentList.prototype.getComponents = function (typeName, components) { - if (!components) - components = []; - for (var i = 0; i < this._components.length; i++) { - var component = this._components[i]; - if (typeof (typeName) == "string") { - if (egret.is(component, typeName)) { - components.push(component); + if (!onlyReturnInitializedComponents) { + for (var i = 0; i < this._componentsToAdd.length; i++) { + var component = this._componentsToAdd[i]; + if (component instanceof type) + return component; } } - else { - if (component instanceof typeName) { - components.push(component); + return null; + }; + ComponentList.prototype.getComponents = function (typeName, components) { + if (!components) + components = []; + for (var i = 0; i < this._components.length; i++) { + var component = this._components[i]; + if (typeof (typeName) == "string") { + if (egret.is(component, typeName)) { + components.push(component); + } + } + else { + if (component instanceof typeName) { + components.push(component); + } } } - } - for (var i = 0; i < this._componentsToAdd.length; i++) { - var component = this._componentsToAdd[i]; - if (typeof (typeName) == "string") { - if (egret.is(component, typeName)) { - components.push(component); + for (var i = 0; i < this._componentsToAdd.length; i++) { + var component = this._componentsToAdd[i]; + if (typeof (typeName) == "string") { + if (egret.is(component, typeName)) { + components.push(component); + } + } + else { + if (component instanceof typeName) { + components.push(component); + } } } - else { - if (component instanceof typeName) { - components.push(component); - } + return components; + }; + ComponentList.prototype.update = function () { + this.updateLists(); + for (var i = 0; i < this._components.length; i++) { + var updatableComponent = this._components[i]; + if (updatableComponent.enabled && + (updatableComponent.updateInterval == 1 || + es.Time.frameCount % updatableComponent.updateInterval == 0)) + updatableComponent.update(); } + }; + ComponentList.prototype.onEntityTransformChanged = function (comp) { + for (var i = 0; i < this._components.length; i++) { + if (this._components[i].enabled) + this._components[i].onEntityTransformChanged(comp); + } + for (var i = 0; i < this._componentsToAdd.length; i++) { + if (this._componentsToAdd[i].enabled) + this._componentsToAdd[i].onEntityTransformChanged(comp); + } + }; + ComponentList.prototype.onEntityEnabled = function () { + for (var i = 0; i < this._components.length; i++) + this._components[i].onEnabled(); + }; + ComponentList.prototype.onEntityDisabled = function () { + for (var i = 0; i < this._components.length; i++) + this._components[i].onDisabled(); + }; + ComponentList.compareUpdatableOrder = new es.IUpdatableComparer(); + return ComponentList; + }()); + es.ComponentList = ComponentList; +})(es || (es = {})); +var es; +(function (es) { + var ComponentTypeManager = (function () { + function ComponentTypeManager() { } - return components; - }; - ComponentList.prototype.update = function () { - this.updateLists(); - for (var i = 0; i < this._components.length; i++) { - var component = this._components[i]; - if (component.enabled && (component.updateInterval == 1 || Time.frameCount % component.updateInterval == 0)) - component.update(); + ComponentTypeManager.add = function (type) { + if (!this._componentTypesMask.has(type)) + this._componentTypesMask[type] = this._componentTypesMask.size; + }; + ComponentTypeManager.getIndexFor = function (type) { + var v = -1; + if (!this._componentTypesMask.has(type)) { + this.add(type); + v = this._componentTypesMask.get(type); + } + return v; + }; + ComponentTypeManager._componentTypesMask = new Map(); + return ComponentTypeManager; + }()); + es.ComponentTypeManager = ComponentTypeManager; +})(es || (es = {})); +var es; +(function (es) { + var EntityList = (function () { + function EntityList(scene) { + this._entities = []; + this._entitiesToAdded = []; + this._entitiesToRemove = []; + this._entityDict = new Map(); + this._unsortedTags = []; + this._tempEntityList = []; + this.scene = scene; } - }; - return ComponentList; -}()); -var ComponentTypeManager = (function () { - function ComponentTypeManager() { - } - ComponentTypeManager.add = function (type) { - if (!this._componentTypesMask.has(type)) - this._componentTypesMask[type] = this._componentTypesMask.size; - }; - ComponentTypeManager.getIndexFor = function (type) { - var v = -1; - if (!this._componentTypesMask.has(type)) { - this.add(type); - v = this._componentTypesMask.get(type); - } - return v; - }; - ComponentTypeManager._componentTypesMask = new Map(); - return ComponentTypeManager; -}()); -var EntityList = (function () { - function EntityList(scene) { - this._entitiesToRemove = []; - this._entitiesToAdded = []; - this._tempEntityList = []; - this._entities = []; - this._entityDict = new Map(); - this._unsortedTags = []; - this.scene = scene; - } - Object.defineProperty(EntityList.prototype, "count", { - get: function () { - return this._entities.length; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(EntityList.prototype, "buffer", { - get: function () { - return this._entities; - }, - enumerable: true, - configurable: true - }); - EntityList.prototype.add = function (entity) { - if (this._entitiesToAdded.indexOf(entity) == -1) - this._entitiesToAdded.push(entity); - }; - EntityList.prototype.remove = function (entity) { - if (this._entitiesToAdded.contains(entity)) { - this._entitiesToAdded.remove(entity); - return; - } - if (!this._entitiesToRemove.contains(entity)) - this._entitiesToRemove.push(entity); - }; - EntityList.prototype.findEntity = function (name) { - for (var i = 0; i < this._entities.length; i++) { - if (this._entities[i].name == name) - return this._entities[i]; - } - return this._entitiesToAdded.firstOrDefault(function (entity) { return entity.name == name; }); - }; - EntityList.prototype.getTagList = function (tag) { - var list = this._entityDict.get(tag); - if (!list) { - list = []; - this._entityDict.set(tag, list); - } - return this._entityDict.get(tag); - }; - EntityList.prototype.addToTagList = function (entity) { - var list = this.getTagList(entity.tag); - if (!list.contains(entity)) { - list.push(entity); - this._unsortedTags.push(entity.tag); - } - }; - EntityList.prototype.removeFromTagList = function (entity) { - var list = this._entityDict.get(entity.tag); - if (list) { - list.remove(entity); - } - }; - EntityList.prototype.update = function () { - for (var i = 0; i < this._entities.length; i++) { - var entity = this._entities[i]; - if (entity.enabled) - entity.update(); - } - }; - EntityList.prototype.removeAllEntities = function () { - this._entitiesToAdded.length = 0; - this.updateLists(); - for (var i = 0; i < this._entities.length; i++) { - this._entities[i]._isDestoryed = true; - this._entities[i].onRemovedFromScene(); - this._entities[i].scene = null; - } - this._entities.length = 0; - this._entityDict.clear(); - }; - EntityList.prototype.updateLists = function () { - var _this = this; - if (this._entitiesToRemove.length > 0) { - var temp = this._entitiesToRemove; - this._entitiesToRemove = this._tempEntityList; - this._tempEntityList = temp; - this._tempEntityList.forEach(function (entity) { - _this._entities.remove(entity); - entity.scene = null; - _this.scene.entityProcessors.onEntityRemoved(entity); - }); - this._tempEntityList.length = 0; - } - if (this._entitiesToAdded.length > 0) { - var temp = this._entitiesToAdded; - this._entitiesToAdded = this._tempEntityList; - this._tempEntityList = temp; - this._tempEntityList.forEach(function (entity) { - if (!_this._entities.contains(entity)) { - _this._entities.push(entity); - entity.scene = _this.scene; - _this.scene.entityProcessors.onEntityAdded(entity); - } - }); - this._tempEntityList.forEach(function (entity) { return entity.onAddedToScene(); }); - this._tempEntityList.length = 0; - } - if (this._unsortedTags.length > 0) { - this._unsortedTags.forEach(function (tag) { - _this._entityDict.get(tag).sort(); - }); + Object.defineProperty(EntityList.prototype, "count", { + get: function () { + return this._entities.length; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(EntityList.prototype, "buffer", { + get: function () { + return this._entities; + }, + enumerable: true, + configurable: true + }); + EntityList.prototype.markEntityListUnsorted = function () { + this._isEntityListUnsorted = true; + }; + EntityList.prototype.markTagUnsorted = function (tag) { + this._unsortedTags.push(tag); + }; + EntityList.prototype.add = function (entity) { + if (this._entitiesToAdded.indexOf(entity) == -1) + this._entitiesToAdded.push(entity); + }; + EntityList.prototype.remove = function (entity) { + if (!this._entitiesToRemove.contains(entity)) { + console.warn("You are trying to remove an entity (" + entity.name + ") that you already removed"); + return; + } + if (this._entitiesToAdded.contains(entity)) { + this._entitiesToAdded.remove(entity); + return; + } + if (!this._entitiesToRemove.contains(entity)) + this._entitiesToRemove.push(entity); + }; + EntityList.prototype.removeAllEntities = function () { this._unsortedTags.length = 0; - } - }; - return EntityList; -}()); -var EntityProcessorList = (function () { - function EntityProcessorList() { - this._processors = []; - } - EntityProcessorList.prototype.add = function (processor) { - this._processors.push(processor); - }; - EntityProcessorList.prototype.remove = function (processor) { - this._processors.remove(processor); - }; - EntityProcessorList.prototype.onComponentAdded = function (entity) { - this.notifyEntityChanged(entity); - }; - EntityProcessorList.prototype.onComponentRemoved = function (entity) { - this.notifyEntityChanged(entity); - }; - EntityProcessorList.prototype.onEntityAdded = function (entity) { - this.notifyEntityChanged(entity); - }; - EntityProcessorList.prototype.onEntityRemoved = function (entity) { - this.removeFromProcessors(entity); - }; - EntityProcessorList.prototype.notifyEntityChanged = function (entity) { - for (var i = 0; i < this._processors.length; i++) { - this._processors[i].onChanged(entity); - } - }; - EntityProcessorList.prototype.removeFromProcessors = function (entity) { - for (var i = 0; i < this._processors.length; i++) { - this._processors[i].remove(entity); - } - }; - EntityProcessorList.prototype.begin = function () { - }; - EntityProcessorList.prototype.update = function () { - for (var i = 0; i < this._processors.length; i++) { - this._processors[i].update(); - } - }; - EntityProcessorList.prototype.lateUpdate = function () { - for (var i = 0; i < this._processors.length; i++) { - this._processors[i].lateUpdate(); - } - }; - EntityProcessorList.prototype.end = function () { - }; - EntityProcessorList.prototype.getProcessor = function () { - for (var i = 0; i < this._processors.length; i++) { - var processor = this._processors[i]; - if (processor instanceof EntitySystem) - return processor; - } - return null; - }; - return EntityProcessorList; -}()); -var Matcher = (function () { - function Matcher() { - this.allSet = new BitSet(); - this.exclusionSet = new BitSet(); - this.oneSet = new BitSet(); - } - Matcher.empty = function () { - return new Matcher(); - }; - Matcher.prototype.getAllSet = function () { - return this.allSet; - }; - Matcher.prototype.getExclusionSet = function () { - return this.exclusionSet; - }; - Matcher.prototype.getOneSet = function () { - return this.oneSet; - }; - Matcher.prototype.IsIntersted = function (e) { - if (!this.allSet.isEmpty()) { - for (var i = this.allSet.nextSetBit(0); i >= 0; i = this.allSet.nextSetBit(i + 1)) { - if (!e.componentBits.get(i)) - return false; + this._entitiesToAdded.length = 0; + this._isEntityListUnsorted = false; + this.updateLists(); + for (var i = 0; i < this._entities.length; i++) { + this._entities[i]._isDestroyed = true; + this._entities[i].onRemovedFromScene(); + this._entities[i].scene = null; } - } - if (!this.exclusionSet.isEmpty() && this.exclusionSet.intersects(e.componentBits)) - return false; - if (!this.oneSet.isEmpty() && !this.oneSet.intersects(e.componentBits)) - return false; - return true; - }; - Matcher.prototype.all = function () { - var _this = this; - var types = []; - for (var _i = 0; _i < arguments.length; _i++) { - types[_i] = arguments[_i]; - } - types.forEach(function (type) { - _this.allSet.set(ComponentTypeManager.getIndexFor(type)); - }); - return this; - }; - Matcher.prototype.exclude = function () { - var _this = this; - var types = []; - for (var _i = 0; _i < arguments.length; _i++) { - types[_i] = arguments[_i]; - } - types.forEach(function (type) { - _this.exclusionSet.set(ComponentTypeManager.getIndexFor(type)); - }); - return this; - }; - Matcher.prototype.one = function () { - var _this = this; - var types = []; - for (var _i = 0; _i < arguments.length; _i++) { - types[_i] = arguments[_i]; - } - types.forEach(function (type) { - _this.oneSet.set(ComponentTypeManager.getIndexFor(type)); - }); - return this; - }; - return Matcher; -}()); -var RenderableComponentList = (function () { - function RenderableComponentList() { - this._components = []; - } - Object.defineProperty(RenderableComponentList.prototype, "count", { - get: function () { - return this._components.length; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(RenderableComponentList.prototype, "buffer", { - get: function () { - return this._components; - }, - enumerable: true, - configurable: true - }); - RenderableComponentList.prototype.add = function (component) { - this._components.push(component); - }; - RenderableComponentList.prototype.remove = function (component) { - this._components.remove(component); - }; - RenderableComponentList.prototype.updateList = function () { - }; - return RenderableComponentList; -}()); -var Time = (function () { - function Time() { - } - ; - Time.update = function (currentTime) { - var dt = (currentTime - this._lastTime) / 1000; - this.deltaTime = dt * this.timeScale; - this.unscaledDeltaTime = dt; - this.frameCount++; - this._lastTime = currentTime; - }; - Time.deltaTime = 0; - Time.timeScale = 1; - Time.frameCount = 0; - Time._lastTime = 0; - return Time; -}()); -var GraphicsCapabilities = (function () { - function GraphicsCapabilities() { - } - GraphicsCapabilities.prototype.initialize = function (device) { - this.platformInitialize(device); - }; - GraphicsCapabilities.prototype.platformInitialize = function (device) { - var gl = new egret.sys.RenderBuffer().context.getInstance(); - this.supportsNonPowerOfTwo = false; - this.supportsTextureFilterAnisotropic = gl.getExtension("EXT_texture_filter_anisotropic") != null; - this.supportsDepth24 = true; - this.supportsPackedDepthStencil = true; - this.supportsDepthNonLinear = false; - this.supportsTextureMaxLevel = true; - this.supportsS3tc = gl.getExtension("WEBGL_compressed_texture_s3tc") != null || - gl.getExtension("WEBGL_compressed_texture_s3tc_srgb") != null; - this.supportsDxt1 = this.supportsS3tc; - this.supportsPvrtc = false; - this.supportsAtitc = gl.getExtension("WEBGL_compressed_texture_astc") != null; - this.supportsFramebufferObjectARB = false; - }; - return GraphicsCapabilities; -}()); -var GraphicsDevice = (function () { - function GraphicsDevice() { - this.graphicsCapabilities = new GraphicsCapabilities(); - this.graphicsCapabilities.initialize(this); - } - return GraphicsDevice; -}()); -var Viewport = (function () { - function Viewport(x, y, width, height) { - this._x = x; - this._y = y; - this._width = width; - this._height = height; - this._minDepth = 0; - this._maxDepth = 1; - } - Object.defineProperty(Viewport.prototype, "aspectRatio", { - get: function () { - if ((this._height != 0) && (this._width != 0)) - return (this._width / this._height); - return 0; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Viewport.prototype, "bounds", { - get: function () { - return new Rectangle(this._x, this._y, this._width, this._height); - }, - set: function (value) { - this._x = value.x; - this._y = value.y; - this._width = value.width; - this._height = value.height; - }, - enumerable: true, - configurable: true - }); - return Viewport; -}()); -var GaussianBlurEffect = (function (_super) { - __extends(GaussianBlurEffect, _super); - function GaussianBlurEffect() { - return _super.call(this, PostProcessor.default_vert, GaussianBlurEffect.blur_frag, { - screenWidth: SceneManager.stage.stageWidth, - screenHeight: SceneManager.stage.stageHeight - }) || this; - } - GaussianBlurEffect.blur_frag = "precision mediump float;\n" + - "uniform sampler2D uSampler;\n" + - "uniform float screenWidth;\n" + - "uniform float screenHeight;\n" + - "float normpdf(in float x, in float sigma)\n" + - "{\n" + - "return 0.39894*exp(-0.5*x*x/(sigma*sigma))/sigma;\n" + - "}\n" + - "void main()\n" + - "{\n" + - "vec3 c = texture2D(uSampler, gl_FragCoord.xy / vec2(screenWidth, screenHeight).xy).rgb;\n" + - "const int mSize = 11;\n" + - "const int kSize = (mSize - 1)/2;\n" + - "float kernel[mSize];\n" + - "vec3 final_colour = vec3(0.0);\n" + - "float sigma = 7.0;\n" + - "float z = 0.0;\n" + - "for (int j = 0; j <= kSize; ++j)\n" + - "{\n" + - "kernel[kSize+j] = kernel[kSize-j] = normpdf(float(j),sigma);\n" + - "}\n" + - "for (int j = 0; j < mSize; ++j)\n" + - "{\n" + - "z += kernel[j];\n" + - "}\n" + - "for (int i = -kSize; i <= kSize; ++i)\n" + - "{\n" + - "for (int j = -kSize; j <= kSize; ++j)\n" + - "{\n" + - "final_colour += kernel[kSize+j]*kernel[kSize+i]*texture2D(uSampler, (gl_FragCoord.xy+vec2(float(i),float(j))) / vec2(screenWidth, screenHeight).xy).rgb;\n" + - "}\n}\n" + - "gl_FragColor = vec4(final_colour/(z*z), 1.0);\n" + - "}"; - return GaussianBlurEffect; -}(egret.CustomFilter)); -var PolygonLightEffect = (function (_super) { - __extends(PolygonLightEffect, _super); - function PolygonLightEffect() { - return _super.call(this, PolygonLightEffect.vertSrc, PolygonLightEffect.fragmentSrc) || this; - } - PolygonLightEffect.vertSrc = "attribute vec2 aVertexPosition;\n" + - "attribute vec2 aTextureCoord;\n" + - "uniform vec2 projectionVector;\n" + - "varying vec2 vTextureCoord;\n" + - "const vec2 center = vec2(-1.0, 1.0);\n" + - "void main(void) {\n" + - " gl_Position = vec4( (aVertexPosition / projectionVector) + center , 0.0, 1.0);\n" + - " vTextureCoord = aTextureCoord;\n" + - "}"; - PolygonLightEffect.fragmentSrc = "precision lowp float;\n" + - "varying vec2 vTextureCoord;\n" + - "uniform sampler2D uSampler;\n" + - "#define SAMPLE_COUNT 15\n" + - "uniform vec2 _sampleOffsets[SAMPLE_COUNT];\n" + - "uniform float _sampleWeights[SAMPLE_COUNT];\n" + - "void main(void) {\n" + - "vec4 c = vec4(0, 0, 0, 0);\n" + - "for( int i = 0; i < SAMPLE_COUNT; i++ )\n" + - " c += texture2D( uSampler, vTextureCoord + _sampleOffsets[i] ) * _sampleWeights[i];\n" + - "gl_FragColor = c;\n" + - "}"; - return PolygonLightEffect; -}(egret.CustomFilter)); -var PostProcessor = (function () { - function PostProcessor(effect) { - if (effect === void 0) { effect = null; } - this.enable = true; - this.effect = effect; - } - PostProcessor.prototype.onAddedToScene = function (scene) { - this.scene = scene; - this.shape = new egret.Shape(); - this.shape.graphics.beginFill(0xFFFFFF, 1); - this.shape.graphics.drawRect(0, 0, SceneManager.stage.stageWidth, SceneManager.stage.stageHeight); - this.shape.graphics.endFill(); - scene.addChild(this.shape); - }; - PostProcessor.prototype.process = function () { - this.drawFullscreenQuad(); - }; - PostProcessor.prototype.onSceneBackBufferSizeChanged = function (newWidth, newHeight) { }; - PostProcessor.prototype.drawFullscreenQuad = function () { - this.scene.filters = [this.effect]; - }; - PostProcessor.prototype.unload = function () { - if (this.effect) { - this.effect = null; - } - this.scene.removeChild(this.shape); - this.scene = null; - }; - PostProcessor.default_vert = "attribute vec2 aVertexPosition;\n" + - "attribute vec2 aTextureCoord;\n" + - "attribute vec2 aColor;\n" + - "uniform vec2 projectionVector;\n" + - "varying vec2 vTextureCoord;\n" + - "varying vec4 vColor;\n" + - "const vec2 center = vec2(-1.0, 1.0);\n" + - "void main(void) {\n" + - "gl_Position = vec4( (aVertexPosition / projectionVector) + center , 0.0, 1.0);\n" + - "vTextureCoord = aTextureCoord;\n" + - "vColor = vec4(aColor.x, aColor.x, aColor.x, aColor.x);\n" + - "}"; - return PostProcessor; -}()); -var GaussianBlurPostProcessor = (function (_super) { - __extends(GaussianBlurPostProcessor, _super); - function GaussianBlurPostProcessor() { - return _super !== null && _super.apply(this, arguments) || this; - } - GaussianBlurPostProcessor.prototype.onAddedToScene = function (scene) { - _super.prototype.onAddedToScene.call(this, scene); - this.effect = new GaussianBlurEffect(); - }; - return GaussianBlurPostProcessor; -}(PostProcessor)); -var Renderer = (function () { - function Renderer() { - } - Renderer.prototype.onAddedToScene = function (scene) { }; - Renderer.prototype.beginRender = function (cam) { - }; - Renderer.prototype.unload = function () { }; - Renderer.prototype.renderAfterStateCheck = function (renderable, cam) { - renderable.render(cam); - }; - return Renderer; -}()); -var DefaultRenderer = (function (_super) { - __extends(DefaultRenderer, _super); - function DefaultRenderer() { - return _super !== null && _super.apply(this, arguments) || this; - } - DefaultRenderer.prototype.render = function (scene) { - var cam = this.camera ? this.camera : scene.camera; - this.beginRender(cam); - for (var i = 0; i < scene.renderableComponents.count; i++) { - var renderable = scene.renderableComponents.buffer[i]; - if (renderable.enabled && renderable.isVisibleFromCamera(cam)) - this.renderAfterStateCheck(renderable, cam); - } - }; - return DefaultRenderer; -}(Renderer)); -var ScreenSpaceRenderer = (function (_super) { - __extends(ScreenSpaceRenderer, _super); - function ScreenSpaceRenderer() { - return _super !== null && _super.apply(this, arguments) || this; - } - ScreenSpaceRenderer.prototype.render = function (scene) { - }; - return ScreenSpaceRenderer; -}(Renderer)); -var PolyLight = (function (_super) { - __extends(PolyLight, _super); - function PolyLight(radius, color, power) { - var _this = _super.call(this) || this; - _this._indices = []; - _this.radius = radius; - _this.power = power; - _this.color = color; - _this.computeTriangleIndices(); - return _this; - } - Object.defineProperty(PolyLight.prototype, "radius", { - get: function () { - return this._radius; - }, - set: function (value) { - this.setRadius(value); - }, - enumerable: true, - configurable: true - }); - PolyLight.prototype.computeTriangleIndices = function (totalTris) { - if (totalTris === void 0) { totalTris = 20; } - this._indices.length = 0; - for (var i = 0; i < totalTris; i += 2) { - this._indices.push(0); - this._indices.push(i + 2); - this._indices.push(i + 1); - } - }; - PolyLight.prototype.setRadius = function (radius) { - if (radius != this._radius) { - this._radius = radius; - this._areBoundsDirty = true; - } - }; - PolyLight.prototype.render = function (camera) { - }; - PolyLight.prototype.reset = function () { - }; - return PolyLight; -}(RenderableComponent)); -var SceneTransition = (function () { - function SceneTransition(sceneLoadAction) { - this.sceneLoadAction = sceneLoadAction; - this.loadsNewScene = sceneLoadAction != null; - } - Object.defineProperty(SceneTransition.prototype, "hasPreviousSceneRender", { - get: function () { - if (!this._hasPreviousSceneRender) { - this._hasPreviousSceneRender = true; - return false; + this._entities.length = 0; + this._entityDict.clear(); + }; + EntityList.prototype.contains = function (entity) { + return this._entities.contains(entity) || this._entitiesToAdded.contains(entity); + }; + EntityList.prototype.getTagList = function (tag) { + var list = this._entityDict.get(tag); + if (!list) { + list = []; + this._entityDict.set(tag, list); } - return true; - }, - enumerable: true, - configurable: true - }); - SceneTransition.prototype.preRender = function () { }; - SceneTransition.prototype.render = function () { - }; - SceneTransition.prototype.onBeginTransition = function () { - return __awaiter(this, void 0, void 0, function () { - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4, this.loadNextScene()]; - case 1: - _a.sent(); - this.transitionComplete(); - return [2]; - } - }); - }); - }; - SceneTransition.prototype.transitionComplete = function () { - SceneManager.sceneTransition = null; - if (this.onTransitionCompleted) { - this.onTransitionCompleted(); - } - }; - SceneTransition.prototype.loadNextScene = function () { - return __awaiter(this, void 0, void 0, function () { - var _a; - return __generator(this, function (_b) { - switch (_b.label) { - case 0: - if (this.onScreenObscured) - this.onScreenObscured(); - if (!this.loadsNewScene) { - this.isNewSceneLoaded = true; - } - _a = SceneManager; - return [4, this.sceneLoadAction()]; - case 1: - _a.scene = _b.sent(); - this.isNewSceneLoaded = true; - return [2]; - } - }); - }); - }; - SceneTransition.prototype.tickEffectProgressProperty = function (filter, duration, easeType, reverseDirection) { - if (reverseDirection === void 0) { reverseDirection = false; } - return new Promise(function (resolve) { - var start = reverseDirection ? 1 : 0; - var end = reverseDirection ? 0 : 1; - egret.Tween.get(filter.uniforms).set({ _progress: start }).to({ _progress: end }, duration * 1000, easeType).call(function () { - resolve(); - }); - }); - }; - return SceneTransition; -}()); -var FadeTransition = (function (_super) { - __extends(FadeTransition, _super); - function FadeTransition(sceneLoadAction) { - var _this = _super.call(this, sceneLoadAction) || this; - _this.fadeToColor = 0x000000; - _this.fadeOutDuration = 0.4; - _this.fadeEaseType = egret.Ease.quadInOut; - _this.delayBeforeFadeInDuration = 0.1; - _this._alpha = 0; - _this._mask = new egret.Shape(); - return _this; - } - FadeTransition.prototype.onBeginTransition = function () { - return __awaiter(this, void 0, void 0, function () { + return this._entityDict.get(tag); + }; + EntityList.prototype.addToTagList = function (entity) { + var list = this.getTagList(entity.tag); + if (!list.contains(entity)) { + list.push(entity); + this._unsortedTags.push(entity.tag); + } + }; + EntityList.prototype.removeFromTagList = function (entity) { + var list = this._entityDict.get(entity.tag); + if (list) { + list.remove(entity); + } + }; + EntityList.prototype.update = function () { + for (var i = 0; i < this._entities.length; i++) { + var entity = this._entities[i]; + if (entity.enabled && (entity.updateInterval == 1 || es.Time.frameCount % entity.updateInterval == 0)) + entity.update(); + } + }; + EntityList.prototype.updateLists = function () { var _this = this; - return __generator(this, function (_a) { - this._mask.graphics.beginFill(this.fadeToColor, 1); - this._mask.graphics.drawRect(0, 0, SceneManager.stage.stageWidth, SceneManager.stage.stageHeight); - this._mask.graphics.endFill(); - SceneManager.stage.addChild(this._mask); - egret.Tween.get(this).to({ _alpha: 1 }, this.fadeOutDuration * 1000, this.fadeEaseType) - .call(function () { return __awaiter(_this, void 0, void 0, function () { - return __generator(this, function (_a) { - switch (_a.label) { - case 0: return [4, this.loadNextScene()]; - case 1: - _a.sent(); - return [2]; - } - }); - }); }).wait(this.delayBeforeFadeInDuration).call(function () { - egret.Tween.get(_this).to({ _alpha: 0 }, _this.fadeOutDuration * 1000, _this.fadeEaseType).call(function () { - _this.transitionComplete(); - SceneManager.stage.removeChild(_this._mask); - }); + if (this._entitiesToRemove.length > 0) { + var temp = this._entitiesToRemove; + this._entitiesToRemove = this._tempEntityList; + this._tempEntityList = temp; + this._tempEntityList.forEach(function (entity) { + _this.removeFromTagList(entity); + _this._entities.remove(entity); + entity.onRemovedFromScene(); + entity.scene = null; + _this.scene.entityProcessors.onEntityRemoved(entity); }); - return [2]; + this._tempEntityList.length = 0; + } + if (this._entitiesToAdded.length > 0) { + var temp = this._entitiesToAdded; + this._entitiesToAdded = this._tempEntityList; + this._tempEntityList = temp; + this._tempEntityList.forEach(function (entity) { + if (!_this._entities.contains(entity)) { + _this._entities.push(entity); + entity.scene = _this.scene; + _this.addToTagList(entity); + _this.scene.entityProcessors.onEntityAdded(entity); + } + }); + this._tempEntityList.forEach(function (entity) { return entity.onAddedToScene(); }); + this._tempEntityList.length = 0; + this._isEntityListUnsorted = true; + } + if (this._isEntityListUnsorted) { + this._entities.sort(); + this._isEntityListUnsorted = false; + } + if (this._unsortedTags.length > 0) { + this._unsortedTags.forEach(function (tag) { + _this._entityDict.get(tag).sort(); + }); + this._unsortedTags.length = 0; + } + }; + EntityList.prototype.findEntity = function (name) { + for (var i = 0; i < this._entities.length; i++) { + if (this._entities[i].name == name) + return this._entities[i]; + } + return this._entitiesToAdded.firstOrDefault(function (entity) { return entity.name == name; }); + }; + EntityList.prototype.entitiesWithTag = function (tag) { + var list = this.getTagList(tag); + var returnList = es.ListPool.obtain(); + for (var i = 0; i < list.length; i++) + returnList.push(list[i]); + return returnList; + }; + EntityList.prototype.entitiesOfType = function (type) { + var list = es.ListPool.obtain(); + for (var i = 0; i < this._entities.length; i++) { + if (this._entities[i] instanceof type) + list.push(this._entities[i]); + } + this._entitiesToAdded.forEach(function (entity) { + if (entity instanceof type) + list.push(entity); }); + return list; + }; + EntityList.prototype.findComponentOfType = function (type) { + for (var i = 0; i < this._entities.length; i++) { + if (this._entities[i].enabled) { + var comp = this._entities[i].getComponent(type); + if (comp) + return comp; + } + } + for (var i = 0; i < this._entitiesToAdded.length; i++) { + var entity = this._entitiesToAdded[i]; + if (entity.enabled) { + var comp = entity.getComponent(type); + if (comp) + return comp; + } + } + return null; + }; + EntityList.prototype.findComponentsOfType = function (type) { + var comps = es.ListPool.obtain(); + for (var i = 0; i < this._entities.length; i++) { + if (this._entities[i].enabled) + this._entities[i].getComponents(type, comps); + } + for (var i = 0; i < this._entitiesToAdded.length; i++) { + var entity = this._entitiesToAdded[i]; + if (entity.enabled) + entity.getComponents(type, comps); + } + return comps; + }; + return EntityList; + }()); + es.EntityList = EntityList; +})(es || (es = {})); +var es; +(function (es) { + var EntityProcessorList = (function () { + function EntityProcessorList() { + this._processors = []; + } + EntityProcessorList.prototype.add = function (processor) { + this._processors.push(processor); + }; + EntityProcessorList.prototype.remove = function (processor) { + this._processors.remove(processor); + }; + EntityProcessorList.prototype.onComponentAdded = function (entity) { + this.notifyEntityChanged(entity); + }; + EntityProcessorList.prototype.onComponentRemoved = function (entity) { + this.notifyEntityChanged(entity); + }; + EntityProcessorList.prototype.onEntityAdded = function (entity) { + this.notifyEntityChanged(entity); + }; + EntityProcessorList.prototype.onEntityRemoved = function (entity) { + this.removeFromProcessors(entity); + }; + EntityProcessorList.prototype.begin = function () { + }; + EntityProcessorList.prototype.update = function () { + for (var i = 0; i < this._processors.length; i++) { + this._processors[i].update(); + } + }; + EntityProcessorList.prototype.lateUpdate = function () { + for (var i = 0; i < this._processors.length; i++) { + this._processors[i].lateUpdate(); + } + }; + EntityProcessorList.prototype.end = function () { + }; + EntityProcessorList.prototype.getProcessor = function () { + for (var i = 0; i < this._processors.length; i++) { + var processor = this._processors[i]; + if (processor instanceof es.EntitySystem) + return processor; + } + return null; + }; + EntityProcessorList.prototype.notifyEntityChanged = function (entity) { + for (var i = 0; i < this._processors.length; i++) { + this._processors[i].onChanged(entity); + } + }; + EntityProcessorList.prototype.removeFromProcessors = function (entity) { + for (var i = 0; i < this._processors.length; i++) { + this._processors[i].remove(entity); + } + }; + return EntityProcessorList; + }()); + es.EntityProcessorList = EntityProcessorList; +})(es || (es = {})); +var es; +(function (es) { + var Matcher = (function () { + function Matcher() { + this.allSet = new es.BitSet(); + this.exclusionSet = new es.BitSet(); + this.oneSet = new es.BitSet(); + } + Matcher.empty = function () { + return new Matcher(); + }; + Matcher.prototype.getAllSet = function () { + return this.allSet; + }; + Matcher.prototype.getExclusionSet = function () { + return this.exclusionSet; + }; + Matcher.prototype.getOneSet = function () { + return this.oneSet; + }; + Matcher.prototype.IsIntersted = function (e) { + if (!this.allSet.isEmpty()) { + for (var i = this.allSet.nextSetBit(0); i >= 0; i = this.allSet.nextSetBit(i + 1)) { + if (!e.componentBits.get(i)) + return false; + } + } + if (!this.exclusionSet.isEmpty() && this.exclusionSet.intersects(e.componentBits)) + return false; + if (!this.oneSet.isEmpty() && !this.oneSet.intersects(e.componentBits)) + return false; + return true; + }; + Matcher.prototype.all = function () { + var _this = this; + var types = []; + for (var _i = 0; _i < arguments.length; _i++) { + types[_i] = arguments[_i]; + } + types.forEach(function (type) { + _this.allSet.set(es.ComponentTypeManager.getIndexFor(type)); + }); + return this; + }; + Matcher.prototype.exclude = function () { + var _this = this; + var types = []; + for (var _i = 0; _i < arguments.length; _i++) { + types[_i] = arguments[_i]; + } + types.forEach(function (type) { + _this.exclusionSet.set(es.ComponentTypeManager.getIndexFor(type)); + }); + return this; + }; + Matcher.prototype.one = function () { + var _this = this; + var types = []; + for (var _i = 0; _i < arguments.length; _i++) { + types[_i] = arguments[_i]; + } + types.forEach(function (type) { + _this.oneSet.set(es.ComponentTypeManager.getIndexFor(type)); + }); + return this; + }; + return Matcher; + }()); + es.Matcher = Matcher; +})(es || (es = {})); +var ObjectUtils = (function () { + function ObjectUtils() { + } + ObjectUtils.clone = function (p, c) { + if (c === void 0) { c = null; } + var c = c || {}; + for (var i in p) { + if (typeof p[i] === 'object') { + c[i] = p[i] instanceof Array ? [] : {}; + this.clone(p[i], c[i]); + } + else { + c[i] = p[i]; + } + } + return c; + }; + return ObjectUtils; +}()); +var es; +(function (es) { + var RenderableComparer = (function () { + function RenderableComparer() { + } + RenderableComparer.prototype.compare = function (self, other) { + return other.renderLayer - self.renderLayer; + }; + return RenderableComparer; + }()); + es.RenderableComparer = RenderableComparer; +})(es || (es = {})); +var es; +(function (es) { + var RenderableComponentList = (function () { + function RenderableComponentList() { + this._components = []; + this._componentsByRenderLayer = new Map(); + this._unsortedRenderLayers = []; + this._componentsNeedSort = true; + } + Object.defineProperty(RenderableComponentList.prototype, "count", { + get: function () { + return this._components.length; + }, + enumerable: true, + configurable: true }); + Object.defineProperty(RenderableComponentList.prototype, "buffer", { + get: function () { + return this._components; + }, + enumerable: true, + configurable: true + }); + RenderableComponentList.prototype.add = function (component) { + this._components.push(component); + this.addToRenderLayerList(component, component.renderLayer); + }; + RenderableComponentList.prototype.remove = function (component) { + this._components.remove(component); + this._componentsByRenderLayer.get(component.renderLayer).remove(component); + }; + RenderableComponentList.prototype.updateRenderableRenderLayer = function (component, oldRenderLayer, newRenderLayer) { + if (this._componentsByRenderLayer.has(oldRenderLayer) && this._componentsByRenderLayer.get(oldRenderLayer).contains(component)) { + this._componentsByRenderLayer.get(oldRenderLayer).remove(component); + this.addToRenderLayerList(component, newRenderLayer); + } + }; + RenderableComponentList.prototype.setRenderLayerNeedsComponentSort = function (renderLayer) { + if (!this._unsortedRenderLayers.contains(renderLayer)) + this._unsortedRenderLayers.push(renderLayer); + this._componentsNeedSort = true; + }; + RenderableComponentList.prototype.setNeedsComponentSort = function () { + this._componentsNeedSort = true; + }; + RenderableComponentList.prototype.addToRenderLayerList = function (component, renderLayer) { + var list = this.componentsWithRenderLayer(renderLayer); + if (!list.contains(component)) { + console.warn("Component renderLayer list already contains this component"); + return; + } + list.push(component); + if (!this._unsortedRenderLayers.contains(renderLayer)) + this._unsortedRenderLayers.push(renderLayer); + this._componentsNeedSort = true; + }; + RenderableComponentList.prototype.componentsWithRenderLayer = function (renderLayer) { + if (!this._componentsByRenderLayer.get(renderLayer)) { + this._componentsByRenderLayer.set(renderLayer, []); + } + return this._componentsByRenderLayer.get(renderLayer); + }; + RenderableComponentList.prototype.updateList = function () { + if (this._componentsNeedSort) { + this._components.sort(RenderableComponentList.compareUpdatableOrder.compare); + this._componentsNeedSort = false; + } + if (this._unsortedRenderLayers.length > 0) { + for (var i = 0, count = this._unsortedRenderLayers.length; i < count; i++) { + var renderLayerComponents = this._componentsByRenderLayer.get(this._unsortedRenderLayers[i]); + if (renderLayerComponents) { + renderLayerComponents.sort(RenderableComponentList.compareUpdatableOrder.compare); + } + } + this._unsortedRenderLayers.length = 0; + } + }; + RenderableComponentList.compareUpdatableOrder = new es.RenderableComparer(); + return RenderableComponentList; + }()); + es.RenderableComponentList = RenderableComponentList; +})(es || (es = {})); +var StringUtils = (function () { + function StringUtils() { + } + StringUtils.matchChineseWord = function (str) { + var patternA = /[\u4E00-\u9FA5]+/gim; + return str.match(patternA); }; - FadeTransition.prototype.render = function () { - this._mask.graphics.clear(); - this._mask.graphics.beginFill(this.fadeToColor, this._alpha); - this._mask.graphics.drawRect(0, 0, SceneManager.stage.stageWidth, SceneManager.stage.stageHeight); - this._mask.graphics.endFill(); + StringUtils.lTrim = function (target) { + var startIndex = 0; + while (this.isWhiteSpace(target.charAt(startIndex))) { + startIndex++; + } + return target.slice(startIndex, target.length); }; - return FadeTransition; -}(SceneTransition)); -var WindTransition = (function (_super) { - __extends(WindTransition, _super); - function WindTransition(sceneLoadAction) { - var _this = _super.call(this, sceneLoadAction) || this; - _this.duration = 1; - _this.easeType = egret.Ease.quadOut; - var vertexSrc = "attribute vec2 aVertexPosition;\n" + + StringUtils.rTrim = function (target) { + var endIndex = target.length - 1; + while (this.isWhiteSpace(target.charAt(endIndex))) { + endIndex--; + } + return target.slice(0, endIndex + 1); + }; + StringUtils.trim = function (target) { + if (target == null) { + return null; + } + return this.rTrim(this.lTrim(target)); + }; + StringUtils.isWhiteSpace = function (str) { + if (str == " " || str == "\t" || str == "\r" || str == "\n") + return true; + return false; + }; + StringUtils.replaceMatch = function (mainStr, targetStr, replaceStr, caseMark) { + if (caseMark === void 0) { caseMark = false; } + var len = mainStr.length; + var tempStr = ""; + var isMatch = false; + var tempTarget = caseMark == true ? targetStr.toLowerCase() : targetStr; + for (var i = 0; i < len; i++) { + isMatch = false; + if (mainStr.charAt(i) == tempTarget.charAt(0)) { + if (mainStr.substr(i, tempTarget.length) == tempTarget) { + isMatch = true; + } + } + if (isMatch) { + tempStr += replaceStr; + i = i + tempTarget.length - 1; + } + else { + tempStr += mainStr.charAt(i); + } + } + return tempStr; + }; + StringUtils.htmlSpecialChars = function (str, reversion) { + if (reversion === void 0) { reversion = false; } + var len = this.specialSigns.length; + for (var i = 0; i < len; i += 2) { + var from = void 0; + var to = void 0; + from = this.specialSigns[i]; + to = this.specialSigns[i + 1]; + if (reversion) { + var temp = from; + from = to; + to = temp; + } + str = this.replaceMatch(str, from, to); + } + return str; + }; + StringUtils.zfill = function (str, width) { + if (width === void 0) { width = 2; } + if (!str) { + return str; + } + width = Math.floor(width); + var slen = str.length; + if (slen >= width) { + return str; + } + var negative = false; + if (str.substr(0, 1) == '-') { + negative = true; + str = str.substr(1); + } + var len = width - slen; + for (var i = 0; i < len; i++) { + str = '0' + str; + } + if (negative) { + str = '-' + str; + } + return str; + }; + StringUtils.reverse = function (str) { + if (str.length > 1) + return this.reverse(str.substring(1)) + str.substring(0, 1); + else + return str; + }; + StringUtils.cutOff = function (str, start, len, order) { + if (order === void 0) { order = true; } + start = Math.floor(start); + len = Math.floor(len); + var length = str.length; + if (start > length) + start = length; + var s = start; + var e = start + len; + var newStr; + if (order) { + newStr = str.substring(0, s) + str.substr(e, length); + } + else { + s = length - 1 - start - len; + e = s + len; + newStr = str.substring(0, s + 1) + str.substr(e + 1, length); + } + return newStr; + }; + StringUtils.strReplace = function (str, rStr) { + var i = 0, len = rStr.length; + for (; i < len; i++) { + if (rStr[i] == null || rStr[i] == "") { + rStr[i] = "无"; + } + str = str.replace("{" + i + "}", rStr[i]); + } + return str; + }; + StringUtils.specialSigns = [ + '&', '&', + '<', '<', + '>', '>', + '"', '"', + "'", ''', + '®', '®', + '©', '©', + '™', '™', + ]; + return StringUtils; +}()); +var es; +(function (es) { + var TextureUtils = (function () { + function TextureUtils() { + } + TextureUtils.convertImageToCanvas = function (texture, rect) { + if (!this.sharedCanvas) { + this.sharedCanvas = egret.sys.createCanvas(); + this.sharedContext = this.sharedCanvas.getContext("2d"); + } + var w = texture.$getTextureWidth(); + var h = texture.$getTextureHeight(); + if (!rect) { + rect = egret.$TempRectangle; + rect.x = 0; + rect.y = 0; + rect.width = w; + rect.height = h; + } + rect.x = Math.min(rect.x, w - 1); + rect.y = Math.min(rect.y, h - 1); + rect.width = Math.min(rect.width, w - rect.x); + rect.height = Math.min(rect.height, h - rect.y); + var iWidth = Math.floor(rect.width); + var iHeight = Math.floor(rect.height); + var surface = this.sharedCanvas; + surface["style"]["width"] = iWidth + "px"; + surface["style"]["height"] = iHeight + "px"; + this.sharedCanvas.width = iWidth; + this.sharedCanvas.height = iHeight; + if (egret.Capabilities.renderMode == "webgl") { + var renderTexture = void 0; + if (!texture.$renderBuffer) { + if (egret.sys.systemRenderer["renderClear"]) { + egret.sys.systemRenderer["renderClear"](); + } + renderTexture = new egret.RenderTexture(); + renderTexture.drawToTexture(new egret.Bitmap(texture)); + } + else { + renderTexture = texture; + } + var pixels = renderTexture.$renderBuffer.getPixels(rect.x, rect.y, iWidth, iHeight); + var x = 0; + var y = 0; + for (var i = 0; i < pixels.length; i += 4) { + this.sharedContext.fillStyle = + 'rgba(' + pixels[i] + + ',' + pixels[i + 1] + + ',' + pixels[i + 2] + + ',' + (pixels[i + 3] / 255) + ')'; + this.sharedContext.fillRect(x, y, 1, 1); + x++; + if (x == iWidth) { + x = 0; + y++; + } + } + if (!texture.$renderBuffer) { + renderTexture.dispose(); + } + return surface; + } + else { + var bitmapData = texture; + var offsetX = Math.round(bitmapData.$offsetX); + var offsetY = Math.round(bitmapData.$offsetY); + var bitmapWidth = bitmapData.$bitmapWidth; + var bitmapHeight = bitmapData.$bitmapHeight; + var $TextureScaleFactor = es.Core._instance.stage.textureScaleFactor; + this.sharedContext.drawImage(bitmapData.$bitmapData.source, bitmapData.$bitmapX + rect.x / $TextureScaleFactor, bitmapData.$bitmapY + rect.y / $TextureScaleFactor, bitmapWidth * rect.width / w, bitmapHeight * rect.height / h, offsetX, offsetY, rect.width, rect.height); + return surface; + } + }; + TextureUtils.toDataURL = function (type, texture, rect, encoderOptions) { + try { + var surface = this.convertImageToCanvas(texture, rect); + var result = surface.toDataURL(type, encoderOptions); + return result; + } + catch (e) { + egret.$error(1033); + } + return null; + }; + TextureUtils.eliFoTevas = function (type, texture, filePath, rect, encoderOptions) { + var surface = this.convertImageToCanvas(texture, rect); + var result = surface.toTempFilePathSync({ + fileType: type.indexOf("png") >= 0 ? "png" : "jpg" + }); + wx.getFileSystemManager().saveFile({ + tempFilePath: result, + filePath: wx.env.USER_DATA_PATH + "/" + filePath, + success: function (res) { + } + }); + return result; + }; + TextureUtils.getPixel32 = function (texture, x, y) { + egret.$warn(1041, "getPixel32", "getPixels"); + return texture.getPixels(x, y); + }; + TextureUtils.getPixels = function (texture, x, y, width, height) { + if (width === void 0) { width = 1; } + if (height === void 0) { height = 1; } + if (egret.Capabilities.renderMode == "webgl") { + var renderTexture = void 0; + if (!texture.$renderBuffer) { + renderTexture = new egret.RenderTexture(); + renderTexture.drawToTexture(new egret.Bitmap(texture)); + } + else { + renderTexture = texture; + } + var pixels = renderTexture.$renderBuffer.getPixels(x, y, width, height); + return pixels; + } + try { + var surface = this.convertImageToCanvas(texture); + var result = this.sharedContext.getImageData(x, y, width, height).data; + return result; + } + catch (e) { + egret.$error(1039); + } + }; + return TextureUtils; + }()); + es.TextureUtils = TextureUtils; +})(es || (es = {})); +var es; +(function (es) { + var Time = (function () { + function Time() { + } + Time.update = function (currentTime) { + var dt = (currentTime - this._lastTime) / 1000; + this.deltaTime = dt * this.timeScale; + this.unscaledDeltaTime = dt; + this._timeSinceSceneLoad += dt; + this.frameCount++; + this._lastTime = currentTime; + }; + Time.sceneChanged = function () { + this._timeSinceSceneLoad = 0; + }; + Time.checkEvery = function (interval) { + return (this._timeSinceSceneLoad / interval) > ((this._timeSinceSceneLoad - this.deltaTime) / interval); + }; + Time.deltaTime = 0; + Time.timeScale = 1; + Time.frameCount = 0; + Time._lastTime = 0; + return Time; + }()); + es.Time = Time; +})(es || (es = {})); +var TimeUtils = (function () { + function TimeUtils() { + } + TimeUtils.monthId = function (d) { + if (d === void 0) { d = null; } + d = d ? d : new Date(); + var y = d.getFullYear(); + var m = d.getMonth() + 1; + var g = m < 10 ? "0" : ""; + return parseInt(y + g + m); + }; + TimeUtils.dateId = function (t) { + if (t === void 0) { t = null; } + t = t ? t : new Date(); + var m = t.getMonth() + 1; + var a = m < 10 ? "0" : ""; + var d = t.getDate(); + var b = d < 10 ? "0" : ""; + return parseInt(t.getFullYear() + a + m + b + d); + }; + TimeUtils.weekId = function (d, first) { + if (d === void 0) { d = null; } + if (first === void 0) { first = true; } + d = d ? d : new Date(); + var c = new Date(); + c.setTime(d.getTime()); + c.setDate(1); + c.setMonth(0); + var year = c.getFullYear(); + var firstDay = c.getDay(); + if (firstDay == 0) { + firstDay = 7; + } + var max = false; + if (firstDay <= 4) { + max = firstDay > 1; + c.setDate(c.getDate() - (firstDay - 1)); + } + else { + c.setDate(c.getDate() + 7 - firstDay + 1); + } + var num = this.diffDay(d, c, false); + if (num < 0) { + c.setDate(1); + c.setMonth(0); + c.setDate(c.getDate() - 1); + return this.weekId(c, false); + } + var week = num / 7; + var weekIdx = Math.floor(week) + 1; + if (weekIdx == 53) { + c.setTime(d.getTime()); + c.setDate(c.getDate() - 1); + var endDay = c.getDay(); + if (endDay == 0) { + endDay = 7; + } + if (first && (!max || endDay < 4)) { + c.setFullYear(c.getFullYear() + 1); + c.setDate(1); + c.setMonth(0); + return this.weekId(c, false); + } + } + var g = weekIdx > 9 ? "" : "0"; + var s = year + "00" + g + weekIdx; + return parseInt(s); + }; + TimeUtils.diffDay = function (a, b, fixOne) { + if (fixOne === void 0) { fixOne = false; } + var x = (a.getTime() - b.getTime()) / 86400000; + return fixOne ? Math.ceil(x) : Math.floor(x); + }; + TimeUtils.getFirstDayOfWeek = function (d) { + d = d ? d : new Date(); + var day = d.getDay() || 7; + return new Date(d.getFullYear(), d.getMonth(), d.getDate() + 1 - day, 0, 0, 0, 0); + }; + TimeUtils.getFirstOfDay = function (d) { + d = d ? d : new Date(); + d.setHours(0, 0, 0, 0); + return d; + }; + TimeUtils.getNextFirstOfDay = function (d) { + return new Date(this.getFirstOfDay(d).getTime() + 86400000); + }; + TimeUtils.formatDate = function (date) { + var y = date.getFullYear(); + var m = date.getMonth() + 1; + m = m < 10 ? '0' + m : m; + var d = date.getDate(); + d = d < 10 ? ('0' + d) : d; + return y + '-' + m + '-' + d; + }; + TimeUtils.formatDateTime = function (date) { + var y = date.getFullYear(); + var m = date.getMonth() + 1; + m = m < 10 ? ('0' + m) : m; + var d = date.getDate(); + d = d < 10 ? ('0' + d) : d; + var h = date.getHours(); + var i = date.getMinutes(); + i = i < 10 ? ('0' + i) : i; + var s = date.getSeconds(); + s = s < 10 ? ('0' + s) : s; + return y + '-' + m + '-' + d + ' ' + h + ':' + i + ":" + s; + }; + TimeUtils.parseDate = function (s) { + var t = Date.parse(s); + if (!isNaN(t)) { + return new Date(Date.parse(s.replace(/-/g, "/"))); + } + else { + return new Date(); + } + }; + TimeUtils.secondToTime = function (time, partition, showHour) { + if (time === void 0) { time = 0; } + if (partition === void 0) { partition = ":"; } + if (showHour === void 0) { showHour = true; } + var hours = Math.floor(time / 3600); + var minutes = Math.floor(time % 3600 / 60); + var seconds = Math.floor(time % 3600 % 60); + var h = hours.toString(); + var m = minutes.toString(); + var s = seconds.toString(); + if (hours < 10) + h = "0" + h; + if (minutes < 10) + m = "0" + m; + if (seconds < 10) + s = "0" + s; + var timeStr; + if (showHour) + timeStr = h + partition + m + partition + s; + else + timeStr = m + partition + s; + return timeStr; + }; + TimeUtils.timeToMillisecond = function (time, partition) { + if (partition === void 0) { partition = ":"; } + var _ary = time.split(partition); + var timeNum = 0; + var len = _ary.length; + for (var i = 0; i < len; i++) { + var n = _ary[i]; + timeNum += n * Math.pow(60, (len - 1 - i)); + } + timeNum *= 1000; + return timeNum.toString(); + }; + return TimeUtils; +}()); +var es; +(function (es) { + var GraphicsCapabilities = (function (_super) { + __extends(GraphicsCapabilities, _super); + function GraphicsCapabilities() { + return _super !== null && _super.apply(this, arguments) || this; + } + GraphicsCapabilities.prototype.initialize = function (device) { + this.platformInitialize(device); + }; + GraphicsCapabilities.prototype.platformInitialize = function (device) { + if (GraphicsCapabilities.runtimeType != egret.RuntimeType.WXGAME) + return; + var capabilities = this; + capabilities["isMobile"] = true; + var systemInfo = wx.getSystemInfoSync(); + var systemStr = systemInfo.system.toLowerCase(); + if (systemStr.indexOf("ios") > -1) { + capabilities["os"] = "iOS"; + } + else if (systemStr.indexOf("android") > -1) { + capabilities["os"] = "Android"; + } + var language = systemInfo.language; + if (language.indexOf('zh') > -1) { + language = "zh-CN"; + } + else { + language = "en-US"; + } + capabilities["language"] = language; + }; + return GraphicsCapabilities; + }(egret.Capabilities)); + es.GraphicsCapabilities = GraphicsCapabilities; +})(es || (es = {})); +var es; +(function (es) { + var GraphicsDevice = (function () { + function GraphicsDevice() { + this.setup(); + this.graphicsCapabilities = new es.GraphicsCapabilities(); + this.graphicsCapabilities.initialize(this); + } + Object.defineProperty(GraphicsDevice.prototype, "viewport", { + get: function () { + return this._viewport; + }, + enumerable: true, + configurable: true + }); + GraphicsDevice.prototype.setup = function () { + this._viewport = new es.Viewport(0, 0, es.Core._instance.stage.stageWidth, es.Core._instance.stage.stageHeight); + }; + return GraphicsDevice; + }()); + es.GraphicsDevice = GraphicsDevice; +})(es || (es = {})); +var es; +(function (es) { + var Viewport = (function () { + function Viewport(x, y, width, height) { + this._x = x; + this._y = y; + this._width = width; + this._height = height; + this._minDepth = 0; + this._maxDepth = 1; + } + Object.defineProperty(Viewport.prototype, "width", { + get: function () { + return this._width; + }, + set: function (value) { + this._width = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Viewport.prototype, "height", { + get: function () { + return this._height; + }, + set: function (value) { + this._height = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Viewport.prototype, "aspectRatio", { + get: function () { + if ((this._height != 0) && (this._width != 0)) + return (this._width / this._height); + return 0; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Viewport.prototype, "bounds", { + get: function () { + return new es.Rectangle(this._x, this._y, this._width, this._height); + }, + set: function (value) { + this._x = value.x; + this._y = value.y; + this._width = value.width; + this._height = value.height; + }, + enumerable: true, + configurable: true + }); + return Viewport; + }()); + es.Viewport = Viewport; +})(es || (es = {})); +var es; +(function (es) { + var GaussianBlurEffect = (function (_super) { + __extends(GaussianBlurEffect, _super); + function GaussianBlurEffect() { + return _super.call(this, es.PostProcessor.default_vert, GaussianBlurEffect.blur_frag, { + screenWidth: es.Core.graphicsDevice.viewport.width, + screenHeight: es.Core.graphicsDevice.viewport.height + }) || this; + } + GaussianBlurEffect.blur_frag = "precision mediump float;\n" + + "uniform sampler2D uSampler;\n" + + "uniform float screenWidth;\n" + + "uniform float screenHeight;\n" + + "float normpdf(in float x, in float sigma)\n" + + "{\n" + + "return 0.39894*exp(-0.5*x*x/(sigma*sigma))/sigma;\n" + + "}\n" + + "void main()\n" + + "{\n" + + "vec3 c = texture2D(uSampler, gl_FragCoord.xy / vec2(screenWidth, screenHeight).xy).rgb;\n" + + "const int mSize = 11;\n" + + "const int kSize = (mSize - 1)/2;\n" + + "float kernel[mSize];\n" + + "vec3 final_colour = vec3(0.0);\n" + + "float sigma = 7.0;\n" + + "float z = 0.0;\n" + + "for (int j = 0; j <= kSize; ++j)\n" + + "{\n" + + "kernel[kSize+j] = kernel[kSize-j] = normpdf(float(j),sigma);\n" + + "}\n" + + "for (int j = 0; j < mSize; ++j)\n" + + "{\n" + + "z += kernel[j];\n" + + "}\n" + + "for (int i = -kSize; i <= kSize; ++i)\n" + + "{\n" + + "for (int j = -kSize; j <= kSize; ++j)\n" + + "{\n" + + "final_colour += kernel[kSize+j]*kernel[kSize+i]*texture2D(uSampler, (gl_FragCoord.xy+vec2(float(i),float(j))) / vec2(screenWidth, screenHeight).xy).rgb;\n" + + "}\n}\n" + + "gl_FragColor = vec4(final_colour/(z*z), 1.0);\n" + + "}"; + return GaussianBlurEffect; + }(egret.CustomFilter)); + es.GaussianBlurEffect = GaussianBlurEffect; +})(es || (es = {})); +var es; +(function (es) { + var PolygonLightEffect = (function (_super) { + __extends(PolygonLightEffect, _super); + function PolygonLightEffect() { + return _super.call(this, PolygonLightEffect.vertSrc, PolygonLightEffect.fragmentSrc) || this; + } + PolygonLightEffect.vertSrc = "attribute vec2 aVertexPosition;\n" + "attribute vec2 aTextureCoord;\n" + "uniform vec2 projectionVector;\n" + "varying vec2 vTextureCoord;\n" + @@ -3236,1745 +4918,3745 @@ var WindTransition = (function (_super) { " gl_Position = vec4( (aVertexPosition / projectionVector) + center , 0.0, 1.0);\n" + " vTextureCoord = aTextureCoord;\n" + "}"; - var fragmentSrc = "precision lowp float;\n" + + PolygonLightEffect.fragmentSrc = "precision lowp float;\n" + "varying vec2 vTextureCoord;\n" + "uniform sampler2D uSampler;\n" + - "uniform float _progress;\n" + - "uniform float _size;\n" + - "uniform float _windSegments;\n" + + "#define SAMPLE_COUNT 15\n" + + "uniform vec2 _sampleOffsets[SAMPLE_COUNT];\n" + + "uniform float _sampleWeights[SAMPLE_COUNT];\n" + "void main(void) {\n" + - "vec2 co = floor(vec2(0.0, vTextureCoord.y * _windSegments));\n" + - "float x = sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453;\n" + - "float r = x - floor(x);\n" + - "float m = smoothstep(0.0, -_size, vTextureCoord.x * (1.0 - _size) + _size * r - (_progress * (1.0 + _size)));\n" + - "vec4 fg = texture2D(uSampler, vTextureCoord);\n" + - "gl_FragColor = mix(fg, vec4(0, 0, 0, 0), m);\n" + + "vec4 c = vec4(0, 0, 0, 0);\n" + + "for( int i = 0; i < SAMPLE_COUNT; i++ )\n" + + " c += texture2D( uSampler, vTextureCoord + _sampleOffsets[i] ) * _sampleWeights[i];\n" + + "gl_FragColor = c;\n" + "}"; - _this._windEffect = new egret.CustomFilter(vertexSrc, fragmentSrc, { - _progress: 0, - _size: 0.3, - _windSegments: 100 - }); - _this._mask = new egret.Shape(); - _this._mask.graphics.beginFill(0xFFFFFF, 1); - _this._mask.graphics.drawRect(0, 0, SceneManager.stage.stageWidth, SceneManager.stage.stageHeight); - _this._mask.graphics.endFill(); - _this._mask.filters = [_this._windEffect]; - SceneManager.stage.addChild(_this._mask); - return _this; - } - Object.defineProperty(WindTransition.prototype, "windSegments", { - set: function (value) { - this._windEffect.uniforms._windSegments = value; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(WindTransition.prototype, "size", { - set: function (value) { - this._windEffect.uniforms._size = value; - }, - enumerable: true, - configurable: true - }); - WindTransition.prototype.onBeginTransition = function () { - return __awaiter(this, void 0, void 0, function () { - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - this.loadNextScene(); - return [4, this.tickEffectProgressProperty(this._windEffect, this.duration, this.easeType)]; - case 1: - _a.sent(); - this.transitionComplete(); - SceneManager.stage.removeChild(this._mask); - return [2]; - } - }); - }); - }; - return WindTransition; -}(SceneTransition)); -var Flags = (function () { - function Flags() { - } - Flags.isFlagSet = function (self, flag) { - return (self & flag) != 0; - }; - Flags.isUnshiftedFlagSet = function (self, flag) { - flag = 1 << flag; - return (self & flag) != 0; - }; - Flags.setFlagExclusive = function (self, flag) { - return 1 << flag; - }; - Flags.setFlag = function (self, flag) { - return (self | 1 << flag); - }; - Flags.unsetFlag = function (self, flag) { - flag = 1 << flag; - return (self & (~flag)); - }; - Flags.invertFlags = function (self) { - return ~self; - }; - return Flags; -}()); -var MathHelper = (function () { - function MathHelper() { - } - MathHelper.toDegrees = function (radians) { - return radians * 57.295779513082320876798154814105; - }; - MathHelper.toRadians = function (degrees) { - return degrees * 0.017453292519943295769236907684886; - }; - MathHelper.map = function (value, leftMin, leftMax, rightMin, rightMax) { - return rightMin + (value - leftMin) * (rightMax - rightMin) / (leftMax - leftMin); - }; - MathHelper.lerp = function (value1, value2, amount) { - return value1 + (value2 - value1) * amount; - }; - MathHelper.clamp = function (value, min, max) { - if (value < min) - return min; - if (value > max) - return max; - return value; - }; - MathHelper.pointOnCirlce = function (circleCenter, radius, angleInDegrees) { - var radians = MathHelper.toRadians(angleInDegrees); - return new Vector2(Math.cos(radians) * radians + circleCenter.x, Math.sin(radians) * radians + circleCenter.y); - }; - MathHelper.isEven = function (value) { - return value % 2 == 0; - }; - MathHelper.Epsilon = 0.00001; - MathHelper.Rad2Deg = 57.29578; - MathHelper.Deg2Rad = 0.0174532924; - return MathHelper; -}()); -var Matrix2D = (function () { - function Matrix2D(m11, m12, m21, m22, m31, m32) { - this.m11 = 0; - this.m12 = 0; - this.m21 = 0; - this.m22 = 0; - this.m31 = 0; - this.m32 = 0; - this.m11 = m11 ? m11 : 1; - this.m12 = m12 ? m12 : 0; - this.m21 = m21 ? m21 : 0; - this.m22 = m22 ? m22 : 1; - this.m31 = m31 ? m31 : 0; - this.m32 = m32 ? m32 : 0; - } - Object.defineProperty(Matrix2D, "identity", { - get: function () { - return Matrix2D._identity; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Matrix2D.prototype, "translation", { - get: function () { - return new Vector2(this.m31, this.m32); - }, - set: function (value) { - this.m31 = value.x; - this.m32 = value.y; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Matrix2D.prototype, "rotation", { - get: function () { - return Math.atan2(this.m21, this.m11); - }, - set: function (value) { - var val1 = Math.cos(value); - var val2 = Math.sin(value); - this.m11 = val1; - this.m12 = val2; - this.m21 = -val2; - this.m22 = val1; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Matrix2D.prototype, "rotationDegrees", { - get: function () { - return MathHelper.toDegrees(this.rotation); - }, - set: function (value) { - this.rotation = MathHelper.toRadians(value); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Matrix2D.prototype, "scale", { - get: function () { - return new Vector2(this.m11, this.m22); - }, - set: function (value) { - this.m11 = value.x; - this.m12 = value.y; - }, - enumerable: true, - configurable: true - }); - Matrix2D.add = function (matrix1, matrix2) { - matrix1.m11 += matrix2.m11; - matrix1.m12 += matrix2.m12; - matrix1.m21 += matrix2.m21; - matrix1.m22 += matrix2.m22; - matrix1.m31 += matrix2.m31; - matrix1.m32 += matrix2.m32; - return matrix1; - }; - Matrix2D.divide = function (matrix1, matrix2) { - matrix1.m11 /= matrix2.m11; - matrix1.m12 /= matrix2.m12; - matrix1.m21 /= matrix2.m21; - matrix1.m22 /= matrix2.m22; - matrix1.m31 /= matrix2.m31; - matrix1.m32 /= matrix2.m32; - return matrix1; - }; - Matrix2D.multiply = function (matrix1, matrix2) { - var result = new Matrix2D(); - var m11 = (matrix1.m11 * matrix2.m11) + (matrix1.m12 * matrix2.m21); - var m12 = (matrix1.m11 * matrix2.m12) + (matrix1.m12 * matrix2.m22); - var m21 = (matrix1.m21 * matrix2.m11) + (matrix1.m22 * matrix2.m21); - var m22 = (matrix1.m21 * matrix2.m12) + (matrix1.m22 * matrix2.m22); - var m31 = (matrix1.m31 * matrix2.m11) + (matrix1.m32 * matrix2.m21) + matrix2.m31; - var m32 = (matrix1.m31 * matrix2.m12) + (matrix1.m32 * matrix2.m22) + matrix2.m32; - result.m11 = m11; - result.m12 = m12; - result.m21 = m21; - result.m22 = m22; - result.m31 = m31; - result.m32 = m32; - return result; - }; - Matrix2D.multiplyTranslation = function (matrix, x, y) { - var trans = Matrix2D.createTranslation(x, y); - return Matrix2D.multiply(matrix, trans); - }; - Matrix2D.prototype.determinant = function () { - return this.m11 * this.m22 - this.m12 * this.m21; - }; - Matrix2D.invert = function (matrix, result) { - if (result === void 0) { result = new Matrix2D(); } - var det = 1 / matrix.determinant(); - result.m11 = matrix.m22 * det; - result.m12 = -matrix.m12 * det; - result.m21 = -matrix.m21 * det; - result.m22 = matrix.m11 * det; - result.m31 = (matrix.m32 * matrix.m21 - matrix.m31 * matrix.m22) * det; - result.m32 = -(matrix.m32 * matrix.m11 - matrix.m31 * matrix.m12) * det; - return result; - }; - Matrix2D.createTranslation = function (xPosition, yPosition) { - var result = new Matrix2D(); - result.m11 = 1; - result.m12 = 0; - result.m21 = 0; - result.m22 = 1; - result.m31 = xPosition; - result.m32 = yPosition; - return result; - }; - Matrix2D.createTranslationVector = function (position) { - return this.createTranslation(position.x, position.y); - }; - Matrix2D.createRotation = function (radians, result) { - result = new Matrix2D(); - var val1 = Math.cos(radians); - var val2 = Math.sin(radians); - result.m11 = val1; - result.m12 = val2; - result.m21 = -val2; - result.m22 = val1; - return result; - }; - Matrix2D.createScale = function (xScale, yScale, result) { - if (result === void 0) { result = new Matrix2D(); } - result.m11 = xScale; - result.m12 = 0; - result.m21 = 0; - result.m22 = yScale; - result.m31 = 0; - result.m32 = 0; - return result; - }; - Matrix2D.prototype.toEgretMatrix = function () { - var matrix = new egret.Matrix(this.m11, this.m12, this.m21, this.m22, this.m31, this.m32); - return matrix; - }; - Matrix2D._identity = new Matrix2D(1, 0, 0, 1, 0, 0); - return Matrix2D; -}()); -var Rectangle = (function (_super) { - __extends(Rectangle, _super); - function Rectangle() { - return _super !== null && _super.apply(this, arguments) || this; - } - Object.defineProperty(Rectangle.prototype, "max", { - get: function () { - return new Vector2(this.right, this.bottom); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Rectangle.prototype, "center", { - get: function () { - return new Vector2(this.x + (this.width / 2), this.y + (this.height / 2)); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Rectangle.prototype, "location", { - get: function () { - return new Vector2(this.x, this.y); - }, - set: function (value) { - this.x = value.x; - this.y = value.y; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Rectangle.prototype, "size", { - get: function () { - return new Vector2(this.width, this.height); - }, - set: function (value) { - this.width = value.x; - this.height = value.y; - }, - enumerable: true, - configurable: true - }); - Rectangle.prototype.intersects = function (value) { - return value.left < this.right && - this.left < value.right && - value.top < this.bottom && - this.top < value.bottom; - }; - Rectangle.prototype.containsInVec = function (value) { - return ((((this.x <= value.x) && (value.x < (this.x + this.width))) && - (this.y <= value.y)) && - (value.y < (this.y + this.height))); - }; - Rectangle.prototype.containsRect = function (value) { - return ((((this.x <= value.x) && (value.x < (this.x + this.width))) && - (this.y <= value.y)) && - (value.y < (this.y + this.height))); - }; - Rectangle.prototype.getHalfSize = function () { - return new Vector2(this.width * 0.5, this.height * 0.5); - }; - Rectangle.fromMinMax = function (minX, minY, maxX, maxY) { - return new Rectangle(minX, minY, maxX - minX, maxY - minY); - }; - Rectangle.prototype.getClosestPointOnRectangleBorderToPoint = function (point) { - var edgeNormal = Vector2.zero; - var res = new Vector2(); - res.x = MathHelper.clamp(point.x, this.left, this.right); - res.y = MathHelper.clamp(point.y, this.top, this.bottom); - if (this.containsInVec(res)) { - var dl = res.x - this.left; - var dr = this.right - res.x; - var dt = res.y - this.top; - var db = this.bottom - res.y; - var min = Math.min(dl, dr, dt, db); - if (min == dt) { - res.y = this.top; - edgeNormal.y = -1; - } - else if (min == db) { - res.y = this.bottom; - edgeNormal.y = 1; - } - else if (min == dl) { - res.x = this.left; - edgeNormal.x = -1; - } - else { - res.x = this.right; - edgeNormal.x = 1; - } + return PolygonLightEffect; + }(egret.CustomFilter)); + es.PolygonLightEffect = PolygonLightEffect; +})(es || (es = {})); +var es; +(function (es) { + var PostProcessor = (function () { + function PostProcessor(effect) { + if (effect === void 0) { effect = null; } + this.enabled = true; + this.effect = effect; } - else { - if (res.x == this.left) - edgeNormal.x = -1; - if (res.x == this.right) - edgeNormal.x = 1; - if (res.y == this.top) - edgeNormal.y = -1; - if (res.y == this.bottom) - edgeNormal.y = 1; - } - return { res: res, edgeNormal: edgeNormal }; - }; - Rectangle.prototype.getClosestPointOnBoundsToOrigin = function () { - var max = this.max; - var minDist = Math.abs(this.location.x); - var boundsPoint = new Vector2(this.location.x, 0); - if (Math.abs(max.x) < minDist) { - minDist = Math.abs(max.x); - boundsPoint.x = max.x; - boundsPoint.y = 0; - } - if (Math.abs(max.y) < minDist) { - minDist = Math.abs(max.y); - boundsPoint.x = 0; - boundsPoint.y = max.y; - } - if (Math.abs(this.location.y) < minDist) { - minDist = Math.abs(this.location.y); - boundsPoint.x = 0; - boundsPoint.y = this.location.y; - } - return boundsPoint; - }; - Rectangle.rectEncompassingPoints = function (points) { - var minX = Number.POSITIVE_INFINITY; - var minY = Number.POSITIVE_INFINITY; - var maxX = Number.NEGATIVE_INFINITY; - var maxY = Number.NEGATIVE_INFINITY; - for (var i = 0; i < points.length; i++) { - var pt = points[i]; - if (pt.x < minX) - minX = pt.x; - if (pt.x > maxX) - maxX = pt.x; - if (pt.y < minY) - minY = pt.y; - if (pt.y > maxY) - maxY = pt.y; - } - return this.fromMinMax(minX, minY, maxX, maxY); - }; - return Rectangle; -}(egret.Rectangle)); -var Vector3 = (function () { - function Vector3(x, y, z) { - this.x = x; - this.y = y; - this.z = z; - } - return Vector3; -}()); -var ColliderTriggerHelper = (function () { - function ColliderTriggerHelper(entity) { - this._activeTriggerIntersections = []; - this._previousTriggerIntersections = []; - this._tempTriggerList = []; - this._entity = entity; - } - ColliderTriggerHelper.prototype.update = function () { - var colliders = this._entity.getComponents(Collider); - for (var i = 0; i < colliders.length; i++) { - var collider = colliders[i]; - var boxcastResult = Physics.boxcastBroadphase(collider.bounds, collider.collidesWithLayers); - collider.bounds = boxcastResult.rect; - var neighbors = boxcastResult.colliders; - var _loop_5 = function (j) { - var neighbor = neighbors[j]; - if (!collider.isTrigger && !neighbor.isTrigger) - return "continue"; - if (collider.overlaps(neighbor)) { - var pair_1 = new Pair(collider, neighbor); - var shouldReportTriggerEvent = this_1._activeTriggerIntersections.findIndex(function (value) { - return value.first == pair_1.first && value.second == pair_1.second; - }) == -1 && this_1._previousTriggerIntersections.findIndex(function (value) { - return value.first == pair_1.first && value.second == pair_1.second; - }) == -1; - if (shouldReportTriggerEvent) - this_1.notifyTriggerListeners(pair_1, true); - if (!this_1._activeTriggerIntersections.contains(pair_1)) - this_1._activeTriggerIntersections.push(pair_1); - } - }; - var this_1 = this; - for (var j = 0; j < neighbors.length; j++) { - _loop_5(j); - } - } - ListPool.free(colliders); - this.checkForExitedColliders(); - }; - ColliderTriggerHelper.prototype.checkForExitedColliders = function () { - var _this = this; - var _loop_6 = function (i) { - var index = this_2._previousTriggerIntersections.findIndex(function (value) { - if (value.first == _this._activeTriggerIntersections[i].first && value.second == _this._activeTriggerIntersections[i].second) - return true; - return false; - }); - if (index != -1) - this_2._previousTriggerIntersections.removeAt(index); + PostProcessor.prototype.onAddedToScene = function (scene) { + this.scene = scene; + this.shape = new egret.Shape(); + this.shape.graphics.beginFill(0xFFFFFF, 1); + this.shape.graphics.drawRect(0, 0, es.Core.graphicsDevice.viewport.width, es.Core.graphicsDevice.viewport.height); + this.shape.graphics.endFill(); + scene.addChild(this.shape); }; - var this_2 = this; - for (var i = 0; i < this._activeTriggerIntersections.length; i++) { - _loop_6(i); - } - for (var i = 0; i < this._previousTriggerIntersections.length; i++) { - this.notifyTriggerListeners(this._previousTriggerIntersections[i], false); - } - this._previousTriggerIntersections.length = 0; - for (var i = 0; i < this._activeTriggerIntersections.length; i++) { - if (!this._previousTriggerIntersections.contains(this._activeTriggerIntersections[i])) { - this._previousTriggerIntersections.push(this._activeTriggerIntersections[i]); + PostProcessor.prototype.process = function () { + this.drawFullscreenQuad(); + }; + PostProcessor.prototype.onSceneBackBufferSizeChanged = function (newWidth, newHeight) { + }; + PostProcessor.prototype.unload = function () { + if (this.effect) { + this.effect = null; } + this.scene.removeChild(this.shape); + this.scene = null; + }; + PostProcessor.prototype.drawFullscreenQuad = function () { + this.scene.filters = [this.effect]; + }; + PostProcessor.default_vert = "attribute vec2 aVertexPosition;\n" + + "attribute vec2 aTextureCoord;\n" + + "attribute vec2 aColor;\n" + + "uniform vec2 projectionVector;\n" + + "varying vec2 vTextureCoord;\n" + + "varying vec4 vColor;\n" + + "const vec2 center = vec2(-1.0, 1.0);\n" + + "void main(void) {\n" + + "gl_Position = vec4( (aVertexPosition / projectionVector) + center , 0.0, 1.0);\n" + + "vTextureCoord = aTextureCoord;\n" + + "vColor = vec4(aColor.x, aColor.x, aColor.x, aColor.x);\n" + + "}"; + return PostProcessor; + }()); + es.PostProcessor = PostProcessor; +})(es || (es = {})); +var es; +(function (es) { + var GaussianBlurPostProcessor = (function (_super) { + __extends(GaussianBlurPostProcessor, _super); + function GaussianBlurPostProcessor() { + return _super !== null && _super.apply(this, arguments) || this; } - this._activeTriggerIntersections.length = 0; - }; - ColliderTriggerHelper.prototype.notifyTriggerListeners = function (collisionPair, isEntering) { - collisionPair.first.entity.getComponents("ITriggerListener", this._tempTriggerList); - for (var i = 0; i < this._tempTriggerList.length; i++) { - if (isEntering) { - this._tempTriggerList[i].onTriggerEnter(collisionPair.second, collisionPair.first); + GaussianBlurPostProcessor.prototype.onAddedToScene = function (scene) { + _super.prototype.onAddedToScene.call(this, scene); + this.effect = new es.GaussianBlurEffect(); + }; + return GaussianBlurPostProcessor; + }(es.PostProcessor)); + es.GaussianBlurPostProcessor = GaussianBlurPostProcessor; +})(es || (es = {})); +var es; +(function (es) { + var Renderer = (function () { + function Renderer(renderOrder, camera) { + if (camera === void 0) { camera = null; } + this.renderOrder = 0; + this.camera = camera; + this.renderOrder = renderOrder; + } + Renderer.prototype.onAddedToScene = function (scene) { + }; + Renderer.prototype.unload = function () { + }; + Renderer.prototype.onSceneBackBufferSizeChanged = function (newWidth, newHeight) { + }; + Renderer.prototype.compareTo = function (other) { + return this.renderOrder - other.renderOrder; + }; + Renderer.prototype.beginRender = function (cam) { + }; + Renderer.prototype.renderAfterStateCheck = function (renderable, cam) { + renderable.render(cam); + }; + return Renderer; + }()); + es.Renderer = Renderer; +})(es || (es = {})); +var es; +(function (es) { + var DefaultRenderer = (function (_super) { + __extends(DefaultRenderer, _super); + function DefaultRenderer() { + return _super.call(this, 0, null) || this; + } + DefaultRenderer.prototype.render = function (scene) { + var cam = this.camera ? this.camera : scene.camera; + this.beginRender(cam); + for (var i = 0; i < scene.renderableComponents.count; i++) { + var renderable = scene.renderableComponents.buffer[i]; + if (renderable.enabled && renderable.isVisibleFromCamera(cam)) + this.renderAfterStateCheck(renderable, cam); + } + }; + return DefaultRenderer; + }(es.Renderer)); + es.DefaultRenderer = DefaultRenderer; +})(es || (es = {})); +var es; +(function (es) { + var ScreenSpaceRenderer = (function (_super) { + __extends(ScreenSpaceRenderer, _super); + function ScreenSpaceRenderer() { + return _super !== null && _super.apply(this, arguments) || this; + } + ScreenSpaceRenderer.prototype.render = function (scene) { + }; + return ScreenSpaceRenderer; + }(es.Renderer)); + es.ScreenSpaceRenderer = ScreenSpaceRenderer; +})(es || (es = {})); +var es; +(function (es) { + var PolyLight = (function (_super) { + __extends(PolyLight, _super); + function PolyLight(radius, color, power) { + var _this = _super.call(this) || this; + _this._indices = []; + _this.radius = radius; + _this.power = power; + _this.color = color; + _this.computeTriangleIndices(); + return _this; + } + Object.defineProperty(PolyLight.prototype, "radius", { + get: function () { + return this._radius; + }, + set: function (value) { + this.setRadius(value); + }, + enumerable: true, + configurable: true + }); + PolyLight.prototype.setRadius = function (radius) { + if (radius != this._radius) { + this._radius = radius; + this._areBoundsDirty = true; + } + }; + PolyLight.prototype.render = function (camera) { + }; + PolyLight.prototype.reset = function () { + }; + PolyLight.prototype.computeTriangleIndices = function (totalTris) { + if (totalTris === void 0) { totalTris = 20; } + this._indices.length = 0; + for (var i = 0; i < totalTris; i += 2) { + this._indices.push(0); + this._indices.push(i + 2); + this._indices.push(i + 1); + } + }; + return PolyLight; + }(es.RenderableComponent)); + es.PolyLight = PolyLight; +})(es || (es = {})); +var es; +(function (es) { + var SceneTransition = (function () { + function SceneTransition(sceneLoadAction) { + this.sceneLoadAction = sceneLoadAction; + this.loadsNewScene = sceneLoadAction != null; + } + Object.defineProperty(SceneTransition.prototype, "hasPreviousSceneRender", { + get: function () { + if (!this._hasPreviousSceneRender) { + this._hasPreviousSceneRender = true; + return false; + } + return true; + }, + enumerable: true, + configurable: true + }); + SceneTransition.prototype.preRender = function () { + }; + SceneTransition.prototype.render = function () { + }; + SceneTransition.prototype.onBeginTransition = function () { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4, this.loadNextScene()]; + case 1: + _a.sent(); + this.transitionComplete(); + return [2]; + } + }); + }); + }; + SceneTransition.prototype.tickEffectProgressProperty = function (filter, duration, easeType, reverseDirection) { + if (reverseDirection === void 0) { reverseDirection = false; } + return new Promise(function (resolve) { + var start = reverseDirection ? 1 : 0; + var end = reverseDirection ? 0 : 1; + egret.Tween.get(filter.uniforms).set({ _progress: start }).to({ _progress: end }, duration * 1000, easeType).call(function () { + resolve(); + }); + }); + }; + SceneTransition.prototype.transitionComplete = function () { + es.Core._instance._sceneTransition = null; + if (this.onTransitionCompleted) { + this.onTransitionCompleted(); + } + }; + SceneTransition.prototype.loadNextScene = function () { + return __awaiter(this, void 0, void 0, function () { + var _a; + return __generator(this, function (_b) { + switch (_b.label) { + case 0: + if (this.onScreenObscured) + this.onScreenObscured(); + if (!this.loadsNewScene) { + this.isNewSceneLoaded = true; + } + _a = es.Core; + return [4, this.sceneLoadAction()]; + case 1: + _a.scene = _b.sent(); + this.isNewSceneLoaded = true; + return [2]; + } + }); + }); + }; + return SceneTransition; + }()); + es.SceneTransition = SceneTransition; +})(es || (es = {})); +var es; +(function (es) { + var FadeTransition = (function (_super) { + __extends(FadeTransition, _super); + function FadeTransition(sceneLoadAction) { + var _this = _super.call(this, sceneLoadAction) || this; + _this.fadeToColor = 0x000000; + _this.fadeOutDuration = 0.4; + _this.fadeEaseType = egret.Ease.quadInOut; + _this.delayBeforeFadeInDuration = 0.1; + _this._alpha = 0; + _this._mask = new egret.Shape(); + return _this; + } + FadeTransition.prototype.onBeginTransition = function () { + return __awaiter(this, void 0, void 0, function () { + var _this = this; + return __generator(this, function (_a) { + this._mask.graphics.beginFill(this.fadeToColor, 1); + this._mask.graphics.drawRect(0, 0, es.Core.graphicsDevice.viewport.width, es.Core.graphicsDevice.viewport.height); + this._mask.graphics.endFill(); + egret.Tween.get(this).to({ _alpha: 1 }, this.fadeOutDuration * 1000, this.fadeEaseType) + .call(function () { return __awaiter(_this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4, this.loadNextScene()]; + case 1: + _a.sent(); + return [2]; + } + }); + }); }).wait(this.delayBeforeFadeInDuration).call(function () { + egret.Tween.get(_this).to({ _alpha: 0 }, _this.fadeOutDuration * 1000, _this.fadeEaseType).call(function () { + _this.transitionComplete(); + }); + }); + return [2]; + }); + }); + }; + FadeTransition.prototype.render = function () { + this._mask.graphics.clear(); + this._mask.graphics.beginFill(this.fadeToColor, this._alpha); + this._mask.graphics.drawRect(0, 0, es.Core.graphicsDevice.viewport.width, es.Core.graphicsDevice.viewport.height); + this._mask.graphics.endFill(); + }; + return FadeTransition; + }(es.SceneTransition)); + es.FadeTransition = FadeTransition; +})(es || (es = {})); +var es; +(function (es) { + var WindTransition = (function (_super) { + __extends(WindTransition, _super); + function WindTransition(sceneLoadAction) { + var _this = _super.call(this, sceneLoadAction) || this; + _this.duration = 1; + _this.easeType = egret.Ease.quadOut; + var vertexSrc = "attribute vec2 aVertexPosition;\n" + + "attribute vec2 aTextureCoord;\n" + + "uniform vec2 projectionVector;\n" + + "varying vec2 vTextureCoord;\n" + + "const vec2 center = vec2(-1.0, 1.0);\n" + + "void main(void) {\n" + + " gl_Position = vec4( (aVertexPosition / projectionVector) + center , 0.0, 1.0);\n" + + " vTextureCoord = aTextureCoord;\n" + + "}"; + var fragmentSrc = "precision lowp float;\n" + + "varying vec2 vTextureCoord;\n" + + "uniform sampler2D uSampler;\n" + + "uniform float _progress;\n" + + "uniform float _size;\n" + + "uniform float _windSegments;\n" + + "void main(void) {\n" + + "vec2 co = floor(vec2(0.0, vTextureCoord.y * _windSegments));\n" + + "float x = sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453;\n" + + "float r = x - floor(x);\n" + + "float m = smoothstep(0.0, -_size, vTextureCoord.x * (1.0 - _size) + _size * r - (_progress * (1.0 + _size)));\n" + + "vec4 fg = texture2D(uSampler, vTextureCoord);\n" + + "gl_FragColor = mix(fg, vec4(0, 0, 0, 0), m);\n" + + "}"; + _this._windEffect = new egret.CustomFilter(vertexSrc, fragmentSrc, { + _progress: 0, + _size: 0.3, + _windSegments: 100 + }); + _this._mask = new egret.Shape(); + _this._mask.graphics.beginFill(0xFFFFFF, 1); + _this._mask.graphics.drawRect(0, 0, es.Core.graphicsDevice.viewport.width, es.Core.graphicsDevice.viewport.height); + _this._mask.graphics.endFill(); + _this._mask.filters = [_this._windEffect]; + return _this; + } + Object.defineProperty(WindTransition.prototype, "windSegments", { + set: function (value) { + this._windEffect.uniforms._windSegments = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(WindTransition.prototype, "size", { + set: function (value) { + this._windEffect.uniforms._size = value; + }, + enumerable: true, + configurable: true + }); + WindTransition.prototype.onBeginTransition = function () { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + this.loadNextScene(); + return [4, this.tickEffectProgressProperty(this._windEffect, this.duration, this.easeType)]; + case 1: + _a.sent(); + this.transitionComplete(); + return [2]; + } + }); + }); + }; + return WindTransition; + }(es.SceneTransition)); + es.WindTransition = WindTransition; +})(es || (es = {})); +var es; +(function (es) { + var Bezier = (function () { + function Bezier() { + } + Bezier.getPoint = function (p0, p1, p2, t) { + t = es.MathHelper.clamp01(t); + var oneMinusT = 1 - t; + return es.Vector2.add(es.Vector2.add(es.Vector2.multiply(new es.Vector2(oneMinusT * oneMinusT), p0), es.Vector2.multiply(new es.Vector2(2 * oneMinusT * t), p1)), es.Vector2.multiply(new es.Vector2(t * t), p2)); + }; + Bezier.getFirstDerivative = function (p0, p1, p2, t) { + return es.Vector2.add(es.Vector2.multiply(new es.Vector2(2 * (1 - t)), es.Vector2.subtract(p1, p0)), es.Vector2.multiply(new es.Vector2(2 * t), es.Vector2.subtract(p2, p1))); + }; + Bezier.getFirstDerivativeThree = function (start, firstControlPoint, secondControlPoint, end, t) { + t = es.MathHelper.clamp01(t); + var oneMunusT = 1 - t; + return es.Vector2.add(es.Vector2.add(es.Vector2.multiply(new es.Vector2(3 * oneMunusT * oneMunusT), es.Vector2.subtract(firstControlPoint, start)), es.Vector2.multiply(new es.Vector2(6 * oneMunusT * t), es.Vector2.subtract(secondControlPoint, firstControlPoint))), es.Vector2.multiply(new es.Vector2(3 * t * t), es.Vector2.subtract(end, secondControlPoint))); + }; + Bezier.getPointThree = function (start, firstControlPoint, secondControlPoint, end, t) { + t = es.MathHelper.clamp01(t); + var oneMunusT = 1 - t; + return es.Vector2.add(es.Vector2.add(es.Vector2.add(es.Vector2.multiply(new es.Vector2(oneMunusT * oneMunusT * oneMunusT), start), es.Vector2.multiply(new es.Vector2(3 * oneMunusT * oneMunusT * t), firstControlPoint)), es.Vector2.multiply(new es.Vector2(3 * oneMunusT * t * t), secondControlPoint)), es.Vector2.multiply(new es.Vector2(t * t * t), end)); + }; + Bezier.getOptimizedDrawingPoints = function (start, firstCtrlPoint, secondCtrlPoint, end, distanceTolerance) { + if (distanceTolerance === void 0) { distanceTolerance = 1; } + var points = es.ListPool.obtain(); + points.push(start); + this.recursiveGetOptimizedDrawingPoints(start, firstCtrlPoint, secondCtrlPoint, end, points, distanceTolerance); + points.push(end); + return points; + }; + Bezier.recursiveGetOptimizedDrawingPoints = function (start, firstCtrlPoint, secondCtrlPoint, end, points, distanceTolerance) { + var pt12 = es.Vector2.divide(es.Vector2.add(start, firstCtrlPoint), new es.Vector2(2)); + var pt23 = es.Vector2.divide(es.Vector2.add(firstCtrlPoint, secondCtrlPoint), new es.Vector2(2)); + var pt34 = es.Vector2.divide(es.Vector2.add(secondCtrlPoint, end), new es.Vector2(2)); + var pt123 = es.Vector2.divide(es.Vector2.add(pt12, pt23), new es.Vector2(2)); + var pt234 = es.Vector2.divide(es.Vector2.add(pt23, pt34), new es.Vector2(2)); + var pt1234 = es.Vector2.divide(es.Vector2.add(pt123, pt234), new es.Vector2(2)); + var deltaLine = es.Vector2.subtract(end, start); + var d2 = Math.abs(((firstCtrlPoint.x, end.x) * deltaLine.y - (firstCtrlPoint.y - end.y) * deltaLine.x)); + var d3 = Math.abs(((secondCtrlPoint.x - end.x) * deltaLine.y - (secondCtrlPoint.y - end.y) * deltaLine.x)); + if ((d2 + d3) * (d2 + d3) < distanceTolerance * (deltaLine.x * deltaLine.x + deltaLine.y * deltaLine.y)) { + points.push(pt1234); + return; + } + this.recursiveGetOptimizedDrawingPoints(start, pt12, pt123, pt1234, points, distanceTolerance); + this.recursiveGetOptimizedDrawingPoints(pt1234, pt234, pt34, end, points, distanceTolerance); + }; + return Bezier; + }()); + es.Bezier = Bezier; +})(es || (es = {})); +var es; +(function (es) { + var Flags = (function () { + function Flags() { + } + Flags.isFlagSet = function (self, flag) { + return (self & flag) != 0; + }; + Flags.isUnshiftedFlagSet = function (self, flag) { + flag = 1 << flag; + return (self & flag) != 0; + }; + Flags.setFlagExclusive = function (self, flag) { + return 1 << flag; + }; + Flags.setFlag = function (self, flag) { + return (self | 1 << flag); + }; + Flags.unsetFlag = function (self, flag) { + flag = 1 << flag; + return (self & (~flag)); + }; + Flags.invertFlags = function (self) { + return ~self; + }; + return Flags; + }()); + es.Flags = Flags; +})(es || (es = {})); +var es; +(function (es) { + var MathHelper = (function () { + function MathHelper() { + } + MathHelper.toDegrees = function (radians) { + return radians * 57.295779513082320876798154814105; + }; + MathHelper.toRadians = function (degrees) { + return degrees * 0.017453292519943295769236907684886; + }; + MathHelper.map = function (value, leftMin, leftMax, rightMin, rightMax) { + return rightMin + (value - leftMin) * (rightMax - rightMin) / (leftMax - leftMin); + }; + MathHelper.lerp = function (value1, value2, amount) { + return value1 + (value2 - value1) * amount; + }; + MathHelper.clamp = function (value, min, max) { + if (value < min) + return min; + if (value > max) + return max; + return value; + }; + MathHelper.pointOnCirlce = function (circleCenter, radius, angleInDegrees) { + var radians = MathHelper.toRadians(angleInDegrees); + return new es.Vector2(Math.cos(radians) * radians + circleCenter.x, Math.sin(radians) * radians + circleCenter.y); + }; + MathHelper.isEven = function (value) { + return value % 2 == 0; + }; + MathHelper.clamp01 = function (value) { + if (value < 0) + return 0; + if (value > 1) + return 1; + return value; + }; + MathHelper.angleBetweenVectors = function (from, to) { + return Math.atan2(to.y - from.y, to.x - from.x); + }; + MathHelper.Epsilon = 0.00001; + MathHelper.Rad2Deg = 57.29578; + MathHelper.Deg2Rad = 0.0174532924; + return MathHelper; + }()); + es.MathHelper = MathHelper; +})(es || (es = {})); +var es; +(function (es) { + es.matrixPool = []; + var Matrix2D = (function (_super) { + __extends(Matrix2D, _super); + function Matrix2D() { + return _super !== null && _super.apply(this, arguments) || this; + } + Object.defineProperty(Matrix2D.prototype, "m11", { + get: function () { + return this.a; + }, + set: function (value) { + this.a = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Matrix2D.prototype, "m12", { + get: function () { + return this.b; + }, + set: function (value) { + this.b = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Matrix2D.prototype, "m21", { + get: function () { + return this.c; + }, + set: function (value) { + this.c = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Matrix2D.prototype, "m22", { + get: function () { + return this.d; + }, + set: function (value) { + this.d = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Matrix2D.prototype, "m31", { + get: function () { + return this.tx; + }, + set: function (value) { + this.tx = value; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Matrix2D.prototype, "m32", { + get: function () { + return this.ty; + }, + set: function (value) { + this.ty = value; + }, + enumerable: true, + configurable: true + }); + Matrix2D.create = function () { + var matrix = es.matrixPool.pop(); + if (!matrix) + matrix = new Matrix2D(); + return matrix; + }; + Matrix2D.prototype.identity = function () { + this.a = this.d = 1; + this.b = this.c = this.tx = this.ty = 0; + return this; + }; + Matrix2D.prototype.translate = function (dx, dy) { + this.tx += dx; + this.ty += dy; + return this; + }; + Matrix2D.prototype.scale = function (sx, sy) { + if (sx !== 1) { + this.a *= sx; + this.c *= sx; + this.tx *= sx; + } + if (sy !== 1) { + this.b *= sy; + this.d *= sy; + this.ty *= sy; + } + return this; + }; + Matrix2D.prototype.rotate = function (angle) { + angle = +angle; + if (angle !== 0) { + angle = angle / DEG_TO_RAD; + var u = Math.cos(angle); + var v = Math.sin(angle); + var ta = this.a; + var tb = this.b; + var tc = this.c; + var td = this.d; + var ttx = this.tx; + var tty = this.ty; + this.a = ta * u - tb * v; + this.b = ta * v + tb * u; + this.c = tc * u - td * v; + this.d = tc * v + td * u; + this.tx = ttx * u - tty * v; + this.ty = ttx * v + tty * u; + } + return this; + }; + Matrix2D.prototype.invert = function () { + this.$invertInto(this); + return this; + }; + Matrix2D.prototype.add = function (matrix) { + this.m11 += matrix.m11; + this.m12 += matrix.m12; + this.m21 += matrix.m21; + this.m22 += matrix.m22; + this.m31 += matrix.m31; + this.m32 += matrix.m32; + return this; + }; + Matrix2D.prototype.substract = function (matrix) { + this.m11 -= matrix.m11; + this.m12 -= matrix.m12; + this.m21 -= matrix.m21; + this.m22 -= matrix.m22; + this.m31 -= matrix.m31; + this.m32 -= matrix.m32; + return this; + }; + Matrix2D.prototype.divide = function (matrix) { + this.m11 /= matrix.m11; + this.m12 /= matrix.m12; + this.m21 /= matrix.m21; + this.m22 /= matrix.m22; + this.m31 /= matrix.m31; + this.m32 /= matrix.m32; + return this; + }; + Matrix2D.prototype.multiply = function (matrix) { + var m11 = (this.m11 * matrix.m11) + (this.m12 * matrix.m21); + var m12 = (this.m11 * matrix.m12) + (this.m12 * matrix.m22); + var m21 = (this.m21 * matrix.m11) + (this.m22 * matrix.m21); + var m22 = (this.m21 * matrix.m12) + (this.m22 * matrix.m22); + var m31 = (this.m31 * matrix.m11) + (this.m32 * matrix.m21) + matrix.m31; + var m32 = (this.m31 * matrix.m12) + (this.m32 * matrix.m22) + matrix.m32; + this.m11 = m11; + this.m12 = m12; + this.m21 = m21; + this.m22 = m22; + this.m31 = m31; + this.m32 = m32; + return this; + }; + Matrix2D.prototype.determinant = function () { + return this.m11 * this.m22 - this.m12 * this.m21; + }; + Matrix2D.prototype.release = function (matrix) { + if (!matrix) + return; + es.matrixPool.push(matrix); + }; + return Matrix2D; + }(egret.Matrix)); + es.Matrix2D = Matrix2D; +})(es || (es = {})); +var es; +(function (es) { + var Rectangle = (function (_super) { + __extends(Rectangle, _super); + function Rectangle() { + return _super !== null && _super.apply(this, arguments) || this; + } + Object.defineProperty(Rectangle.prototype, "max", { + get: function () { + return new es.Vector2(this.right, this.bottom); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Rectangle.prototype, "center", { + get: function () { + return new es.Vector2(this.x + (this.width / 2), this.y + (this.height / 2)); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Rectangle.prototype, "location", { + get: function () { + return new es.Vector2(this.x, this.y); + }, + set: function (value) { + this.x = value.x; + this.y = value.y; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Rectangle.prototype, "size", { + get: function () { + return new es.Vector2(this.width, this.height); + }, + set: function (value) { + this.width = value.x; + this.height = value.y; + }, + enumerable: true, + configurable: true + }); + Rectangle.fromMinMax = function (minX, minY, maxX, maxY) { + return new Rectangle(minX, minY, maxX - minX, maxY - minY); + }; + Rectangle.rectEncompassingPoints = function (points) { + var minX = Number.POSITIVE_INFINITY; + var minY = Number.POSITIVE_INFINITY; + var maxX = Number.NEGATIVE_INFINITY; + var maxY = Number.NEGATIVE_INFINITY; + for (var i = 0; i < points.length; i++) { + var pt = points[i]; + if (pt.x < minX) + minX = pt.x; + if (pt.x > maxX) + maxX = pt.x; + if (pt.y < minY) + minY = pt.y; + if (pt.y > maxY) + maxY = pt.y; + } + return this.fromMinMax(minX, minY, maxX, maxY); + }; + Rectangle.prototype.intersects = function (value) { + return value.left < this.right && + this.left < value.right && + value.top < this.bottom && + this.top < value.bottom; + }; + Rectangle.prototype.rayIntersects = function (ray) { + var distance = 0; + var maxValue = Number.MAX_VALUE; + if (Math.abs(ray.direction.x) < 1E-06) { + if ((ray.start.x < this.x) || (ray.start.x > this.x + this.width)) + return distance; } else { - this._tempTriggerList[i].onTriggerExit(collisionPair.second, collisionPair.first); + var num11 = 1 / ray.direction.x; + var num8 = (this.x - ray.start.x) * num11; + var num7 = (this.x + this.width - ray.start.x) * num11; + if (num8 > num7) { + var num14 = num8; + num8 = num7; + num7 = num14; + } + distance = Math.max(num8, distance); + maxValue = Math.min(num7, maxValue); + if (distance > maxValue) + return distance; } - this._tempTriggerList.length = 0; - if (collisionPair.second.entity) { - collisionPair.second.entity.getComponents("ITriggerListener", this._tempTriggerList); - for (var i_2 = 0; i_2 < this._tempTriggerList.length; i_2++) { - if (isEntering) { - this._tempTriggerList[i_2].onTriggerEnter(collisionPair.first, collisionPair.second); - } - else { - this._tempTriggerList[i_2].onTriggerExit(collisionPair.first, collisionPair.second); + if (Math.abs(ray.direction.y) < 1E-06) { + if ((ray.start.y < this.y) || (ray.start.y > this.y + this.height)) + return distance; + } + else { + var num10 = 1 / ray.direction.y; + var num6 = (this.y - ray.start.y) * num10; + var num5 = (this.y + this.height - ray.start.y) * num10; + if (num6 > num5) { + var num13 = num6; + num6 = num5; + num5 = num13; + } + distance = Math.max(num6, distance); + maxValue = Math.max(num5, maxValue); + if (distance > maxValue) + return distance; + } + return distance; + }; + Rectangle.prototype.containsRect = function (value) { + return ((((this.x <= value.x) && (value.x < (this.x + this.width))) && + (this.y <= value.y)) && + (value.y < (this.y + this.height))); + }; + Rectangle.prototype.contains = function (x, y) { + return ((((this.x <= x) && (x < (this.x + this.width))) && (this.y <= y)) && (y < (this.y + this.height))); + }; + Rectangle.prototype.getHalfSize = function () { + return new es.Vector2(this.width * 0.5, this.height * 0.5); + }; + Rectangle.prototype.getClosestPointOnRectangleBorderToPoint = function (point, edgeNormal) { + edgeNormal = es.Vector2.zero; + var res = new es.Vector2(); + res.x = es.MathHelper.clamp(point.x, this.left, this.right); + res.y = es.MathHelper.clamp(point.y, this.top, this.bottom); + if (this.contains(res.x, res.y)) { + var dl = res.x - this.left; + var dr = this.right - res.x; + var dt = res.y - this.top; + var db = this.bottom - res.y; + var min = Math.min(dl, dr, dt, db); + if (min == dt) { + res.y = this.top; + edgeNormal.y = -1; + } + else if (min == db) { + res.y = this.bottom; + edgeNormal.y = 1; + } + else if (min == dl) { + res.x = this.left; + edgeNormal.x = -1; + } + else { + res.x = this.right; + edgeNormal.x = 1; + } + } + else { + if (res.x == this.left) + edgeNormal.x = -1; + if (res.x == this.right) + edgeNormal.x = 1; + if (res.y == this.top) + edgeNormal.y = -1; + if (res.y == this.bottom) + edgeNormal.y = 1; + } + return res; + }; + Rectangle.prototype.getClosestPointOnBoundsToOrigin = function () { + var max = this.max; + var minDist = Math.abs(this.location.x); + var boundsPoint = new es.Vector2(this.location.x, 0); + if (Math.abs(max.x) < minDist) { + minDist = Math.abs(max.x); + boundsPoint.x = max.x; + boundsPoint.y = 0; + } + if (Math.abs(max.y) < minDist) { + minDist = Math.abs(max.y); + boundsPoint.x = 0; + boundsPoint.y = max.y; + } + if (Math.abs(this.location.y) < minDist) { + minDist = Math.abs(this.location.y); + boundsPoint.x = 0; + boundsPoint.y = this.location.y; + } + return boundsPoint; + }; + Rectangle.prototype.calculateBounds = function (parentPosition, position, origin, scale, rotation, width, height) { + if (rotation == 0) { + this.x = parentPosition.x + position.x - origin.x * scale.x; + this.y = parentPosition.y + position.y - origin.y * scale.y; + this.width = width * scale.x; + this.height = height * scale.y; + } + else { + var worldPosX = parentPosition.x + position.x; + var worldPosY = parentPosition.y + position.y; + this._transformMat = es.Matrix2D.create().translate(-worldPosX - origin.x, -worldPosY - origin.y); + this._tempMat = es.Matrix2D.create().scale(scale.x, scale.y); + this._transformMat = this._transformMat.multiply(this._tempMat); + this._tempMat = es.Matrix2D.create().rotate(rotation); + this._transformMat = this._transformMat.multiply(this._tempMat); + this._tempMat = es.Matrix2D.create().translate(worldPosX, worldPosY); + this._transformMat = this._transformMat.multiply(this._tempMat); + var topLeft = new es.Vector2(worldPosX, worldPosY); + var topRight = new es.Vector2(worldPosX + width, worldPosY); + var bottomLeft = new es.Vector2(worldPosX, worldPosY + height); + var bottomRight = new es.Vector2(worldPosX + width, worldPosY + height); + topLeft = es.Vector2Ext.transformR(topLeft, this._transformMat); + topRight = es.Vector2Ext.transformR(topRight, this._transformMat); + bottomLeft = es.Vector2Ext.transformR(bottomLeft, this._transformMat); + bottomRight = es.Vector2Ext.transformR(bottomRight, this._transformMat); + var minX = Math.min(topLeft.x, bottomRight.x, topRight.x, bottomLeft.x); + var maxX = Math.max(topLeft.x, bottomRight.x, topRight.x, bottomLeft.x); + var minY = Math.min(topLeft.y, bottomRight.y, topRight.y, bottomLeft.y); + var maxY = Math.max(topLeft.y, bottomRight.y, topRight.y, bottomLeft.y); + this.location = new es.Vector2(minX, minY); + this.width = maxX - minX; + this.height = maxY - minY; + } + }; + return Rectangle; + }(egret.Rectangle)); + es.Rectangle = Rectangle; +})(es || (es = {})); +var es; +(function (es) { + var Vector3 = (function () { + function Vector3(x, y, z) { + this.x = x; + this.y = y; + this.z = z; + } + return Vector3; + }()); + es.Vector3 = Vector3; +})(es || (es = {})); +var es; +(function (es) { + var ColliderTriggerHelper = (function () { + function ColliderTriggerHelper(entity) { + this._activeTriggerIntersections = []; + this._previousTriggerIntersections = []; + this._tempTriggerList = []; + this._entity = entity; + } + ColliderTriggerHelper.prototype.update = function () { + var colliders = this._entity.getComponents(es.Collider); + for (var i = 0; i < colliders.length; i++) { + var collider = colliders[i]; + var neighbors = es.Physics.boxcastBroadphase(collider.bounds, collider.collidesWithLayers); + var _loop_5 = function (j) { + var neighbor = neighbors[j]; + if (!collider.isTrigger && !neighbor.isTrigger) + return "continue"; + if (collider.overlaps(neighbor)) { + var pair_1 = new es.Pair(collider, neighbor); + var shouldReportTriggerEvent = this_1._activeTriggerIntersections.findIndex(function (value) { + return value.first == pair_1.first && value.second == pair_1.second; + }) == -1 && this_1._previousTriggerIntersections.findIndex(function (value) { + return value.first == pair_1.first && value.second == pair_1.second; + }) == -1; + if (shouldReportTriggerEvent) + this_1.notifyTriggerListeners(pair_1, true); + if (!this_1._activeTriggerIntersections.contains(pair_1)) + this_1._activeTriggerIntersections.push(pair_1); } + }; + var this_1 = this; + for (var j = 0; j < neighbors.length; j++) { + _loop_5(j); + } + } + es.ListPool.free(colliders); + this.checkForExitedColliders(); + }; + ColliderTriggerHelper.prototype.checkForExitedColliders = function () { + var _this = this; + var _loop_6 = function (i) { + var index = this_2._previousTriggerIntersections.findIndex(function (value) { + if (value.first == _this._activeTriggerIntersections[i].first && value.second == _this._activeTriggerIntersections[i].second) + return true; + return false; + }); + if (index != -1) + this_2._previousTriggerIntersections.removeAt(index); + }; + var this_2 = this; + for (var i = 0; i < this._activeTriggerIntersections.length; i++) { + _loop_6(i); + } + for (var i = 0; i < this._previousTriggerIntersections.length; i++) { + this.notifyTriggerListeners(this._previousTriggerIntersections[i], false); + } + this._previousTriggerIntersections.length = 0; + for (var i = 0; i < this._activeTriggerIntersections.length; i++) { + if (!this._previousTriggerIntersections.contains(this._activeTriggerIntersections[i])) { + this._previousTriggerIntersections.push(this._activeTriggerIntersections[i]); + } + } + this._activeTriggerIntersections.length = 0; + }; + ColliderTriggerHelper.prototype.notifyTriggerListeners = function (collisionPair, isEntering) { + collisionPair.first.entity.getComponents("ITriggerListener", this._tempTriggerList); + for (var i = 0; i < this._tempTriggerList.length; i++) { + if (isEntering) { + this._tempTriggerList[i].onTriggerEnter(collisionPair.second, collisionPair.first); + } + else { + this._tempTriggerList[i].onTriggerExit(collisionPair.second, collisionPair.first); } this._tempTriggerList.length = 0; + if (collisionPair.second.entity) { + collisionPair.second.entity.getComponents("ITriggerListener", this._tempTriggerList); + for (var i_2 = 0; i_2 < this._tempTriggerList.length; i_2++) { + if (isEntering) { + this._tempTriggerList[i_2].onTriggerEnter(collisionPair.first, collisionPair.second); + } + else { + this._tempTriggerList[i_2].onTriggerExit(collisionPair.first, collisionPair.second); + } + } + this._tempTriggerList.length = 0; + } } + }; + return ColliderTriggerHelper; + }()); + es.ColliderTriggerHelper = ColliderTriggerHelper; +})(es || (es = {})); +var es; +(function (es) { + var PointSectors; + (function (PointSectors) { + PointSectors[PointSectors["center"] = 0] = "center"; + PointSectors[PointSectors["top"] = 1] = "top"; + PointSectors[PointSectors["bottom"] = 2] = "bottom"; + PointSectors[PointSectors["topLeft"] = 9] = "topLeft"; + PointSectors[PointSectors["topRight"] = 5] = "topRight"; + PointSectors[PointSectors["left"] = 8] = "left"; + PointSectors[PointSectors["right"] = 4] = "right"; + PointSectors[PointSectors["bottomLeft"] = 10] = "bottomLeft"; + PointSectors[PointSectors["bottomRight"] = 6] = "bottomRight"; + })(PointSectors = es.PointSectors || (es.PointSectors = {})); + var Collisions = (function () { + function Collisions() { } - }; - return ColliderTriggerHelper; -}()); -var PointSectors; -(function (PointSectors) { - PointSectors[PointSectors["center"] = 0] = "center"; - PointSectors[PointSectors["top"] = 1] = "top"; - PointSectors[PointSectors["bottom"] = 2] = "bottom"; - PointSectors[PointSectors["topLeft"] = 9] = "topLeft"; - PointSectors[PointSectors["topRight"] = 5] = "topRight"; - PointSectors[PointSectors["left"] = 8] = "left"; - PointSectors[PointSectors["right"] = 4] = "right"; - PointSectors[PointSectors["bottomLeft"] = 10] = "bottomLeft"; - PointSectors[PointSectors["bottomRight"] = 6] = "bottomRight"; -})(PointSectors || (PointSectors = {})); -var Collisions = (function () { - function Collisions() { - } - Collisions.isLineToLine = function (a1, a2, b1, b2) { - var b = Vector2.subtract(a2, a1); - var d = Vector2.subtract(b2, b1); - var bDotDPerp = b.x * d.y - b.y * d.x; - if (bDotDPerp == 0) - return false; - var c = Vector2.subtract(b1, a1); - var t = (c.x * d.y - c.y * d.x) / bDotDPerp; - if (t < 0 || t > 1) - return false; - var u = (c.x * b.y - c.y * b.x) / bDotDPerp; - if (u < 0 || u > 1) - return false; - return true; - }; - Collisions.lineToLineIntersection = function (a1, a2, b1, b2) { - var intersection = new Vector2(0, 0); - var b = Vector2.subtract(a2, a1); - var d = Vector2.subtract(b2, b1); - var bDotDPerp = b.x * d.y - b.y * d.x; - if (bDotDPerp == 0) - return intersection; - var c = Vector2.subtract(b1, a1); - var t = (c.x * d.y - c.y * d.x) / bDotDPerp; - if (t < 0 || t > 1) - return intersection; - var u = (c.x * b.y - c.y * b.x) / bDotDPerp; - if (u < 0 || u > 1) - return intersection; - intersection = Vector2.add(a1, new Vector2(t * b.x, t * b.y)); - return intersection; - }; - Collisions.closestPointOnLine = function (lineA, lineB, closestTo) { - var v = Vector2.subtract(lineB, lineA); - var w = Vector2.subtract(closestTo, lineA); - var t = Vector2.dot(w, v) / Vector2.dot(v, v); - t = MathHelper.clamp(t, 0, 1); - return Vector2.add(lineA, new Vector2(v.x * t, v.y * t)); - }; - Collisions.isCircleToCircle = function (circleCenter1, circleRadius1, circleCenter2, circleRadius2) { - return Vector2.distanceSquared(circleCenter1, circleCenter2) < (circleRadius1 + circleRadius2) * (circleRadius1 + circleRadius2); - }; - Collisions.isCircleToLine = function (circleCenter, radius, lineFrom, lineTo) { - return Vector2.distanceSquared(circleCenter, this.closestPointOnLine(lineFrom, lineTo, circleCenter)) < radius * radius; - }; - Collisions.isCircleToPoint = function (circleCenter, radius, point) { - return Vector2.distanceSquared(circleCenter, point) < radius * radius; - }; - Collisions.isRectToCircle = function (rect, cPosition, cRadius) { - var ew = rect.width * 0.5; - var eh = rect.height * 0.5; - var vx = Math.max(0, Math.max(cPosition.x - rect.x) - ew); - var vy = Math.max(0, Math.max(cPosition.y - rect.y) - eh); - return vx * vx + vy * vy < cRadius * cRadius; - }; - Collisions.isRectToLine = function (rect, lineFrom, lineTo) { - var fromSector = this.getSector(rect.x, rect.y, rect.width, rect.height, lineFrom); - var toSector = this.getSector(rect.x, rect.y, rect.width, rect.height, lineTo); - if (fromSector == PointSectors.center || toSector == PointSectors.center) { + Collisions.isLineToLine = function (a1, a2, b1, b2) { + var b = es.Vector2.subtract(a2, a1); + var d = es.Vector2.subtract(b2, b1); + var bDotDPerp = b.x * d.y - b.y * d.x; + if (bDotDPerp == 0) + return false; + var c = es.Vector2.subtract(b1, a1); + var t = (c.x * d.y - c.y * d.x) / bDotDPerp; + if (t < 0 || t > 1) + return false; + var u = (c.x * b.y - c.y * b.x) / bDotDPerp; + if (u < 0 || u > 1) + return false; return true; - } - else if ((fromSector & toSector) != 0) { + }; + Collisions.lineToLineIntersection = function (a1, a2, b1, b2) { + var intersection = new es.Vector2(0, 0); + var b = es.Vector2.subtract(a2, a1); + var d = es.Vector2.subtract(b2, b1); + var bDotDPerp = b.x * d.y - b.y * d.x; + if (bDotDPerp == 0) + return intersection; + var c = es.Vector2.subtract(b1, a1); + var t = (c.x * d.y - c.y * d.x) / bDotDPerp; + if (t < 0 || t > 1) + return intersection; + var u = (c.x * b.y - c.y * b.x) / bDotDPerp; + if (u < 0 || u > 1) + return intersection; + intersection = es.Vector2.add(a1, new es.Vector2(t * b.x, t * b.y)); + return intersection; + }; + Collisions.closestPointOnLine = function (lineA, lineB, closestTo) { + var v = es.Vector2.subtract(lineB, lineA); + var w = es.Vector2.subtract(closestTo, lineA); + var t = es.Vector2.dot(w, v) / es.Vector2.dot(v, v); + t = es.MathHelper.clamp(t, 0, 1); + return es.Vector2.add(lineA, new es.Vector2(v.x * t, v.y * t)); + }; + Collisions.isCircleToCircle = function (circleCenter1, circleRadius1, circleCenter2, circleRadius2) { + return es.Vector2.distanceSquared(circleCenter1, circleCenter2) < (circleRadius1 + circleRadius2) * (circleRadius1 + circleRadius2); + }; + Collisions.isCircleToLine = function (circleCenter, radius, lineFrom, lineTo) { + return es.Vector2.distanceSquared(circleCenter, this.closestPointOnLine(lineFrom, lineTo, circleCenter)) < radius * radius; + }; + Collisions.isCircleToPoint = function (circleCenter, radius, point) { + return es.Vector2.distanceSquared(circleCenter, point) < radius * radius; + }; + Collisions.isRectToCircle = function (rect, cPosition, cRadius) { + var ew = rect.width * 0.5; + var eh = rect.height * 0.5; + var vx = Math.max(0, Math.max(cPosition.x - rect.x) - ew); + var vy = Math.max(0, Math.max(cPosition.y - rect.y) - eh); + return vx * vx + vy * vy < cRadius * cRadius; + }; + Collisions.isRectToLine = function (rect, lineFrom, lineTo) { + var fromSector = this.getSector(rect.x, rect.y, rect.width, rect.height, lineFrom); + var toSector = this.getSector(rect.x, rect.y, rect.width, rect.height, lineTo); + if (fromSector == PointSectors.center || toSector == PointSectors.center) { + return true; + } + else if ((fromSector & toSector) != 0) { + return false; + } + else { + var both = fromSector | toSector; + var edgeFrom = void 0; + var edgeTo = void 0; + if ((both & PointSectors.top) != 0) { + edgeFrom = new es.Vector2(rect.x, rect.y); + edgeTo = new es.Vector2(rect.x + rect.width, rect.y); + if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo)) + return true; + } + if ((both & PointSectors.bottom) != 0) { + edgeFrom = new es.Vector2(rect.x, rect.y + rect.height); + edgeTo = new es.Vector2(rect.x + rect.width, rect.y + rect.height); + if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo)) + return true; + } + if ((both & PointSectors.left) != 0) { + edgeFrom = new es.Vector2(rect.x, rect.y); + edgeTo = new es.Vector2(rect.x, rect.y + rect.height); + if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo)) + return true; + } + if ((both & PointSectors.right) != 0) { + edgeFrom = new es.Vector2(rect.x + rect.width, rect.y); + edgeTo = new es.Vector2(rect.x + rect.width, rect.y + rect.height); + if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo)) + return true; + } + } return false; + }; + Collisions.isRectToPoint = function (rX, rY, rW, rH, point) { + return point.x >= rX && point.y >= rY && point.x < rX + rW && point.y < rY + rH; + }; + Collisions.getSector = function (rX, rY, rW, rH, point) { + var sector = PointSectors.center; + if (point.x < rX) + sector |= PointSectors.left; + else if (point.x >= rX + rW) + sector |= PointSectors.right; + if (point.y < rY) + sector |= PointSectors.top; + else if (point.y >= rY + rH) + sector |= PointSectors.bottom; + return sector; + }; + return Collisions; + }()); + es.Collisions = Collisions; +})(es || (es = {})); +var es; +(function (es) { + var Physics = (function () { + function Physics() { } - else { - var both = fromSector | toSector; - var edgeFrom = void 0; - var edgeTo = void 0; - if ((both & PointSectors.top) != 0) { - edgeFrom = new Vector2(rect.x, rect.y); - edgeTo = new Vector2(rect.x + rect.width, rect.y); - if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo)) + Physics.reset = function () { + this._spatialHash = new es.SpatialHash(this.spatialHashCellSize); + }; + Physics.clear = function () { + this._spatialHash.clear(); + }; + Physics.overlapCircleAll = function (center, randius, results, layerMask) { + if (layerMask === void 0) { layerMask = -1; } + if (results.length == 0) { + console.error("An empty results array was passed in. No results will ever be returned."); + return; + } + return this._spatialHash.overlapCircle(center, randius, results, layerMask); + }; + Physics.boxcastBroadphase = function (rect, layerMask) { + if (layerMask === void 0) { layerMask = this.allLayers; } + return this._spatialHash.aabbBroadphase(rect, null, layerMask); + }; + Physics.boxcastBroadphaseExcludingSelf = function (collider, rect, layerMask) { + if (layerMask === void 0) { layerMask = this.allLayers; } + return this._spatialHash.aabbBroadphase(rect, collider, layerMask); + }; + Physics.addCollider = function (collider) { + Physics._spatialHash.register(collider); + }; + Physics.removeCollider = function (collider) { + Physics._spatialHash.remove(collider); + }; + Physics.updateCollider = function (collider) { + this._spatialHash.remove(collider); + this._spatialHash.register(collider); + }; + Physics.debugDraw = function (secondsToDisplay) { + this._spatialHash.debugDraw(secondsToDisplay, 2); + }; + Physics.spatialHashCellSize = 100; + Physics.allLayers = -1; + Physics.raycastsHitTriggers = false; + Physics.raycastsStartInColliders = false; + return Physics; + }()); + es.Physics = Physics; +})(es || (es = {})); +var es; +(function (es) { + var Ray2D = (function () { + function Ray2D(position, end) { + this.start = position; + this.end = end; + this.direction = es.Vector2.subtract(this.end, this.start); + } + return Ray2D; + }()); + es.Ray2D = Ray2D; +})(es || (es = {})); +var es; +(function (es) { + var RaycastHit = (function () { + function RaycastHit(collider, fraction, distance, point, normal) { + this.fraction = 0; + this.distance = 0; + this.point = es.Vector2.zero; + this.normal = es.Vector2.zero; + this.collider = collider; + this.fraction = fraction; + this.distance = distance; + this.point = point; + this.centroid = es.Vector2.zero; + } + RaycastHit.prototype.setValues = function (collider, fraction, distance, point) { + this.collider = collider; + this.fraction = fraction; + this.distance = distance; + this.point = point; + }; + RaycastHit.prototype.setValuesNonCollider = function (fraction, distance, point, normal) { + this.fraction = fraction; + this.distance = distance; + this.point = point; + this.normal = normal; + }; + RaycastHit.prototype.reset = function () { + this.collider = null; + this.fraction = this.distance = 0; + }; + RaycastHit.prototype.toString = function () { + return "[RaycastHit] fraction: " + this.fraction + ", distance: " + this.distance + ", normal: " + this.normal + ", centroid: " + this.centroid + ", point: " + this.point; + }; + return RaycastHit; + }()); + es.RaycastHit = RaycastHit; +})(es || (es = {})); +var es; +(function (es) { + var Shape = (function () { + function Shape() { + } + Shape.prototype.clone = function () { + return ObjectUtils.clone(this); + }; + return Shape; + }()); + es.Shape = Shape; +})(es || (es = {})); +var es; +(function (es) { + var Polygon = (function (_super) { + __extends(Polygon, _super); + function Polygon(points, isBox) { + var _this = _super.call(this) || this; + _this._areEdgeNormalsDirty = true; + _this.isUnrotated = true; + _this.setPoints(points); + _this.isBox = isBox; + return _this; + } + Object.defineProperty(Polygon.prototype, "edgeNormals", { + get: function () { + if (this._areEdgeNormalsDirty) + this.buildEdgeNormals(); + return this._edgeNormals; + }, + enumerable: true, + configurable: true + }); + Polygon.prototype.setPoints = function (points) { + this.points = points; + this.recalculateCenterAndEdgeNormals(); + this._originalPoints = []; + for (var i = 0; i < this.points.length; i++) { + this._originalPoints.push(this.points[i]); + } + }; + Polygon.prototype.recalculateCenterAndEdgeNormals = function () { + this._polygonCenter = Polygon.findPolygonCenter(this.points); + this._areEdgeNormalsDirty = true; + }; + Polygon.prototype.buildEdgeNormals = function () { + var totalEdges = this.isBox ? 2 : this.points.length; + if (this._edgeNormals == null || this._edgeNormals.length != totalEdges) + this._edgeNormals = new Array(totalEdges); + var p2; + for (var i = 0; i < totalEdges; i++) { + var p1 = this.points[i]; + if (i + 1 >= this.points.length) + p2 = this.points[0]; + else + p2 = this.points[i + 1]; + var perp = es.Vector2Ext.perpendicular(p1, p2); + perp = es.Vector2.normalize(perp); + this._edgeNormals[i] = perp; + } + }; + Polygon.buildSymmetricalPolygon = function (vertCount, radius) { + var verts = new Array(vertCount); + for (var i = 0; i < vertCount; i++) { + var a = 2 * Math.PI * (i / vertCount); + verts[i] = es.Vector2.multiply(new es.Vector2(Math.cos(a), Math.sin(a)), new es.Vector2(radius)); + } + return verts; + }; + Polygon.recenterPolygonVerts = function (points) { + var center = this.findPolygonCenter(points); + for (var i = 0; i < points.length; i++) + points[i] = es.Vector2.subtract(points[i], center); + }; + Polygon.findPolygonCenter = function (points) { + var x = 0, y = 0; + for (var i = 0; i < points.length; i++) { + x += points[i].x; + y += points[i].y; + } + return new es.Vector2(x / points.length, y / points.length); + }; + Polygon.getFarthestPointInDirection = function (points, direction) { + var index = 0; + var maxDot = es.Vector2.dot(points[index], direction); + for (var i = 1; i < points.length; i++) { + var dot = es.Vector2.dot(points[i], direction); + if (dot > maxDot) { + maxDot = dot; + index = i; + } + } + return points[index]; + }; + Polygon.getClosestPointOnPolygonToPoint = function (points, point, distanceSquared, edgeNormal) { + distanceSquared = Number.MAX_VALUE; + edgeNormal = new es.Vector2(0, 0); + var closestPoint = new es.Vector2(0, 0); + var tempDistanceSquared; + for (var i = 0; i < points.length; i++) { + var j = i + 1; + if (j == points.length) + j = 0; + var closest = es.ShapeCollisions.closestPointOnLine(points[i], points[j], point); + tempDistanceSquared = es.Vector2.distanceSquared(point, closest); + if (tempDistanceSquared < distanceSquared) { + distanceSquared = tempDistanceSquared; + closestPoint = closest; + var line = es.Vector2.subtract(points[j], points[i]); + edgeNormal = new es.Vector2(-line.y, line.x); + } + } + es.Vector2Ext.normalize(edgeNormal); + return closestPoint; + }; + Polygon.rotatePolygonVerts = function (radians, originalPoints, rotatedPoints) { + var cos = Math.cos(radians); + var sin = Math.sign(radians); + for (var i = 0; i < originalPoints.length; i++) { + var position = originalPoints[i]; + rotatedPoints[i] = new es.Vector2(position.x * cos + position.y * -sin, position.x * sin + position.y * cos); + } + }; + Polygon.prototype.recalculateBounds = function (collider) { + this.center = collider.localOffset; + if (collider.shouldColliderScaleAndRotateWithTransform) { + var hasUnitScale = true; + var tempMat = void 0; + var combinedMatrix = es.Matrix2D.create().translate(-this._polygonCenter.x, -this._polygonCenter.y); + if (collider.entity.transform.scale != es.Vector2.zero) { + tempMat = es.Matrix2D.create().scale(collider.entity.transform.scale.x, collider.entity.transform.scale.y); + combinedMatrix = combinedMatrix.multiply(tempMat); + hasUnitScale = false; + this.center = es.Vector2.multiply(collider.localOffset, collider.entity.transform.scale); + } + if (collider.entity.transform.rotation != 0) { + tempMat = es.Matrix2D.create().rotate(collider.entity.transform.rotation); + combinedMatrix = combinedMatrix.multiply(tempMat); + var offsetAngle = Math.atan2(collider.localOffset.y, collider.localOffset.x) * es.MathHelper.Rad2Deg; + var offsetLength = hasUnitScale ? collider._localOffsetLength : + es.Vector2.multiply(collider.localOffset, collider.entity.transform.scale).length(); + this.center = es.MathHelper.pointOnCirlce(es.Vector2.zero, offsetLength, collider.entity.transform.rotation + offsetAngle); + } + tempMat = es.Matrix2D.create().translate(this._polygonCenter.x, this._polygonCenter.y); + combinedMatrix = combinedMatrix.multiply(tempMat); + es.Vector2Ext.transform(this._originalPoints, combinedMatrix, this.points); + this.isUnrotated = collider.entity.transform.rotation == 0; + if (collider._isRotationDirty) + this._areEdgeNormalsDirty = true; + } + this.position = es.Vector2.add(collider.entity.transform.position, this.center); + this.bounds = es.Rectangle.rectEncompassingPoints(this.points); + this.bounds.location = this.bounds.location.add(this.position); + }; + Polygon.prototype.overlaps = function (other) { + var result = new es.CollisionResult(); + if (other instanceof Polygon) + return es.ShapeCollisions.polygonToPolygon(this, other, result); + if (other instanceof es.Circle) { + if (es.ShapeCollisions.circleToPolygon(other, this, result)) { + result.invertResult(); return true; + } + return false; } - if ((both & PointSectors.bottom) != 0) { - edgeFrom = new Vector2(rect.x, rect.y + rect.height); - edgeTo = new Vector2(rect.x + rect.width, rect.y + rect.height); - if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo)) + throw new Error("overlaps of Pologon to " + other + " are not supported"); + }; + Polygon.prototype.collidesWithShape = function (other, result) { + if (other instanceof Polygon) { + return es.ShapeCollisions.polygonToPolygon(this, other, result); + } + if (other instanceof es.Circle) { + if (es.ShapeCollisions.circleToPolygon(other, this, result)) { + result.invertResult(); return true; + } + return false; } - if ((both & PointSectors.left) != 0) { - edgeFrom = new Vector2(rect.x, rect.y); - edgeTo = new Vector2(rect.x, rect.y + rect.height); - if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo)) - return true; + throw new Error("overlaps of Polygon to " + other + " are not supported"); + }; + Polygon.prototype.collidesWithLine = function (start, end, hit) { + return es.ShapeCollisions.lineToPoly(start, end, this, hit); + }; + Polygon.prototype.containsPoint = function (point) { + point = es.Vector2.subtract(point, this.position); + var isInside = false; + for (var i = 0, j = this.points.length - 1; i < this.points.length; j = i++) { + if (((this.points[i].y > point.y) != (this.points[j].y > point.y)) && + (point.x < (this.points[j].x - this.points[i].x) * (point.y - this.points[i].y) / (this.points[j].y - this.points[i].y) + + this.points[i].x)) { + isInside = !isInside; + } } - if ((both & PointSectors.right) != 0) { - edgeFrom = new Vector2(rect.x + rect.width, rect.y); - edgeTo = new Vector2(rect.x + rect.width, rect.y + rect.height); - if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo)) - return true; + return isInside; + }; + Polygon.prototype.pointCollidesWithShape = function (point, result) { + return es.ShapeCollisions.pointToPoly(point, this, result); + }; + return Polygon; + }(es.Shape)); + es.Polygon = Polygon; +})(es || (es = {})); +var es; +(function (es) { + var Box = (function (_super) { + __extends(Box, _super); + function Box(width, height) { + var _this = _super.call(this, Box.buildBox(width, height), true) || this; + _this.width = width; + _this.height = height; + return _this; + } + Box.buildBox = function (width, height) { + var halfWidth = width / 2; + var halfHeight = height / 2; + var verts = new Array(4); + verts[0] = new es.Vector2(-halfWidth, -halfHeight); + verts[1] = new es.Vector2(halfWidth, -halfHeight); + verts[2] = new es.Vector2(halfWidth, halfHeight); + verts[3] = new es.Vector2(-halfWidth, halfHeight); + return verts; + }; + Box.prototype.updateBox = function (width, height) { + this.width = width; + this.height = height; + var halfWidth = width / 2; + var halfHeight = height / 2; + this.points[0] = new es.Vector2(-halfWidth, -halfHeight); + this.points[1] = new es.Vector2(halfWidth, -halfHeight); + this.points[2] = new es.Vector2(halfWidth, halfHeight); + this.points[3] = new es.Vector2(-halfWidth, halfHeight); + for (var i = 0; i < this.points.length; i++) + this._originalPoints[i] = this.points[i]; + }; + Box.prototype.overlaps = function (other) { + if (this.isUnrotated) { + if (other instanceof Box && other.isUnrotated) + return this.bounds.intersects(other.bounds); + if (other instanceof es.Circle) + return es.Collisions.isRectToCircle(this.bounds, other.position, other.radius); } - } - return false; - }; - Collisions.isRectToPoint = function (rX, rY, rW, rH, point) { - return point.x >= rX && point.y >= rY && point.x < rX + rW && point.y < rY + rH; - }; - Collisions.getSector = function (rX, rY, rW, rH, point) { - var sector = PointSectors.center; - if (point.x < rX) - sector |= PointSectors.left; - else if (point.x >= rX + rW) - sector |= PointSectors.right; - if (point.y < rY) - sector |= PointSectors.top; - else if (point.y >= rY + rH) - sector |= PointSectors.bottom; - return sector; - }; - return Collisions; -}()); -var Physics = (function () { - function Physics() { - } - Physics.reset = function () { - this._spatialHash = new SpatialHash(this.spatialHashCellSize); - }; - Physics.clear = function () { - this._spatialHash.clear(); - }; - Physics.overlapCircleAll = function (center, randius, results, layerMask) { - if (layerMask === void 0) { layerMask = -1; } - return this._spatialHash.overlapCircle(center, randius, results, layerMask); - }; - Physics.boxcastBroadphase = function (rect, layerMask) { - if (layerMask === void 0) { layerMask = this.allLayers; } - var boxcastResult = this._spatialHash.aabbBroadphase(rect, null, layerMask); - return { colliders: boxcastResult.tempHashSet, rect: boxcastResult.bounds }; - }; - Physics.boxcastBroadphaseExcludingSelf = function (collider, rect, layerMask) { - if (layerMask === void 0) { layerMask = this.allLayers; } - return this._spatialHash.aabbBroadphase(rect, collider, layerMask); - }; - Physics.addCollider = function (collider) { - Physics._spatialHash.register(collider); - }; - Physics.removeCollider = function (collider) { - Physics._spatialHash.remove(collider); - }; - Physics.updateCollider = function (collider) { - this._spatialHash.remove(collider); - this._spatialHash.register(collider); - }; - Physics.spatialHashCellSize = 100; - Physics.allLayers = -1; - return Physics; -}()); -var Shape = (function () { - function Shape() { - } - return Shape; -}()); -var Polygon = (function (_super) { - __extends(Polygon, _super); - function Polygon(points, isBox) { - var _this = _super.call(this) || this; - _this.isUnrotated = true; - _this._areEdgeNormalsDirty = true; - _this.setPoints(points); - _this.isBox = isBox; - return _this; - } - Object.defineProperty(Polygon.prototype, "edgeNormals", { - get: function () { - if (this._areEdgeNormalsDirty) - this.buildEdgeNormals(); - return this._edgeNormals; - }, - enumerable: true, - configurable: true - }); - Polygon.prototype.buildEdgeNormals = function () { - var totalEdges = this.isBox ? 2 : this.points.length; - if (this._edgeNormals == null || this._edgeNormals.length != totalEdges) - this._edgeNormals = new Array(totalEdges); - var p2; - for (var i = 0; i < totalEdges; i++) { - var p1 = this.points[i]; - if (i + 1 >= this.points.length) - p2 = this.points[0]; - else - p2 = this.points[i + 1]; - var perp = Vector2Ext.perpendicular(p1, p2); - perp = Vector2.normalize(perp); - this._edgeNormals[i] = perp; - } - }; - Polygon.prototype.setPoints = function (points) { - this.points = points; - this.recalculateCenterAndEdgeNormals(); - this._originalPoints = []; - for (var i = 0; i < this.points.length; i++) { - this._originalPoints.push(this.points[i]); - } - }; - Polygon.prototype.collidesWithShape = function (other) { - var result = new CollisionResult(); - if (other instanceof Polygon) { - return ShapeCollisions.polygonToPolygon(this, other); - } - if (other instanceof Circle) { - result = ShapeCollisions.circleToPolygon(other, this); - if (result) { - result.invertResult(); - return result; + return _super.prototype.overlaps.call(this, other); + }; + Box.prototype.collidesWithShape = function (other, result) { + if (other instanceof Box && other.isUnrotated) { + return es.ShapeCollisions.boxToBox(this, other, result); } - return null; + return _super.prototype.collidesWithShape.call(this, other, result); + }; + Box.prototype.containsPoint = function (point) { + if (this.isUnrotated) + return this.bounds.contains(point.x, point.y); + return _super.prototype.containsPoint.call(this, point); + }; + Box.prototype.pointCollidesWithShape = function (point, result) { + if (this.isUnrotated) + return es.ShapeCollisions.pointToBox(point, this, result); + return _super.prototype.pointCollidesWithShape.call(this, point, result); + }; + return Box; + }(es.Polygon)); + es.Box = Box; +})(es || (es = {})); +var es; +(function (es) { + var Circle = (function (_super) { + __extends(Circle, _super); + function Circle(radius) { + var _this = _super.call(this) || this; + _this.radius = radius; + _this._originalRadius = radius; + return _this; } - throw new Error("overlaps of Polygon to " + other + " are not supported"); - }; - Polygon.prototype.recalculateCenterAndEdgeNormals = function () { - this._polygonCenter = Polygon.findPolygonCenter(this.points); - this._areEdgeNormalsDirty = true; - }; - Polygon.prototype.overlaps = function (other) { - var result; - if (other instanceof Polygon) - return ShapeCollisions.polygonToPolygon(this, other); - if (other instanceof Circle) { - result = ShapeCollisions.circleToPolygon(other, this); - if (result) { - result.invertResult(); + Circle.prototype.recalculateBounds = function (collider) { + this.center = collider.localOffset; + if (collider.shouldColliderScaleAndRotateWithTransform) { + var scale = collider.entity.transform.scale; + var hasUnitScale = scale.x == 1 && scale.y == 1; + var maxScale = Math.max(scale.x, scale.y); + this.radius = this._originalRadius * maxScale; + if (collider.entity.transform.rotation != 0) { + var offsetAngle = Math.atan2(collider.localOffset.y, collider.localOffset.x) * es.MathHelper.Rad2Deg; + var offsetLength = hasUnitScale ? collider._localOffsetLength : es.Vector2.multiply(collider.localOffset, collider.entity.transform.scale).length(); + this.center = es.MathHelper.pointOnCirlce(es.Vector2.zero, offsetLength, collider.entity.transform.rotation + offsetAngle); + } + } + this.position = es.Vector2.add(collider.transform.position, this.center); + this.bounds = new es.Rectangle(this.position.x - this.radius, this.position.y - this.radius, this.radius * 2, this.radius * 2); + }; + Circle.prototype.overlaps = function (other) { + var result = new es.CollisionResult(); + if (other instanceof es.Box && other.isUnrotated) + return es.Collisions.isRectToCircle(other.bounds, this.position, this.radius); + if (other instanceof Circle) + return es.Collisions.isCircleToCircle(this.position, this.radius, other.position, other.radius); + if (other instanceof es.Polygon) + return es.ShapeCollisions.circleToPolygon(this, other, result); + throw new Error("overlaps of circle to " + other + " are not supported"); + }; + Circle.prototype.collidesWithShape = function (other, result) { + if (other instanceof es.Box && other.isUnrotated) { + return es.ShapeCollisions.circleToBox(this, other, result); + } + if (other instanceof Circle) { + return es.ShapeCollisions.circleToCircle(this, other, result); + } + if (other instanceof es.Polygon) { + return es.ShapeCollisions.circleToPolygon(this, other, result); + } + throw new Error("Collisions of Circle to " + other + " are not supported"); + }; + Circle.prototype.collidesWithLine = function (start, end, hit) { + return es.ShapeCollisions.lineToCircle(start, end, this, hit); + }; + Circle.prototype.containsPoint = function (point) { + return (es.Vector2.subtract(point, this.position)).lengthSquared() <= this.radius * this.radius; + }; + Circle.prototype.pointCollidesWithShape = function (point, result) { + return es.ShapeCollisions.pointToCircle(point, this, result); + }; + return Circle; + }(es.Shape)); + es.Circle = Circle; +})(es || (es = {})); +var es; +(function (es) { + var CollisionResult = (function () { + function CollisionResult() { + this.normal = es.Vector2.zero; + this.minimumTranslationVector = es.Vector2.zero; + this.point = es.Vector2.zero; + } + CollisionResult.prototype.removeHorizontal = function (deltaMovement) { + if (Math.sign(this.normal.x) != Math.sign(deltaMovement.x) || (deltaMovement.x == 0 && this.normal.x != 0)) { + var responseDistance = this.minimumTranslationVector.length(); + var fix = responseDistance / this.normal.y; + if (Math.abs(this.normal.x) != 1 && Math.abs(fix) < Math.abs(deltaMovement.y * 3)) { + this.minimumTranslationVector = new es.Vector2(0, -fix); + } + } + }; + CollisionResult.prototype.invertResult = function () { + this.minimumTranslationVector = es.Vector2.negate(this.minimumTranslationVector); + this.normal = es.Vector2.negate(this.normal); + return this; + }; + CollisionResult.prototype.toString = function () { + return "[CollisionResult] normal: " + this.normal + ", minimumTranslationVector: " + this.minimumTranslationVector; + }; + return CollisionResult; + }()); + es.CollisionResult = CollisionResult; +})(es || (es = {})); +var es; +(function (es) { + var RealtimeCollisions = (function () { + function RealtimeCollisions() { + } + RealtimeCollisions.intersectMovingCircleToBox = function (s, b, movement) { + var e = b.bounds; + e.inflate(s.radius, s.radius); + var ray = new es.Ray2D(es.Vector2.subtract(s.position, movement), s.position); + var time = e.rayIntersects(ray); + if (time > 1) + return time; + var point = es.Vector2.add(ray.start, es.Vector2.add(ray.direction, new es.Vector2(time))); + var u, v = 0; + if (point.x < b.bounds.left) + u |= 1; + if (point.x > b.bounds.right) + v |= 1; + if (point.y < b.bounds.top) + u |= 2; + if (point.y > b.bounds.bottom) + v |= 2; + var m = u + v; + if (m == 3) { + console.log("m == 3. corner " + es.Time.frameCount); + } + if ((m & (m - 1)) == 0) { + return time; + } + return time; + }; + return RealtimeCollisions; + }()); + es.RealtimeCollisions = RealtimeCollisions; +})(es || (es = {})); +var es; +(function (es) { + var ShapeCollisions = (function () { + function ShapeCollisions() { + } + ShapeCollisions.polygonToPolygon = function (first, second, result) { + var isIntersecting = true; + var firstEdges = first.edgeNormals; + var secondEdges = second.edgeNormals; + var minIntervalDistance = Number.POSITIVE_INFINITY; + var translationAxis = new es.Vector2(); + var polygonOffset = es.Vector2.subtract(first.position, second.position); + var axis; + for (var edgeIndex = 0; edgeIndex < firstEdges.length + secondEdges.length; edgeIndex++) { + if (edgeIndex < firstEdges.length) { + axis = firstEdges[edgeIndex]; + } + else { + axis = secondEdges[edgeIndex - firstEdges.length]; + } + var minA = 0; + var minB = 0; + var maxA = 0; + var maxB = 0; + var intervalDist = 0; + var ta = this.getInterval(axis, first, minA, maxA); + minA = ta.min; + minB = ta.max; + var tb = this.getInterval(axis, second, minB, maxB); + minB = tb.min; + maxB = tb.max; + var relativeIntervalOffset = es.Vector2.dot(polygonOffset, axis); + minA += relativeIntervalOffset; + maxA += relativeIntervalOffset; + intervalDist = this.intervalDistance(minA, maxA, minB, maxB); + if (intervalDist > 0) + isIntersecting = false; + if (!isIntersecting) + return false; + intervalDist = Math.abs(intervalDist); + if (intervalDist < minIntervalDistance) { + minIntervalDistance = intervalDist; + translationAxis = axis; + if (es.Vector2.dot(translationAxis, polygonOffset) < 0) + translationAxis = new es.Vector2(-translationAxis); + } + } + result.normal = translationAxis; + result.minimumTranslationVector = es.Vector2.multiply(new es.Vector2(-translationAxis.x, -translationAxis.y), new es.Vector2(minIntervalDistance)); + return true; + }; + ShapeCollisions.intervalDistance = function (minA, maxA, minB, maxB) { + if (minA < minB) + return minB - maxA; + return minA - minB; + }; + ShapeCollisions.getInterval = function (axis, polygon, min, max) { + var dot = es.Vector2.dot(polygon.points[0], axis); + min = max = dot; + for (var i = 1; i < polygon.points.length; i++) { + dot = es.Vector2.dot(polygon.points[i], axis); + if (dot < min) { + min = dot; + } + else if (dot > max) { + max = dot; + } + } + return { min: min, max: max }; + }; + ShapeCollisions.circleToPolygon = function (circle, polygon, result) { + var poly2Circle = es.Vector2.subtract(circle.position, polygon.position); + var distanceSquared = 0; + var closestPoint = es.Polygon.getClosestPointOnPolygonToPoint(polygon.points, poly2Circle, distanceSquared, result.normal); + var circleCenterInsidePoly = polygon.containsPoint(circle.position); + if (distanceSquared > circle.radius * circle.radius && !circleCenterInsidePoly) + return false; + var mtv; + if (circleCenterInsidePoly) { + mtv = es.Vector2.multiply(result.normal, new es.Vector2(Math.sqrt(distanceSquared) - circle.radius)); + } + else { + if (distanceSquared == 0) { + mtv = es.Vector2.multiply(result.normal, new es.Vector2(circle.radius)); + } + else { + var distance = Math.sqrt(distanceSquared); + mtv = es.Vector2.multiply(new es.Vector2(-es.Vector2.subtract(poly2Circle, closestPoint)), new es.Vector2((circle.radius - distanceSquared) / distance)); + } + } + result.minimumTranslationVector = mtv; + result.point = es.Vector2.add(closestPoint, polygon.position); + return true; + }; + ShapeCollisions.circleToBox = function (circle, box, result) { + var closestPointOnBounds = box.bounds.getClosestPointOnRectangleBorderToPoint(circle.position, result.normal); + if (box.containsPoint(circle.position)) { + result.point = closestPointOnBounds; + var safePlace = es.Vector2.add(closestPointOnBounds, es.Vector2.multiply(result.normal, new es.Vector2(circle.radius))); + result.minimumTranslationVector = es.Vector2.subtract(circle.position, safePlace); + return true; + } + var sqrDistance = es.Vector2.distanceSquared(closestPointOnBounds, circle.position); + if (sqrDistance == 0) { + result.minimumTranslationVector = es.Vector2.multiply(result.normal, new es.Vector2(circle.radius)); + } + else if (sqrDistance <= circle.radius * circle.radius) { + result.normal = es.Vector2.subtract(circle.position, closestPointOnBounds); + var depth = result.normal.length() - circle.radius; + result.point = closestPointOnBounds; + result.normal = es.Vector2Ext.normalize(result.normal); + result.minimumTranslationVector = es.Vector2.multiply(new es.Vector2(depth), result.normal); return true; } return false; - } - throw new Error("overlaps of Pologon to " + other + " are not supported"); - }; - Polygon.findPolygonCenter = function (points) { - var x = 0, y = 0; - for (var i = 0; i < points.length; i++) { - x += points[i].x; - y += points[i].y; - } - return new Vector2(x / points.length, y / points.length); - }; - Polygon.getClosestPointOnPolygonToPoint = function (points, point) { - var distanceSquared = Number.MAX_VALUE; - var edgeNormal = new Vector2(0, 0); - var closestPoint = new Vector2(0, 0); - var tempDistanceSquared; - for (var i = 0; i < points.length; i++) { - var j = i + 1; - if (j == points.length) - j = 0; - var closest = ShapeCollisions.closestPointOnLine(points[i], points[j], point); - tempDistanceSquared = Vector2.distanceSquared(point, closest); - if (tempDistanceSquared < distanceSquared) { - distanceSquared = tempDistanceSquared; - closestPoint = closest; - var line = Vector2.subtract(points[j], points[i]); - edgeNormal.x = -line.y; - edgeNormal.y = line.x; + }; + ShapeCollisions.pointToCircle = function (point, circle, result) { + var distanceSquared = es.Vector2.distanceSquared(point, circle.position); + var sumOfRadii = 1 + circle.radius; + var collided = distanceSquared < sumOfRadii * sumOfRadii; + if (collided) { + result.normal = es.Vector2.normalize(es.Vector2.subtract(point, circle.position)); + var depth = sumOfRadii - Math.sqrt(distanceSquared); + result.minimumTranslationVector = es.Vector2.multiply(new es.Vector2(-depth, -depth), result.normal); + result.point = es.Vector2.add(circle.position, es.Vector2.multiply(result.normal, new es.Vector2(circle.radius, circle.radius))); + return true; } - } - edgeNormal = Vector2.normalize(edgeNormal); - return { closestPoint: closestPoint, distanceSquared: distanceSquared, edgeNormal: edgeNormal }; - }; - Polygon.prototype.pointCollidesWithShape = function (point) { - return ShapeCollisions.pointToPoly(point, this); - }; - Polygon.prototype.containsPoint = function (point) { - point = Vector2.subtract(point, this.position); - var isInside = false; - for (var i = 0, j = this.points.length - 1; i < this.points.length; j = i++) { - if (((this.points[i].y > point.y) != (this.points[j].y > point.y)) && - (point.x < (this.points[j].x - this.points[i].x) * (point.y - this.points[i].y) / (this.points[j].y - this.points[i].y) + - this.points[i].x)) { - isInside = !isInside; + return false; + }; + ShapeCollisions.pointToBox = function (point, box, result) { + if (box.containsPoint(point)) { + result.point = box.bounds.getClosestPointOnRectangleBorderToPoint(point, result.normal); + result.minimumTranslationVector = es.Vector2.subtract(point, result.point); + return true; } - } - return isInside; - }; - Polygon.buildSymmertricalPolygon = function (vertCount, radius) { - var verts = new Array(vertCount); - for (var i = 0; i < vertCount; i++) { - var a = 2 * Math.PI * (i / vertCount); - verts[i] = new Vector2(Math.cos(a), Math.sin(a) * radius); - } - return verts; - }; - Polygon.prototype.recalculateBounds = function (collider) { - this.center = collider.localOffset; - if (collider.shouldColliderScaleAndRotateWithTransform) { - var hasUnitScale = true; - var tempMat = void 0; - var combinedMatrix = Matrix2D.createTranslation(-this._polygonCenter.x, -this._polygonCenter.y); - if (collider.entity.scale != Vector2.one) { - tempMat = Matrix2D.createScale(collider.entity.scale.x, collider.entity.scale.y); - combinedMatrix = Matrix2D.multiply(combinedMatrix, tempMat); - hasUnitScale = false; - var scaledOffset = Vector2.multiply(collider.localOffset, collider.entity.scale); - this.center = scaledOffset; + return false; + }; + ShapeCollisions.closestPointOnLine = function (lineA, lineB, closestTo) { + var v = es.Vector2.subtract(lineB, lineA); + var w = es.Vector2.subtract(closestTo, lineA); + var t = es.Vector2.dot(w, v) / es.Vector2.dot(v, v); + t = es.MathHelper.clamp(t, 0, 1); + return es.Vector2.add(lineA, es.Vector2.multiply(v, new es.Vector2(t, t))); + }; + ShapeCollisions.pointToPoly = function (point, poly, result) { + if (poly.containsPoint(point)) { + var distanceSquared = 0; + var closestPoint = es.Polygon.getClosestPointOnPolygonToPoint(poly.points, es.Vector2.subtract(point, poly.position), distanceSquared, result.normal); + result.minimumTranslationVector = es.Vector2.multiply(result.normal, new es.Vector2(Math.sqrt(distanceSquared), Math.sqrt(distanceSquared))); + result.point = es.Vector2.add(closestPoint, poly.position); + return true; } - if (collider.entity.rotation != 0) { - tempMat = Matrix2D.createRotation(collider.entity.rotation, tempMat); - combinedMatrix = Matrix2D.multiply(combinedMatrix, tempMat); - var offsetAngle = Math.atan2(collider.localOffset.y, collider.localOffset.x) * MathHelper.Rad2Deg; - var offsetLength = hasUnitScale ? collider._localOffsetLength : (Vector2.multiply(collider.localOffset, collider.entity.scale)).length(); - this.center = MathHelper.pointOnCirlce(Vector2.zero, offsetLength, MathHelper.toDegrees(collider.entity.rotation) + offsetAngle); + return false; + }; + ShapeCollisions.circleToCircle = function (first, second, result) { + var distanceSquared = es.Vector2.distanceSquared(first.position, second.position); + var sumOfRadii = first.radius + second.radius; + var collided = distanceSquared < sumOfRadii * sumOfRadii; + if (collided) { + result.normal = es.Vector2.normalize(es.Vector2.subtract(first.position, second.position)); + var depth = sumOfRadii - Math.sqrt(distanceSquared); + result.minimumTranslationVector = es.Vector2.multiply(new es.Vector2(-depth), result.normal); + result.point = es.Vector2.add(second.position, es.Vector2.multiply(result.normal, new es.Vector2(second.radius))); + return true; } - tempMat = Matrix2D.createTranslation(this._polygonCenter.x, this._polygonCenter.y); - combinedMatrix = Matrix2D.multiply(combinedMatrix, tempMat); - Vector2Ext.transform(this._originalPoints, combinedMatrix, this.points); - this.isUnrotated = collider.entity.rotation == 0; - } - this.position = Vector2.add(collider.entity.position, this.center); - this.bounds = Rectangle.rectEncompassingPoints(this.points); - this.bounds.location = Vector2.add(this.bounds.location, this.position); - }; - return Polygon; -}(Shape)); -var Box = (function (_super) { - __extends(Box, _super); - function Box(width, height) { - var _this = _super.call(this, Box.buildBox(width, height), true) || this; - _this.width = width; - _this.height = height; - return _this; - } - Box.buildBox = function (width, height) { - var halfWidth = width / 2; - var halfHeight = height / 2; - var verts = new Array(4); - verts[0] = new Vector2(-halfWidth, -halfHeight); - verts[1] = new Vector2(halfWidth, -halfHeight); - verts[2] = new Vector2(halfWidth, halfHeight); - verts[3] = new Vector2(-halfWidth, halfHeight); - return verts; - }; - Box.prototype.overlaps = function (other) { - if (this.isUnrotated) { - if (other instanceof Box && other.isUnrotated) - return this.bounds.intersects(other.bounds); - if (other instanceof Circle) - return Collisions.isRectToCircle(this.bounds, other.position, other.radius); - } - return _super.prototype.overlaps.call(this, other); - }; - Box.prototype.collidesWithShape = function (other) { - if (this.isUnrotated && other instanceof Box && other.isUnrotated) { - return ShapeCollisions.boxToBox(this, other); - } - return _super.prototype.collidesWithShape.call(this, other); - }; - Box.prototype.updateBox = function (width, height) { - this.width = width; - this.height = height; - var halfWidth = width / 2; - var halfHeight = height / 2; - this.points[0] = new Vector2(-halfWidth, -halfHeight); - this.points[1] = new Vector2(halfWidth, -halfHeight); - this.points[2] = new Vector2(halfWidth, halfHeight); - this.points[3] = new Vector2(-halfWidth, halfHeight); - for (var i = 0; i < this.points.length; i++) - this._originalPoints[i] = this.points[i]; - }; - Box.prototype.containsPoint = function (point) { - if (this.isUnrotated) - return this.bounds.containsInVec(point); - return _super.prototype.containsPoint.call(this, point); - }; - return Box; -}(Polygon)); -var Circle = (function (_super) { - __extends(Circle, _super); - function Circle(radius) { - var _this = _super.call(this) || this; - _this.radius = radius; - _this._originalRadius = radius; - return _this; - } - Circle.prototype.pointCollidesWithShape = function (point) { - return ShapeCollisions.pointToCircle(point, this); - }; - Circle.prototype.collidesWithShape = function (other) { - if (other instanceof Box && other.isUnrotated) { - return ShapeCollisions.circleToBox(this, other); - } - if (other instanceof Circle) { - return ShapeCollisions.circleToCircle(this, other); - } - if (other instanceof Polygon) { - return ShapeCollisions.circleToPolygon(this, other); - } - throw new Error("Collisions of Circle to " + other + " are not supported"); - }; - Circle.prototype.recalculateBounds = function (collider) { - this.center = collider.localOffset; - if (collider.shouldColliderScaleAndRotateWithTransform) { - var scale = collider.entity.scale; - var hasUnitScale = scale.x == 1 && scale.y == 1; - var maxScale = Math.max(scale.x, scale.y); - this.radius = this._originalRadius * maxScale; - if (collider.entity.rotation != 0) { - var offsetAngle = Math.atan2(collider.localOffset.y, collider.localOffset.x) * MathHelper.Rad2Deg; - var offsetLength = hasUnitScale ? collider._localOffsetLength : (Vector2.multiply(collider.localOffset, collider.entity.scale)).length(); - this.center = MathHelper.pointOnCirlce(Vector2.zero, offsetLength, MathHelper.toDegrees(collider.entity.rotation) + offsetAngle); + return false; + }; + ShapeCollisions.boxToBox = function (first, second, result) { + var minkowskiDiff = this.minkowskiDifference(first, second); + if (minkowskiDiff.contains(0, 0)) { + result.minimumTranslationVector = minkowskiDiff.getClosestPointOnBoundsToOrigin(); + if (result.minimumTranslationVector.equals(es.Vector2.zero)) + return false; + result.normal = new es.Vector2(-result.minimumTranslationVector.x, -result.minimumTranslationVector.y); + result.normal = result.normal.normalize(); + return true; } - } - this.position = Vector2.add(collider.entity.position, this.center); - this.bounds = new Rectangle(this.position.x - this.radius, this.position.y - this.radius, this.radius * 2, this.radius * 2); - }; - Circle.prototype.overlaps = function (other) { - if (other instanceof Box && other.isUnrotated) - return Collisions.isRectToCircle(other.bounds, this.position, this.radius); - if (other instanceof Circle) - return Collisions.isCircleToCircle(this.position, this.radius, other.position, other.radius); - if (other instanceof Polygon) - return ShapeCollisions.circleToPolygon(this, other); - throw new Error("overlaps of circle to " + other + " are not supported"); - }; - return Circle; -}(Shape)); -var CollisionResult = (function () { - function CollisionResult() { - this.minimumTranslationVector = Vector2.zero; - this.normal = Vector2.zero; - this.point = Vector2.zero; - } - CollisionResult.prototype.invertResult = function () { - this.minimumTranslationVector = Vector2.negate(this.minimumTranslationVector); - this.normal = Vector2.negate(this.normal); - }; - return CollisionResult; -}()); -var ShapeCollisions = (function () { - function ShapeCollisions() { - } - ShapeCollisions.polygonToPolygon = function (first, second) { - var result = new CollisionResult(); - var isIntersecting = true; - var firstEdges = first.edgeNormals; - var secondEdges = second.edgeNormals; - var minIntervalDistance = Number.POSITIVE_INFINITY; - var translationAxis = new Vector2(); - var polygonOffset = Vector2.subtract(first.position, second.position); - var axis; - for (var edgeIndex = 0; edgeIndex < firstEdges.length + secondEdges.length; edgeIndex++) { - if (edgeIndex < firstEdges.length) { - axis = firstEdges[edgeIndex]; - } - else { - axis = secondEdges[edgeIndex - firstEdges.length]; - } - var minA = 0; - var minB = 0; - var maxA = 0; - var maxB = 0; - var intervalDist = 0; - var ta = this.getInterval(axis, first, minA, maxA); - minA = ta.min; - minB = ta.max; - var tb = this.getInterval(axis, second, minB, maxB); - minB = tb.min; - maxB = tb.max; - var relativeIntervalOffset = Vector2.dot(polygonOffset, axis); - minA += relativeIntervalOffset; - maxA += relativeIntervalOffset; - intervalDist = this.intervalDistance(minA, maxA, minB, maxB); - if (intervalDist > 0) - isIntersecting = false; - if (!isIntersecting) - return null; - intervalDist = Math.abs(intervalDist); - if (intervalDist < minIntervalDistance) { - minIntervalDistance = intervalDist; - translationAxis = axis; - if (Vector2.dot(translationAxis, polygonOffset) < 0) - translationAxis = new Vector2(-translationAxis); - } - } - result.normal = translationAxis; - result.minimumTranslationVector = Vector2.multiply(new Vector2(-translationAxis.x, -translationAxis.y), new Vector2(minIntervalDistance)); - return result; - }; - ShapeCollisions.intervalDistance = function (minA, maxA, minB, maxB) { - if (minA < minB) - return minB - maxA; - return minA - minB; - }; - ShapeCollisions.getInterval = function (axis, polygon, min, max) { - var dot = Vector2.dot(polygon.points[0], axis); - min = max = dot; - for (var i = 1; i < polygon.points.length; i++) { - dot = Vector2.dot(polygon.points[i], axis); - if (dot < min) { - min = dot; - } - else if (dot > max) { - max = dot; - } - } - return { min: min, max: max }; - }; - ShapeCollisions.circleToPolygon = function (circle, polygon) { - var result = new CollisionResult(); - var poly2Circle = Vector2.subtract(circle.position, polygon.position); - var gpp = Polygon.getClosestPointOnPolygonToPoint(polygon.points, poly2Circle); - var closestPoint = gpp.closestPoint; - var distanceSquared = gpp.distanceSquared; - result.normal = gpp.edgeNormal; - var circleCenterInsidePoly = polygon.containsPoint(circle.position); - if (distanceSquared > circle.radius * circle.radius && !circleCenterInsidePoly) - return null; - var mtv; - if (circleCenterInsidePoly) { - mtv = Vector2.multiply(result.normal, new Vector2(Math.sqrt(distanceSquared) - circle.radius)); - } - else { - if (distanceSquared == 0) { - mtv = Vector2.multiply(result.normal, new Vector2(circle.radius)); - } - else { - var distance = Math.sqrt(distanceSquared); - mtv = Vector2.multiply(new Vector2(-Vector2.subtract(poly2Circle, closestPoint)), new Vector2((circle.radius - distanceSquared) / distance)); - } - } - result.minimumTranslationVector = mtv; - result.point = Vector2.add(closestPoint, polygon.position); - return result; - }; - ShapeCollisions.circleToBox = function (circle, box) { - var result = new CollisionResult(); - var closestPointOnBounds = box.bounds.getClosestPointOnRectangleBorderToPoint(circle.position).res; - if (box.containsPoint(circle.position)) { - result.point = closestPointOnBounds; - var safePlace = Vector2.add(closestPointOnBounds, Vector2.subtract(result.normal, new Vector2(circle.radius))); - result.minimumTranslationVector = Vector2.subtract(circle.position, safePlace); - return result; - } - var sqrDistance = Vector2.distanceSquared(closestPointOnBounds, circle.position); - if (sqrDistance == 0) { - result.minimumTranslationVector = Vector2.multiply(result.normal, new Vector2(circle.radius)); - } - else if (sqrDistance <= circle.radius * circle.radius) { - result.normal = Vector2.subtract(circle.position, closestPointOnBounds); - var depth = result.normal.length() - circle.radius; - result.normal = Vector2Ext.normalize(result.normal); - result.minimumTranslationVector = Vector2.multiply(new Vector2(depth), result.normal); - return result; - } - return null; - }; - ShapeCollisions.pointToCircle = function (point, circle) { - var result = new CollisionResult(); - var distanceSquared = Vector2.distanceSquared(point, circle.position); - var sumOfRadii = 1 + circle.radius; - var collided = distanceSquared < sumOfRadii * sumOfRadii; - if (collided) { - result.normal = Vector2.normalize(Vector2.subtract(point, circle.position)); - var depth = sumOfRadii - Math.sqrt(distanceSquared); - result.minimumTranslationVector = Vector2.multiply(new Vector2(-depth, -depth), result.normal); - result.point = Vector2.add(circle.position, Vector2.multiply(result.normal, new Vector2(circle.radius, circle.radius))); - return result; - } - return null; - }; - ShapeCollisions.closestPointOnLine = function (lineA, lineB, closestTo) { - var v = Vector2.subtract(lineB, lineA); - var w = Vector2.subtract(closestTo, lineA); - var t = Vector2.dot(w, v) / Vector2.dot(v, v); - t = MathHelper.clamp(t, 0, 1); - return Vector2.add(lineA, Vector2.multiply(v, new Vector2(t, t))); - }; - ShapeCollisions.pointToPoly = function (point, poly) { - var result = new CollisionResult(); - if (poly.containsPoint(point)) { - var distanceSquared = void 0; - var gpp = Polygon.getClosestPointOnPolygonToPoint(poly.points, Vector2.subtract(point, poly.position)); - var closestPoint = gpp.closestPoint; - distanceSquared = gpp.distanceSquared; - result.normal = gpp.edgeNormal; - result.minimumTranslationVector = Vector2.multiply(result.normal, new Vector2(Math.sqrt(distanceSquared), Math.sqrt(distanceSquared))); - result.point = Vector2.add(closestPoint, poly.position); - return result; - } - return null; - }; - ShapeCollisions.circleToCircle = function (first, second) { - var result = new CollisionResult(); - var distanceSquared = Vector2.distanceSquared(first.position, second.position); - var sumOfRadii = first.radius + second.radius; - var collided = distanceSquared < sumOfRadii * sumOfRadii; - if (collided) { - result.normal = Vector2.normalize(Vector2.subtract(first.position, second.position)); - var depth = sumOfRadii - Math.sqrt(distanceSquared); - result.minimumTranslationVector = Vector2.multiply(new Vector2(-depth), result.normal); - result.point = Vector2.add(second.position, Vector2.multiply(result.normal, new Vector2(second.radius))); - return result; - } - return null; - }; - ShapeCollisions.boxToBox = function (first, second) { - var result = new CollisionResult(); - var minkowskiDiff = this.minkowskiDifference(first, second); - if (minkowskiDiff.containsInVec(new Vector2(0, 0))) { - result.minimumTranslationVector = minkowskiDiff.getClosestPointOnBoundsToOrigin(); - if (result.minimumTranslationVector.x == 0 && result.minimumTranslationVector.y == 0) - return null; - result.normal = new Vector2(-result.minimumTranslationVector.x, -result.minimumTranslationVector.y); - result.normal.normalize(); - return result; - } - return null; - }; - ShapeCollisions.minkowskiDifference = function (first, second) { - var positionOffset = Vector2.subtract(first.position, Vector2.add(first.bounds.location, Vector2.divide(first.bounds.size, new Vector2(2)))); - var topLeft = Vector2.subtract(Vector2.add(first.bounds.location, positionOffset), second.bounds.max); - var fullSize = Vector2.add(first.bounds.size, second.bounds.size); - return new Rectangle(topLeft.x, topLeft.y, fullSize.x, fullSize.y); - }; - return ShapeCollisions; -}()); -var SpatialHash = (function () { - function SpatialHash(cellSize) { - if (cellSize === void 0) { cellSize = 100; } - this.gridBounds = new Rectangle(); - this._overlapTestCircle = new Circle(0); - this._tempHashSet = []; - this._cellDict = new NumberDictionary(); - this._cellSize = cellSize; - this._inverseCellSize = 1 / this._cellSize; - this._raycastParser = new RaycastResultParser(); - } - SpatialHash.prototype.remove = function (collider) { - var bounds = collider.registeredPhysicsBounds; - var p1 = this.cellCoords(bounds.x, bounds.y); - var p2 = this.cellCoords(bounds.right, bounds.bottom); - for (var x = p1.x; x <= p2.x; x++) { - for (var y = p1.y; y <= p2.y; y++) { - var cell = this.cellAtPosition(x, y); - if (!cell) - console.error("removing Collider [" + collider + "] from a cell that it is not present in"); - else - cell.remove(collider); - } - } - }; - SpatialHash.prototype.register = function (collider) { - var bounds = collider.bounds; - collider.registeredPhysicsBounds = bounds; - var p1 = this.cellCoords(bounds.x, bounds.y); - var p2 = this.cellCoords(bounds.right, bounds.bottom); - if (!this.gridBounds.containsInVec(new Vector2(p1.x, p1.y))) { - this.gridBounds = RectangleExt.union(this.gridBounds, p1); - } - if (!this.gridBounds.containsInVec(new Vector2(p2.x, p2.y))) { - this.gridBounds = RectangleExt.union(this.gridBounds, p2); - } - for (var x = p1.x; x <= p2.x; x++) { - for (var y = p1.y; y <= p2.y; y++) { - var c = this.cellAtPosition(x, y, true); - c.push(collider); - } - } - }; - SpatialHash.prototype.clear = function () { - this._cellDict.clear(); - }; - SpatialHash.prototype.overlapCircle = function (circleCenter, radius, results, layerMask) { - var bounds = new Rectangle(circleCenter.x - radius, circleCenter.y - radius, radius * 2, radius * 2); - this._overlapTestCircle.radius = radius; - this._overlapTestCircle.position = circleCenter; - var resultCounter = 0; - var aabbBroadphaseResult = this.aabbBroadphase(bounds, null, layerMask); - bounds = aabbBroadphaseResult.bounds; - var potentials = aabbBroadphaseResult.tempHashSet; - for (var i = 0; i < potentials.length; i++) { - var collider = potentials[i]; - if (collider instanceof BoxCollider) { - results[resultCounter] = collider; - resultCounter++; - } - else { - throw new Error("overlapCircle against this collider type is not implemented!"); - } - if (resultCounter == results.length) - return resultCounter; - } - return resultCounter; - }; - SpatialHash.prototype.aabbBroadphase = function (bounds, excludeCollider, layerMask) { - this._tempHashSet.length = 0; - var p1 = this.cellCoords(bounds.x, bounds.y); - var p2 = this.cellCoords(bounds.right, bounds.bottom); - for (var x = p1.x; x <= p2.x; x++) { - for (var y = p1.y; y <= p2.y; y++) { - var cell = this.cellAtPosition(x, y); - if (!cell) - continue; - for (var i = 0; i < cell.length; i++) { - var collider = cell[i]; - if (collider == excludeCollider || !Flags.isFlagSet(layerMask, collider.physicsLayer)) - continue; - if (bounds.intersects(collider.bounds)) { - if (this._tempHashSet.indexOf(collider) == -1) - this._tempHashSet.push(collider); + return false; + }; + ShapeCollisions.minkowskiDifference = function (first, second) { + var positionOffset = es.Vector2.subtract(first.position, es.Vector2.add(first.bounds.location, es.Vector2.divide(first.bounds.size, new es.Vector2(2)))); + var topLeft = es.Vector2.subtract(es.Vector2.add(first.bounds.location, positionOffset), second.bounds.max); + var fullSize = es.Vector2.add(first.bounds.size, second.bounds.size); + return new es.Rectangle(topLeft.x, topLeft.y, fullSize.x, fullSize.y); + }; + ShapeCollisions.lineToPoly = function (start, end, polygon, hit) { + var normal = es.Vector2.zero; + var intersectionPoint = es.Vector2.zero; + var fraction = Number.MAX_VALUE; + var hasIntersection = false; + for (var j = polygon.points.length - 1, i = 0; i < polygon.points.length; j = i, i++) { + var edge1 = es.Vector2.add(polygon.position, polygon.points[j]); + var edge2 = es.Vector2.add(polygon.position, polygon.points[i]); + var intersection = es.Vector2.zero; + if (this.lineToLine(edge1, edge2, start, end, intersection)) { + hasIntersection = true; + var distanceFraction = (intersection.x - start.x) / (end.x - start.x); + if (Number.isNaN(distanceFraction) || Number.isFinite(distanceFraction)) + distanceFraction = (intersection.y - start.y) / (end.y - start.y); + if (distanceFraction < fraction) { + var edge = es.Vector2.subtract(edge2, edge1); + normal = new es.Vector2(edge.y, -edge.x); + fraction = distanceFraction; + intersectionPoint = intersection; } } } - } - return { tempHashSet: this._tempHashSet, bounds: bounds }; - }; - SpatialHash.prototype.cellAtPosition = function (x, y, createCellIfEmpty) { - if (createCellIfEmpty === void 0) { createCellIfEmpty = false; } - var cell = this._cellDict.tryGetValue(x, y); - if (!cell) { - if (createCellIfEmpty) { - cell = []; - this._cellDict.add(x, y, cell); + if (hasIntersection) { + normal = normal.normalize(); + var distance = es.Vector2.distance(start, intersectionPoint); + hit.setValuesNonCollider(fraction, distance, intersectionPoint, normal); + return true; } - } - return cell; - }; - SpatialHash.prototype.cellCoords = function (x, y) { - return new Vector2(Math.floor(x * this._inverseCellSize), Math.floor(y * this._inverseCellSize)); - }; - return SpatialHash; -}()); -var RaycastResultParser = (function () { - function RaycastResultParser() { - } - return RaycastResultParser; -}()); -var NumberDictionary = (function () { - function NumberDictionary() { - this._store = new Map(); - } - NumberDictionary.prototype.getKey = function (x, y) { - return Long.fromNumber(x).shiftLeft(32).or(this.intToUint(y)).toString(); - }; - NumberDictionary.prototype.intToUint = function (i) { - if (i >= 0) - return i; - else - return 4294967296 + i; - }; - NumberDictionary.prototype.add = function (x, y, list) { - this._store.set(this.getKey(x, y), list); - }; - NumberDictionary.prototype.remove = function (obj) { - this._store.forEach(function (list) { - if (list.contains(obj)) - list.remove(obj); - }); - }; - NumberDictionary.prototype.tryGetValue = function (x, y) { - return this._store.get(this.getKey(x, y)); - }; - NumberDictionary.prototype.clear = function () { - this._store.clear(); - }; - return NumberDictionary; -}()); -var ContentManager = (function () { - function ContentManager() { - this.loadedAssets = new Map(); - } - ContentManager.prototype.loadRes = function (name, local) { - var _this = this; - if (local === void 0) { local = true; } - return new Promise(function (resolve, reject) { - var res = _this.loadedAssets.get(name); - if (res) { - resolve(res); - return; - } - if (local) { - RES.getResAsync(name).then(function (data) { - _this.loadedAssets.set(name, data); - resolve(data); - }).catch(function (err) { - console.error("资源加载错误:", name, err); - reject(err); - }); + return false; + }; + ShapeCollisions.lineToLine = function (a1, a2, b1, b2, intersection) { + var b = es.Vector2.subtract(a2, a1); + var d = es.Vector2.subtract(b2, b1); + var bDotDPerp = b.x * d.y - b.y * d.x; + if (bDotDPerp == 0) + return false; + var c = es.Vector2.subtract(b1, a1); + var t = (c.x * d.y - c.y * d.x) / bDotDPerp; + if (t < 0 || t > 1) + return false; + var u = (c.x * b.y - c.y * b.x) / bDotDPerp; + if (u < 0 || u > 1) + return false; + intersection = intersection.add(a1).add(es.Vector2.multiply(new es.Vector2(t), b)); + return true; + }; + ShapeCollisions.lineToCircle = function (start, end, s, hit) { + var lineLength = es.Vector2.distance(start, end); + var d = es.Vector2.divide(es.Vector2.subtract(end, start), new es.Vector2(lineLength)); + var m = es.Vector2.subtract(start, s.position); + var b = es.Vector2.dot(m, d); + var c = es.Vector2.dot(m, m) - s.radius * s.radius; + if (c > 0 && b > 0) + return false; + var discr = b * b - c; + if (discr < 0) + return false; + hit.fraction = -b - Math.sqrt(discr); + if (hit.fraction < 0) + hit.fraction = 0; + hit.point = es.Vector2.add(start, es.Vector2.multiply(new es.Vector2(hit.fraction), d)); + hit.distance = es.Vector2.distance(start, hit.point); + hit.normal = es.Vector2.normalize(es.Vector2.subtract(hit.point, s.position)); + hit.fraction = hit.distance / lineLength; + return true; + }; + ShapeCollisions.boxToBoxCast = function (first, second, movement, hit) { + var minkowskiDiff = this.minkowskiDifference(first, second); + if (minkowskiDiff.contains(0, 0)) { + var mtv = minkowskiDiff.getClosestPointOnBoundsToOrigin(); + if (mtv.equals(es.Vector2.zero)) + return false; + hit.normal = new es.Vector2(-mtv.x); + hit.normal = hit.normal.normalize(); + hit.distance = 0; + hit.fraction = 0; + return true; } else { - RES.getResByUrl(name).then(function (data) { - _this.loadedAssets.set(name, data); - resolve(data); - }).catch(function (err) { - console.error("资源加载错误:", name, err); - reject(err); - }); + var ray = new es.Ray2D(es.Vector2.zero, new es.Vector2(-movement.x)); + var fraction = minkowskiDiff.rayIntersects(ray); + if (fraction <= 1) { + hit.fraction = fraction; + hit.distance = movement.length() * fraction; + hit.normal = new es.Vector2(-movement.x); + hit.normal = hit.normal.normalize(); + hit.centroid = es.Vector2.add(first.bounds.center, es.Vector2.multiply(movement, new es.Vector2(fraction))); + return true; + } } - }); - }; - ContentManager.prototype.dispose = function () { - this.loadedAssets.forEach(function (value) { - var assetsToRemove = value; - assetsToRemove.dispose(); - }); - this.loadedAssets.clear(); - }; - return ContentManager; -}()); -var Emitter = (function () { - function Emitter() { - this._messageTable = new Map(); + return false; + }; + return ShapeCollisions; + }()); + es.ShapeCollisions = ShapeCollisions; +})(es || (es = {})); +var es; +(function (es) { + var SpatialHash = (function () { + function SpatialHash(cellSize) { + if (cellSize === void 0) { cellSize = 100; } + this.gridBounds = new es.Rectangle(); + this._overlapTestCircle = new es.Circle(0); + this._cellDict = new NumberDictionary(); + this._tempHashSet = []; + this._cellSize = cellSize; + this._inverseCellSize = 1 / this._cellSize; + this._raycastParser = new RaycastResultParser(); + } + SpatialHash.prototype.register = function (collider) { + var bounds = collider.bounds; + collider.registeredPhysicsBounds = bounds; + var p1 = this.cellCoords(bounds.x, bounds.y); + var p2 = this.cellCoords(bounds.right, bounds.bottom); + if (!this.gridBounds.contains(p1.x, p1.y)) { + this.gridBounds = es.RectangleExt.union(this.gridBounds, p1); + } + if (!this.gridBounds.contains(p2.x, p2.y)) { + this.gridBounds = es.RectangleExt.union(this.gridBounds, p2); + } + for (var x = p1.x; x <= p2.x; x++) { + for (var y = p1.y; y <= p2.y; y++) { + var c = this.cellAtPosition(x, y, true); + if (!c.firstOrDefault(function (c) { return c.hashCode == collider.hashCode; })) + c.push(collider); + } + } + }; + SpatialHash.prototype.remove = function (collider) { + var bounds = collider.registeredPhysicsBounds; + var p1 = this.cellCoords(bounds.x, bounds.y); + var p2 = this.cellCoords(bounds.right, bounds.bottom); + for (var x = p1.x; x <= p2.x; x++) { + for (var y = p1.y; y <= p2.y; y++) { + var cell = this.cellAtPosition(x, y); + if (!cell) + console.error("removing Collider [" + collider + "] from a cell that it is not present in"); + else + cell.remove(collider); + } + } + }; + SpatialHash.prototype.removeWithBruteForce = function (obj) { + this._cellDict.remove(obj); + }; + SpatialHash.prototype.clear = function () { + this._cellDict.clear(); + }; + SpatialHash.prototype.debugDraw = function (secondsToDisplay, textScale) { + if (textScale === void 0) { textScale = 1; } + for (var x = this.gridBounds.x; x <= this.gridBounds.right; x++) { + for (var y = this.gridBounds.y; y <= this.gridBounds.bottom; y++) { + var cell = this.cellAtPosition(x, y); + if (cell && cell.length > 0) + this.debugDrawCellDetails(x, y, cell.length, secondsToDisplay, textScale); + } + } + }; + SpatialHash.prototype.aabbBroadphase = function (bounds, excludeCollider, layerMask) { + this._tempHashSet.length = 0; + var p1 = this.cellCoords(bounds.x, bounds.y); + var p2 = this.cellCoords(bounds.right, bounds.bottom); + for (var x = p1.x; x <= p2.x; x++) { + for (var y = p1.y; y <= p2.y; y++) { + var cell = this.cellAtPosition(x, y); + if (!cell) + continue; + var _loop_7 = function (i) { + var collider = cell[i]; + if (collider == excludeCollider || !es.Flags.isFlagSet(layerMask, collider.physicsLayer)) + return "continue"; + if (bounds.intersects(collider.bounds)) { + if (!this_3._tempHashSet.firstOrDefault(function (c) { return c.hashCode == collider.hashCode; })) + this_3._tempHashSet.push(collider); + } + }; + var this_3 = this; + for (var i = 0; i < cell.length; i++) { + _loop_7(i); + } + } + } + return this._tempHashSet; + }; + SpatialHash.prototype.overlapCircle = function (circleCenter, radius, results, layerMask) { + var bounds = new es.Rectangle(circleCenter.x - radius, circleCenter.y - radius, radius * 2, radius * 2); + this._overlapTestCircle.radius = radius; + this._overlapTestCircle.position = circleCenter; + var resultCounter = 0; + var potentials = this.aabbBroadphase(bounds, null, layerMask); + for (var i = 0; i < potentials.length; i++) { + var collider = potentials[i]; + if (collider instanceof es.BoxCollider) { + results[resultCounter] = collider; + resultCounter++; + } + else if (collider instanceof es.CircleCollider) { + if (collider.shape.overlaps(this._overlapTestCircle)) { + results[resultCounter] = collider; + resultCounter++; + } + } + else if (collider instanceof es.PolygonCollider) { + if (collider.shape.overlaps(this._overlapTestCircle)) { + results[resultCounter] = collider; + resultCounter++; + } + } + else { + throw new Error("overlapCircle against this collider type is not implemented!"); + } + if (resultCounter == results.length) + return resultCounter; + } + return resultCounter; + }; + SpatialHash.prototype.cellCoords = function (x, y) { + return new es.Vector2(Math.floor(x * this._inverseCellSize), Math.floor(y * this._inverseCellSize)); + }; + SpatialHash.prototype.cellAtPosition = function (x, y, createCellIfEmpty) { + if (createCellIfEmpty === void 0) { createCellIfEmpty = false; } + var cell = this._cellDict.tryGetValue(x, y); + if (!cell) { + if (createCellIfEmpty) { + cell = []; + this._cellDict.add(x, y, cell); + } + } + return cell; + }; + SpatialHash.prototype.debugDrawCellDetails = function (x, y, cellCount, secondsToDisplay, textScale) { + if (secondsToDisplay === void 0) { secondsToDisplay = 0.5; } + if (textScale === void 0) { textScale = 1; } + }; + return SpatialHash; + }()); + es.SpatialHash = SpatialHash; + var NumberDictionary = (function () { + function NumberDictionary() { + this._store = new Map(); + } + NumberDictionary.prototype.add = function (x, y, list) { + this._store.set(this.getKey(x, y), list); + }; + NumberDictionary.prototype.remove = function (obj) { + this._store.forEach(function (list) { + if (list.contains(obj)) + list.remove(obj); + }); + }; + NumberDictionary.prototype.tryGetValue = function (x, y) { + return this._store.get(this.getKey(x, y)); + }; + NumberDictionary.prototype.clear = function () { + this._store.clear(); + }; + NumberDictionary.prototype.getKey = function (x, y) { + return Long.fromNumber(x).shiftLeft(32).or(Long.fromNumber(y, true)).toString(); + }; + return NumberDictionary; + }()); + es.NumberDictionary = NumberDictionary; + var RaycastResultParser = (function () { + function RaycastResultParser() { + this._checkedColliders = []; + this._cellHits = []; + } + RaycastResultParser.prototype.start = function (ray, hits, layerMask) { + this._ray = ray; + this._hits = hits; + this._layerMask = layerMask; + this.hitCounter = 0; + }; + RaycastResultParser.prototype.checkRayIntersection = function (cellX, cellY, cell) { + var fraction = 0; + for (var i = 0; i < cell.length; i++) { + var potential = cell[i]; + if (this._checkedColliders.contains(potential)) + continue; + this._checkedColliders.push(potential); + if (potential.isTrigger && !es.Physics.raycastsHitTriggers) + continue; + if (!es.Flags.isFlagSet(this._layerMask, potential.physicsLayer)) + continue; + var colliderBounds = potential.bounds; + var fraction_1 = colliderBounds.rayIntersects(this._ray); + if (fraction_1 <= 1) { + if (potential.shape.collidesWithLine(this._ray.start, this._ray.end, this._tempHit)) { + if (!es.Physics.raycastsStartInColliders && potential.shape.containsPoint(this._ray.start)) + continue; + this._tempHit.collider = potential; + this._cellHits.push(this._tempHit); + } + } + } + if (this._cellHits.length == 0) + return false; + this._cellHits.sort(RaycastResultParser.compareRaycastHits); + for (var i = 0; i < this._cellHits.length; i++) { + this._hits[this.hitCounter] = this._cellHits[i]; + this.hitCounter++; + if (this.hitCounter == this._hits.length) + return true; + } + return false; + }; + RaycastResultParser.prototype.reset = function () { + this._hits = null; + this._checkedColliders.length = 0; + this._cellHits.length = 0; + }; + RaycastResultParser.compareRaycastHits = function (a, b) { + return a.distance - b.distance; + }; + return RaycastResultParser; + }()); + es.RaycastResultParser = RaycastResultParser; +})(es || (es = {})); +var ArrayUtils = (function () { + function ArrayUtils() { } - Emitter.prototype.addObserver = function (eventType, handler) { - var list = this._messageTable.get(eventType); - if (!list) { - list = []; - this._messageTable.set(eventType, list); - } - if (list.contains(handler)) - console.warn("您试图添加相同的观察者两次"); - list.push(handler); - }; - Emitter.prototype.removeObserver = function (eventType, handler) { - this._messageTable.get(eventType).remove(handler); - }; - Emitter.prototype.emit = function (eventType, data) { - var list = this._messageTable.get(eventType); - if (list) { - for (var i = list.length - 1; i >= 0; i--) - list[i](data); - } - }; - return Emitter; -}()); -var GlobalManager = (function () { - function GlobalManager() { - } - Object.defineProperty(GlobalManager.prototype, "enabled", { - get: function () { - return this._enabled; - }, - set: function (value) { - this.setEnabled(value); - }, - enumerable: true, - configurable: true - }); - GlobalManager.prototype.setEnabled = function (isEnabled) { - if (this._enabled != isEnabled) { - this._enabled = isEnabled; - if (this._enabled) { - this.onEnabled(); - } - else { - this.onDisabled(); + ArrayUtils.bubbleSort = function (ary) { + var isExchange = false; + for (var i = 0; i < ary.length; i++) { + isExchange = false; + for (var j = ary.length - 1; j > i; j--) { + if (ary[j] < ary[j - 1]) { + var temp = ary[j]; + ary[j] = ary[j - 1]; + ary[j - 1] = temp; + isExchange = true; + } } + if (!isExchange) + break; } }; - GlobalManager.prototype.onEnabled = function () { }; - GlobalManager.prototype.onDisabled = function () { }; - GlobalManager.prototype.update = function () { }; - GlobalManager.registerGlobalManager = function (manager) { - this.globalManagers.push(manager); - manager.enabled = true; + ArrayUtils.insertionSort = function (ary) { + var len = ary.length; + for (var i = 1; i < len; i++) { + var val = ary[i]; + for (var j = i; j > 0 && ary[j - 1] > val; j--) { + ary[j] = ary[j - 1]; + } + ary[j] = val; + } }; - GlobalManager.unregisterGlobalManager = function (manager) { - this.globalManagers.remove(manager); - manager.enabled = false; + ArrayUtils.binarySearch = function (ary, value) { + var startIndex = 0; + var endIndex = ary.length; + var sub = (startIndex + endIndex) >> 1; + while (startIndex < endIndex) { + if (value <= ary[sub]) + endIndex = sub; + else if (value >= ary[sub]) + startIndex = sub + 1; + sub = (startIndex + endIndex) >> 1; + } + if (ary[startIndex] == value) + return startIndex; + return -1; }; - GlobalManager.getGlobalManager = function (type) { - for (var i = 0; i < this.globalManagers.length; i++) { - if (this.globalManagers[i] instanceof type) - return this.globalManagers[i]; + ArrayUtils.findElementIndex = function (ary, num) { + var len = ary.length; + for (var i = 0; i < len; ++i) { + if (ary[i] == num) + return i; } return null; }; - GlobalManager.globalManagers = []; - return GlobalManager; -}()); -var TouchState = (function () { - function TouchState() { - this.x = 0; - this.y = 0; - this.touchPoint = -1; - this.touchDown = false; - } - Object.defineProperty(TouchState.prototype, "position", { - get: function () { - return new Vector2(this.x, this.y); - }, - enumerable: true, - configurable: true - }); - TouchState.prototype.reset = function () { - this.x = 0; - this.y = 0; - this.touchDown = false; - this.touchPoint = -1; + ArrayUtils.getMaxElementIndex = function (ary) { + var matchIndex = 0; + var len = ary.length; + for (var j = 1; j < len; j++) { + if (ary[j] > ary[matchIndex]) + matchIndex = j; + } + return matchIndex; }; - return TouchState; -}()); -var Input = (function () { - function Input() { - } - Object.defineProperty(Input, "touchPosition", { - get: function () { - if (!this._gameTouchs[0]) - return Vector2.zero; - return this._gameTouchs[0].position; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Input, "maxSupportedTouch", { - get: function () { - return this._stage.maxTouches; - }, - set: function (value) { - this._stage.maxTouches = value; - this.initTouchCache(); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Input, "resolutionScale", { - get: function () { - return this._resolutionScale; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Input, "totalTouchCount", { - get: function () { - return this._totalTouchCount; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Input, "gameTouchs", { - get: function () { - return this._gameTouchs; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Input, "touchPositionDelta", { - get: function () { - var delta = Vector2.subtract(this.touchPosition, this._previousTouchState.position); - if (delta.length() > 0) { - this.setpreviousTouchState(this._gameTouchs[0]); + ArrayUtils.getMinElementIndex = function (ary) { + var matchIndex = 0; + var len = ary.length; + for (var j = 1; j < len; j++) { + if (ary[j] < ary[matchIndex]) + matchIndex = j; + } + return matchIndex; + }; + ArrayUtils.getUniqueAry = function (ary) { + var uAry = []; + var newAry = []; + var count = ary.length; + for (var i = 0; i < count; ++i) { + var value = ary[i]; + if (uAry.indexOf(value) == -1) + uAry.push(value); + } + count = uAry.length; + for (var i = count - 1; i >= 0; --i) { + newAry.unshift(uAry[i]); + } + return newAry; + }; + ArrayUtils.getDifferAry = function (aryA, aryB) { + aryA = this.getUniqueAry(aryA); + aryB = this.getUniqueAry(aryB); + var ary = aryA.concat(aryB); + var uObj = {}; + var newAry = []; + var count = ary.length; + for (var j = 0; j < count; ++j) { + if (!uObj[ary[j]]) { + uObj[ary[j]] = {}; + uObj[ary[j]].count = 0; + uObj[ary[j]].key = ary[j]; + uObj[ary[j]].count++; } - return delta; - }, - enumerable: true, - configurable: true - }); - Input.initialize = function (stage) { - if (this._init) + else { + if (uObj[ary[j]] instanceof Object) { + uObj[ary[j]].count++; + } + } + } + for (var i in uObj) { + if (uObj[i].count != 2) { + newAry.unshift(uObj[i].key); + } + } + return newAry; + }; + ArrayUtils.swap = function (array, index1, index2) { + var temp = array[index1]; + array[index1] = array[index2]; + array[index2] = temp; + }; + ArrayUtils.clearList = function (ary) { + if (!ary) return; - this._init = true; - this._stage = stage; - this._stage.addEventListener(egret.TouchEvent.TOUCH_BEGIN, this.touchBegin, this); - this._stage.addEventListener(egret.TouchEvent.TOUCH_MOVE, this.touchMove, this); - this._stage.addEventListener(egret.TouchEvent.TOUCH_END, this.touchEnd, this); - this._stage.addEventListener(egret.TouchEvent.TOUCH_CANCEL, this.touchEnd, this); - this._stage.addEventListener(egret.TouchEvent.TOUCH_RELEASE_OUTSIDE, this.touchEnd, this); - this.initTouchCache(); - }; - Input.initTouchCache = function () { - this._totalTouchCount = 0; - this._touchIndex = 0; - this._gameTouchs.length = 0; - for (var i = 0; i < this.maxSupportedTouch; i++) { - this._gameTouchs.push(new TouchState()); + var length = ary.length; + for (var i = length - 1; i >= 0; i -= 1) { + ary.splice(i, 1); } }; - Input.touchBegin = function (evt) { - if (this._touchIndex < this.maxSupportedTouch) { - this._gameTouchs[this._touchIndex].touchPoint = evt.touchPointID; - this._gameTouchs[this._touchIndex].touchDown = evt.touchDown; - this._gameTouchs[this._touchIndex].x = evt.stageX; - this._gameTouchs[this._touchIndex].y = evt.stageY; - if (this._touchIndex == 0) { - this.setpreviousTouchState(this._gameTouchs[0]); - } - this._touchIndex++; - this._totalTouchCount++; - } + ArrayUtils.cloneList = function (ary) { + if (!ary) + return null; + return ary.slice(0, ary.length); }; - Input.touchMove = function (evt) { - if (evt.touchPointID == this._gameTouchs[0].touchPoint) { - this.setpreviousTouchState(this._gameTouchs[0]); - } - var touchIndex = this._gameTouchs.findIndex(function (touch) { return touch.touchPoint == evt.touchPointID; }); - if (touchIndex != -1) { - var touchData = this._gameTouchs[touchIndex]; - touchData.x = evt.stageX; - touchData.y = evt.stageY; - } - }; - Input.touchEnd = function (evt) { - var touchIndex = this._gameTouchs.findIndex(function (touch) { return touch.touchPoint == evt.touchPointID; }); - if (touchIndex != -1) { - var touchData = this._gameTouchs[touchIndex]; - touchData.reset(); - if (touchIndex == 0) - this._previousTouchState.reset(); - this._totalTouchCount--; - if (this.totalTouchCount == 0) { - this._touchIndex = 0; - } - } - }; - Input.setpreviousTouchState = function (touchState) { - this._previousTouchState = new TouchState(); - this._previousTouchState.x = touchState.position.x; - this._previousTouchState.y = touchState.position.y; - this._previousTouchState.touchPoint = touchState.touchPoint; - this._previousTouchState.touchDown = touchState.touchDown; - }; - Input.scaledPosition = function (position) { - var scaledPos = new Vector2(position.x - this._resolutionOffset.x, position.y - this._resolutionOffset.y); - return Vector2.multiply(scaledPos, this.resolutionScale); - }; - Input._init = false; - Input._previousTouchState = new TouchState(); - Input._gameTouchs = []; - Input._resolutionOffset = new Vector2(); - Input._resolutionScale = Vector2.one; - Input._touchIndex = 0; - Input._totalTouchCount = 0; - return Input; -}()); -var ListPool = (function () { - function ListPool() { - } - ListPool.warmCache = function (cacheCount) { - cacheCount -= this._objectQueue.length; - if (cacheCount > 0) { - for (var i = 0; i < cacheCount; i++) { - this._objectQueue.unshift([]); - } - } - }; - ListPool.trimCache = function (cacheCount) { - while (cacheCount > this._objectQueue.length) - this._objectQueue.shift(); - }; - ListPool.clearCache = function () { - this._objectQueue.length = 0; - }; - ListPool.obtain = function () { - if (this._objectQueue.length > 0) - return this._objectQueue.shift(); - return []; - }; - ListPool.free = function (obj) { - this._objectQueue.unshift(obj); - obj.length = 0; - }; - ListPool._objectQueue = []; - return ListPool; -}()); -var Pair = (function () { - function Pair(first, second) { - this.first = first; - this.second = second; - } - Pair.prototype.clear = function () { - this.first = this.second = null; - }; - Pair.prototype.equals = function (other) { - return this.first == other.first && this.second == other.second; - }; - return Pair; -}()); -var RectangleExt = (function () { - function RectangleExt() { - } - RectangleExt.union = function (first, point) { - var rect = new Rectangle(point.x, point.y, 0, 0); - return this.unionR(first, rect); - }; - RectangleExt.unionR = function (value1, value2) { - var result = new Rectangle(); - result.x = Math.min(value1.x, value2.x); - result.y = Math.min(value1.y, value2.y); - result.width = Math.max(value1.right, value2.right) - result.x; - result.height = Math.max(value1.bottom, value2.bottom) - result.y; - return result; - }; - return RectangleExt; -}()); -var Triangulator = (function () { - function Triangulator() { - this.triangleIndices = []; - this._triPrev = new Array(12); - this._triNext = new Array(12); - } - Triangulator.prototype.triangulate = function (points, arePointsCCW) { - if (arePointsCCW === void 0) { arePointsCCW = true; } - var count = points.length; - this.initialize(count); - var iterations = 0; - var index = 0; - while (count > 3 && iterations < 500) { - iterations++; - var isEar = true; - var a = points[this._triPrev[index]]; - var b = points[index]; - var c = points[this._triNext[index]]; - if (Vector2Ext.isTriangleCCW(a, b, c)) { - var k = this._triNext[this._triNext[index]]; - do { - if (Triangulator.testPointTriangle(points[k], a, b, c)) { - isEar = false; - break; - } - k = this._triNext[k]; - } while (k != this._triPrev[index]); - } - else { - isEar = false; - } - if (isEar) { - this.triangleIndices.push(this._triPrev[index]); - this.triangleIndices.push(index); - this.triangleIndices.push(this._triNext[index]); - this._triNext[this._triPrev[index]] = this._triNext[index]; - this._triPrev[this._triNext[index]] = this._triPrev[index]; - count--; - index = this._triPrev[index]; - } - else { - index = this._triNext[index]; - } - } - this.triangleIndices.push(this._triPrev[index]); - this.triangleIndices.push(index); - this.triangleIndices.push(this._triNext[index]); - if (!arePointsCCW) - this.triangleIndices.reverse(); - }; - Triangulator.prototype.initialize = function (count) { - this.triangleIndices.length = 0; - if (this._triNext.length < count) { - this._triNext.reverse(); - this._triNext = new Array(Math.max(this._triNext.length * 2, count)); - } - if (this._triPrev.length < count) { - this._triPrev.reverse(); - this._triPrev = new Array(Math.max(this._triPrev.length * 2, count)); - } - for (var i = 0; i < count; i++) { - this._triPrev[i] = i - 1; - this._triNext[i] = i + 1; - } - this._triPrev[0] = count - 1; - this._triNext[count - 1] = 0; - }; - Triangulator.testPointTriangle = function (point, a, b, c) { - if (Vector2Ext.cross(Vector2.subtract(point, a), Vector2.subtract(b, a)) < 0) - return false; - if (Vector2Ext.cross(Vector2.subtract(point, b), Vector2.subtract(c, b)) < 0) - return false; - if (Vector2Ext.cross(Vector2.subtract(point, c), Vector2.subtract(a, c)) < 0) + ArrayUtils.equals = function (ary1, ary2) { + if (ary1 == ary2) + return true; + var length = ary1.length; + if (length != ary2.length) return false; + while (length--) { + if (ary1[length] != ary2[length]) + return false; + } return true; }; - return Triangulator; -}()); -var Vector2Ext = (function () { - function Vector2Ext() { - } - Vector2Ext.isTriangleCCW = function (a, center, c) { - return this.cross(Vector2.subtract(center, a), Vector2.subtract(c, center)) < 0; - }; - Vector2Ext.cross = function (u, v) { - return u.y * v.x - u.x * v.y; - }; - Vector2Ext.perpendicular = function (first, second) { - return new Vector2(-1 * (second.y - first.y), second.x - first.x); - }; - Vector2Ext.normalize = function (vec) { - var magnitude = Math.sqrt((vec.x * vec.x) + (vec.y * vec.y)); - if (magnitude > MathHelper.Epsilon) { - vec = Vector2.divide(vec, new Vector2(magnitude)); - } + ArrayUtils.insert = function (ary, index, value) { + if (!ary) + return null; + var length = ary.length; + if (index > length) + index = length; + if (index < 0) + index = 0; + if (index == length) + ary.push(value); + else if (index == 0) + ary.unshift(value); else { - vec.x = vec.y = 0; + for (var i = length - 1; i >= index; i -= 1) { + ary[i + 1] = ary[i]; + } + ary[index] = value; } - return vec; + return value; }; - Vector2Ext.transformA = function (sourceArray, sourceIndex, matrix, destinationArray, destinationIndex, length) { - for (var i = 0; i < length; i++) { - var position = sourceArray[sourceIndex + i]; - var destination = destinationArray[destinationIndex + i]; - destination.x = (position.x * matrix.m11) + (position.y * matrix.m21) + matrix.m31; - destination.y = (position.x * matrix.m12) + (position.y * matrix.m22) + matrix.m32; - destinationArray[destinationIndex + i] = destination; - } - }; - Vector2Ext.transformR = function (position, matrix) { - var x = (position.x * matrix.m11) + (position.y * matrix.m21) + matrix.m31; - var y = (position.x * matrix.m12) + (position.y * matrix.m22) + matrix.m32; - return new Vector2(x, y); - }; - Vector2Ext.transform = function (sourceArray, matrix, destinationArray) { - this.transformA(sourceArray, 0, matrix, destinationArray, 0, sourceArray.length); - }; - Vector2Ext.round = function (vec) { - return new Vector2(Math.round(vec.x), Math.round(vec.y)); - }; - return Vector2Ext; + return ArrayUtils; }()); +var Base64Utils = (function () { + function Base64Utils() { + } + Base64Utils.decode = function (input, isNotStr) { + if (isNotStr === void 0) { isNotStr = true; } + var output = ""; + var chr1, chr2, chr3; + var enc1, enc2, enc3, enc4; + var i = 0; + input = this.getConfKey(input); + input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); + while (i < input.length) { + enc1 = this._keyAll.indexOf(input.charAt(i++)); + enc2 = this._keyAll.indexOf(input.charAt(i++)); + enc3 = this._keyAll.indexOf(input.charAt(i++)); + enc4 = this._keyAll.indexOf(input.charAt(i++)); + chr1 = (enc1 << 2) | (enc2 >> 4); + chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); + chr3 = ((enc3 & 3) << 6) | enc4; + output = output + String.fromCharCode(chr1); + if (enc3 != 64) { + if (chr2 == 0) { + if (isNotStr) + output = output + String.fromCharCode(chr2); + } + else { + output = output + String.fromCharCode(chr2); + } + } + if (enc4 != 64) { + if (chr3 == 0) { + if (isNotStr) + output = output + String.fromCharCode(chr3); + } + else { + output = output + String.fromCharCode(chr3); + } + } + } + output = this._utf8_decode(output); + return output; + }; + Base64Utils._utf8_encode = function (string) { + string = string.replace(/\r\n/g, "\n"); + var utftext = ""; + for (var n = 0; n < string.length; n++) { + var c = string.charCodeAt(n); + if (c < 128) { + utftext += String.fromCharCode(c); + } + else if ((c > 127) && (c < 2048)) { + utftext += String.fromCharCode((c >> 6) | 192); + utftext += String.fromCharCode((c & 63) | 128); + } + else { + utftext += String.fromCharCode((c >> 12) | 224); + utftext += String.fromCharCode(((c >> 6) & 63) | 128); + utftext += String.fromCharCode((c & 63) | 128); + } + } + return utftext; + }; + Base64Utils._utf8_decode = function (utftext) { + var string = ""; + var i = 0; + var c = 0; + var c1 = 0; + var c2 = 0; + var c3 = 0; + while (i < utftext.length) { + c = utftext.charCodeAt(i); + if (c < 128) { + string += String.fromCharCode(c); + i++; + } + else if ((c > 191) && (c < 224)) { + c2 = utftext.charCodeAt(i + 1); + string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); + i += 2; + } + else { + c2 = utftext.charCodeAt(i + 1); + c3 = utftext.charCodeAt(i + 2); + string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); + i += 3; + } + } + return string; + }; + Base64Utils.getConfKey = function (key) { + return key.slice(1, key.length); + }; + Base64Utils._keyNum = "0123456789+/"; + Base64Utils._keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + Base64Utils._keyAll = Base64Utils._keyNum + Base64Utils._keyStr; + Base64Utils.encode = function (input) { + var output = ""; + var chr1, chr2, chr3, enc1, enc2, enc3, enc4; + var i = 0; + input = this._utf8_encode(input); + while (i < input.length) { + chr1 = input.charCodeAt(i++); + chr2 = input.charCodeAt(i++); + chr3 = input.charCodeAt(i++); + enc1 = chr1 >> 2; + enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); + enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); + enc4 = chr3 & 63; + if (isNaN(chr2)) { + enc3 = enc4 = 64; + } + else if (isNaN(chr3)) { + enc4 = 64; + } + output = output + + this._keyAll.charAt(enc1) + this._keyAll.charAt(enc2) + + this._keyAll.charAt(enc3) + this._keyAll.charAt(enc4); + } + return this._keyStr.charAt(Math.floor((Math.random() * this._keyStr.length))) + output; + }; + return Base64Utils; +}()); +var es; +(function (es) { + var ContentManager = (function () { + function ContentManager() { + this.loadedAssets = new Map(); + } + ContentManager.prototype.loadRes = function (name, local) { + var _this = this; + if (local === void 0) { local = true; } + return new Promise(function (resolve, reject) { + var res = _this.loadedAssets.get(name); + if (res) { + resolve(res); + return; + } + if (local) { + RES.getResAsync(name).then(function (data) { + _this.loadedAssets.set(name, data); + resolve(data); + }).catch(function (err) { + console.error("资源加载错误:", name, err); + reject(err); + }); + } + else { + RES.getResByUrl(name).then(function (data) { + _this.loadedAssets.set(name, data); + resolve(data); + }).catch(function (err) { + console.error("资源加载错误:", name, err); + reject(err); + }); + } + }); + }; + ContentManager.prototype.dispose = function () { + this.loadedAssets.forEach(function (value) { + var assetsToRemove = value; + assetsToRemove.dispose(); + }); + this.loadedAssets.clear(); + }; + return ContentManager; + }()); + es.ContentManager = ContentManager; +})(es || (es = {})); +var es; +(function (es) { + var DrawUtils = (function () { + function DrawUtils() { + } + DrawUtils.drawLine = function (shape, start, end, color, thickness) { + if (thickness === void 0) { thickness = 1; } + this.drawLineAngle(shape, start, es.MathHelper.angleBetweenVectors(start, end), es.Vector2.distance(start, end), color, thickness); + }; + DrawUtils.drawLineAngle = function (shape, start, radians, length, color, thickness) { + if (thickness === void 0) { thickness = 1; } + shape.graphics.beginFill(color); + shape.graphics.drawRect(start.x, start.y, 1, 1); + shape.graphics.endFill(); + shape.scaleX = length; + shape.scaleY = thickness; + shape.$anchorOffsetX = 0; + shape.$anchorOffsetY = 0; + shape.rotation = radians; + }; + DrawUtils.drawHollowRect = function (shape, rect, color, thickness) { + if (thickness === void 0) { thickness = 1; } + this.drawHollowRectR(shape, rect.x, rect.y, rect.width, rect.height, color, thickness); + }; + DrawUtils.drawHollowRectR = function (shape, x, y, width, height, color, thickness) { + if (thickness === void 0) { thickness = 1; } + var tl = new es.Vector2(x, y).round(); + var tr = new es.Vector2(x + width, y).round(); + var br = new es.Vector2(x + width, y + height).round(); + var bl = new es.Vector2(x, y + height).round(); + this.drawLine(shape, tl, tr, color, thickness); + this.drawLine(shape, tr, br, color, thickness); + this.drawLine(shape, br, bl, color, thickness); + this.drawLine(shape, bl, tl, color, thickness); + }; + DrawUtils.drawPixel = function (shape, position, color, size) { + if (size === void 0) { size = 1; } + var destRect = new es.Rectangle(position.x, position.y, size, size); + if (size != 1) { + destRect.x -= size * 0.5; + destRect.y -= size * 0.5; + } + shape.graphics.beginFill(color); + shape.graphics.drawRect(destRect.x, destRect.y, destRect.width, destRect.height); + shape.graphics.endFill(); + }; + DrawUtils.getColorMatrix = function (color) { + var colorMatrix = [ + 1, 0, 0, 0, 0, + 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, + 0, 0, 0, 1, 0 + ]; + colorMatrix[0] = Math.floor(color / 256 / 256) / 255; + colorMatrix[6] = Math.floor(color / 256 % 256) / 255; + colorMatrix[12] = color % 256 / 255; + return new egret.ColorMatrixFilter(colorMatrix); + }; + return DrawUtils; + }()); + es.DrawUtils = DrawUtils; +})(es || (es = {})); +var es; +(function (es) { + var FuncPack = (function () { + function FuncPack(func, context) { + this.func = func; + this.context = context; + } + return FuncPack; + }()); + es.FuncPack = FuncPack; + var Emitter = (function () { + function Emitter() { + this._messageTable = new Map(); + } + Emitter.prototype.addObserver = function (eventType, handler, context) { + var list = this._messageTable.get(eventType); + if (!list) { + list = []; + this._messageTable.set(eventType, list); + } + if (list.findIndex(function (funcPack) { return funcPack.func == handler; }) != -1) + console.warn("您试图添加相同的观察者两次"); + list.push(new FuncPack(handler, context)); + }; + Emitter.prototype.removeObserver = function (eventType, handler) { + var messageData = this._messageTable.get(eventType); + var index = messageData.findIndex(function (data) { return data.func == handler; }); + if (index != -1) + messageData.removeAt(index); + }; + Emitter.prototype.emit = function (eventType, data) { + var list = this._messageTable.get(eventType); + if (list) { + for (var i = list.length - 1; i >= 0; i--) + list[i].func.call(list[i].context, data); + } + }; + return Emitter; + }()); + es.Emitter = Emitter; +})(es || (es = {})); +var es; +(function (es) { + var GlobalManager = (function () { + function GlobalManager() { + } + Object.defineProperty(GlobalManager.prototype, "enabled", { + get: function () { + return this._enabled; + }, + set: function (value) { + this.setEnabled(value); + }, + enumerable: true, + configurable: true + }); + GlobalManager.prototype.setEnabled = function (isEnabled) { + if (this._enabled != isEnabled) { + this._enabled = isEnabled; + if (this._enabled) { + this.onEnabled(); + } + else { + this.onDisabled(); + } + } + }; + GlobalManager.prototype.onEnabled = function () { + }; + GlobalManager.prototype.onDisabled = function () { + }; + GlobalManager.prototype.update = function () { + }; + return GlobalManager; + }()); + es.GlobalManager = GlobalManager; +})(es || (es = {})); +var es; +(function (es) { + var TouchState = (function () { + function TouchState() { + this.x = 0; + this.y = 0; + this.touchPoint = -1; + this.touchDown = false; + } + Object.defineProperty(TouchState.prototype, "position", { + get: function () { + return new es.Vector2(this.x, this.y); + }, + enumerable: true, + configurable: true + }); + TouchState.prototype.reset = function () { + this.x = 0; + this.y = 0; + this.touchDown = false; + this.touchPoint = -1; + }; + return TouchState; + }()); + es.TouchState = TouchState; + var Input = (function () { + function Input() { + } + Object.defineProperty(Input, "gameTouchs", { + get: function () { + return this._gameTouchs; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Input, "resolutionScale", { + get: function () { + return this._resolutionScale; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Input, "totalTouchCount", { + get: function () { + return this._totalTouchCount; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Input, "touchPosition", { + get: function () { + if (!this._gameTouchs[0]) + return es.Vector2.zero; + return this._gameTouchs[0].position; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Input, "maxSupportedTouch", { + get: function () { + return es.Core._instance.stage.maxTouches; + }, + set: function (value) { + es.Core._instance.stage.maxTouches = value; + this.initTouchCache(); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Input, "touchPositionDelta", { + get: function () { + var delta = es.Vector2.subtract(this.touchPosition, this._previousTouchState.position); + if (delta.length() > 0) { + this.setpreviousTouchState(this._gameTouchs[0]); + } + return delta; + }, + enumerable: true, + configurable: true + }); + Input.initialize = function () { + if (this._init) + return; + this._init = true; + es.Core._instance.stage.addEventListener(egret.TouchEvent.TOUCH_BEGIN, this.touchBegin, this); + es.Core._instance.stage.addEventListener(egret.TouchEvent.TOUCH_MOVE, this.touchMove, this); + es.Core._instance.stage.addEventListener(egret.TouchEvent.TOUCH_END, this.touchEnd, this); + es.Core._instance.stage.addEventListener(egret.TouchEvent.TOUCH_CANCEL, this.touchEnd, this); + es.Core._instance.stage.addEventListener(egret.TouchEvent.TOUCH_RELEASE_OUTSIDE, this.touchEnd, this); + this.initTouchCache(); + }; + Input.scaledPosition = function (position) { + var scaledPos = new es.Vector2(position.x - this._resolutionOffset.x, position.y - this._resolutionOffset.y); + return es.Vector2.multiply(scaledPos, this.resolutionScale); + }; + Input.initTouchCache = function () { + this._totalTouchCount = 0; + this._touchIndex = 0; + this._gameTouchs.length = 0; + for (var i = 0; i < this.maxSupportedTouch; i++) { + this._gameTouchs.push(new TouchState()); + } + }; + Input.touchBegin = function (evt) { + if (this._touchIndex < this.maxSupportedTouch) { + this._gameTouchs[this._touchIndex].touchPoint = evt.touchPointID; + this._gameTouchs[this._touchIndex].touchDown = evt.touchDown; + this._gameTouchs[this._touchIndex].x = evt.stageX; + this._gameTouchs[this._touchIndex].y = evt.stageY; + if (this._touchIndex == 0) { + this.setpreviousTouchState(this._gameTouchs[0]); + } + this._touchIndex++; + this._totalTouchCount++; + } + }; + Input.touchMove = function (evt) { + if (evt.touchPointID == this._gameTouchs[0].touchPoint) { + this.setpreviousTouchState(this._gameTouchs[0]); + } + var touchIndex = this._gameTouchs.findIndex(function (touch) { return touch.touchPoint == evt.touchPointID; }); + if (touchIndex != -1) { + var touchData = this._gameTouchs[touchIndex]; + touchData.x = evt.stageX; + touchData.y = evt.stageY; + } + }; + Input.touchEnd = function (evt) { + var touchIndex = this._gameTouchs.findIndex(function (touch) { return touch.touchPoint == evt.touchPointID; }); + if (touchIndex != -1) { + var touchData = this._gameTouchs[touchIndex]; + touchData.reset(); + if (touchIndex == 0) + this._previousTouchState.reset(); + this._totalTouchCount--; + if (this.totalTouchCount == 0) { + this._touchIndex = 0; + } + } + }; + Input.setpreviousTouchState = function (touchState) { + this._previousTouchState = new TouchState(); + this._previousTouchState.x = touchState.position.x; + this._previousTouchState.y = touchState.position.y; + this._previousTouchState.touchPoint = touchState.touchPoint; + this._previousTouchState.touchDown = touchState.touchDown; + }; + Input._init = false; + Input._previousTouchState = new TouchState(); + Input._resolutionOffset = new es.Vector2(); + Input._touchIndex = 0; + Input._gameTouchs = []; + Input._resolutionScale = es.Vector2.one; + Input._totalTouchCount = 0; + return Input; + }()); + es.Input = Input; +})(es || (es = {})); +var KeyboardUtils = (function () { + function KeyboardUtils() { + } + KeyboardUtils.init = function () { + this.keyDownDict = {}; + this.keyUpDict = {}; + document.addEventListener("keydown", this.onKeyDonwHander); + document.addEventListener("keyup", this.onKeyUpHander); + }; + KeyboardUtils.registerKey = function (key, fun, thisObj, type) { + if (type === void 0) { type = 0; } + var args = []; + for (var _i = 4; _i < arguments.length; _i++) { + args[_i - 4] = arguments[_i]; + } + var keyDict = type ? this.keyUpDict : this.keyDownDict; + keyDict[key] = { "fun": fun, args: args, "thisObj": thisObj }; + }; + KeyboardUtils.unregisterKey = function (key, type) { + if (type === void 0) { type = 0; } + var keyDict = type ? this.keyUpDict : this.keyDownDict; + delete keyDict[key]; + }; + KeyboardUtils.destroy = function () { + this.keyDownDict = null; + this.keyUpDict = null; + document.removeEventListener("keydown", this.onKeyDonwHander); + document.removeEventListener("keyup", this.onKeyUpHander); + }; + KeyboardUtils.onKeyDonwHander = function (event) { + if (!this.keyDownDict) + return; + var key = this.keyCodeToString(event.keyCode); + var o = this.keyDownDict[key]; + if (o) { + var fun = o["fun"]; + var thisObj = o["thisObj"]; + var args = o["args"]; + fun.apply(thisObj, args); + } + }; + KeyboardUtils.onKeyUpHander = function (event) { + if (!this.keyUpDict) + return; + var key = this.keyCodeToString(event.keyCode); + var o = this.keyUpDict[key]; + if (o) { + var fun = o["fun"]; + var thisObj = o["thisObj"]; + var args = o["args"]; + fun.apply(thisObj, args); + } + }; + KeyboardUtils.keyCodeToString = function (keyCode) { + switch (keyCode) { + case 8: + return this.BACK_SPACE; + case 9: + return this.TAB; + case 13: + return this.ENTER; + case 16: + return this.SHIFT; + case 17: + return this.CTRL; + case 19: + return this.PAUSE_BREAK; + case 20: + return this.CAPS_LOCK; + case 27: + return this.ESC; + case 32: + return this.SPACE; + case 33: + return this.PAGE_UP; + case 34: + return this.PAGE_DOWN; + case 35: + return this.END; + case 36: + return this.HOME; + case 37: + return this.LEFT; + case 38: + return this.UP; + case 39: + return this.RIGHT; + case 40: + return this.DOWN; + case 45: + return this.INSERT; + case 46: + return this.DELETE; + case 91: + return this.WINDOWS; + case 112: + return this.F1; + case 113: + return this.F2; + case 114: + return this.F3; + case 115: + return this.F4; + case 116: + return this.F5; + case 117: + return this.F6; + case 118: + return this.F7; + case 119: + return this.F8; + case 120: + return this.F9; + case 122: + return this.F11; + case 123: + return this.F12; + case 144: + return this.NUM_LOCK; + case 145: + return this.SCROLL_LOCK; + default: + return String.fromCharCode(keyCode); + } + }; + KeyboardUtils.TYPE_KEY_DOWN = 0; + KeyboardUtils.TYPE_KEY_UP = 1; + KeyboardUtils.A = "A"; + KeyboardUtils.B = "B"; + KeyboardUtils.C = "C"; + KeyboardUtils.D = "D"; + KeyboardUtils.E = "E"; + KeyboardUtils.F = "F"; + KeyboardUtils.G = "G"; + KeyboardUtils.H = "H"; + KeyboardUtils.I = "I"; + KeyboardUtils.J = "J"; + KeyboardUtils.K = "K"; + KeyboardUtils.L = "L"; + KeyboardUtils.M = "M"; + KeyboardUtils.N = "N"; + KeyboardUtils.O = "O"; + KeyboardUtils.P = "P"; + KeyboardUtils.Q = "Q"; + KeyboardUtils.R = "R"; + KeyboardUtils.S = "S"; + KeyboardUtils.T = "T"; + KeyboardUtils.U = "U"; + KeyboardUtils.V = "V"; + KeyboardUtils.W = "W"; + KeyboardUtils.X = "X"; + KeyboardUtils.Y = "Y"; + KeyboardUtils.Z = "Z"; + KeyboardUtils.ESC = "Esc"; + KeyboardUtils.F1 = "F1"; + KeyboardUtils.F2 = "F2"; + KeyboardUtils.F3 = "F3"; + KeyboardUtils.F4 = "F4"; + KeyboardUtils.F5 = "F5"; + KeyboardUtils.F6 = "F6"; + KeyboardUtils.F7 = "F7"; + KeyboardUtils.F8 = "F8"; + KeyboardUtils.F9 = "F9"; + KeyboardUtils.F10 = "F10"; + KeyboardUtils.F11 = "F11"; + KeyboardUtils.F12 = "F12"; + KeyboardUtils.NUM_1 = "1"; + KeyboardUtils.NUM_2 = "2"; + KeyboardUtils.NUM_3 = "3"; + KeyboardUtils.NUM_4 = "4"; + KeyboardUtils.NUM_5 = "5"; + KeyboardUtils.NUM_6 = "6"; + KeyboardUtils.NUM_7 = "7"; + KeyboardUtils.NUM_8 = "8"; + KeyboardUtils.NUM_9 = "9"; + KeyboardUtils.NUM_0 = "0"; + KeyboardUtils.TAB = "Tab"; + KeyboardUtils.CTRL = "Ctrl"; + KeyboardUtils.ALT = "Alt"; + KeyboardUtils.SHIFT = "Shift"; + KeyboardUtils.CAPS_LOCK = "Caps Lock"; + KeyboardUtils.ENTER = "Enter"; + KeyboardUtils.SPACE = "Space"; + KeyboardUtils.BACK_SPACE = "Back Space"; + KeyboardUtils.INSERT = "Insert"; + KeyboardUtils.DELETE = "Page Down"; + KeyboardUtils.HOME = "Home"; + KeyboardUtils.END = "Page Down"; + KeyboardUtils.PAGE_UP = "Page Up"; + KeyboardUtils.PAGE_DOWN = "Page Down"; + KeyboardUtils.LEFT = "Left"; + KeyboardUtils.RIGHT = "Right"; + KeyboardUtils.UP = "Up"; + KeyboardUtils.DOWN = "Down"; + KeyboardUtils.PAUSE_BREAK = "Pause Break"; + KeyboardUtils.NUM_LOCK = "Num Lock"; + KeyboardUtils.SCROLL_LOCK = "Scroll Lock"; + KeyboardUtils.WINDOWS = "Windows"; + return KeyboardUtils; +}()); +var es; +(function (es) { + var ListPool = (function () { + function ListPool() { + } + ListPool.warmCache = function (cacheCount) { + cacheCount -= this._objectQueue.length; + if (cacheCount > 0) { + for (var i = 0; i < cacheCount; i++) { + this._objectQueue.unshift([]); + } + } + }; + ListPool.trimCache = function (cacheCount) { + while (cacheCount > this._objectQueue.length) + this._objectQueue.shift(); + }; + ListPool.clearCache = function () { + this._objectQueue.length = 0; + }; + ListPool.obtain = function () { + if (this._objectQueue.length > 0) + return this._objectQueue.shift(); + return []; + }; + ListPool.free = function (obj) { + this._objectQueue.unshift(obj); + obj.length = 0; + }; + ListPool._objectQueue = []; + return ListPool; + }()); + es.ListPool = ListPool; +})(es || (es = {})); +var THREAD_ID = Math.floor(Math.random() * 1000) + "-" + Date.now(); +var nextTick = function (fn) { + setTimeout(fn, 0); +}; +var LockUtils = (function () { + function LockUtils(key) { + this._keyX = "mutex_key_" + key + "_X"; + this._keyY = "mutex_key_" + key + "_Y"; + this.setItem = egret.localStorage.setItem.bind(localStorage); + this.getItem = egret.localStorage.getItem.bind(localStorage); + this.removeItem = egret.localStorage.removeItem.bind(localStorage); + } + LockUtils.prototype.lock = function () { + var _this = this; + return new Promise(function (resolve, reject) { + var fn = function () { + _this.setItem(_this._keyX, THREAD_ID); + if (!_this.getItem(_this._keyY) === null) { + nextTick(fn); + } + _this.setItem(_this._keyY, THREAD_ID); + if (_this.getItem(_this._keyX) !== THREAD_ID) { + setTimeout(function () { + if (_this.getItem(_this._keyY) !== THREAD_ID) { + nextTick(fn); + return; + } + resolve(); + _this.removeItem(_this._keyY); + }, 10); + } + else { + resolve(); + _this.removeItem(_this._keyY); + } + }; + fn(); + }); + }; + return LockUtils; +}()); +var es; +(function (es) { + var Pair = (function () { + function Pair(first, second) { + this.first = first; + this.second = second; + } + Pair.prototype.clear = function () { + this.first = this.second = null; + }; + Pair.prototype.equals = function (other) { + return this.first == other.first && this.second == other.second; + }; + return Pair; + }()); + es.Pair = Pair; +})(es || (es = {})); +var RandomUtils = (function () { + function RandomUtils() { + } + RandomUtils.randrange = function (start, stop, step) { + if (step === void 0) { step = 1; } + if (step == 0) + throw new Error('step 不能为 0'); + var width = stop - start; + if (width == 0) + throw new Error('没有可用的范围(' + start + ',' + stop + ')'); + if (width < 0) + width = start - stop; + var n = Math.floor((width + step - 1) / step); + return Math.floor(this.random() * n) * step + Math.min(start, stop); + }; + RandomUtils.randint = function (a, b) { + a = Math.floor(a); + b = Math.floor(b); + if (a > b) + a++; + else + b++; + return this.randrange(a, b); + }; + RandomUtils.randnum = function (a, b) { + return this.random() * (b - a) + a; + }; + RandomUtils.shuffle = function (array) { + array.sort(this._randomCompare); + return array; + }; + RandomUtils.choice = function (sequence) { + if (!sequence.hasOwnProperty("length")) + throw new Error('无法对此对象执行此操作'); + var index = Math.floor(this.random() * sequence.length); + if (sequence instanceof String) + return String(sequence).charAt(index); + else + return sequence[index]; + }; + RandomUtils.sample = function (sequence, num) { + var len = sequence.length; + if (num <= 0 || len < num) + throw new Error("采样数量不够"); + var selected = []; + var indices = []; + for (var i = 0; i < num; i++) { + var index = Math.floor(this.random() * len); + while (indices.indexOf(index) >= 0) + index = Math.floor(this.random() * len); + selected.push(sequence[index]); + indices.push(index); + } + return selected; + }; + RandomUtils.random = function () { + return Math.random(); + }; + RandomUtils.boolean = function (chance) { + if (chance === void 0) { chance = .5; } + return (this.random() < chance) ? true : false; + }; + RandomUtils._randomCompare = function (a, b) { + return (this.random() > .5) ? 1 : -1; + }; + return RandomUtils; +}()); +var es; +(function (es) { + var RectangleExt = (function () { + function RectangleExt() { + } + RectangleExt.union = function (first, point) { + var rect = new es.Rectangle(point.x, point.y, 0, 0); + var result = new es.Rectangle(); + result.x = Math.min(first.x, rect.x); + result.y = Math.min(first.y, rect.y); + result.width = Math.max(first.right, rect.right) - result.x; + result.height = Math.max(first.bottom, result.bottom) - result.y; + return result; + }; + return RectangleExt; + }()); + es.RectangleExt = RectangleExt; +})(es || (es = {})); +var es; +(function (es) { + var Triangulator = (function () { + function Triangulator() { + this.triangleIndices = []; + this._triPrev = new Array(12); + this._triNext = new Array(12); + } + Triangulator.testPointTriangle = function (point, a, b, c) { + if (es.Vector2Ext.cross(es.Vector2.subtract(point, a), es.Vector2.subtract(b, a)) < 0) + return false; + if (es.Vector2Ext.cross(es.Vector2.subtract(point, b), es.Vector2.subtract(c, b)) < 0) + return false; + if (es.Vector2Ext.cross(es.Vector2.subtract(point, c), es.Vector2.subtract(a, c)) < 0) + return false; + return true; + }; + Triangulator.prototype.triangulate = function (points, arePointsCCW) { + if (arePointsCCW === void 0) { arePointsCCW = true; } + var count = points.length; + this.initialize(count); + var iterations = 0; + var index = 0; + while (count > 3 && iterations < 500) { + iterations++; + var isEar = true; + var a = points[this._triPrev[index]]; + var b = points[index]; + var c = points[this._triNext[index]]; + if (es.Vector2Ext.isTriangleCCW(a, b, c)) { + var k = this._triNext[this._triNext[index]]; + do { + if (Triangulator.testPointTriangle(points[k], a, b, c)) { + isEar = false; + break; + } + k = this._triNext[k]; + } while (k != this._triPrev[index]); + } + else { + isEar = false; + } + if (isEar) { + this.triangleIndices.push(this._triPrev[index]); + this.triangleIndices.push(index); + this.triangleIndices.push(this._triNext[index]); + this._triNext[this._triPrev[index]] = this._triNext[index]; + this._triPrev[this._triNext[index]] = this._triPrev[index]; + count--; + index = this._triPrev[index]; + } + else { + index = this._triNext[index]; + } + } + this.triangleIndices.push(this._triPrev[index]); + this.triangleIndices.push(index); + this.triangleIndices.push(this._triNext[index]); + if (!arePointsCCW) + this.triangleIndices.reverse(); + }; + Triangulator.prototype.initialize = function (count) { + this.triangleIndices.length = 0; + if (this._triNext.length < count) { + this._triNext.reverse(); + this._triNext = new Array(Math.max(this._triNext.length * 2, count)); + } + if (this._triPrev.length < count) { + this._triPrev.reverse(); + this._triPrev = new Array(Math.max(this._triPrev.length * 2, count)); + } + for (var i = 0; i < count; i++) { + this._triPrev[i] = i - 1; + this._triNext[i] = i + 1; + } + this._triPrev[0] = count - 1; + this._triNext[count - 1] = 0; + }; + return Triangulator; + }()); + es.Triangulator = Triangulator; +})(es || (es = {})); +var es; +(function (es) { + var Vector2Ext = (function () { + function Vector2Ext() { + } + Vector2Ext.isTriangleCCW = function (a, center, c) { + return this.cross(es.Vector2.subtract(center, a), es.Vector2.subtract(c, center)) < 0; + }; + Vector2Ext.cross = function (u, v) { + return u.y * v.x - u.x * v.y; + }; + Vector2Ext.perpendicular = function (first, second) { + return new es.Vector2(-1 * (second.y - first.y), second.x - first.x); + }; + Vector2Ext.normalize = function (vec) { + var magnitude = Math.sqrt((vec.x * vec.x) + (vec.y * vec.y)); + if (magnitude > es.MathHelper.Epsilon) { + vec = es.Vector2.divide(vec, new es.Vector2(magnitude)); + } + else { + vec.x = vec.y = 0; + } + return vec; + }; + Vector2Ext.transformA = function (sourceArray, sourceIndex, matrix, destinationArray, destinationIndex, length) { + for (var i = 0; i < length; i++) { + var position = sourceArray[sourceIndex + i]; + var destination = destinationArray[destinationIndex + i]; + destination.x = (position.x * matrix.m11) + (position.y * matrix.m21) + matrix.m31; + destination.y = (position.x * matrix.m12) + (position.y * matrix.m22) + matrix.m32; + destinationArray[destinationIndex + i] = destination; + } + }; + Vector2Ext.transformR = function (position, matrix) { + var x = (position.x * matrix.m11) + (position.y * matrix.m21) + matrix.m31; + var y = (position.x * matrix.m12) + (position.y * matrix.m22) + matrix.m32; + return new es.Vector2(x, y); + }; + Vector2Ext.transform = function (sourceArray, matrix, destinationArray) { + this.transformA(sourceArray, 0, matrix, destinationArray, 0, sourceArray.length); + }; + Vector2Ext.round = function (vec) { + return new es.Vector2(Math.round(vec.x), Math.round(vec.y)); + }; + return Vector2Ext; + }()); + es.Vector2Ext = Vector2Ext; +})(es || (es = {})); +var WebGLUtils = (function () { + function WebGLUtils() { + } + WebGLUtils.getContext = function () { + var canvas = document.getElementsByTagName('canvas')[0]; + return canvas.getContext('2d'); + }; + return WebGLUtils; +}()); +var es; +(function (es) { + var Layout = (function () { + function Layout() { + this.clientArea = new es.Rectangle(0, 0, es.Core.graphicsDevice.viewport.width, es.Core.graphicsDevice.viewport.height); + this.safeArea = this.clientArea; + } + Layout.prototype.place = function (size, horizontalMargin, verticalMargine, alignment) { + var rc = new es.Rectangle(0, 0, size.x, size.y); + if ((alignment & Alignment.left) != 0) { + rc.x = this.clientArea.x + (this.clientArea.width * horizontalMargin); + } + else if ((alignment & Alignment.right) != 0) { + rc.x = this.clientArea.x + (this.clientArea.width * (1 - horizontalMargin)) - rc.width; + } + else if ((alignment & Alignment.horizontalCenter) != 0) { + rc.x = this.clientArea.x + (this.clientArea.width - rc.width) / 2 + (horizontalMargin * this.clientArea.width); + } + else { + } + if ((alignment & Alignment.top) != 0) { + rc.y = this.clientArea.y + (this.clientArea.height * verticalMargine); + } + else if ((alignment & Alignment.bottom) != 0) { + rc.y = this.clientArea.y + (this.clientArea.height * (1 - verticalMargine)) - rc.height; + } + else if ((alignment & Alignment.verticalCenter) != 0) { + rc.y = this.clientArea.y + (this.clientArea.height - rc.height) / 2 + (verticalMargine * this.clientArea.height); + } + else { + } + if (rc.left < this.safeArea.left) + rc.x = this.safeArea.left; + if (rc.right > this.safeArea.right) + rc.x = this.safeArea.right - rc.width; + if (rc.top < this.safeArea.top) + rc.y = this.safeArea.top; + if (rc.bottom > this.safeArea.bottom) + rc.y = this.safeArea.bottom - rc.height; + return rc; + }; + return Layout; + }()); + es.Layout = Layout; + var Alignment; + (function (Alignment) { + Alignment[Alignment["none"] = 0] = "none"; + Alignment[Alignment["left"] = 1] = "left"; + Alignment[Alignment["right"] = 2] = "right"; + Alignment[Alignment["horizontalCenter"] = 4] = "horizontalCenter"; + Alignment[Alignment["top"] = 8] = "top"; + Alignment[Alignment["bottom"] = 16] = "bottom"; + Alignment[Alignment["verticalCenter"] = 32] = "verticalCenter"; + Alignment[Alignment["topLeft"] = 9] = "topLeft"; + Alignment[Alignment["topRight"] = 10] = "topRight"; + Alignment[Alignment["topCenter"] = 12] = "topCenter"; + Alignment[Alignment["bottomLeft"] = 17] = "bottomLeft"; + Alignment[Alignment["bottomRight"] = 18] = "bottomRight"; + Alignment[Alignment["bottomCenter"] = 20] = "bottomCenter"; + Alignment[Alignment["centerLeft"] = 33] = "centerLeft"; + Alignment[Alignment["centerRight"] = 34] = "centerRight"; + Alignment[Alignment["center"] = 36] = "center"; + })(Alignment = es.Alignment || (es.Alignment = {})); +})(es || (es = {})); +var stopwatch; +(function (stopwatch) { + var Stopwatch = (function () { + function Stopwatch(getSystemTime) { + if (getSystemTime === void 0) { getSystemTime = _defaultSystemTimeGetter; } + this.getSystemTime = getSystemTime; + this._stopDuration = 0; + this._completeSlices = []; + } + Stopwatch.prototype.getState = function () { + if (this._startSystemTime === undefined) { + return State.IDLE; + } + else if (this._stopSystemTime === undefined) { + return State.RUNNING; + } + else { + return State.STOPPED; + } + }; + Stopwatch.prototype.isIdle = function () { + return this.getState() === State.IDLE; + }; + Stopwatch.prototype.isRunning = function () { + return this.getState() === State.RUNNING; + }; + Stopwatch.prototype.isStopped = function () { + return this.getState() === State.STOPPED; + }; + Stopwatch.prototype.slice = function () { + return this.recordPendingSlice(); + }; + Stopwatch.prototype.getCompletedSlices = function () { + return Array.from(this._completeSlices); + }; + Stopwatch.prototype.getCompletedAndPendingSlices = function () { + return this._completeSlices.concat([this.getPendingSlice()]); + }; + Stopwatch.prototype.getPendingSlice = function () { + return this.calculatePendingSlice(); + }; + Stopwatch.prototype.getTime = function () { + return this.caculateStopwatchTime(); + }; + Stopwatch.prototype.reset = function () { + this._startSystemTime = this._pendingSliceStartStopwatchTime = this._stopSystemTime = undefined; + this._stopDuration = 0; + this._completeSlices = []; + }; + Stopwatch.prototype.start = function (forceReset) { + if (forceReset === void 0) { forceReset = false; } + if (forceReset) { + this.reset(); + } + if (this._stopSystemTime !== undefined) { + var systemNow = this.getSystemTime(); + var stopDuration = systemNow - this._stopSystemTime; + this._stopDuration += stopDuration; + this._stopSystemTime = undefined; + } + else if (this._startSystemTime === undefined) { + var systemNow = this.getSystemTime(); + this._startSystemTime = systemNow; + this._pendingSliceStartStopwatchTime = 0; + } + }; + Stopwatch.prototype.stop = function (recordPendingSlice) { + if (recordPendingSlice === void 0) { recordPendingSlice = false; } + if (this._startSystemTime === undefined) { + return 0; + } + var systemTimeOfStopwatchTime = this.getSystemTimeOfCurrentStopwatchTime(); + if (recordPendingSlice) { + this.recordPendingSlice(this.caculateStopwatchTime(systemTimeOfStopwatchTime)); + } + this._stopSystemTime = systemTimeOfStopwatchTime; + return this.getTime(); + }; + Stopwatch.prototype.calculatePendingSlice = function (endStopwatchTime) { + if (this._pendingSliceStartStopwatchTime === undefined) { + return Object.freeze({ startTime: 0, endTime: 0, duration: 0 }); + } + if (endStopwatchTime === undefined) { + endStopwatchTime = this.getTime(); + } + return Object.freeze({ + startTime: this._pendingSliceStartStopwatchTime, + endTime: endStopwatchTime, + duration: endStopwatchTime - this._pendingSliceStartStopwatchTime + }); + }; + Stopwatch.prototype.caculateStopwatchTime = function (endSystemTime) { + if (this._startSystemTime === undefined) + return 0; + if (endSystemTime === undefined) + endSystemTime = this.getSystemTimeOfCurrentStopwatchTime(); + return endSystemTime - this._startSystemTime - this._stopDuration; + }; + Stopwatch.prototype.getSystemTimeOfCurrentStopwatchTime = function () { + return this._stopSystemTime === undefined ? this.getSystemTime() : this._stopSystemTime; + }; + Stopwatch.prototype.recordPendingSlice = function (endStopwatchTime) { + if (this._pendingSliceStartStopwatchTime !== undefined) { + if (endStopwatchTime === undefined) { + endStopwatchTime = this.getTime(); + } + var slice = this.calculatePendingSlice(endStopwatchTime); + this._pendingSliceStartStopwatchTime = slice.endTime; + this._completeSlices.push(slice); + return slice; + } + else { + return this.calculatePendingSlice(); + } + }; + return Stopwatch; + }()); + stopwatch.Stopwatch = Stopwatch; + var State; + (function (State) { + State["IDLE"] = "IDLE"; + State["RUNNING"] = "RUNNING"; + State["STOPPED"] = "STOPPED"; + })(State || (State = {})); + function setDefaultSystemTimeGetter(systemTimeGetter) { + if (systemTimeGetter === void 0) { systemTimeGetter = Date.now; } + _defaultSystemTimeGetter = systemTimeGetter; + } + stopwatch.setDefaultSystemTimeGetter = setDefaultSystemTimeGetter; + var _defaultSystemTimeGetter = Date.now; +})(stopwatch || (stopwatch = {})); +var es; +(function (es) { + var TimeRuler = (function () { + function TimeRuler() { + this.showLog = false; + this._frameKey = 'frame'; + this._logKey = 'log'; + this.markers = []; + this.stopwacth = new stopwatch.Stopwatch(); + this._markerNameToIdMap = new Map(); + this._logs = new Array(2); + for (var i = 0; i < this._logs.length; ++i) + this._logs[i] = new FrameLog(); + this.sampleFrames = this.targetSampleFrames = 1; + this.width = es.Core.graphicsDevice.viewport.width * 0.8; + es.Core.emitter.addObserver(es.CoreEvents.GraphicsDeviceReset, this.onGraphicsDeviceReset, this); + this.onGraphicsDeviceReset(); + } + Object.defineProperty(TimeRuler, "Instance", { + get: function () { + if (!this._instance) + this._instance = new TimeRuler(); + return this._instance; + }, + enumerable: true, + configurable: true + }); + TimeRuler.prototype.startFrame = function () { + var _this = this; + var lock = new LockUtils(this._frameKey); + lock.lock().then(function () { + _this._updateCount = parseInt(egret.localStorage.getItem(_this._frameKey), 10); + if (isNaN(_this._updateCount)) + _this._updateCount = 0; + var count = _this._updateCount; + count += 1; + egret.localStorage.setItem(_this._frameKey, count.toString()); + if (_this.enabled && (1 < count && count < TimeRuler.maxSampleFrames)) + return; + _this._prevLog = _this._logs[_this.frameCount++ & 0x1]; + _this._curLog = _this._logs[_this.frameCount & 0x1]; + var endFrameTime = _this.stopwacth.getTime(); + for (var barIndex = 0; barIndex < _this._prevLog.bars.length; ++barIndex) { + var prevBar = _this._prevLog.bars[barIndex]; + var nextBar = _this._curLog.bars[barIndex]; + for (var nest = 0; nest < prevBar.nestCount; ++nest) { + var markerIdx = prevBar.markerNests[nest]; + prevBar.markers[markerIdx].endTime = endFrameTime; + nextBar.markerNests[nest] = nest; + nextBar.markers[nest].markerId = prevBar.markers[markerIdx].markerId; + nextBar.markers[nest].beginTime = 0; + nextBar.markers[nest].endTime = -1; + nextBar.markers[nest].color = prevBar.markers[markerIdx].color; + } + for (var markerIdx = 0; markerIdx < prevBar.markCount; ++markerIdx) { + var duration = prevBar.markers[markerIdx].endTime - prevBar.markers[markerIdx].beginTime; + var markerId = prevBar.markers[markerIdx].markerId; + var m = _this.markers[markerId]; + m.logs[barIndex].color = prevBar.markers[markerIdx].color; + if (!m.logs[barIndex].initialized) { + m.logs[barIndex].min = duration; + m.logs[barIndex].max = duration; + m.logs[barIndex].avg = duration; + m.logs[barIndex].initialized = true; + } + else { + m.logs[barIndex].min = Math.min(m.logs[barIndex].min, duration); + m.logs[barIndex].max = Math.min(m.logs[barIndex].max, duration); + m.logs[barIndex].avg += duration; + m.logs[barIndex].avg *= 0.5; + if (m.logs[barIndex].samples++ >= TimeRuler.logSnapDuration) { + m.logs[barIndex].snapMin = m.logs[barIndex].min; + m.logs[barIndex].snapMax = m.logs[barIndex].max; + m.logs[barIndex].snapAvg = m.logs[barIndex].avg; + m.logs[barIndex].samples = 0; + } + } + } + nextBar.markCount = prevBar.nestCount; + nextBar.nestCount = prevBar.nestCount; + } + _this.stopwacth.reset(); + _this.stopwacth.start(); + }); + }; + TimeRuler.prototype.beginMark = function (markerName, color, barIndex) { + var _this = this; + if (barIndex === void 0) { barIndex = 0; } + var lock = new LockUtils(this._frameKey); + lock.lock().then(function () { + if (barIndex < 0 || barIndex >= TimeRuler.maxBars) + throw new Error("barIndex argument out of range"); + var bar = _this._curLog.bars[barIndex]; + if (bar.markCount >= TimeRuler.maxSamples) { + throw new Error("exceeded sample count. either set larger number to timeruler.maxsaple or lower sample count"); + } + if (bar.nestCount >= TimeRuler.maxNestCall) { + throw new Error("exceeded nest count. either set larger number to timeruler.maxnestcall or lower nest calls"); + } + var markerId = _this._markerNameToIdMap.get(markerName); + if (isNaN(markerId)) { + markerId = _this.markers.length; + _this._markerNameToIdMap.set(markerName, markerId); + } + bar.markerNests[bar.nestCount++] = bar.markCount; + bar.markers[bar.markCount].markerId = markerId; + bar.markers[bar.markCount].color = color; + bar.markers[bar.markCount].beginTime = _this.stopwacth.getTime(); + bar.markers[bar.markCount].endTime = -1; + }); + }; + TimeRuler.prototype.endMark = function (markerName, barIndex) { + var _this = this; + if (barIndex === void 0) { barIndex = 0; } + var lock = new LockUtils(this._frameKey); + lock.lock().then(function () { + if (barIndex < 0 || barIndex >= TimeRuler.maxBars) + throw new Error("barIndex argument out of range"); + var bar = _this._curLog.bars[barIndex]; + if (bar.nestCount <= 0) { + throw new Error("call beginMark method before calling endMark method"); + } + var markerId = _this._markerNameToIdMap.get(markerName); + if (isNaN(markerId)) { + throw new Error("Marker " + markerName + " is not registered. Make sure you specifed same name as you used for beginMark method"); + } + var markerIdx = bar.markerNests[--bar.nestCount]; + if (bar.markers[markerIdx].markerId != markerId) { + throw new Error("Incorrect call order of beginMark/endMark method. beginMark(A), beginMark(B), endMark(B), endMark(A) But you can't called it like beginMark(A), beginMark(B), endMark(A), endMark(B)."); + } + bar.markers[markerIdx].endTime = _this.stopwacth.getTime(); + }); + }; + TimeRuler.prototype.getAverageTime = function (barIndex, markerName) { + if (barIndex < 0 || barIndex >= TimeRuler.maxBars) { + throw new Error("barIndex argument out of range"); + } + var result = 0; + var markerId = this._markerNameToIdMap.get(markerName); + if (markerId) { + result = this.markers[markerId].logs[barIndex].avg; + } + return result; + }; + TimeRuler.prototype.resetLog = function () { + var _this = this; + var lock = new LockUtils(this._logKey); + lock.lock().then(function () { + var count = parseInt(egret.localStorage.getItem(_this._logKey), 10); + count += 1; + egret.localStorage.setItem(_this._logKey, count.toString()); + _this.markers.forEach(function (markerInfo) { + for (var i = 0; i < markerInfo.logs.length; ++i) { + markerInfo.logs[i].initialized = false; + markerInfo.logs[i].snapMin = 0; + markerInfo.logs[i].snapMax = 0; + markerInfo.logs[i].snapAvg = 0; + markerInfo.logs[i].min = 0; + markerInfo.logs[i].max = 0; + markerInfo.logs[i].avg = 0; + markerInfo.logs[i].samples = 0; + } + }); + }); + }; + TimeRuler.prototype.render = function (position, width) { + if (position === void 0) { position = this._position; } + if (width === void 0) { width = this.width; } + egret.localStorage.setItem(this._frameKey, "0"); + if (!this.showLog) + return; + var height = 0; + var maxTime = 0; + this._prevLog.bars.forEach(function (bar) { + if (bar.markCount > 0) { + height += TimeRuler.barHeight + TimeRuler.barPadding * 2; + maxTime = Math.max(maxTime, bar.markers[bar.markCount - 1].endTime); + } + }); + var frameSpan = 1 / 60 * 1000; + var sampleSpan = this.sampleFrames * frameSpan; + if (maxTime > sampleSpan) { + this._frameAdjust = Math.max(0, this._frameAdjust) + 1; + } + else { + this._frameAdjust = Math.min(0, this._frameAdjust) - 1; + } + if (Math.max(this._frameAdjust) > TimeRuler.autoAdjustDelay) { + this.sampleFrames = Math.min(TimeRuler.maxSampleFrames, this.sampleFrames); + this.sampleFrames = Math.max(this.targetSampleFrames, (maxTime / frameSpan) + 1); + this._frameAdjust = 0; + } + var msToPs = width / sampleSpan; + var startY = position.y - (height - TimeRuler.barHeight); + var y = startY; + }; + TimeRuler.prototype.onGraphicsDeviceReset = function () { + var layout = new es.Layout(); + this._position = layout.place(new es.Vector2(this.width, TimeRuler.barHeight), 0, 0.01, es.Alignment.bottomCenter).location; + }; + TimeRuler.maxBars = 8; + TimeRuler.maxSamples = 256; + TimeRuler.maxNestCall = 32; + TimeRuler.barHeight = 8; + TimeRuler.maxSampleFrames = 4; + TimeRuler.logSnapDuration = 120; + TimeRuler.barPadding = 2; + TimeRuler.autoAdjustDelay = 30; + return TimeRuler; + }()); + es.TimeRuler = TimeRuler; + var FrameLog = (function () { + function FrameLog() { + this.bars = new Array(TimeRuler.maxBars); + this.bars.fill(new MarkerCollection(), 0, TimeRuler.maxBars); + } + return FrameLog; + }()); + es.FrameLog = FrameLog; + var MarkerCollection = (function () { + function MarkerCollection() { + this.markers = new Array(TimeRuler.maxSamples); + this.markCount = 0; + this.markerNests = new Array(TimeRuler.maxNestCall); + this.nestCount = 0; + this.markers.fill(new Marker(), 0, TimeRuler.maxSamples); + this.markerNests.fill(0, 0, TimeRuler.maxNestCall); + } + return MarkerCollection; + }()); + es.MarkerCollection = MarkerCollection; + var Marker = (function () { + function Marker() { + this.markerId = 0; + this.beginTime = 0; + this.endTime = 0; + this.color = 0x000000; + } + return Marker; + }()); + es.Marker = Marker; + var MarkerInfo = (function () { + function MarkerInfo(name) { + this.logs = new Array(TimeRuler.maxBars); + this.name = name; + this.logs.fill(new MarkerLog(), 0, TimeRuler.maxBars); + } + return MarkerInfo; + }()); + es.MarkerInfo = MarkerInfo; + var MarkerLog = (function () { + function MarkerLog() { + this.snapMin = 0; + this.snapMax = 0; + this.snapAvg = 0; + this.min = 0; + this.max = 0; + this.avg = 0; + this.samples = 0; + this.color = 0x000000; + this.initialized = false; + } + return MarkerLog; + }()); + es.MarkerLog = MarkerLog; +})(es || (es = {})); diff --git a/source/bin/framework.min.js b/source/bin/framework.min.js index e9723556..e6cf4f42 100644 --- a/source/bin/framework.min.js +++ b/source/bin/framework.min.js @@ -1 +1 @@ -window.framework={},window.__extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])};return function(e,n){function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}();var __awaiter=this&&this.__awaiter||function(t,e,n,i){return new(n||(n=Promise))(function(o,r){function s(t){try{c(i.next(t))}catch(t){r(t)}}function a(t){try{c(i.throw(t))}catch(t){r(t)}}function c(t){t.done?o(t.value):new n(function(e){e(t.value)}).then(s,a)}c((i=i.apply(t,e||[])).next())})},__generator=this&&this.__generator||function(t,e){var n,i,o,r,s={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return r={next:a(0),throw:a(1),return:a(2)},"function"==typeof Symbol&&(r[Symbol.iterator]=function(){return this}),r;function a(r){return function(a){return function(r){if(n)throw new TypeError("Generator is already executing.");for(;s;)try{if(n=1,i&&(o=2&r[0]?i.return:r[0]?i.throw||((o=i.return)&&o.call(i),0):i.next)&&!(o=o.call(i,r[1])).done)return o;switch(i=0,o&&(r=[2&r[0],o.value]),r[0]){case 0:case 1:o=r;break;case 4:return s.label++,{value:r[1],done:!1};case 5:s.label++,i=r[1],r=[0];continue;case 7:r=s.ops.pop(),s.trys.pop();continue;default:if(!(o=(o=s.trys).length>0&&o[o.length-1])&&(6===r[0]||2===r[0])){s=0;continue}if(3===r[0]&&(!o||r[1]>o[0]&&r[1]-1}(this,t)},Array.prototype.firstOrDefault=function(t){return function(t,e){var n=t.findIndex(e);return-1==n?null:t[n]}(this,t)},Array.prototype.find=function(t){return function(t,e){return t.firstOrDefault(e)}(this,t)},Array.prototype.where=function(t){return function(t,e){if("function"==typeof t.reduce)return t.reduce(function(n,i,o){return e.call(arguments[2],i,o,t)&&n.push(i),n},[]);for(var n=[],i=0,o=t.length;i=0&&t.splice(n,1)}while(n>=0)}(this,t)},Array.prototype.remove=function(t){return function(t,e){var n=t.findIndex(function(t){return t===e});return n>=0&&(t.splice(n,1),!0)}(this,t)},Array.prototype.removeAt=function(t){return function(t,e){t.splice(e,1)}(this,t)},Array.prototype.removeRange=function(t,e){return function(t,e,n){t.splice(e,n)}(this,t,e)},Array.prototype.select=function(t){return function(t,e){if("function"==typeof t.reduce)return t.reduce(function(n,i,o){return n.push(e.call(arguments[2],i,o,t)),n},[]);for(var n=[],i=0,o=t.length;ir?1:-1}),t}(this,t,e)},Array.prototype.orderByDescending=function(t,e){return function(t,e,n){return t.sort(function(t,i){var o=e(t),r=e(i);return n?-n(o,r):o0;){if("break"===c())break}return o?this.recontructPath(r,e,n):null},t.hasKey=function(t,e){for(var n,i=t.keys();!(n=i.next()).done;)if(JSON.stringify(n.value)==JSON.stringify(e))return!0;return!1},t.getKey=function(t,e){for(var n,i,o=t.keys(),r=t.values();n=o.next(),i=r.next(),!n.done;)if(JSON.stringify(n.value)==JSON.stringify(e))return i.value;return null},t.recontructPath=function(t,e,n){var i=[],o=n;for(i.push(n);o!=e;)o=this.getKey(t,o),i.push(o);return i.reverse(),i},t}(),AStarNode=function(t){function e(e){var n=t.call(this)||this;return n.data=e,n}return __extends(e,t),e}(PriorityQueueNode),AstarGridGraph=function(){function t(t,e){this.dirs=[new Vector2(1,0),new Vector2(0,-1),new Vector2(-1,0),new Vector2(0,1)],this.walls=[],this.weightedNodes=[],this.defaultWeight=1,this.weightedNodeWeight=5,this._neighbors=new Array(4),this._width=t,this._height=e}return t.prototype.isNodeInBounds=function(t){return 0<=t.x&&t.x0&&this.hasHigherPriority(t,n)?this.cascadeUp(t):this.cascadeDown(t)},t.prototype.cascadeDown=function(t){for(var e,n=t.queueIndex;;){e=t;var i=2*n;if(i>this._numNodes){t.queueIndex=n,this._nodes[n]=t;break}var o=this._nodes[i];this.hasHigherPriority(o,e)&&(e=o);var r=i+1;if(r<=this._numNodes){var s=this._nodes[r];this.hasHigherPriority(s,e)&&(e=s)}if(e==t){t.queueIndex=n,this._nodes[n]=t;break}this._nodes[n]=e;var a=e.queueIndex;e.queueIndex=n,n=a}},t.prototype.cascadeUp=function(t){for(var e=Math.floor(t.queueIndex/2);e>=1;){var n=this._nodes[e];if(this.hasHigherPriority(n,t))break;this.swap(t,n),e=Math.floor(t.queueIndex/2)}},t.prototype.swap=function(t,e){this._nodes[t.queueIndex]=e,this._nodes[e.queueIndex]=t;var n=t.queueIndex;t.queueIndex=e.queueIndex,e.queueIndex=n},t.prototype.hasHigherPriority=function(t,e){return t.priority0;){if("break"===a())break}return o?AStarPathfinder.recontructPath(s,e,n):null},t.hasKey=function(t,e){for(var n,i=t.keys();!(n=i.next()).done;)if(JSON.stringify(n.value)==JSON.stringify(e))return!0;return!1},t}(),UnweightedGraph=function(){function t(){this.edges=new Map}return t.prototype.addEdgesForNode=function(t,e){return this.edges.set(t,e),this},t.prototype.getNeighbors=function(t){return this.edges.get(t)},t}(),Vector2=function(){function t(t,e){this.x=0,this.y=0,this.x=t||0,this.y=e||this.x}return Object.defineProperty(t,"zero",{get:function(){return t.zeroVector2},enumerable:!0,configurable:!0}),Object.defineProperty(t,"one",{get:function(){return t.unitVector2},enumerable:!0,configurable:!0}),Object.defineProperty(t,"unitX",{get:function(){return t.unitXVector},enumerable:!0,configurable:!0}),Object.defineProperty(t,"unitY",{get:function(){return t.unitYVector},enumerable:!0,configurable:!0}),t.add=function(e,n){var i=new t(0,0);return i.x=e.x+n.x,i.y=e.y+n.y,i},t.divide=function(e,n){var i=new t(0,0);return i.x=e.x/n.x,i.y=e.y/n.y,i},t.multiply=function(e,n){var i=new t(0,0);return i.x=e.x*n.x,i.y=e.y*n.y,i},t.subtract=function(e,n){var i=new t(0,0);return i.x=e.x-n.x,i.y=e.y-n.y,i},t.prototype.normalize=function(){var t=1/Math.sqrt(this.x*this.x+this.y*this.y);this.x*=t,this.y*=t},t.prototype.length=function(){return Math.sqrt(this.x*this.x+this.y*this.y)},t.prototype.round=function(){return new t(Math.round(this.x),Math.round(this.y))},t.normalize=function(t){var e=1/Math.sqrt(t.x*t.x+t.y*t.y);return t.x*=e,t.y*=e,t},t.dot=function(t,e){return t.x*e.x+t.y*e.y},t.distanceSquared=function(t,e){var n=t.x-e.x,i=t.y-e.y;return n*n+i*i},t.clamp=function(e,n,i){return new t(MathHelper.clamp(e.x,n.x,i.x),MathHelper.clamp(e.y,n.y,i.y))},t.lerp=function(e,n,i){return new t(MathHelper.lerp(e.x,n.x,i),MathHelper.lerp(e.y,n.y,i))},t.transform=function(e,n){return new t(e.x*n.m11+e.y*n.m21,e.x*n.m12+e.y*n.m22)},t.distance=function(t,e){var n=t.x-e.x,i=t.y-e.y;return Math.sqrt(n*n+i*i)},t.negate=function(e){var n=new t;return n.x=-e.x,n.y=-e.y,n},t.unitYVector=new t(0,1),t.unitXVector=new t(1,0),t.unitVector2=new t(1,1),t.zeroVector2=new t(0,0),t}(),UnweightedGridGraph=function(){function t(e,n,i){void 0===i&&(i=!1),this.walls=[],this._neighbors=new Array(4),this._width=e,this._hegiht=n,this._dirs=i?t.COMPASS_DIRS:t.CARDINAL_DIRS}return t.prototype.isNodeInBounds=function(t){return 0<=t.x&&t.x0;){if("break"===c())break}return o?this.recontructPath(r,e,n):null},t.hasKey=function(t,e){for(var n,i=t.keys();!(n=i.next()).done;)if(JSON.stringify(n.value)==JSON.stringify(e))return!0;return!1},t.getKey=function(t,e){for(var n,i,o=t.keys(),r=t.values();n=o.next(),i=r.next(),!n.done;)if(JSON.stringify(n.value)==JSON.stringify(e))return i.value;return null},t.recontructPath=function(t,e,n){var i=[],o=n;for(i.push(n);o!=e;)o=this.getKey(t,o),i.push(o);return i.reverse(),i},t}(),DebugDefaults=function(){function t(){}return t.verletParticle=14431326,t.verletConstraintEdge=4406838,t}(),Component=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e._enabled=!0,e.updateInterval=1,e}return __extends(e,t),Object.defineProperty(e.prototype,"enabled",{get:function(){return this.entity?this.entity.enabled&&this._enabled:this._enabled},set:function(t){this.setEnabled(t)},enumerable:!0,configurable:!0}),e.prototype.setEnabled=function(t){return this._enabled!=t&&(this._enabled=t,this._enabled?this.onEnabled():this.onDisabled()),this},e.prototype.initialize=function(){},e.prototype.onAddedToEntity=function(){},e.prototype.onRemovedFromEntity=function(){},e.prototype.onEnabled=function(){},e.prototype.onDisabled=function(){},e.prototype.update=function(){},e.prototype.debugRender=function(){},e.prototype.onEntityTransformChanged=function(t){},e.prototype.registerComponent=function(){this.entity.componentBits.set(ComponentTypeManager.getIndexFor(this),!1),this.entity.scene.entityProcessors.onComponentAdded(this.entity)},e.prototype.deregisterComponent=function(){this.entity.componentBits.set(ComponentTypeManager.getIndexFor(this)),this.entity.scene.entityProcessors.onComponentRemoved(this.entity)},e}(egret.DisplayObjectContainer),Entity=function(t){function e(n){var i=t.call(this)||this;return i._updateOrder=0,i._enabled=!0,i._tag=0,i.name=n,i.components=new ComponentList(i),i.id=e._idGenerator++,i.componentBits=new BitSet,i}return __extends(e,t),Object.defineProperty(e.prototype,"isDestoryed",{get:function(){return this._isDestoryed},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"position",{get:function(){return new Vector2(this.x,this.y)},set:function(t){this.$setX(t.x),this.$setY(t.y),this.onEntityTransformChanged(TransformComponent.position)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"scale",{get:function(){return new Vector2(this.scaleX,this.scaleY)},set:function(t){this.$setScaleX(t.x),this.$setScaleY(t.y),this.onEntityTransformChanged(TransformComponent.scale)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"rotation",{set:function(t){this.$setRotation(t),this.onEntityTransformChanged(TransformComponent.rotation)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"enabled",{get:function(){return this._enabled},set:function(t){this.setEnabled(t)},enumerable:!0,configurable:!0}),e.prototype.setEnabled=function(t){return this._enabled!=t&&(this._enabled=t),this},Object.defineProperty(e.prototype,"tag",{get:function(){return this._tag},set:function(t){this.setTag(t)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"stage",{get:function(){return this.scene?this.scene.stage:null},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"updateOrder",{get:function(){return this._updateOrder},set:function(t){this.setUpdateOrder(t)},enumerable:!0,configurable:!0}),e.prototype.roundPosition=function(){this.position=Vector2Ext.round(this.position)},e.prototype.setUpdateOrder=function(t){if(this._updateOrder!=t)return this._updateOrder=t,this.scene,this},e.prototype.setTag=function(t){return this._tag!=t&&(this.scene&&this.scene.entities.removeFromTagList(this),this._tag=t,this.scene&&this.scene.entities.addToTagList(this)),this},e.prototype.attachToScene=function(t){this.scene=t,t.entities.add(this),this.components.registerAllComponents();for(var e=0;e=0;t--){this.getChildAt(t).entity.destroy()}},e}(egret.DisplayObjectContainer);!function(t){t[t.rotation=0]="rotation",t[t.scale=1]="scale",t[t.position=2]="position"}(TransformComponent||(TransformComponent={}));var CameraStyle,Scene=function(t){function e(){var e=t.call(this)||this;return e.enablePostProcessing=!0,e._renderers=[],e._postProcessors=[],e.entityProcessors=new EntityProcessorList,e.renderableComponents=new RenderableComponentList,e.entities=new EntityList(e),e.content=new ContentManager,e.width=SceneManager.stage.stageWidth,e.height=SceneManager.stage.stageHeight,e.addEventListener(egret.Event.ACTIVATE,e.onActive,e),e.addEventListener(egret.Event.DEACTIVATE,e.onDeactive,e),e}return __extends(e,t),e.prototype.createEntity=function(t){var e=new Entity(t);return e.position=new Vector2(0,0),this.addEntity(e)},e.prototype.addEntity=function(t){this.entities.add(t),t.scene=this,this.addChild(t);for(var e=0;e=0;e--)GlobalManager.globalManagers[e].enabled&&GlobalManager.globalManagers[e].update();if(t.sceneTransition&&(!t.sceneTransition||t.sceneTransition.loadsNewScene&&!t.sceneTransition.isNewSceneLoaded)||t._scene.update(),t._nextScene){t._scene.end();for(e=0;et&&(this._zoom=t),this._maximumZoom=t,this},e.prototype.setZoom=function(t){var e=MathHelper.clamp(t,-1,1);return this._zoom=0==e?1:e<0?MathHelper.map(e,-1,0,this._minimumZoom,1):MathHelper.map(e,0,1,1,this._maximumZoom),SceneManager.scene.scaleX=this._zoom,SceneManager.scene.scaleY=this._zoom,this},e.prototype.setRotation=function(t){return SceneManager.scene.rotation=t,this},e.prototype.setPosition=function(t){return this.entity.position=t,this},e.prototype.follow=function(t,e){void 0===e&&(e=CameraStyle.cameraWindow),this.targetEntity=t,this.cameraStyle=e;var n=new Rectangle(0,0,SceneManager.stage.stageWidth,SceneManager.stage.stageHeight);switch(this.cameraStyle){case CameraStyle.cameraWindow:var i=n.width/6,o=n.height/3;this.deadzone=new Rectangle((n.width-i)/2,(n.height-o)/2,i,o);break;case CameraStyle.lockOn:this.deadzone=new Rectangle(n.width/2,n.height/2,10,10)}},e.prototype.update=function(){var t=new Rectangle(0,0,SceneManager.stage.stageWidth,SceneManager.stage.stageHeight),e=Vector2.multiply(new Vector2(t.width,t.height),new Vector2(.5));this._worldSpaceDeadZone.x=this.position.x-e.x+this.deadzone.x+this.focusOffset.x,this._worldSpaceDeadZone.y=this.position.y-e.y+this.deadzone.y+this.focusOffset.y,this._worldSpaceDeadZone.width=this.deadzone.width,this._worldSpaceDeadZone.height=this.deadzone.height,this.targetEntity&&this.updateFollow(),this.position=Vector2.lerp(this.position,Vector2.add(this.position,this._desiredPositionDelta),this.followLerp),this.entity.roundPosition(),this.mapLockEnabled&&(this.position=this.clampToMapSize(this.position),this.entity.roundPosition())},e.prototype.clampToMapSize=function(t){var e=new Rectangle(0,0,SceneManager.stage.stageWidth,SceneManager.stage.stageHeight),n=Vector2.multiply(new Vector2(e.width,e.height),new Vector2(.5)),i=new Vector2(this.mapSize.x-n.x,this.mapSize.y-n.y);return Vector2.clamp(t,n,i)},e.prototype.updateFollow=function(){if(this._desiredPositionDelta.x=this._desiredPositionDelta.y=0,this.cameraStyle==CameraStyle.lockOn){var t=this.targetEntity.position.x,e=this.targetEntity.position.y;this._worldSpaceDeadZone.x>t?this._desiredPositionDelta.x=t-this._worldSpaceDeadZone.x:this._worldSpaceDeadZone.xe&&(this._desiredPositionDelta.y=e-this._worldSpaceDeadZone.y)}else{if(!this._targetCollider&&(this._targetCollider=this.targetEntity.getComponent(Collider),!this._targetCollider))return;var n=this.targetEntity.getComponent(Collider).bounds;this._worldSpaceDeadZone.containsRect(n)||(this._worldSpaceDeadZone.left>n.left?this._desiredPositionDelta.x=n.left-this._worldSpaceDeadZone.left:this._worldSpaceDeadZone.rightn.top&&(this._desiredPositionDelta.y=n.top-this._worldSpaceDeadZone.top))}},e}(Component);!function(t){t[t.lockOn=0]="lockOn",t[t.cameraWindow=1]="cameraWindow"}(CameraStyle||(CameraStyle={}));var LoopMode,State,ComponentPool=function(){function t(t){this._type=t,this._cache=[]}return t.prototype.obtain=function(){try{return this._cache.length>0?this._cache.shift():new this._type}catch(t){throw new Error(this._type+t)}},t.prototype.free=function(t){t.reset(),this._cache.push(t)},t}(),PooledComponent=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return __extends(e,t),e}(Component),RenderableComponent=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e._areBoundsDirty=!0,e._bounds=new Rectangle,e._localOffset=Vector2.zero,e.color=0,e}return __extends(e,t),Object.defineProperty(e.prototype,"width",{get:function(){return this.getWidth()},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"height",{get:function(){return this.getHeight()},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"isVisible",{get:function(){return this._isVisible},set:function(t){this._isVisible=t,this._isVisible?this.onBecameVisible():this.onBecameInvisible()},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"bounds",{get:function(){return new Rectangle(this.getBounds().x,this.getBounds().y,this.getBounds().width,this.getBounds().height)},enumerable:!0,configurable:!0}),e.prototype.getWidth=function(){return this.bounds.width},e.prototype.getHeight=function(){return this.bounds.height},e.prototype.onBecameVisible=function(){},e.prototype.onBecameInvisible=function(){},e.prototype.isVisibleFromCamera=function(t){return this.isVisible=t.getBounds().intersects(this.getBounds()),this.isVisible},e}(PooledComponent),Mesh=function(t){function e(){var e=t.call(this)||this;return e._mesh=new egret.Mesh,e}return __extends(e,t),e.prototype.setTexture=function(t){return this._mesh.texture=t,this},e.prototype.onAddedToEntity=function(){this.addChild(this._mesh)},e.prototype.onRemovedFromEntity=function(){this.removeChild(this._mesh)},e.prototype.render=function(t){this.x=this.entity.position.x-t.position.x+t.origin.x,this.y=this.entity.position.y-t.position.y+t.origin.y},e.prototype.reset=function(){},e}(RenderableComponent),Sprite=function(){return function(t,e,n){void 0===e&&(e=new Rectangle(0,0,t.textureWidth,t.textureHeight)),void 0===n&&(n=e.getHalfSize()),this.uvs=new Rectangle,this.texture2D=t,this.sourceRect=e,this.center=new Vector2(.5*e.width,.5*e.height),this.origin=n;var i=1/t.textureWidth,o=1/t.textureHeight;this.uvs.x=e.x*i,this.uvs.y=e.y*o,this.uvs.width=e.width*i,this.uvs.height=e.height*o}}(),SpriteAnimation=function(){return function(t,e){this.sprites=t,this.frameRate=e}}(),SpriteRenderer=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return __extends(e,t),Object.defineProperty(e.prototype,"sprite",{get:function(){return this._sprite},set:function(t){this.setSprite(t)},enumerable:!0,configurable:!0}),e.prototype.setSprite=function(t){return this.removeChildren(),this._sprite=t,this._sprite&&(this.anchorOffsetX=this._sprite.origin.x/this._sprite.sourceRect.width,this.anchorOffsetY=this._sprite.origin.y/this._sprite.sourceRect.height),this.bitmap=new egret.Bitmap(t.texture2D),this.addChild(this.bitmap),this},e.prototype.setColor=function(t){var e=[1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0];e[0]=Math.floor(t/256/256)/255,e[6]=Math.floor(t/256%256)/255,e[12]=t%256/255;var n=new egret.ColorMatrixFilter(e);return this.filters=[n],this},e.prototype.isVisibleFromCamera=function(t){return this.isVisible=new Rectangle(0,0,this.stage.stageWidth,this.stage.stageHeight).intersects(this.bounds),this.visible=this.isVisible,this.isVisible},e.prototype.render=function(t){this.x=-t.position.x+t.origin.x,this.y=-t.position.y+t.origin.y},e.prototype.onRemovedFromEntity=function(){this.parent&&this.parent.removeChild(this)},e.prototype.reset=function(){},e}(RenderableComponent),SpriteAnimator=function(t){function e(e){var n=t.call(this)||this;return n.speed=1,n.animationState=State.none,n._animations=new Map,n._elapsedTime=0,e&&n.setSprite(e),n}return __extends(e,t),Object.defineProperty(e.prototype,"isRunning",{get:function(){return this.animationState==State.running},enumerable:!0,configurable:!0}),e.prototype.addAnimation=function(t,e){return!this.sprite&&e.sprites.length>0&&this.setSprite(e.sprites[0]),this._animations[t]=e,this},e.prototype.play=function(t,e){void 0===e&&(e=null),this.currentAnimation=this._animations[t],this.currentAnimationName=t,this.currentFrame=0,this.animationState=State.running,this.sprite=this.currentAnimation.sprites[0],this._elapsedTime=0,this._loopMode=e||LoopMode.loop},e.prototype.isAnimationActive=function(t){return this.currentAnimation&&this.currentAnimationName==t},e.prototype.pause=function(){this.animationState=State.paused},e.prototype.unPause=function(){this.animationState=State.running},e.prototype.stop=function(){this.currentAnimation=null,this.currentAnimationName=null,this.currentFrame=0,this.animationState=State.none},e.prototype.update=function(){if(this.animationState==State.running&&this.currentAnimation){var t=this.currentAnimation,e=1/(t.frameRate*this.speed),n=e*t.sprites.length;this._elapsedTime+=Time.deltaTime;var i=Math.abs(this._elapsedTime);if(this._loopMode==LoopMode.once&&i>n||this._loopMode==LoopMode.pingPongOnce&&i>2*n)return this.animationState=State.completed,this._elapsedTime=0,this.currentFrame=0,void(this.sprite=t.sprites[this.currentFrame]);var o=Math.floor(i/e),r=t.sprites.length;if(r>2&&(this._loopMode==LoopMode.pingPong||this._loopMode==LoopMode.pingPongOnce)){var s=r-1;this.currentFrame=s-Math.abs(s-o%(2*s))}else this.currentFrame=o%r;this.sprite=t.sprites[this.currentFrame]}},e}(SpriteRenderer);!function(t){t[t.loop=0]="loop",t[t.once=1]="once",t[t.clampForever=2]="clampForever",t[t.pingPong=3]="pingPong",t[t.pingPongOnce=4]="pingPongOnce"}(LoopMode||(LoopMode={})),function(t){t[t.none=0]="none",t[t.running=1]="running",t[t.paused=2]="paused",t[t.completed=3]="completed"}(State||(State={}));var PointSectors,TiledSpriteRenderer=function(t){function e(e){var n=t.call(this)||this;return n.setSprite(e),n.sourceRect=e.sourceRect,n}return __extends(e,t),Object.defineProperty(e.prototype,"scrollX",{get:function(){return this.sourceRect.x},set:function(t){this.sourceRect.x=t},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"scrollY",{get:function(){return this.sourceRect.y},set:function(t){this.sourceRect.y=t},enumerable:!0,configurable:!0}),e.prototype.render=function(e){if(this.sprite){t.prototype.render.call(this,e);var n=new egret.RenderTexture,i=new egret.Bitmap(this.sprite.texture2D),o=new egret.Rectangle(this.sourceRect.x,this.sourceRect.y,this.sourceRect.width,this.sourceRect.height);n.drawToTexture(i,o),this.bitmap.texture=n}},e}(SpriteRenderer),Mover=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return __extends(e,t),e.prototype.onAddedToEntity=function(){this._triggerHelper=new ColliderTriggerHelper(this.entity)},e.prototype.calculateMovement=function(t){var e=new CollisionResult;if(!this.entity.getComponent(Collider)||!this._triggerHelper)return null;for(var n=this.entity.getComponents(Collider),i=0;i>6;0!=(e&t.LONG_MASK)&&n++,this._bits=new Array(n)}return t.prototype.and=function(t){for(var e,n=Math.min(this._bits.length,t._bits.length),i=0;i=0;)this._bits[e]&=~t._bits[e]},t.prototype.cardinality=function(){for(var t=0,e=this._bits.length-1;e>=0;e--){var n=this._bits[e];if(0!=n)if(-1!=n){var i=((n=((n=(n>>1&0x5555555555555400)+(0x5555555555555400&n))>>2&0x3333333333333400)+(0x3333333333333400&n))>>32)+n;t+=((i=((i=(i>>4&252645135)+(252645135&i))>>8&16711935)+(16711935&i))>>16&65535)+(65535&i)}else t+=64}return t},t.prototype.clear=function(t){if(null!=t){var e=t>>6;this.ensure(e),this._bits[e]&=~(1<=this._bits.length){var e=new Number[t+1];e=this._bits.copyWithin(0,0,this._bits.length),this._bits=e}},t.prototype.get=function(t){var e=t>>6;return!(e>=this._bits.length)&&0!=(this._bits[e]&1<=0;)if(0!=(this._bits[e]&t._bits[e]))return!0;return!1},t.prototype.isEmpty=function(){for(var t=this._bits.length-1;t>=0;t--)if(this._bits[t])return!1;return!0},t.prototype.nextSetBit=function(t){for(var e=t>>6,n=1<>6;this.ensure(n),this._bits[n]|=1<0){for(var t=0;t0){t=0;for(var e=this._componentsToAdd.length;t0){var e=this._entitiesToRemove;this._entitiesToRemove=this._tempEntityList,this._tempEntityList=e,this._tempEntityList.forEach(function(e){t._entities.remove(e),e.scene=null,t.scene.entityProcessors.onEntityRemoved(e)}),this._tempEntityList.length=0}if(this._entitiesToAdded.length>0){e=this._entitiesToAdded;this._entitiesToAdded=this._tempEntityList,this._tempEntityList=e,this._tempEntityList.forEach(function(e){t._entities.contains(e)||(t._entities.push(e),e.scene=t.scene,t.scene.entityProcessors.onEntityAdded(e))}),this._tempEntityList.forEach(function(t){return t.onAddedToScene()}),this._tempEntityList.length=0}this._unsortedTags.length>0&&(this._unsortedTags.forEach(function(e){t._entityDict.get(e).sort()}),this._unsortedTags.length=0)},t}(),EntityProcessorList=function(){function t(){this._processors=[]}return t.prototype.add=function(t){this._processors.push(t)},t.prototype.remove=function(t){this._processors.remove(t)},t.prototype.onComponentAdded=function(t){this.notifyEntityChanged(t)},t.prototype.onComponentRemoved=function(t){this.notifyEntityChanged(t)},t.prototype.onEntityAdded=function(t){this.notifyEntityChanged(t)},t.prototype.onEntityRemoved=function(t){this.removeFromProcessors(t)},t.prototype.notifyEntityChanged=function(t){for(var e=0;e=0;e=this.allSet.nextSetBit(e+1))if(!t.componentBits.get(e))return!1;return!(!this.exclusionSet.isEmpty()&&this.exclusionSet.intersects(t.componentBits))&&!(!this.oneSet.isEmpty()&&!this.oneSet.intersects(t.componentBits))},t.prototype.all=function(){for(var t=this,e=[],n=0;nn?n:t},t.pointOnCirlce=function(e,n,i){var o=t.toRadians(i);return new Vector2(Math.cos(o)*o+e.x,Math.sin(o)*o+e.y)},t.isEven=function(t){return t%2==0},t.Epsilon=1e-5,t.Rad2Deg=57.29578,t.Deg2Rad=.0174532924,t}(),Matrix2D=function(){function t(t,e,n,i,o,r){this.m11=0,this.m12=0,this.m21=0,this.m22=0,this.m31=0,this.m32=0,this.m11=t||1,this.m12=e||0,this.m21=n||0,this.m22=i||1,this.m31=o||0,this.m32=r||0}return Object.defineProperty(t,"identity",{get:function(){return t._identity},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"translation",{get:function(){return new Vector2(this.m31,this.m32)},set:function(t){this.m31=t.x,this.m32=t.y},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"rotation",{get:function(){return Math.atan2(this.m21,this.m11)},set:function(t){var e=Math.cos(t),n=Math.sin(t);this.m11=e,this.m12=n,this.m21=-n,this.m22=e},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"rotationDegrees",{get:function(){return MathHelper.toDegrees(this.rotation)},set:function(t){this.rotation=MathHelper.toRadians(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"scale",{get:function(){return new Vector2(this.m11,this.m22)},set:function(t){this.m11=t.x,this.m12=t.y},enumerable:!0,configurable:!0}),t.add=function(t,e){return t.m11+=e.m11,t.m12+=e.m12,t.m21+=e.m21,t.m22+=e.m22,t.m31+=e.m31,t.m32+=e.m32,t},t.divide=function(t,e){return t.m11/=e.m11,t.m12/=e.m12,t.m21/=e.m21,t.m22/=e.m22,t.m31/=e.m31,t.m32/=e.m32,t},t.multiply=function(e,n){var i=new t,o=e.m11*n.m11+e.m12*n.m21,r=e.m11*n.m12+e.m12*n.m22,s=e.m21*n.m11+e.m22*n.m21,a=e.m21*n.m12+e.m22*n.m22,c=e.m31*n.m11+e.m32*n.m21+n.m31,h=e.m31*n.m12+e.m32*n.m22+n.m32;return i.m11=o,i.m12=r,i.m21=s,i.m22=a,i.m31=c,i.m32=h,i},t.multiplyTranslation=function(e,n,i){var o=t.createTranslation(n,i);return t.multiply(e,o)},t.prototype.determinant=function(){return this.m11*this.m22-this.m12*this.m21},t.invert=function(e,n){void 0===n&&(n=new t);var i=1/e.determinant();return n.m11=e.m22*i,n.m12=-e.m12*i,n.m21=-e.m21*i,n.m22=e.m11*i,n.m31=(e.m32*e.m21-e.m31*e.m22)*i,n.m32=-(e.m32*e.m11-e.m31*e.m12)*i,n},t.createTranslation=function(e,n){var i=new t;return i.m11=1,i.m12=0,i.m21=0,i.m22=1,i.m31=e,i.m32=n,i},t.createTranslationVector=function(t){return this.createTranslation(t.x,t.y)},t.createRotation=function(e,n){n=new t;var i=Math.cos(e),o=Math.sin(e);return n.m11=i,n.m12=o,n.m21=-o,n.m22=i,n},t.createScale=function(e,n,i){return void 0===i&&(i=new t),i.m11=e,i.m12=0,i.m21=0,i.m22=n,i.m31=0,i.m32=0,i},t.prototype.toEgretMatrix=function(){return new egret.Matrix(this.m11,this.m12,this.m21,this.m22,this.m31,this.m32)},t._identity=new t(1,0,0,1,0,0),t}(),Rectangle=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return __extends(e,t),Object.defineProperty(e.prototype,"max",{get:function(){return new Vector2(this.right,this.bottom)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"center",{get:function(){return new Vector2(this.x+this.width/2,this.y+this.height/2)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"location",{get:function(){return new Vector2(this.x,this.y)},set:function(t){this.x=t.x,this.y=t.y},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"size",{get:function(){return new Vector2(this.width,this.height)},set:function(t){this.width=t.x,this.height=t.y},enumerable:!0,configurable:!0}),e.prototype.intersects=function(t){return t.lefti&&(i=s.x),s.yo&&(o=s.y)}return this.fromMinMax(e,n,i,o)},e}(egret.Rectangle),Vector3=function(){return function(t,e,n){this.x=t,this.y=e,this.z=n}}(),ColliderTriggerHelper=function(){function t(t){this._activeTriggerIntersections=[],this._previousTriggerIntersections=[],this._tempTriggerList=[],this._entity=t}return t.prototype.update=function(){for(var t=this._entity.getComponents(Collider),e=0;e1)return!1;var h=(a.x*o.y-a.y*o.x)/s;return!(h<0||h>1)},t.lineToLineIntersection=function(t,e,n,i){var o=new Vector2(0,0),r=Vector2.subtract(e,t),s=Vector2.subtract(i,n),a=r.x*s.y-r.y*s.x;if(0==a)return o;var c=Vector2.subtract(n,t),h=(c.x*s.y-c.y*s.x)/a;if(h<0||h>1)return o;var u=(c.x*r.y-c.y*r.x)/a;return u<0||u>1?o:o=Vector2.add(t,new Vector2(h*r.x,h*r.y))},t.closestPointOnLine=function(t,e,n){var i=Vector2.subtract(e,t),o=Vector2.subtract(n,t),r=Vector2.dot(o,i)/Vector2.dot(i,i);return r=MathHelper.clamp(r,0,1),Vector2.add(t,new Vector2(i.x*r,i.y*r))},t.isCircleToCircle=function(t,e,n,i){return Vector2.distanceSquared(t,n)<(e+i)*(e+i)},t.isCircleToLine=function(t,e,n,i){return Vector2.distanceSquared(t,this.closestPointOnLine(n,i,t))=t&&o.y>=e&&o.x=t+n&&(r|=PointSectors.right),o.y=e+i&&(r|=PointSectors.bottom),r},t}(),Physics=function(){function t(){}return t.reset=function(){this._spatialHash=new SpatialHash(this.spatialHashCellSize)},t.clear=function(){this._spatialHash.clear()},t.overlapCircleAll=function(t,e,n,i){return void 0===i&&(i=-1),this._spatialHash.overlapCircle(t,e,n,i)},t.boxcastBroadphase=function(t,e){void 0===e&&(e=this.allLayers);var n=this._spatialHash.aabbBroadphase(t,null,e);return{colliders:n.tempHashSet,rect:n.bounds}},t.boxcastBroadphaseExcludingSelf=function(t,e,n){return void 0===n&&(n=this.allLayers),this._spatialHash.aabbBroadphase(e,t,n)},t.addCollider=function(e){t._spatialHash.register(e)},t.removeCollider=function(e){t._spatialHash.remove(e)},t.updateCollider=function(t){this._spatialHash.remove(t),this._spatialHash.register(t)},t.spatialHashCellSize=100,t.allLayers=-1,t}(),Shape=function(){return function(){}}(),Polygon=function(t){function e(e,n){var i=t.call(this)||this;return i.isUnrotated=!0,i._areEdgeNormalsDirty=!0,i.setPoints(e),i.isBox=n,i}return __extends(e,t),Object.defineProperty(e.prototype,"edgeNormals",{get:function(){return this._areEdgeNormalsDirty&&this.buildEdgeNormals(),this._edgeNormals},enumerable:!0,configurable:!0}),e.prototype.buildEdgeNormals=function(){var t,e=this.isBox?2:this.points.length;null!=this._edgeNormals&&this._edgeNormals.length==e||(this._edgeNormals=new Array(e));for(var n=0;n=this.points.length?this.points[0]:this.points[n+1];var o=Vector2Ext.perpendicular(i,t);o=Vector2.normalize(o),this._edgeNormals[n]=o}},e.prototype.setPoints=function(t){this.points=t,this.recalculateCenterAndEdgeNormals(),this._originalPoints=[];for(var e=0;et.y!=this.points[i].y>t.y&&t.x<(this.points[i].x-this.points[n].x)*(t.y-this.points[n].y)/(this.points[i].y-this.points[n].y)+this.points[n].x&&(e=!e);return e},e.buildSymmertricalPolygon=function(t,e){for(var n=new Array(t),i=0;i0&&(o=!1),!o)return null;(g=Math.abs(g))i&&(i=o);return{min:n,max:i}},t.circleToPolygon=function(t,e){var n=new CollisionResult,i=Vector2.subtract(t.position,e.position),o=Polygon.getClosestPointOnPolygonToPoint(e.points,i),r=o.closestPoint,s=o.distanceSquared;n.normal=o.edgeNormal;var a,c=e.containsPoint(t.position);if(s>t.radius*t.radius&&!c)return null;if(c)a=Vector2.multiply(n.normal,new Vector2(Math.sqrt(s)-t.radius));else if(0==s)a=Vector2.multiply(n.normal,new Vector2(t.radius));else{var h=Math.sqrt(s);a=Vector2.multiply(new Vector2(-Vector2.subtract(i,r)),new Vector2((t.radius-s)/h))}return n.minimumTranslationVector=a,n.point=Vector2.add(r,e.position),n},t.circleToBox=function(t,e){var n=new CollisionResult,i=e.bounds.getClosestPointOnRectangleBorderToPoint(t.position).res;if(e.containsPoint(t.position)){n.point=i;var o=Vector2.add(i,Vector2.subtract(n.normal,new Vector2(t.radius)));return n.minimumTranslationVector=Vector2.subtract(t.position,o),n}var r=Vector2.distanceSquared(i,t.position);if(0==r)n.minimumTranslationVector=Vector2.multiply(n.normal,new Vector2(t.radius));else if(r<=t.radius*t.radius){n.normal=Vector2.subtract(t.position,i);var s=n.normal.length()-t.radius;return n.normal=Vector2Ext.normalize(n.normal),n.minimumTranslationVector=Vector2.multiply(new Vector2(s),n.normal),n}return null},t.pointToCircle=function(t,e){var n=new CollisionResult,i=Vector2.distanceSquared(t,e.position),o=1+e.radius;if(i=0?t:4294967296+t},t.prototype.add=function(t,e,n){this._store.set(this.getKey(t,e),n)},t.prototype.remove=function(t){this._store.forEach(function(e){e.contains(t)&&e.remove(t)})},t.prototype.tryGetValue=function(t,e){return this._store.get(this.getKey(t,e))},t.prototype.clear=function(){this._store.clear()},t}(),ContentManager=function(){function t(){this.loadedAssets=new Map}return t.prototype.loadRes=function(t,e){var n=this;return void 0===e&&(e=!0),new Promise(function(i,o){var r=n.loadedAssets.get(t);r?i(r):e?RES.getResAsync(t).then(function(e){n.loadedAssets.set(t,e),i(e)}).catch(function(e){console.error("资源加载错误:",t,e),o(e)}):RES.getResByUrl(t).then(function(e){n.loadedAssets.set(t,e),i(e)}).catch(function(e){console.error("资源加载错误:",t,e),o(e)})})},t.prototype.dispose=function(){this.loadedAssets.forEach(function(t){t.dispose()}),this.loadedAssets.clear()},t}(),Emitter=function(){function t(){this._messageTable=new Map}return t.prototype.addObserver=function(t,e){var n=this._messageTable.get(t);n||(n=[],this._messageTable.set(t,n)),n.contains(e)&&console.warn("您试图添加相同的观察者两次"),n.push(e)},t.prototype.removeObserver=function(t,e){this._messageTable.get(t).remove(e)},t.prototype.emit=function(t,e){var n=this._messageTable.get(t);if(n)for(var i=n.length-1;i>=0;i--)n[i](e)},t}(),GlobalManager=function(){function t(){}return Object.defineProperty(t.prototype,"enabled",{get:function(){return this._enabled},set:function(t){this.setEnabled(t)},enumerable:!0,configurable:!0}),t.prototype.setEnabled=function(t){this._enabled!=t&&(this._enabled=t,this._enabled?this.onEnabled():this.onDisabled())},t.prototype.onEnabled=function(){},t.prototype.onDisabled=function(){},t.prototype.update=function(){},t.registerGlobalManager=function(t){this.globalManagers.push(t),t.enabled=!0},t.unregisterGlobalManager=function(t){this.globalManagers.remove(t),t.enabled=!1},t.getGlobalManager=function(t){for(var e=0;e0&&this.setpreviousTouchState(this._gameTouchs[0]),t},enumerable:!0,configurable:!0}),t.initialize=function(t){this._init||(this._init=!0,this._stage=t,this._stage.addEventListener(egret.TouchEvent.TOUCH_BEGIN,this.touchBegin,this),this._stage.addEventListener(egret.TouchEvent.TOUCH_MOVE,this.touchMove,this),this._stage.addEventListener(egret.TouchEvent.TOUCH_END,this.touchEnd,this),this._stage.addEventListener(egret.TouchEvent.TOUCH_CANCEL,this.touchEnd,this),this._stage.addEventListener(egret.TouchEvent.TOUCH_RELEASE_OUTSIDE,this.touchEnd,this),this.initTouchCache())},t.initTouchCache=function(){this._totalTouchCount=0,this._touchIndex=0,this._gameTouchs.length=0;for(var t=0;t0)for(var e=0;ethis._objectQueue.length;)this._objectQueue.shift()},t.clearCache=function(){this._objectQueue.length=0},t.obtain=function(){return this._objectQueue.length>0?this._objectQueue.shift():[]},t.free=function(t){this._objectQueue.unshift(t),t.length=0},t._objectQueue=[],t}(),Pair=function(){function t(t,e){this.first=t,this.second=e}return t.prototype.clear=function(){this.first=this.second=null},t.prototype.equals=function(t){return this.first==t.first&&this.second==t.second},t}(),RectangleExt=function(){function t(){}return t.union=function(t,e){var n=new Rectangle(e.x,e.y,0,0);return this.unionR(t,n)},t.unionR=function(t,e){var n=new Rectangle;return n.x=Math.min(t.x,e.x),n.y=Math.min(t.y,e.y),n.width=Math.max(t.right,e.right)-n.x,n.height=Math.max(t.bottom,e.bottom)-n.y,n},t}(),Triangulator=function(){function t(){this.triangleIndices=[],this._triPrev=new Array(12),this._triNext=new Array(12)}return t.prototype.triangulate=function(e,n){void 0===n&&(n=!0);var i=e.length;this.initialize(i);for(var o=0,r=0;i>3&&o<500;){o++;var s=!0,a=e[this._triPrev[r]],c=e[r],h=e[this._triNext[r]];if(Vector2Ext.isTriangleCCW(a,c,h)){var u=this._triNext[this._triNext[r]];do{if(t.testPointTriangle(e[u],a,c,h)){s=!1;break}u=this._triNext[u]}while(u!=this._triPrev[r])}else s=!1;s?(this.triangleIndices.push(this._triPrev[r]),this.triangleIndices.push(r),this.triangleIndices.push(this._triNext[r]),this._triNext[this._triPrev[r]]=this._triNext[r],this._triPrev[this._triNext[r]]=this._triPrev[r],i--,r=this._triPrev[r]):r=this._triNext[r]}this.triangleIndices.push(this._triPrev[r]),this.triangleIndices.push(r),this.triangleIndices.push(this._triNext[r]),n||this.triangleIndices.reverse()},t.prototype.initialize=function(t){this.triangleIndices.length=0,this._triNext.lengthMathHelper.Epsilon?t=Vector2.divide(t,new Vector2(e)):t.x=t.y=0,t},t.transformA=function(t,e,n,i,o,r){for(var s=0;s0&&r[r.length-1])&&(6===o[0]||2===o[0])){s=0;continue}if(3===o[0]&&(!r||o[1]>r[0]&&o[1]-1}(this,t)},Array.prototype.firstOrDefault=function(t){return function(t,e){var n=t.findIndex(e);return-1==n?null:t[n]}(this,t)},Array.prototype.find=function(t){return function(t,e){return t.firstOrDefault(e)}(this,t)},Array.prototype.where=function(t){return function(t,e){if("function"==typeof t.reduce)return t.reduce(function(n,i,r){return e.call(arguments[2],i,r,t)&&n.push(i),n},[]);for(var n=[],i=0,r=t.length;i=0&&t.splice(n,1)}while(n>=0)}(this,t)},Array.prototype.remove=function(t){return function(t,e){var n=t.findIndex(function(t){return t===e});return n>=0&&(t.splice(n,1),!0)}(this,t)},Array.prototype.removeAt=function(t){return function(t,e){t.splice(e,1)}(this,t)},Array.prototype.removeRange=function(t,e){return function(t,e,n){t.splice(e,n)}(this,t,e)},Array.prototype.select=function(t){return function(t,e){if("function"==typeof t.reduce)return t.reduce(function(n,i,r){return n.push(e.call(arguments[2],i,r,t)),n},[]);for(var n=[],i=0,r=t.length;io?1:-1}),t}(this,t,e)},Array.prototype.orderByDescending=function(t,e){return function(t,e,n){return t.sort(function(t,i){var r=e(t),o=e(i);return n?-n(r,o):r0;){if("break"===u())break}return s?this.recontructPath(a,i,r):null},e.recontructPath=function(t,e,n){var i=[],r=n;for(i.push(n);r!=e;)r=this.getKey(t,r),i.push(r);return i.reverse(),i},e.hasKey=function(t,e){for(var n,i=t.keys();!(n=i.next()).done;)if(JSON.stringify(n.value)==JSON.stringify(e))return!0;return!1},e.getKey=function(t,e){for(var n,i,r=t.keys(),o=t.values();n=r.next(),i=o.next(),!n.done;)if(JSON.stringify(n.value)==JSON.stringify(e))return i.value;return null},e}();t.AStarPathfinder=e;var n=function(t){function e(e){var n=t.call(this)||this;return n.data=e,n}return __extends(e,t),e}(t.PriorityQueueNode);t.AStarNode=n}(es||(es={})),function(t){var e=function(){function e(e,n){this.dirs=[new t.Vector2(1,0),new t.Vector2(0,-1),new t.Vector2(-1,0),new t.Vector2(0,1)],this.walls=[],this.weightedNodes=[],this.defaultWeight=1,this.weightedNodeWeight=5,this._neighbors=new Array(4),this._width=e,this._height=n}return e.prototype.isNodeInBounds=function(t){return 0<=t.x&&t.x=this._nodes.length?(console.error("node.QueueIndex has been corrupted. Did you change it manually? Or add this node to another queue?"),!1):this._nodes[t.queueIndex]==t:(console.error("node cannot be null"),!1)},t.prototype.enqueue=function(t,e){t.priority=e,this._numNodes++,this._nodes[this._numNodes]=t,t.queueIndex=this._numNodes,t.insertionIndex=this._numNodesEverEnqueued++,this.cascadeUp(this._nodes[this._numNodes])},t.prototype.dequeue=function(){var t=this._nodes[1];return this.remove(t),t},t.prototype.remove=function(t){if(t.queueIndex==this._numNodes)return this._nodes[this._numNodes]=null,void this._numNodes--;var e=this._nodes[this._numNodes];this.swap(t,e),delete this._nodes[this._numNodes],this._numNodes--,this.onNodeUpdated(e)},t.prototype.isValidQueue=function(){for(var t=1;t0&&this.hasHigherPriority(t,n)?this.cascadeUp(t):this.cascadeDown(t)},t.prototype.cascadeDown=function(t){for(var e,n=t.queueIndex;;){e=t;var i=2*n;if(i>this._numNodes){t.queueIndex=n,this._nodes[n]=t;break}var r=this._nodes[i];this.hasHigherPriority(r,e)&&(e=r);var o=i+1;if(o<=this._numNodes){var s=this._nodes[o];this.hasHigherPriority(s,e)&&(e=s)}if(e==t){t.queueIndex=n,this._nodes[n]=t;break}this._nodes[n]=e;var a=e.queueIndex;e.queueIndex=n,n=a}},t.prototype.cascadeUp=function(t){for(var e=Math.floor(t.queueIndex/2);e>=1;){var n=this._nodes[e];if(this.hasHigherPriority(n,t))break;this.swap(t,n),e=Math.floor(t.queueIndex/2)}},t.prototype.swap=function(t,e){this._nodes[t.queueIndex]=e,this._nodes[e.queueIndex]=t;var n=t.queueIndex;t.queueIndex=e.queueIndex,e.queueIndex=n},t.prototype.hasHigherPriority=function(t,e){return t.priority0;){if("break"===c())break}return o?t.AStarPathfinder.recontructPath(a,n,i):null},e.hasKey=function(t,e){for(var n,i=t.keys();!(n=i.next()).done;)if(JSON.stringify(n.value)==JSON.stringify(e))return!0;return!1},e}();t.BreadthFirstPathfinder=e}(es||(es={})),function(t){var e=function(){function t(){this.edges=new Map}return t.prototype.addEdgesForNode=function(t,e){return this.edges.set(t,e),this},t.prototype.getNeighbors=function(t){return this.edges.get(t)},t}();t.UnweightedGraph=e}(es||(es={})),function(t){var e=function(){function e(t,e){this.x=0,this.y=0,this.x=t||0,this.y=null!=e?e:this.x}return Object.defineProperty(e,"zero",{get:function(){return e.zeroVector2},enumerable:!0,configurable:!0}),Object.defineProperty(e,"one",{get:function(){return e.unitVector2},enumerable:!0,configurable:!0}),Object.defineProperty(e,"unitX",{get:function(){return e.unitXVector},enumerable:!0,configurable:!0}),Object.defineProperty(e,"unitY",{get:function(){return e.unitYVector},enumerable:!0,configurable:!0}),e.add=function(t,n){var i=new e(0,0);return i.x=t.x+n.x,i.y=t.y+n.y,i},e.divide=function(t,n){var i=new e(0,0);return i.x=t.x/n.x,i.y=t.y/n.y,i},e.multiply=function(t,n){var i=new e(0,0);return i.x=t.x*n.x,i.y=t.y*n.y,i},e.subtract=function(t,n){var i=new e(0,0);return i.x=t.x-n.x,i.y=t.y-n.y,i},e.normalize=function(t){var e=1/Math.sqrt(t.x*t.x+t.y*t.y);return t.x*=e,t.y*=e,t},e.dot=function(t,e){return t.x*e.x+t.y*e.y},e.distanceSquared=function(t,e){var n=t.x-e.x,i=t.y-e.y;return n*n+i*i},e.clamp=function(n,i,r){return new e(t.MathHelper.clamp(n.x,i.x,r.x),t.MathHelper.clamp(n.y,i.y,r.y))},e.lerp=function(n,i,r){return new e(t.MathHelper.lerp(n.x,i.x,r),t.MathHelper.lerp(n.y,i.y,r))},e.transform=function(t,n){return new e(t.x*n.m11+t.y*n.m21+n.m31,t.x*n.m12+t.y*n.m22+n.m32)},e.distance=function(t,e){var n=t.x-e.x,i=t.y-e.y;return Math.sqrt(n*n+i*i)},e.negate=function(t){var n=new e;return n.x=-t.x,n.y=-t.y,n},e.prototype.add=function(t){return this.x+=t.x,this.y+=t.y,this},e.prototype.divide=function(t){return this.x/=t.x,this.y/=t.y,this},e.prototype.multiply=function(t){return this.x*=t.x,this.y*=t.y,this},e.prototype.subtract=function(t){return this.x-=t.x,this.y-=t.y,this},e.prototype.normalize=function(){var t=1/Math.sqrt(this.x*this.x+this.y*this.y);return this.x*=t,this.y*=t,this},e.prototype.length=function(){return Math.sqrt(this.x*this.x+this.y*this.y)},e.prototype.lengthSquared=function(){return this.x*this.x+this.y*this.y},e.prototype.round=function(){return new e(Math.round(this.x),Math.round(this.y))},e.prototype.equals=function(t){return t.x==this.x&&t.y==this.y},e.unitYVector=new e(0,1),e.unitXVector=new e(1,0),e.unitVector2=new e(1,1),e.zeroVector2=new e(0,0),e}();t.Vector2=e}(es||(es={})),function(t){var e=function(){function e(t,n,i){void 0===i&&(i=!1),this.walls=[],this._neighbors=new Array(4),this._width=t,this._hegiht=n,this._dirs=i?e.COMPASS_DIRS:e.CARDINAL_DIRS}return e.prototype.isNodeInBounds=function(t){return 0<=t.x&&t.x0;){if("break"===u())break}return s?this.recontructPath(a,i,r):null},n.recontructPath=function(t,e,n){var i=[],r=n;for(i.push(n);r!=e;)r=this.getKey(t,r),i.push(r);return i.reverse(),i},n.hasKey=function(t,e){for(var n,i=t.keys();!(n=i.next()).done;)if(JSON.stringify(n.value)==JSON.stringify(e))return!0;return!1},n.getKey=function(t,e){for(var n,i,r=t.keys(),o=t.values();n=r.next(),i=o.next(),!n.done;)if(JSON.stringify(n.value)==JSON.stringify(e))return i.value;return null},n}();t.WeightedPathfinder=n}(es||(es={})),function(t){var e=function(){function e(){}return e.drawHollowRect=function(e,n,i){void 0===i&&(i=0),this._debugDrawItems.push(new t.DebugDrawItem(e,n,i))},e.render=function(){if(this._debugDrawItems.length>0){var e=new egret.Shape;t.Core.scene&&t.Core.scene.addChild(e);for(var n=this._debugDrawItems.length-1;n>=0;n--){this._debugDrawItems[n].draw(e)&&this._debugDrawItems.removeAt(n)}}},e._debugDrawItems=[],e}();t.Debug=e}(es||(es={})),function(t){var e=function(){function t(){}return t.verletParticle=14431326,t.verletConstraintEdge=4406838,t}();t.DebugDefaults=e}(es||(es={})),function(t){var e;!function(t){t[t.line=0]="line",t[t.hollowRectangle=1]="hollowRectangle",t[t.pixel=2]="pixel",t[t.text=3]="text"}(e=t.DebugDrawType||(t.DebugDrawType={}));var n=function(){function n(t,n,i){this.rectangle=t,this.color=n,this.duration=i,this.drawType=e.hollowRectangle}return n.prototype.draw=function(n){switch(this.drawType){case e.line:t.DrawUtils.drawLine(n,this.start,this.end,this.color);break;case e.hollowRectangle:t.DrawUtils.drawHollowRect(n,this.rectangle,this.color);break;case e.pixel:t.DrawUtils.drawPixel(n,new t.Vector2(this.x,this.y),this.color,this.size);break;case e.text:}return this.duration-=t.Time.deltaTime,this.duration<0},n}();t.DebugDrawItem=n}(es||(es={})),function(t){var e=function(t){function e(){var e=null!==t&&t.apply(this,arguments)||this;return e.updateInterval=1,e._enabled=!0,e._updateOrder=0,e}return __extends(e,t),Object.defineProperty(e.prototype,"transform",{get:function(){return this.entity.transform},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"enabled",{get:function(){return this.entity?this.entity.enabled&&this._enabled:this._enabled},set:function(t){this.setEnabled(t)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"updateOrder",{get:function(){return this._updateOrder},set:function(t){this.setUpdateOrder(t)},enumerable:!0,configurable:!0}),e.prototype.initialize=function(){},e.prototype.onAddedToEntity=function(){},e.prototype.onRemovedFromEntity=function(){},e.prototype.onEntityTransformChanged=function(t){},e.prototype.debugRender=function(){},e.prototype.onEnabled=function(){},e.prototype.onDisabled=function(){},e.prototype.update=function(){},e.prototype.setEnabled=function(t){return this._enabled!=t&&(this._enabled=t,this._enabled?this.onEnabled():this.onDisabled()),this},e.prototype.setUpdateOrder=function(t){return this._updateOrder!=t&&(this._updateOrder=t),this},e.prototype.clone=function(){var t=ObjectUtils.clone(this);return t.entity=null,t},e}(egret.HashObject);t.Component=e}(es||(es={})),function(t){var e=function(e){function n(){var i=e.call(this)||this;return i._globalManagers=[],n._instance=i,n.emitter=new t.Emitter,n.content=new t.ContentManager,i.addEventListener(egret.Event.ADDED_TO_STAGE,i.onAddToStage,i),i}return __extends(n,e),Object.defineProperty(n,"Instance",{get:function(){return this._instance},enumerable:!0,configurable:!0}),Object.defineProperty(n,"scene",{get:function(){return this._instance?this._instance._scene:null},set:function(t){t?null==this._instance._scene?(this._instance._scene=t,this._instance.addChild(t),this._instance._scene.begin(),n.Instance.onSceneChanged()):this._instance._nextScene=t:console.error("场景不能为空")},enumerable:!0,configurable:!0}),n.startSceneTransition=function(t){if(!this._instance._sceneTransition)return this._instance._sceneTransition=t,t;console.warn("在前一个场景完成之前,不能开始一个新的场景转换。")},n.registerGlobalManager=function(t){this._instance._globalManagers.push(t),t.enabled=!0},n.unregisterGlobalManager=function(t){this._instance._globalManagers.remove(t),t.enabled=!1},n.getGlobalManager=function(t){for(var e=0;e=0;e--)this._globalManagers[e].enabled&&this._globalManagers[e].update();return this._sceneTransition&&(!this._sceneTransition||this._sceneTransition.loadsNewScene&&!this._sceneTransition.isNewSceneLoaded)||this._scene.update(),this._nextScene?(this.removeChild(this._scene),this._scene.end(),this._scene=this._nextScene,this._nextScene=null,this.onSceneChanged(),this.addChild(this._scene),[4,this._scene.begin()]):[3,2];case 1:n.sent(),n.label=2;case 2:return[4,this.draw()];case 3:return n.sent(),[2]}})})},n.prototype.onAddToStage=function(){n.graphicsDevice=new t.GraphicsDevice,this.addEventListener(egret.Event.RESIZE,this.onGraphicsDeviceReset,this),this.addEventListener(egret.StageOrientationEvent.ORIENTATION_CHANGE,this.onOrientationChanged,this),this.addEventListener(egret.Event.ENTER_FRAME,this.update,this),t.Input.initialize(),this.initialize()},n}(egret.DisplayObjectContainer);t.Core=e}(es||(es={})),function(t){!function(t){t[t.GraphicsDeviceReset=0]="GraphicsDeviceReset",t[t.SceneChanged=1]="SceneChanged",t[t.OrientationChanged=2]="OrientationChanged"}(t.CoreEvents||(t.CoreEvents={}))}(es||(es={})),function(t){var e=function(){function e(n){this.updateInterval=1,this._tag=0,this._enabled=!0,this._updateOrder=0,this.components=new t.ComponentList(this),this.transform=new t.Transform(this),this.name=n,this.id=e._idGenerator++,this.componentBits=new t.BitSet}return Object.defineProperty(e.prototype,"isDestroyed",{get:function(){return this._isDestroyed},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"tag",{get:function(){return this._tag},set:function(t){this.setTag(t)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"enabled",{get:function(){return this._enabled},set:function(t){this.setEnabled(t)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"updateOrder",{get:function(){return this._updateOrder},set:function(t){this.setUpdateOrder(t)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"parent",{get:function(){return this.transform.parent},set:function(t){this.transform.setParent(t)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"childCount",{get:function(){return this.transform.childCount},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"position",{get:function(){return this.transform.position},set:function(t){this.transform.setPosition(t.x,t.y)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"localPosition",{get:function(){return this.transform.localPosition},set:function(t){this.transform.setLocalPosition(t)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"rotation",{get:function(){return this.transform.rotation},set:function(t){this.transform.setRotation(t)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"rotationDegrees",{get:function(){return this.transform.rotationDegrees},set:function(t){this.transform.setRotationDegrees(t)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"localRotation",{get:function(){return this.transform.localRotation},set:function(t){this.transform.setLocalRotation(t)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"localRotationDegrees",{get:function(){return this.transform.localRotationDegrees},set:function(t){this.transform.setLocalRotationDegrees(t)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"scale",{get:function(){return this.transform.scale},set:function(t){this.transform.setScale(t)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"localScale",{get:function(){return this.transform.localScale},set:function(t){this.transform.setLocalScale(t)},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"worldInverseTransform",{get:function(){return this.transform.worldInverseTransform},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"localToWorldTransform",{get:function(){return this.transform.localToWorldTransform},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"worldToLocalTransform",{get:function(){return this.transform.worldToLocalTransform},enumerable:!0,configurable:!0}),e.prototype.onTransformChanged=function(t){this.components.onEntityTransformChanged(t)},e.prototype.setTag=function(t){return this._tag!=t&&(this.scene&&this.scene.entities.removeFromTagList(this),this._tag=t,this.scene&&this.scene.entities.addToTagList(this)),this},e.prototype.setEnabled=function(t){return this._enabled!=t&&(this._enabled=t,this._enabled?this.components.onEntityEnabled():this.components.onEntityDisabled()),this},e.prototype.setUpdateOrder=function(t){if(this._updateOrder!=t)return this._updateOrder=t,this.scene&&(this.scene.entities.markEntityListUnsorted(),this.scene.entities.markTagUnsorted(this.tag)),this},e.prototype.destroy=function(){this._isDestroyed=!0,this.scene.entities.remove(this),this.transform.parent=null;for(var t=this.transform.childCount-1;t>=0;t--){this.transform.getChild(t).entity.destroy()}},e.prototype.detachFromScene=function(){this.scene.entities.remove(this),this.components.deregisterAllComponents();for(var t=0;te.x?-1:1,i=t.Vector2.normalize(t.Vector2.subtract(this.position,e));this.rotation=n*Math.acos(t.Vector2.dot(i,t.Vector2.unitY))},i.prototype.setLocalRotation=function(t){return this._localRotation=t,this._localDirty=this._positionDirty=this._localPositionDirty=this._localRotationDirty=this._localScaleDirty=!0,this.setDirty(e.rotationDirty),this},i.prototype.setLocalRotationDegrees=function(e){return this.setLocalRotation(t.MathHelper.toRadians(e))},i.prototype.setScale=function(e){return this._scale=e,this.parent?this.localScale=t.Vector2.divide(e,this.parent._scale):this.localScale=e,this},i.prototype.setLocalScale=function(t){return this._localScale=t,this._localDirty=this._positionDirty=this._localScaleDirty=!0,this.setDirty(e.scaleDirty),this},i.prototype.roundPosition=function(){this.position=this._position.round()},i.prototype.updateTransform=function(){this.hierarchyDirty!=e.clean&&(this.parent&&this.parent.updateTransform(),this._localDirty&&(this._localPositionDirty&&(this._translationMatrix=t.Matrix2D.create().translate(this._localPosition.x,this._localPosition.y),this._localPositionDirty=!1),this._localRotationDirty&&(this._rotationMatrix=t.Matrix2D.create().rotate(this._localRotation),this._localRotationDirty=!1),this._localScaleDirty&&(this._scaleMatrix=t.Matrix2D.create().scale(this._localScale.x,this._localScale.y),this._localScaleDirty=!1),this._localTransform=this._scaleMatrix.multiply(this._rotationMatrix),this._localTransform=this._localTransform.multiply(this._translationMatrix),this.parent||(this._worldTransform=this._localTransform,this._rotation=this._localRotation,this._scale=this._localScale,this._worldInverseDirty=!0),this._localDirty=!1),this.parent&&(this._worldTransform=this._localTransform.multiply(this.parent._worldTransform),this._rotation=this._localRotation+this.parent._rotation,this._scale=t.Vector2.multiply(this.parent._scale,this._localScale),this._worldInverseDirty=!0),this._worldToLocalDirty=!0,this._positionDirty=!0,this.hierarchyDirty=e.clean)},i.prototype.setDirty=function(e){if(0==(this.hierarchyDirty&e)){switch(this.hierarchyDirty|=e,e){case t.DirtyType.positionDirty:this.entity.onTransformChanged(transform.Component.position);break;case t.DirtyType.rotationDirty:this.entity.onTransformChanged(transform.Component.rotation);break;case t.DirtyType.scaleDirty:this.entity.onTransformChanged(transform.Component.scale)}this._children||(this._children=[]);for(var n=0;nt&&(this._zoom=t),this._maximumZoom=t,this;console.error("maximumZoom must be greater than zero")},r.prototype.onEntityTransformChanged=function(t){this._areMatrixedDirty=!0},r.prototype.zoomIn=function(t){this.zoom+=t},r.prototype.zoomOut=function(t){this.zoom-=t},r.prototype.worldToScreenPoint=function(e){return this.updateMatrixes(),e=t.Vector2.transform(e,this._transformMatrix)},r.prototype.screenToWorldPoint=function(e){return this.updateMatrixes(),e=t.Vector2.transform(e,this._inverseTransformMatrix)},r.prototype.mouseToWorldPoint=function(){return this.screenToWorldPoint(t.Input.touchPosition)},r.prototype.onAddedToEntity=function(){this.follow(this._targetEntity,this._cameraStyle)},r.prototype.update=function(){var e=t.Vector2.multiply(new t.Vector2(this.bounds.width,this.bounds.height),new t.Vector2(.5));this._worldSpaceDeadZone.x=this.position.x-e.x*t.Core.scene.scaleX+this.deadzone.x+this.focusOffset.x,this._worldSpaceDeadZone.y=this.position.y-e.y*t.Core.scene.scaleY+this.deadzone.y+this.focusOffset.y,this._worldSpaceDeadZone.width=this.deadzone.width,this._worldSpaceDeadZone.height=this.deadzone.height,this._targetEntity&&this.updateFollow(),this.position=t.Vector2.lerp(this.position,t.Vector2.add(this.position,this._desiredPositionDelta),this.followLerp),this.entity.transform.roundPosition(),this.mapLockEnabled&&(this.position=this.clampToMapSize(this.position),this.entity.transform.roundPosition())},r.prototype.clampToMapSize=function(e){var n=t.Vector2.multiply(new t.Vector2(this.bounds.width,this.bounds.height),new t.Vector2(.5)),i=new t.Vector2(this.mapSize.x-n.x,this.mapSize.y-n.y);return t.Vector2.clamp(e,n,i)},r.prototype.updateFollow=function(){if(this._desiredPositionDelta.x=this._desiredPositionDelta.y=0,this._cameraStyle==e.lockOn){var n=this._targetEntity.transform.position.x,i=this._targetEntity.transform.position.y;this._worldSpaceDeadZone.x>n?this._desiredPositionDelta.x=n-this._worldSpaceDeadZone.x:this._worldSpaceDeadZone.xi&&(this._desiredPositionDelta.y=i-this._worldSpaceDeadZone.y)}else{if(!this._targetCollider&&(this._targetCollider=this._targetEntity.getComponent(t.Collider),!this._targetCollider))return;var r=this._targetEntity.getComponent(t.Collider).bounds;this._worldSpaceDeadZone.containsRect(r)||(this._worldSpaceDeadZone.left>r.left?this._desiredPositionDelta.x=r.left-this._worldSpaceDeadZone.left:this._worldSpaceDeadZone.rightr.top&&(this._desiredPositionDelta.y=r.top-this._worldSpaceDeadZone.top))}},r.prototype.follow=function(n,i){switch(void 0===i&&(i=e.cameraWindow),this._targetEntity=n,this._cameraStyle=i,this._cameraStyle){case e.cameraWindow:var r=this.bounds.width/6,o=this.bounds.height/3;this.deadzone=new t.Rectangle((this.bounds.width-r)/2,(this.bounds.height-o)/2,r,o);break;case e.lockOn:this.deadzone=new t.Rectangle(this.bounds.width/2,this.bounds.height/2,10,10)}},r.prototype.setCenteredDeadzone=function(e,n){this.deadzone=new t.Rectangle((this.bounds.width-e)/2,(this.bounds.height-n)/2,e,n)},r.prototype.updateMatrixes=function(){var e;this._areMatrixedDirty&&(this._transformMatrix=t.Matrix2D.create().translate(-this.entity.transform.position.x,-this.entity.transform.position.y),1!=this._zoom&&(e=t.Matrix2D.create().scale(this._zoom,this._zoom),this._transformMatrix=this._transformMatrix.multiply(e)),0!=this.entity.transform.rotation&&(e=t.Matrix2D.create().rotate(this.entity.transform.rotation),this._transformMatrix=this._transformMatrix.multiply(e)),e=t.Matrix2D.create().translate(this._origin.x,this._origin.y),this._transformMatrix=this._transformMatrix.multiply(e),this._inverseTransformMatrix=this._transformMatrix.invert(),this._areBoundsDirty=!0,this._areMatrixedDirty=!1)},r}(t.Component);t.Camera=i}(es||(es={})),function(t){var e=function(){function t(t){this._type=t,this._cache=[]}return t.prototype.obtain=function(){try{return this._cache.length>0?this._cache.shift():new this._type}catch(t){throw new Error(this._type+t)}},t.prototype.free=function(t){t.reset(),this._cache.push(t)},t}();t.ComponentPool=e}(es||(es={})),function(t){var e=function(){function t(){}return t.prototype.compare=function(t,e){return t.updateOrder-e.updateOrder},t}();t.IUpdatableComparer=e}(es||(es={})),function(t){var e=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return __extends(e,t),e}(t.Component);t.PooledComponent=e}(es||(es={})),function(t){var e=function(e){function n(){var n=null!==e&&e.apply(this,arguments)||this;return n.displayObject=new egret.DisplayObject,n.color=0,n._areBoundsDirty=!0,n._localOffset=t.Vector2.zero,n._renderLayer=0,n._bounds=new t.Rectangle,n}return __extends(n,e),Object.defineProperty(n.prototype,"width",{get:function(){return this.bounds.width},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"height",{get:function(){return this.bounds.height},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"localOffset",{get:function(){return this._localOffset},set:function(t){this.setLocalOffset(t)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"renderLayer",{get:function(){return this._renderLayer},set:function(t){},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"bounds",{get:function(){return this._areBoundsDirty&&(this._bounds.calculateBounds(this.entity.transform.position,this._localOffset,t.Vector2.zero,this.entity.transform.scale,this.entity.transform.rotation,this.width,this.height),this._areBoundsDirty=!1),this._bounds},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"isVisible",{get:function(){return this._isVisible},set:function(t){this._isVisible!=t&&(this._isVisible=t,this._isVisible?this.onBecameVisible():this.onBecameInvisible())},enumerable:!0,configurable:!0}),n.prototype.onEntityTransformChanged=function(t){this._areBoundsDirty=!0},n.prototype.isVisibleFromCamera=function(t){return this.isVisible=t.bounds.intersects(this.bounds),this.isVisible},n.prototype.setRenderLayer=function(t){if(t!=this._renderLayer){var e=this._renderLayer;this._renderLayer=t,this.entity&&this.entity.scene&&this.entity.scene.renderableComponents.updateRenderableRenderLayer(this,e,this._renderLayer)}return this},n.prototype.setColor=function(t){return this.color=t,this},n.prototype.setLocalOffset=function(t){return this._localOffset!=t&&(this._localOffset=t),this},n.prototype.sync=function(t){this.displayObject.x=this.entity.position.x+this.localOffset.x-t.position.x+t.origin.x,this.displayObject.y=this.entity.position.y+this.localOffset.y-t.position.y+t.origin.y,this.displayObject.scaleX=this.entity.scale.x,this.displayObject.scaleY=this.entity.scale.y,this.displayObject.rotation=this.entity.rotation},n.prototype.toString=function(){return"[RenderableComponent] renderLayer: "+this.renderLayer},n.prototype.onBecameVisible=function(){this.displayObject.visible=this.isVisible},n.prototype.onBecameInvisible=function(){this.displayObject.visible=this.isVisible},n}(t.Component);t.RenderableComponent=e}(es||(es={})),function(t){var e=function(t){function e(){var e=t.call(this)||this;return e._mesh=new egret.Mesh,e}return __extends(e,t),e.prototype.setTexture=function(t){return this._mesh.texture=t,this._mesh.$renderNode=new egret.sys.RenderNode,this},e.prototype.reset=function(){},e.prototype.render=function(t){},e}(t.RenderableComponent);t.Mesh=e}(es||(es={})),function(t){var e=egret.Bitmap,n=function(n){function i(e){void 0===e&&(e=null);var i=n.call(this)||this;return e instanceof t.Sprite?i.setSprite(e):e instanceof egret.Texture&&i.setSprite(new t.Sprite(e)),i}return __extends(i,n),Object.defineProperty(i.prototype,"bounds",{get:function(){return this._areBoundsDirty&&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=!1),this._bounds},enumerable:!0,configurable:!0}),Object.defineProperty(i.prototype,"originNormalized",{get:function(){return new t.Vector2(this._origin.x/this.width*this.entity.transform.scale.x,this._origin.y/this.height*this.entity.transform.scale.y)},set:function(e){this.setOrigin(new t.Vector2(e.x*this.width/this.entity.transform.scale.x,e.y*this.height/this.entity.transform.scale.y))},enumerable:!0,configurable:!0}),Object.defineProperty(i.prototype,"origin",{get:function(){return this._origin},set:function(t){this.setOrigin(t)},enumerable:!0,configurable:!0}),Object.defineProperty(i.prototype,"sprite",{get:function(){return this._sprite},set:function(t){this.setSprite(t)},enumerable:!0,configurable:!0}),i.prototype.setSprite=function(t){return this._sprite=t,this._sprite&&(this._origin=this._sprite.origin,this.displayObject.anchorOffsetX=this._origin.x,this.displayObject.anchorOffsetY=this._origin.y),this.displayObject=new e(t.texture2D),this},i.prototype.setOrigin=function(t){return this._origin!=t&&(this._origin=t,this.displayObject.anchorOffsetX=this._origin.x,this.displayObject.anchorOffsetY=this._origin.y,this._areBoundsDirty=!0),this},i.prototype.setOriginNormalized=function(e){return this.setOrigin(new t.Vector2(e.x*this.width/this.entity.transform.scale.x,e.y*this.height/this.entity.transform.scale.y)),this},i.prototype.render=function(t){this.sync(t),this.displayObject.x=this.entity.position.x-this.origin.x+this.localOffset.x-t.position.x+t.origin.x,this.displayObject.y=this.entity.position.y-this.origin.y+this.localOffset.y-t.position.y+t.origin.y},i}(t.RenderableComponent);t.SpriteRenderer=n}(es||(es={})),function(t){var e=function(e){function n(n){var i=e.call(this,n)||this;return i._sourceRect=new t.Rectangle,i._textureScale=t.Vector2.one,i._inverseTexScale=t.Vector2.one,i._sourceRect=n.sourceRect,i.displayObject.$fillMode=egret.BitmapFillMode.REPEAT,i}return __extends(n,e),Object.defineProperty(n.prototype,"bounds",{get:function(){return this._areBoundsDirty&&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=!1),this._bounds},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"scrollX",{get:function(){return this._sourceRect.x},set:function(t){this._sourceRect.x=t},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"scrollY",{get:function(){return this._sourceRect.y},set:function(t){this._sourceRect.y=t},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"textureScale",{get:function(){return this._textureScale},set:function(e){this._textureScale=e,this._inverseTexScale=new t.Vector2(1/this._textureScale.x,1/this._textureScale.y),this._sourceRect.width=this._sprite.sourceRect.width*this._inverseTexScale.x,this._sourceRect.height=this._sprite.sourceRect.height*this._inverseTexScale.y},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"width",{get:function(){return this._sourceRect.width},set:function(t){this._areBoundsDirty=!0,this._sourceRect.width=t},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"height",{get:function(){return this._sourceRect.height},set:function(t){this._areBoundsDirty=!0,this._sourceRect.height=t},enumerable:!0,configurable:!0}),n.prototype.render=function(t){var n=this.displayObject;n.width=this.width,n.height=this.height,e.prototype.render.call(this,t)},n}(t.SpriteRenderer);t.TiledSpriteRenderer=e}(es||(es={})),function(t){var e=function(e){function n(t){var n=e.call(this,t)||this;return n.scrollSpeedX=15,n.scroolSpeedY=0,n._scrollX=0,n._scrollY=0,n}return __extends(n,e),Object.defineProperty(n.prototype,"textureScale",{get:function(){return this._textureScale},set:function(e){this._textureScale=e,this._inverseTexScale=new t.Vector2(1/this._textureScale.x,1/this._textureScale.y)},enumerable:!0,configurable:!0}),n.prototype.update=function(){this._scrollX+=this.scrollSpeedX*t.Time.deltaTime,this._scrollY+=this.scroolSpeedY*t.Time.deltaTime,this._sourceRect.x=this._scrollX,this._sourceRect.y=this._scrollY},n}(t.TiledSpriteRenderer);t.ScrollingSpriteRenderer=e}(es||(es={})),function(t){var e=function(){return function(e,n,i){void 0===n&&(n=new t.Rectangle(0,0,e.textureWidth,e.textureHeight)),void 0===i&&(i=n.getHalfSize()),this.uvs=new t.Rectangle,this.texture2D=e,this.sourceRect=n,this.center=new t.Vector2(.5*n.width,.5*n.height),this.origin=i;var r=1/e.textureWidth,o=1/e.textureHeight;this.uvs.x=n.x*r,this.uvs.y=n.y*o,this.uvs.width=n.width*r,this.uvs.height=n.height*o}}();t.Sprite=e}(es||(es={})),function(t){var e=function(){return function(t,e){this.sprites=t,this.frameRate=e}}();t.SpriteAnimation=e}(es||(es={})),function(t){var e,n;!function(t){t[t.loop=0]="loop",t[t.once=1]="once",t[t.clampForever=2]="clampForever",t[t.pingPong=3]="pingPong",t[t.pingPongOnce=4]="pingPongOnce"}(e=t.LoopMode||(t.LoopMode={})),function(t){t[t.none=0]="none",t[t.running=1]="running",t[t.paused=2]="paused",t[t.completed=3]="completed"}(n=t.State||(t.State={}));var i=function(i){function r(t){var e=i.call(this,t)||this;return e.speed=1,e.animationState=n.none,e._elapsedTime=0,e._animations=new Map,e}return __extends(r,i),Object.defineProperty(r.prototype,"isRunning",{get:function(){return this.animationState==n.running},enumerable:!0,configurable:!0}),Object.defineProperty(r.prototype,"animations",{get:function(){return this._animations},enumerable:!0,configurable:!0}),r.prototype.update=function(){if(this.animationState==n.running&&this.currentAnimation){var i=this.currentAnimation,r=1/(i.frameRate*this.speed),o=r*i.sprites.length;this._elapsedTime+=t.Time.deltaTime;var s=Math.abs(this._elapsedTime);if(this._loopMode==e.once&&s>o||this._loopMode==e.pingPongOnce&&s>2*o)return this.animationState=n.completed,this._elapsedTime=0,this.currentFrame=0,void(this.sprite=i.sprites[this.currentFrame]);var a=Math.floor(s/r),c=i.sprites.length;if(c>2&&(this._loopMode==e.pingPong||this._loopMode==e.pingPongOnce)){var h=c-1;this.currentFrame=h-Math.abs(h-a%(2*h))}else this.currentFrame=a%c;this.sprite=i.sprites[this.currentFrame]}},r.prototype.addAnimation=function(t,e){return!this.sprite&&e.sprites.length>0&&this.setSprite(e.sprites[0]),this._animations[t]=e,this},r.prototype.play=function(t,i){void 0===i&&(i=null),this.currentAnimation=this._animations[t],this.currentAnimationName=t,this.currentFrame=0,this.animationState=n.running,this.sprite=this.currentAnimation.sprites[0],this._elapsedTime=0,this._loopMode=i||e.loop},r.prototype.isAnimationActive=function(t){return this.currentAnimation&&this.currentAnimationName==t},r.prototype.pause=function(){this.animationState=n.paused},r.prototype.unPause=function(){this.animationState=n.running},r.prototype.stop=function(){this.currentAnimation=null,this.currentAnimationName=null,this.currentFrame=0,this.animationState=n.none},r}(t.SpriteRenderer);t.SpriteAnimator=i}(es||(es={})),function(t){var e=function(e){function n(){return null!==e&&e.apply(this,arguments)||this}return __extends(n,e),n.prototype.onAddedToEntity=function(){this._triggerHelper=new t.ColliderTriggerHelper(this.entity)},n.prototype.calculateMovement=function(e,n){if(!this.entity.getComponent(t.Collider)||!this._triggerHelper)return!1;for(var i=this.entity.getComponents(t.Collider),r=0;r>6;0!=(e&t.LONG_MASK)&&n++,this._bits=new Array(n)}return t.prototype.and=function(t){for(var e,n=Math.min(this._bits.length,t._bits.length),i=0;i=0;)this._bits[e]&=~t._bits[e]},t.prototype.cardinality=function(){for(var t=0,e=this._bits.length-1;e>=0;e--){var n=this._bits[e];if(0!=n)if(-1!=n){var i=((n=((n=(n>>1&0x5555555555555400)+(0x5555555555555400&n))>>2&0x3333333333333400)+(0x3333333333333400&n))>>32)+n;t+=((i=((i=(i>>4&252645135)+(252645135&i))>>8&16711935)+(16711935&i))>>16&65535)+(65535&i)}else t+=64}return t},t.prototype.clear=function(t){if(null!=t){var e=t>>6;this.ensure(e),this._bits[e]&=~(1<>6;return!(e>=this._bits.length)&&0!=(this._bits[e]&1<=0;)if(0!=(this._bits[e]&t._bits[e]))return!0;return!1},t.prototype.isEmpty=function(){for(var t=this._bits.length-1;t>=0;t--)if(this._bits[t])return!1;return!0},t.prototype.nextSetBit=function(t){for(var e=t>>6,n=1<>6;this.ensure(n),this._bits[n]|=1<=this._bits.length){var e=new Number[t+1];e=this._bits.copyWithin(0,0,this._bits.length),this._bits=e}},t.LONG_MASK=63,t}();t.BitSet=e}(es||(es={})),function(t){var e=function(){function e(t){this._components=[],this._componentsToAdd=[],this._componentsToRemove=[],this._tempBufferList=[],this._entity=t}return Object.defineProperty(e.prototype,"count",{get:function(){return this._components.length},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"buffer",{get:function(){return this._components},enumerable:!0,configurable:!0}),e.prototype.markEntityListUnsorted=function(){this._isComponentListUnsorted=!0},e.prototype.add=function(t){this._componentsToAdd.push(t)},e.prototype.remove=function(t){this._componentsToRemove.contains(t)&&console.warn("You are trying to remove a Component ("+t+") that you already removed"),this._componentsToAdd.contains(t)?this._componentsToAdd.remove(t):this._componentsToRemove.push(t)},e.prototype.removeAllComponents=function(){for(var t=0;t0){for(var n=0;n0){n=0;for(var i=this._componentsToAdd.length;n0){var e=this._entitiesToRemove;this._entitiesToRemove=this._tempEntityList,this._tempEntityList=e,this._tempEntityList.forEach(function(e){t.removeFromTagList(e),t._entities.remove(e),e.onRemovedFromScene(),e.scene=null,t.scene.entityProcessors.onEntityRemoved(e)}),this._tempEntityList.length=0}if(this._entitiesToAdded.length>0){e=this._entitiesToAdded;this._entitiesToAdded=this._tempEntityList,this._tempEntityList=e,this._tempEntityList.forEach(function(e){t._entities.contains(e)||(t._entities.push(e),e.scene=t.scene,t.addToTagList(e),t.scene.entityProcessors.onEntityAdded(e))}),this._tempEntityList.forEach(function(t){return t.onAddedToScene()}),this._tempEntityList.length=0,this._isEntityListUnsorted=!0}this._isEntityListUnsorted&&(this._entities.sort(),this._isEntityListUnsorted=!1),this._unsortedTags.length>0&&(this._unsortedTags.forEach(function(e){t._entityDict.get(e).sort()}),this._unsortedTags.length=0)},e.prototype.findEntity=function(t){for(var e=0;e=0;e=this.allSet.nextSetBit(e+1))if(!t.componentBits.get(e))return!1;return!(!this.exclusionSet.isEmpty()&&this.exclusionSet.intersects(t.componentBits))&&!(!this.oneSet.isEmpty()&&!this.oneSet.intersects(t.componentBits))},e.prototype.all=function(){for(var e=this,n=[],i=0;i0){for(var t=0,n=this._unsortedRenderLayers.length;t=e)return t;var i=!1;"-"==t.substr(0,1)&&(i=!0,t=t.substr(1));for(var r=e-n,o=0;o1?this.reverse(t.substring(1))+t.substring(0,1):t},t.cutOff=function(t,e,n,i){void 0===i&&(i=!0),e=Math.floor(e),n=Math.floor(n);var r=t.length;e>r&&(e=r);var o,s=e,a=e+n;return i?o=t.substring(0,s)+t.substr(a,r):(a=(s=r-1-e-n)+n,o=t.substring(0,s+1)+t.substr(a+1,r)),o},t.strReplace=function(t,e){for(var n=0,i=e.length;n",">",'"',""","'","'","®","®","©","©","™","™"],t}();!function(t){var e=function(){function e(){}return e.convertImageToCanvas=function(e,n){this.sharedCanvas||(this.sharedCanvas=egret.sys.createCanvas(),this.sharedContext=this.sharedCanvas.getContext("2d"));var i=e.$getTextureWidth(),r=e.$getTextureHeight();n||((n=egret.$TempRectangle).x=0,n.y=0,n.width=i,n.height=r),n.x=Math.min(n.x,i-1),n.y=Math.min(n.y,r-1),n.width=Math.min(n.width,i-n.x),n.height=Math.min(n.height,r-n.y);var o=Math.floor(n.width),s=Math.floor(n.height),a=this.sharedCanvas;if(a.style.width=o+"px",a.style.height=s+"px",this.sharedCanvas.width=o,this.sharedCanvas.height=s,"webgl"==egret.Capabilities.renderMode){var c=void 0;e.$renderBuffer?c=e:(egret.sys.systemRenderer.renderClear&&egret.sys.systemRenderer.renderClear(),(c=new egret.RenderTexture).drawToTexture(new egret.Bitmap(e)));for(var h=c.$renderBuffer.getPixels(n.x,n.y,o,s),u=0,l=0,p=0;p=0?"png":"jpg"});return wx.getFileSystemManager().saveFile({tempFilePath:o,filePath:wx.env.USER_DATA_PATH+"/"+n,success:function(t){}}),o},e.getPixel32=function(t,e,n){return egret.$warn(1041,"getPixel32","getPixels"),t.getPixels(e,n)},e.getPixels=function(t,e,n,i,r){if(void 0===i&&(i=1),void 0===r&&(r=1),"webgl"==egret.Capabilities.renderMode){var o=void 0;return t.$renderBuffer?o=t:(o=new egret.RenderTexture).drawToTexture(new egret.Bitmap(t)),o.$renderBuffer.getPixels(e,n,i,r)}try{this.convertImageToCanvas(t);return this.sharedContext.getImageData(e,n,i,r).data}catch(t){egret.$error(1039)}},e}();t.TextureUtils=e}(es||(es={})),function(t){var e=function(){function t(){}return t.update=function(t){var e=(t-this._lastTime)/1e3;this.deltaTime=e*this.timeScale,this.unscaledDeltaTime=e,this._timeSinceSceneLoad+=e,this.frameCount++,this._lastTime=t},t.sceneChanged=function(){this._timeSinceSceneLoad=0},t.checkEvery=function(t){return this._timeSinceSceneLoad/t>(this._timeSinceSceneLoad-this.deltaTime)/t},t.deltaTime=0,t.timeScale=1,t.frameCount=0,t._lastTime=0,t}();t.Time=e}(es||(es={}));var TimeUtils=function(){function t(){}return t.monthId=function(t){void 0===t&&(t=null);var e=(t=t||new Date).getFullYear(),n=t.getMonth()+1;return parseInt(e+(n<10?"0":"")+n)},t.dateId=function(t){void 0===t&&(t=null);var e=(t=t||new Date).getMonth()+1,n=e<10?"0":"",i=t.getDate(),r=i<10?"0":"";return parseInt(t.getFullYear()+n+e+r+i)},t.weekId=function(t,e){void 0===t&&(t=null),void 0===e&&(e=!0),t=t||new Date;var n=new Date;n.setTime(t.getTime()),n.setDate(1),n.setMonth(0);var i=n.getFullYear(),r=n.getDay();0==r&&(r=7);var o=!1;r<=4?(o=r>1,n.setDate(n.getDate()-(r-1))):n.setDate(n.getDate()+7-r+1);var s=this.diffDay(t,n,!1);if(s<0)return n.setDate(1),n.setMonth(0),n.setDate(n.getDate()-1),this.weekId(n,!1);var a=s/7,c=Math.floor(a)+1;if(53==c){n.setTime(t.getTime()),n.setDate(n.getDate()-1);var h=n.getDay();if(0==h&&(h=7),e&&(!o||h<4))return n.setFullYear(n.getFullYear()+1),n.setDate(1),n.setMonth(0),this.weekId(n,!1)}return parseInt(i+"00"+(c>9?"":"0")+c)},t.diffDay=function(t,e,n){void 0===n&&(n=!1);var i=(t.getTime()-e.getTime())/864e5;return n?Math.ceil(i):Math.floor(i)},t.getFirstDayOfWeek=function(t){var e=(t=t||new Date).getDay()||7;return new Date(t.getFullYear(),t.getMonth(),t.getDate()+1-e,0,0,0,0)},t.getFirstOfDay=function(t){return(t=t||new Date).setHours(0,0,0,0),t},t.getNextFirstOfDay=function(t){return new Date(this.getFirstOfDay(t).getTime()+864e5)},t.formatDate=function(t){var e=t.getFullYear(),n=t.getMonth()+1;n=n<10?"0"+n:n;var i=t.getDate();return e+"-"+n+"-"+(i=i<10?"0"+i:i)},t.formatDateTime=function(t){var e=t.getFullYear(),n=t.getMonth()+1;n=n<10?"0"+n:n;var i=t.getDate();i=i<10?"0"+i:i;var r=t.getHours(),o=t.getMinutes();o=o<10?"0"+o:o;var s=t.getSeconds();return e+"-"+n+"-"+i+" "+r+":"+o+":"+(s=s<10?"0"+s:s)},t.parseDate=function(t){var e=Date.parse(t);return isNaN(e)?new Date:new Date(Date.parse(t.replace(/-/g,"/")))},t.secondToTime=function(t,e,n){void 0===t&&(t=0),void 0===e&&(e=":"),void 0===n&&(n=!0);var i=Math.floor(t/3600),r=Math.floor(t%3600/60),o=Math.floor(t%3600%60),s=i.toString(),a=r.toString(),c=o.toString();return i<10&&(s="0"+s),r<10&&(a="0"+a),o<10&&(c="0"+c),n?s+e+a+e+c:a+e+c},t.timeToMillisecond=function(t,e){void 0===e&&(e=":");for(var n=t.split(e),i=0,r=n.length,o=0;o-1?this.os="iOS":i.indexOf("android")>-1&&(this.os="Android");var r=n.language;r=r.indexOf("zh")>-1?"zh-CN":"en-US",this.language=r}},e}(egret.Capabilities);t.GraphicsCapabilities=e}(es||(es={})),function(t){var e=function(){function e(){this.setup(),this.graphicsCapabilities=new t.GraphicsCapabilities,this.graphicsCapabilities.initialize(this)}return Object.defineProperty(e.prototype,"viewport",{get:function(){return this._viewport},enumerable:!0,configurable:!0}),e.prototype.setup=function(){this._viewport=new t.Viewport(0,0,t.Core._instance.stage.stageWidth,t.Core._instance.stage.stageHeight)},e}();t.GraphicsDevice=e}(es||(es={})),function(t){var e=function(){function e(t,e,n,i){this._x=t,this._y=e,this._width=n,this._height=i,this._minDepth=0,this._maxDepth=1}return Object.defineProperty(e.prototype,"width",{get:function(){return this._width},set:function(t){this._width=t},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"height",{get:function(){return this._height},set:function(t){this._height=t},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"aspectRatio",{get:function(){return 0!=this._height&&0!=this._width?this._width/this._height:0},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"bounds",{get:function(){return new t.Rectangle(this._x,this._y,this._width,this._height)},set:function(t){this._x=t.x,this._y=t.y,this._width=t.width,this._height=t.height},enumerable:!0,configurable:!0}),e}();t.Viewport=e}(es||(es={})),function(t){var e=function(e){function n(){return e.call(this,t.PostProcessor.default_vert,n.blur_frag,{screenWidth:t.Core.graphicsDevice.viewport.width,screenHeight:t.Core.graphicsDevice.viewport.height})||this}return __extends(n,e),n.blur_frag="precision mediump float;\nuniform sampler2D uSampler;\nuniform float screenWidth;\nuniform float screenHeight;\nfloat normpdf(in float x, in float sigma)\n{\nreturn 0.39894*exp(-0.5*x*x/(sigma*sigma))/sigma;\n}\nvoid main()\n{\nvec3 c = texture2D(uSampler, gl_FragCoord.xy / vec2(screenWidth, screenHeight).xy).rgb;\nconst int mSize = 11;\nconst int kSize = (mSize - 1)/2;\nfloat kernel[mSize];\nvec3 final_colour = vec3(0.0);\nfloat sigma = 7.0;\nfloat z = 0.0;\nfor (int j = 0; j <= kSize; ++j)\n{\nkernel[kSize+j] = kernel[kSize-j] = normpdf(float(j),sigma);\n}\nfor (int j = 0; j < mSize; ++j)\n{\nz += kernel[j];\n}\nfor (int i = -kSize; i <= kSize; ++i)\n{\nfor (int j = -kSize; j <= kSize; ++j)\n{\nfinal_colour += kernel[kSize+j]*kernel[kSize+i]*texture2D(uSampler, (gl_FragCoord.xy+vec2(float(i),float(j))) / vec2(screenWidth, screenHeight).xy).rgb;\n}\n}\ngl_FragColor = vec4(final_colour/(z*z), 1.0);\n}",n}(egret.CustomFilter);t.GaussianBlurEffect=e}(es||(es={})),function(t){var e=function(t){function e(){return t.call(this,e.vertSrc,e.fragmentSrc)||this}return __extends(e,t),e.vertSrc="attribute vec2 aVertexPosition;\nattribute vec2 aTextureCoord;\nuniform vec2 projectionVector;\nvarying vec2 vTextureCoord;\nconst vec2 center = vec2(-1.0, 1.0);\nvoid main(void) {\n gl_Position = vec4( (aVertexPosition / projectionVector) + center , 0.0, 1.0);\n vTextureCoord = aTextureCoord;\n}",e.fragmentSrc="precision lowp float;\nvarying vec2 vTextureCoord;\nuniform sampler2D uSampler;\n#define SAMPLE_COUNT 15\nuniform vec2 _sampleOffsets[SAMPLE_COUNT];\nuniform float _sampleWeights[SAMPLE_COUNT];\nvoid main(void) {\nvec4 c = vec4(0, 0, 0, 0);\nfor( int i = 0; i < SAMPLE_COUNT; i++ )\n c += texture2D( uSampler, vTextureCoord + _sampleOffsets[i] ) * _sampleWeights[i];\ngl_FragColor = c;\n}",e}(egret.CustomFilter);t.PolygonLightEffect=e}(es||(es={})),function(t){var e=function(){function e(t){void 0===t&&(t=null),this.enabled=!0,this.effect=t}return e.prototype.onAddedToScene=function(e){this.scene=e,this.shape=new egret.Shape,this.shape.graphics.beginFill(16777215,1),this.shape.graphics.drawRect(0,0,t.Core.graphicsDevice.viewport.width,t.Core.graphicsDevice.viewport.height),this.shape.graphics.endFill(),e.addChild(this.shape)},e.prototype.process=function(){this.drawFullscreenQuad()},e.prototype.onSceneBackBufferSizeChanged=function(t,e){},e.prototype.unload=function(){this.effect&&(this.effect=null),this.scene.removeChild(this.shape),this.scene=null},e.prototype.drawFullscreenQuad=function(){this.scene.filters=[this.effect]},e.default_vert="attribute vec2 aVertexPosition;\nattribute vec2 aTextureCoord;\nattribute vec2 aColor;\nuniform vec2 projectionVector;\nvarying vec2 vTextureCoord;\nvarying vec4 vColor;\nconst vec2 center = vec2(-1.0, 1.0);\nvoid main(void) {\ngl_Position = vec4( (aVertexPosition / projectionVector) + center , 0.0, 1.0);\nvTextureCoord = aTextureCoord;\nvColor = vec4(aColor.x, aColor.x, aColor.x, aColor.x);\n}",e}();t.PostProcessor=e}(es||(es={})),function(t){var e=function(e){function n(){return null!==e&&e.apply(this,arguments)||this}return __extends(n,e),n.prototype.onAddedToScene=function(n){e.prototype.onAddedToScene.call(this,n),this.effect=new t.GaussianBlurEffect},n}(t.PostProcessor);t.GaussianBlurPostProcessor=e}(es||(es={})),function(t){var e=function(){function t(t,e){void 0===e&&(e=null),this.renderOrder=0,this.camera=e,this.renderOrder=t}return t.prototype.onAddedToScene=function(t){},t.prototype.unload=function(){},t.prototype.onSceneBackBufferSizeChanged=function(t,e){},t.prototype.compareTo=function(t){return this.renderOrder-t.renderOrder},t.prototype.beginRender=function(t){},t.prototype.renderAfterStateCheck=function(t,e){t.render(e)},t}();t.Renderer=e}(es||(es={})),function(t){var e=function(t){function e(){return t.call(this,0,null)||this}return __extends(e,t),e.prototype.render=function(t){var e=this.camera?this.camera:t.camera;this.beginRender(e);for(var n=0;nn?n:t},e.pointOnCirlce=function(n,i,r){var o=e.toRadians(r);return new t.Vector2(Math.cos(o)*o+n.x,Math.sin(o)*o+n.y)},e.isEven=function(t){return t%2==0},e.clamp01=function(t){return t<0?0:t>1?1:t},e.angleBetweenVectors=function(t,e){return Math.atan2(e.y-t.y,e.x-t.x)},e.Epsilon=1e-5,e.Rad2Deg=57.29578,e.Deg2Rad=.0174532924,e}();t.MathHelper=e}(es||(es={})),function(t){t.matrixPool=[];var e=function(e){function n(){return null!==e&&e.apply(this,arguments)||this}return __extends(n,e),Object.defineProperty(n.prototype,"m11",{get:function(){return this.a},set:function(t){this.a=t},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"m12",{get:function(){return this.b},set:function(t){this.b=t},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"m21",{get:function(){return this.c},set:function(t){this.c=t},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"m22",{get:function(){return this.d},set:function(t){this.d=t},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"m31",{get:function(){return this.tx},set:function(t){this.tx=t},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"m32",{get:function(){return this.ty},set:function(t){this.ty=t},enumerable:!0,configurable:!0}),n.create=function(){var e=t.matrixPool.pop();return e||(e=new n),e},n.prototype.identity=function(){return this.a=this.d=1,this.b=this.c=this.tx=this.ty=0,this},n.prototype.translate=function(t,e){return this.tx+=t,this.ty+=e,this},n.prototype.scale=function(t,e){return 1!==t&&(this.a*=t,this.c*=t,this.tx*=t),1!==e&&(this.b*=e,this.d*=e,this.ty*=e),this},n.prototype.rotate=function(t){if(0!==(t=+t)){t/=DEG_TO_RAD;var e=Math.cos(t),n=Math.sin(t),i=this.a,r=this.b,o=this.c,s=this.d,a=this.tx,c=this.ty;this.a=i*e-r*n,this.b=i*n+r*e,this.c=o*e-s*n,this.d=o*n+s*e,this.tx=a*e-c*n,this.ty=a*n+c*e}return this},n.prototype.invert=function(){return this.$invertInto(this),this},n.prototype.add=function(t){return this.m11+=t.m11,this.m12+=t.m12,this.m21+=t.m21,this.m22+=t.m22,this.m31+=t.m31,this.m32+=t.m32,this},n.prototype.substract=function(t){return this.m11-=t.m11,this.m12-=t.m12,this.m21-=t.m21,this.m22-=t.m22,this.m31-=t.m31,this.m32-=t.m32,this},n.prototype.divide=function(t){return this.m11/=t.m11,this.m12/=t.m12,this.m21/=t.m21,this.m22/=t.m22,this.m31/=t.m31,this.m32/=t.m32,this},n.prototype.multiply=function(t){var e=this.m11*t.m11+this.m12*t.m21,n=this.m11*t.m12+this.m12*t.m22,i=this.m21*t.m11+this.m22*t.m21,r=this.m21*t.m12+this.m22*t.m22,o=this.m31*t.m11+this.m32*t.m21+t.m31,s=this.m31*t.m12+this.m32*t.m22+t.m32;return this.m11=e,this.m12=n,this.m21=i,this.m22=r,this.m31=o,this.m32=s,this},n.prototype.determinant=function(){return this.m11*this.m22-this.m12*this.m21},n.prototype.release=function(e){e&&t.matrixPool.push(e)},n}(egret.Matrix);t.Matrix2D=e}(es||(es={})),function(t){var e=function(e){function n(){return null!==e&&e.apply(this,arguments)||this}return __extends(n,e),Object.defineProperty(n.prototype,"max",{get:function(){return new t.Vector2(this.right,this.bottom)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"center",{get:function(){return new t.Vector2(this.x+this.width/2,this.y+this.height/2)},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"location",{get:function(){return new t.Vector2(this.x,this.y)},set:function(t){this.x=t.x,this.y=t.y},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"size",{get:function(){return new t.Vector2(this.width,this.height)},set:function(t){this.width=t.x,this.height=t.y},enumerable:!0,configurable:!0}),n.fromMinMax=function(t,e,i,r){return new n(t,e,i-t,r-e)},n.rectEncompassingPoints=function(t){for(var e=Number.POSITIVE_INFINITY,n=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY,r=Number.NEGATIVE_INFINITY,o=0;oi&&(i=s.x),s.yr&&(r=s.y)}return this.fromMinMax(e,n,i,r)},n.prototype.intersects=function(t){return t.leftthis.x+this.width)return e}else{var i=1/t.direction.x,r=(this.x-t.start.x)*i,o=(this.x+this.width-t.start.x)*i;if(r>o){var s=r;r=o,o=s}if((e=Math.max(r,e))>(n=Math.min(o,n)))return e}if(Math.abs(t.direction.y)<1e-6){if(t.start.ythis.y+this.height)return e}else{var a=1/t.direction.y,c=(this.y-t.start.y)*a,h=(this.y+this.height-t.start.y)*a;if(c>h){var u=c;c=h,h=u}if((e=Math.max(c,e))>(n=Math.max(h,n)))return e}return e},n.prototype.containsRect=function(t){return this.x<=t.x&&t.x1)return!1;var u=(c.x*o.y-c.y*o.x)/a;return!(u<0||u>1)},n.lineToLineIntersection=function(e,n,i,r){var o=new t.Vector2(0,0),s=t.Vector2.subtract(n,e),a=t.Vector2.subtract(r,i),c=s.x*a.y-s.y*a.x;if(0==c)return o;var h=t.Vector2.subtract(i,e),u=(h.x*a.y-h.y*a.x)/c;if(u<0||u>1)return o;var l=(h.x*s.y-h.y*s.x)/c;return l<0||l>1?o:o=t.Vector2.add(e,new t.Vector2(u*s.x,u*s.y))},n.closestPointOnLine=function(e,n,i){var r=t.Vector2.subtract(n,e),o=t.Vector2.subtract(i,e),s=t.Vector2.dot(o,r)/t.Vector2.dot(r,r);return s=t.MathHelper.clamp(s,0,1),t.Vector2.add(e,new t.Vector2(r.x*s,r.y*s))},n.isCircleToCircle=function(e,n,i,r){return t.Vector2.distanceSquared(e,i)<(n+r)*(n+r)},n.isCircleToLine=function(e,n,i,r){return t.Vector2.distanceSquared(e,this.closestPointOnLine(i,r,e))=t&&r.y>=e&&r.x=t+i&&(s|=e.right),o.y=n+r&&(s|=e.bottom),s},n}();t.Collisions=n}(es||(es={})),function(t){var e=function(){function e(){}return e.reset=function(){this._spatialHash=new t.SpatialHash(this.spatialHashCellSize)},e.clear=function(){this._spatialHash.clear()},e.overlapCircleAll=function(t,e,n,i){if(void 0===i&&(i=-1),0!=n.length)return this._spatialHash.overlapCircle(t,e,n,i);console.error("An empty results array was passed in. No results will ever be returned.")},e.boxcastBroadphase=function(t,e){return void 0===e&&(e=this.allLayers),this._spatialHash.aabbBroadphase(t,null,e)},e.boxcastBroadphaseExcludingSelf=function(t,e,n){return void 0===n&&(n=this.allLayers),this._spatialHash.aabbBroadphase(e,t,n)},e.addCollider=function(t){e._spatialHash.register(t)},e.removeCollider=function(t){e._spatialHash.remove(t)},e.updateCollider=function(t){this._spatialHash.remove(t),this._spatialHash.register(t)},e.debugDraw=function(t){this._spatialHash.debugDraw(t,2)},e.spatialHashCellSize=100,e.allLayers=-1,e.raycastsHitTriggers=!1,e.raycastsStartInColliders=!1,e}();t.Physics=e}(es||(es={})),function(t){var e=function(){return function(e,n){this.start=e,this.end=n,this.direction=t.Vector2.subtract(this.end,this.start)}}();t.Ray2D=e}(es||(es={})),function(t){var e=function(){function e(e,n,i,r,o){this.fraction=0,this.distance=0,this.point=t.Vector2.zero,this.normal=t.Vector2.zero,this.collider=e,this.fraction=n,this.distance=i,this.point=r,this.centroid=t.Vector2.zero}return e.prototype.setValues=function(t,e,n,i){this.collider=t,this.fraction=e,this.distance=n,this.point=i},e.prototype.setValuesNonCollider=function(t,e,n,i){this.fraction=t,this.distance=e,this.point=n,this.normal=i},e.prototype.reset=function(){this.collider=null,this.fraction=this.distance=0},e.prototype.toString=function(){return"[RaycastHit] fraction: "+this.fraction+", distance: "+this.distance+", normal: "+this.normal+", centroid: "+this.centroid+", point: "+this.point},e}();t.RaycastHit=e}(es||(es={})),function(t){var e=function(){function t(){}return t.prototype.clone=function(){return ObjectUtils.clone(this)},t}();t.Shape=e}(es||(es={})),function(t){var e=function(e){function n(t,n){var i=e.call(this)||this;return i._areEdgeNormalsDirty=!0,i.isUnrotated=!0,i.setPoints(t),i.isBox=n,i}return __extends(n,e),Object.defineProperty(n.prototype,"edgeNormals",{get:function(){return this._areEdgeNormalsDirty&&this.buildEdgeNormals(),this._edgeNormals},enumerable:!0,configurable:!0}),n.prototype.setPoints=function(t){this.points=t,this.recalculateCenterAndEdgeNormals(),this._originalPoints=[];for(var e=0;e=this.points.length?this.points[0]:this.points[i+1];var o=t.Vector2Ext.perpendicular(r,e);o=t.Vector2.normalize(o),this._edgeNormals[i]=o}},n.buildSymmetricalPolygon=function(e,n){for(var i=new Array(e),r=0;rr&&(r=s,i=o)}return e[i]},n.getClosestPointOnPolygonToPoint=function(e,n,i,r){i=Number.MAX_VALUE,r=new t.Vector2(0,0);for(var o,s=new t.Vector2(0,0),a=0;ae.y!=this.points[r].y>e.y&&e.x<(this.points[r].x-this.points[i].x)*(e.y-this.points[i].y)/(this.points[r].y-this.points[i].y)+this.points[i].x&&(n=!n);return n},n.prototype.pointCollidesWithShape=function(e,n){return t.ShapeCollisions.pointToPoly(e,this,n)},n}(t.Shape);t.Polygon=e}(es||(es={})),function(t){var e=function(e){function n(t,i){var r=e.call(this,n.buildBox(t,i),!0)||this;return r.width=t,r.height=i,r}return __extends(n,e),n.buildBox=function(e,n){var i=e/2,r=n/2,o=new Array(4);return o[0]=new t.Vector2(-i,-r),o[1]=new t.Vector2(i,-r),o[2]=new t.Vector2(i,r),o[3]=new t.Vector2(-i,r),o},n.prototype.updateBox=function(e,n){this.width=e,this.height=n;var i=e/2,r=n/2;this.points[0]=new t.Vector2(-i,-r),this.points[1]=new t.Vector2(i,-r),this.points[2]=new t.Vector2(i,r),this.points[3]=new t.Vector2(-i,r);for(var o=0;o1)return s;var a,c=t.Vector2.add(o.start,t.Vector2.add(o.direction,new t.Vector2(s))),h=0;c.xn.bounds.right&&(h|=1),c.yn.bounds.bottom&&(h|=2);var u=a+h;return 3==u&&console.log("m == 3. corner "+t.Time.frameCount),s},e}();t.RealtimeCollisions=e}(es||(es={})),function(t){var e=function(){function e(){}return e.polygonToPolygon=function(e,n,i){for(var r,o=!0,s=e.edgeNormals,a=n.edgeNormals,c=Number.POSITIVE_INFINITY,h=new t.Vector2,u=t.Vector2.subtract(e.position,n.position),l=0;l0&&(o=!1),!o)return!1;(m=Math.abs(m))r&&(r=o);return{min:i,max:r}},e.circleToPolygon=function(e,n,i){var r,o=t.Vector2.subtract(e.position,n.position),s=t.Polygon.getClosestPointOnPolygonToPoint(n.points,o,0,i.normal),a=n.containsPoint(e.position);if(0>e.radius*e.radius&&!a)return!1;a?r=t.Vector2.multiply(i.normal,new t.Vector2(Math.sqrt(0)-e.radius)):r=t.Vector2.multiply(i.normal,new t.Vector2(e.radius));return i.minimumTranslationVector=r,i.point=t.Vector2.add(s,n.position),!0},e.circleToBox=function(e,n,i){var r=n.bounds.getClosestPointOnRectangleBorderToPoint(e.position,i.normal);if(n.containsPoint(e.position)){i.point=r;var o=t.Vector2.add(r,t.Vector2.multiply(i.normal,new t.Vector2(e.radius)));return i.minimumTranslationVector=t.Vector2.subtract(e.position,o),!0}var s=t.Vector2.distanceSquared(r,e.position);if(0==s)i.minimumTranslationVector=t.Vector2.multiply(i.normal,new t.Vector2(e.radius));else if(s<=e.radius*e.radius){i.normal=t.Vector2.subtract(e.position,r);var a=i.normal.length()-e.radius;return i.point=r,i.normal=t.Vector2Ext.normalize(i.normal),i.minimumTranslationVector=t.Vector2.multiply(new t.Vector2(a),i.normal),!0}return!1},e.pointToCircle=function(e,n,i){var r=t.Vector2.distanceSquared(e,n.position),o=1+n.radius;if(r1)return!1;var l=(h.x*s.y-h.y*s.x)/c;return!(l<0||l>1)&&(o=o.add(e).add(t.Vector2.multiply(new t.Vector2(u),s)),!0)},e.lineToCircle=function(e,n,i,r){var o=t.Vector2.distance(e,n),s=t.Vector2.divide(t.Vector2.subtract(n,e),new t.Vector2(o)),a=t.Vector2.subtract(e,i.position),c=t.Vector2.dot(a,s),h=t.Vector2.dot(a,a)-i.radius*i.radius;if(h>0&&c>0)return!1;var u=c*c-h;return!(u<0)&&(r.fraction=-c-Math.sqrt(u),r.fraction<0&&(r.fraction=0),r.point=t.Vector2.add(e,t.Vector2.multiply(new t.Vector2(r.fraction),s)),r.distance=t.Vector2.distance(e,r.point),r.normal=t.Vector2.normalize(t.Vector2.subtract(r.point,i.position)),r.fraction=r.distance/o,!0)},e.boxToBoxCast=function(e,n,i,r){var o=this.minkowskiDifference(e,n);if(o.contains(0,0)){var s=o.getClosestPointOnBoundsToOrigin();return!s.equals(t.Vector2.zero)&&(r.normal=new t.Vector2(-s.x),r.normal=r.normal.normalize(),r.distance=0,r.fraction=0,!0)}var a=new t.Ray2D(t.Vector2.zero,new t.Vector2(-i.x)),c=o.rayIntersects(a);return c<=1&&(r.fraction=c,r.distance=i.length()*c,r.normal=new t.Vector2(-i.x),r.normal=r.normal.normalize(),r.centroid=t.Vector2.add(e.bounds.center,t.Vector2.multiply(i,new t.Vector2(c))),!0)},e}();t.ShapeCollisions=e}(es||(es={})),function(t){var e=function(){function e(e){void 0===e&&(e=100),this.gridBounds=new t.Rectangle,this._overlapTestCircle=new t.Circle(0),this._cellDict=new n,this._tempHashSet=[],this._cellSize=e,this._inverseCellSize=1/this._cellSize,this._raycastParser=new i}return e.prototype.register=function(e){var n=e.bounds;e.registeredPhysicsBounds=n;var i=this.cellCoords(n.x,n.y),r=this.cellCoords(n.right,n.bottom);this.gridBounds.contains(i.x,i.y)||(this.gridBounds=t.RectangleExt.union(this.gridBounds,i)),this.gridBounds.contains(r.x,r.y)||(this.gridBounds=t.RectangleExt.union(this.gridBounds,r));for(var o=i.x;o<=r.x;o++)for(var s=i.y;s<=r.y;s++){var a=this.cellAtPosition(o,s,!0);a.firstOrDefault(function(t){return t.hashCode==e.hashCode})||a.push(e)}},e.prototype.remove=function(t){for(var e=t.registeredPhysicsBounds,n=this.cellCoords(e.x,e.y),i=this.cellCoords(e.right,e.bottom),r=n.x;r<=i.x;r++)for(var o=n.y;o<=i.y;o++){var s=this.cellAtPosition(r,o);s?s.remove(t):console.error("removing Collider ["+t+"] from a cell that it is not present in")}},e.prototype.removeWithBruteForce=function(t){this._cellDict.remove(t)},e.prototype.clear=function(){this._cellDict.clear()},e.prototype.debugDraw=function(t,e){void 0===e&&(e=1);for(var n=this.gridBounds.x;n<=this.gridBounds.right;n++)for(var i=this.gridBounds.y;i<=this.gridBounds.bottom;i++){var r=this.cellAtPosition(n,i);r&&r.length>0&&this.debugDrawCellDetails(n,i,r.length,t,e)}},e.prototype.aabbBroadphase=function(e,n,i){this._tempHashSet.length=0;for(var r=this.cellCoords(e.x,e.y),o=this.cellCoords(e.right,e.bottom),s=r.x;s<=o.x;s++)for(var a=r.y;a<=o.y;a++){var c=this.cellAtPosition(s,a);if(c)for(var h=function(r){var o=c[r];if(o==n||!t.Flags.isFlagSet(i,o.physicsLayer))return"continue";e.intersects(o.bounds)&&(u._tempHashSet.firstOrDefault(function(t){return t.hashCode==o.hashCode})||u._tempHashSet.push(o))},u=this,l=0;ln;i--)if(t[i]0&&t[r-1]>i;r--)t[r]=t[r-1];t[r]=i}},t.binarySearch=function(t,e){for(var n=0,i=t.length,r=n+i>>1;n=t[r]&&(n=r+1),r=n+i>>1;return t[n]==e?n:-1},t.findElementIndex=function(t,e){for(var n=t.length,i=0;it[e]&&(e=i);return e},t.getMinElementIndex=function(t){for(var e=0,n=t.length,i=1;i=0;--r)n.unshift(e[r]);return n},t.getDifferAry=function(t,e){t=this.getUniqueAry(t),e=this.getUniqueAry(e);for(var n=t.concat(e),i={},r=[],o=n.length,s=0;s=0;e-=1)t.splice(e,1)},t.cloneList=function(t){return t?t.slice(0,t.length):null},t.equals=function(t,e){if(t==e)return!0;var n=t.length;if(n!=e.length)return!1;for(;n--;)if(t[n]!=e[n])return!1;return!0},t.insert=function(t,e,n){if(!t)return null;var i=t.length;if(e>i&&(e=i),e<0&&(e=0),e==i)t.push(n);else if(0==e)t.unshift(n);else{for(var r=i-1;r>=e;r-=1)t[r+1]=t[r];t[e]=n}return n},t}(),Base64Utils=function(){function t(){}return t.decode=function(t,e){void 0===e&&(e=!0);var n,i,r,o,s,a,c="",h=0;for(t=(t=this.getConfKey(t)).replace(/[^A-Za-z0-9\+\/\=]/g,"");h>4,i=(15&o)<<4|(s=this._keyAll.indexOf(t.charAt(h++)))>>2,r=(3&s)<<6|(a=this._keyAll.indexOf(t.charAt(h++))),c+=String.fromCharCode(n),64!=s&&(0==i?e&&(c+=String.fromCharCode(i)):c+=String.fromCharCode(i)),64!=a&&(0==r?e&&(c+=String.fromCharCode(r)):c+=String.fromCharCode(r));return c=this._utf8_decode(c)},t._utf8_encode=function(t){t=t.replace(/\r\n/g,"\n");for(var e="",n=0;n127&&i<2048?(e+=String.fromCharCode(i>>6|192),e+=String.fromCharCode(63&i|128)):(e+=String.fromCharCode(i>>12|224),e+=String.fromCharCode(i>>6&63|128),e+=String.fromCharCode(63&i|128))}return e},t._utf8_decode=function(t){for(var e="",n=0,i=0,r=0,o=0;n191&&i<224?(r=t.charCodeAt(n+1),e+=String.fromCharCode((31&i)<<6|63&r),n+=2):(r=t.charCodeAt(n+1),o=t.charCodeAt(n+2),e+=String.fromCharCode((15&i)<<12|(63&r)<<6|63&o),n+=3);return e},t.getConfKey=function(t){return t.slice(1,t.length)},t._keyNum="0123456789+/",t._keyStr="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",t._keyAll=t._keyNum+t._keyStr,t.encode=function(t){var e,n,i,r,o,s,a,c="",h=0;for(t=this._utf8_encode(t);h>2,o=(3&e)<<4|(n=t.charCodeAt(h++))>>4,s=(15&n)<<2|(i=t.charCodeAt(h++))>>6,a=63&i,isNaN(n)?s=a=64:isNaN(i)&&(a=64),c=c+this._keyAll.charAt(r)+this._keyAll.charAt(o)+this._keyAll.charAt(s)+this._keyAll.charAt(a);return this._keyStr.charAt(Math.floor(Math.random()*this._keyStr.length))+c},t}();!function(t){var e=function(){function t(){this.loadedAssets=new Map}return t.prototype.loadRes=function(t,e){var n=this;return void 0===e&&(e=!0),new Promise(function(i,r){var o=n.loadedAssets.get(t);o?i(o):e?RES.getResAsync(t).then(function(e){n.loadedAssets.set(t,e),i(e)}).catch(function(e){console.error("资源加载错误:",t,e),r(e)}):RES.getResByUrl(t).then(function(e){n.loadedAssets.set(t,e),i(e)}).catch(function(e){console.error("资源加载错误:",t,e),r(e)})})},t.prototype.dispose=function(){this.loadedAssets.forEach(function(t){t.dispose()}),this.loadedAssets.clear()},t}();t.ContentManager=e}(es||(es={})),function(t){var e=function(){function e(){}return e.drawLine=function(e,n,i,r,o){void 0===o&&(o=1),this.drawLineAngle(e,n,t.MathHelper.angleBetweenVectors(n,i),t.Vector2.distance(n,i),r,o)},e.drawLineAngle=function(t,e,n,i,r,o){void 0===o&&(o=1),t.graphics.beginFill(r),t.graphics.drawRect(e.x,e.y,1,1),t.graphics.endFill(),t.scaleX=i,t.scaleY=o,t.$anchorOffsetX=0,t.$anchorOffsetY=0,t.rotation=n},e.drawHollowRect=function(t,e,n,i){void 0===i&&(i=1),this.drawHollowRectR(t,e.x,e.y,e.width,e.height,n,i)},e.drawHollowRectR=function(e,n,i,r,o,s,a){void 0===a&&(a=1);var c=new t.Vector2(n,i).round(),h=new t.Vector2(n+r,i).round(),u=new t.Vector2(n+r,i+o).round(),l=new t.Vector2(n,i+o).round();this.drawLine(e,c,h,s,a),this.drawLine(e,h,u,s,a),this.drawLine(e,u,l,s,a),this.drawLine(e,l,c,s,a)},e.drawPixel=function(e,n,i,r){void 0===r&&(r=1);var o=new t.Rectangle(n.x,n.y,r,r);1!=r&&(o.x-=.5*r,o.y-=.5*r),e.graphics.beginFill(i),e.graphics.drawRect(o.x,o.y,o.width,o.height),e.graphics.endFill()},e.getColorMatrix=function(t){var e=[1,0,0,0,0,0,1,0,0,0,0,0,1,0,0,0,0,0,1,0];return e[0]=Math.floor(t/256/256)/255,e[6]=Math.floor(t/256%256)/255,e[12]=t%256/255,new egret.ColorMatrixFilter(e)},e}();t.DrawUtils=e}(es||(es={})),function(t){var e=function(){return function(t,e){this.func=t,this.context=e}}();t.FuncPack=e;var n=function(){function t(){this._messageTable=new Map}return t.prototype.addObserver=function(t,n,i){var r=this._messageTable.get(t);r||(r=[],this._messageTable.set(t,r)),-1!=r.findIndex(function(t){return t.func==n})&&console.warn("您试图添加相同的观察者两次"),r.push(new e(n,i))},t.prototype.removeObserver=function(t,e){var n=this._messageTable.get(t),i=n.findIndex(function(t){return t.func==e});-1!=i&&n.removeAt(i)},t.prototype.emit=function(t,e){var n=this._messageTable.get(t);if(n)for(var i=n.length-1;i>=0;i--)n[i].func.call(n[i].context,e)},t}();t.Emitter=n}(es||(es={})),function(t){var e=function(){function t(){}return Object.defineProperty(t.prototype,"enabled",{get:function(){return this._enabled},set:function(t){this.setEnabled(t)},enumerable:!0,configurable:!0}),t.prototype.setEnabled=function(t){this._enabled!=t&&(this._enabled=t,this._enabled?this.onEnabled():this.onDisabled())},t.prototype.onEnabled=function(){},t.prototype.onDisabled=function(){},t.prototype.update=function(){},t}();t.GlobalManager=e}(es||(es={})),function(t){var e=function(){function e(){this.x=0,this.y=0,this.touchPoint=-1,this.touchDown=!1}return Object.defineProperty(e.prototype,"position",{get:function(){return new t.Vector2(this.x,this.y)},enumerable:!0,configurable:!0}),e.prototype.reset=function(){this.x=0,this.y=0,this.touchDown=!1,this.touchPoint=-1},e}();t.TouchState=e;var n=function(){function n(){}return Object.defineProperty(n,"gameTouchs",{get:function(){return this._gameTouchs},enumerable:!0,configurable:!0}),Object.defineProperty(n,"resolutionScale",{get:function(){return this._resolutionScale},enumerable:!0,configurable:!0}),Object.defineProperty(n,"totalTouchCount",{get:function(){return this._totalTouchCount},enumerable:!0,configurable:!0}),Object.defineProperty(n,"touchPosition",{get:function(){return this._gameTouchs[0]?this._gameTouchs[0].position:t.Vector2.zero},enumerable:!0,configurable:!0}),Object.defineProperty(n,"maxSupportedTouch",{get:function(){return t.Core._instance.stage.maxTouches},set:function(e){t.Core._instance.stage.maxTouches=e,this.initTouchCache()},enumerable:!0,configurable:!0}),Object.defineProperty(n,"touchPositionDelta",{get:function(){var e=t.Vector2.subtract(this.touchPosition,this._previousTouchState.position);return e.length()>0&&this.setpreviousTouchState(this._gameTouchs[0]),e},enumerable:!0,configurable:!0}),n.initialize=function(){this._init||(this._init=!0,t.Core._instance.stage.addEventListener(egret.TouchEvent.TOUCH_BEGIN,this.touchBegin,this),t.Core._instance.stage.addEventListener(egret.TouchEvent.TOUCH_MOVE,this.touchMove,this),t.Core._instance.stage.addEventListener(egret.TouchEvent.TOUCH_END,this.touchEnd,this),t.Core._instance.stage.addEventListener(egret.TouchEvent.TOUCH_CANCEL,this.touchEnd,this),t.Core._instance.stage.addEventListener(egret.TouchEvent.TOUCH_RELEASE_OUTSIDE,this.touchEnd,this),this.initTouchCache())},n.scaledPosition=function(e){var n=new t.Vector2(e.x-this._resolutionOffset.x,e.y-this._resolutionOffset.y);return t.Vector2.multiply(n,this.resolutionScale)},n.initTouchCache=function(){this._totalTouchCount=0,this._touchIndex=0,this._gameTouchs.length=0;for(var t=0;t0)for(var e=0;ethis._objectQueue.length;)this._objectQueue.shift()},t.clearCache=function(){this._objectQueue.length=0},t.obtain=function(){return this._objectQueue.length>0?this._objectQueue.shift():[]},t.free=function(t){this._objectQueue.unshift(t),t.length=0},t._objectQueue=[],t}();t.ListPool=e}(es||(es={}));var THREAD_ID=Math.floor(1e3*Math.random())+"-"+Date.now(),nextTick=function(t){setTimeout(t,0)},LockUtils=function(){function t(t){this._keyX="mutex_key_"+t+"_X",this._keyY="mutex_key_"+t+"_Y",this.setItem=egret.localStorage.setItem.bind(localStorage),this.getItem=egret.localStorage.getItem.bind(localStorage),this.removeItem=egret.localStorage.removeItem.bind(localStorage)}return t.prototype.lock=function(){var t=this;return new Promise(function(e,n){var i=function(){t.setItem(t._keyX,THREAD_ID),null===!t.getItem(t._keyY)&&nextTick(i),t.setItem(t._keyY,THREAD_ID),t.getItem(t._keyX)!==THREAD_ID?setTimeout(function(){t.getItem(t._keyY)===THREAD_ID?(e(),t.removeItem(t._keyY)):nextTick(i)},10):(e(),t.removeItem(t._keyY))};i()})},t}();!function(t){var e=function(){function t(t,e){this.first=t,this.second=e}return t.prototype.clear=function(){this.first=this.second=null},t.prototype.equals=function(t){return this.first==t.first&&this.second==t.second},t}();t.Pair=e}(es||(es={}));var RandomUtils=function(){function t(){}return t.randrange=function(t,e,n){if(void 0===n&&(n=1),0==n)throw new Error("step 不能为 0");var i=e-t;if(0==i)throw new Error("没有可用的范围("+t+","+e+")");i<0&&(i=t-e);var r=Math.floor((i+n-1)/n);return Math.floor(this.random()*r)*n+Math.min(t,e)},t.randint=function(t,e){return(t=Math.floor(t))>(e=Math.floor(e))?t++:e++,this.randrange(t,e)},t.randnum=function(t,e){return this.random()*(e-t)+t},t.shuffle=function(t){return t.sort(this._randomCompare),t},t.choice=function(t){if(!t.hasOwnProperty("length"))throw new Error("无法对此对象执行此操作");var e=Math.floor(this.random()*t.length);return t instanceof String?String(t).charAt(e):t[e]},t.sample=function(t,e){var n=t.length;if(e<=0||n=0;)s=Math.floor(this.random()*n);i.push(t[s]),r.push(s)}return i},t.random=function(){return Math.random()},t.boolean=function(t){return void 0===t&&(t=.5),this.random().5?1:-1},t}();!function(t){var e=function(){function e(){}return e.union=function(e,n){var i=new t.Rectangle(n.x,n.y,0,0),r=new t.Rectangle;return r.x=Math.min(e.x,i.x),r.y=Math.min(e.y,i.y),r.width=Math.max(e.right,i.right)-r.x,r.height=Math.max(e.bottom,r.bottom)-r.y,r},e}();t.RectangleExt=e}(es||(es={})),function(t){var e=function(){function e(){this.triangleIndices=[],this._triPrev=new Array(12),this._triNext=new Array(12)}return e.testPointTriangle=function(e,n,i,r){return!(t.Vector2Ext.cross(t.Vector2.subtract(e,n),t.Vector2.subtract(i,n))<0)&&(!(t.Vector2Ext.cross(t.Vector2.subtract(e,i),t.Vector2.subtract(r,i))<0)&&!(t.Vector2Ext.cross(t.Vector2.subtract(e,r),t.Vector2.subtract(n,r))<0))},e.prototype.triangulate=function(n,i){void 0===i&&(i=!0);var r=n.length;this.initialize(r);for(var o=0,s=0;r>3&&o<500;){o++;var a=!0,c=n[this._triPrev[s]],h=n[s],u=n[this._triNext[s]];if(t.Vector2Ext.isTriangleCCW(c,h,u)){var l=this._triNext[this._triNext[s]];do{if(e.testPointTriangle(n[l],c,h,u)){a=!1;break}l=this._triNext[l]}while(l!=this._triPrev[s])}else a=!1;a?(this.triangleIndices.push(this._triPrev[s]),this.triangleIndices.push(s),this.triangleIndices.push(this._triNext[s]),this._triNext[this._triPrev[s]]=this._triNext[s],this._triPrev[this._triNext[s]]=this._triPrev[s],r--,s=this._triPrev[s]):s=this._triNext[s]}this.triangleIndices.push(this._triPrev[s]),this.triangleIndices.push(s),this.triangleIndices.push(this._triNext[s]),i||this.triangleIndices.reverse()},e.prototype.initialize=function(t){this.triangleIndices.length=0,this._triNext.lengtht.MathHelper.Epsilon?e=t.Vector2.divide(e,new t.Vector2(n)):e.x=e.y=0,e},e.transformA=function(t,e,n,i,r,o){for(var s=0;sthis.safeArea.right&&(s.x=this.safeArea.right-s.width),s.topthis.safeArea.bottom&&(s.y=this.safeArea.bottom-s.height),s},n}();t.Layout=n,function(t){t[t.none=0]="none",t[t.left=1]="left",t[t.right=2]="right",t[t.horizontalCenter=4]="horizontalCenter",t[t.top=8]="top",t[t.bottom=16]="bottom",t[t.verticalCenter=32]="verticalCenter",t[t.topLeft=9]="topLeft",t[t.topRight=10]="topRight",t[t.topCenter=12]="topCenter",t[t.bottomLeft=17]="bottomLeft",t[t.bottomRight=18]="bottomRight",t[t.bottomCenter=20]="bottomCenter",t[t.centerLeft=33]="centerLeft",t[t.centerRight=34]="centerRight",t[t.center=36]="center"}(e=t.Alignment||(t.Alignment={}))}(es||(es={})),function(t){var e,n=function(){function t(t){void 0===t&&(t=i),this.getSystemTime=t,this._stopDuration=0,this._completeSlices=[]}return t.prototype.getState=function(){return void 0===this._startSystemTime?e.IDLE:void 0===this._stopSystemTime?e.RUNNING:e.STOPPED},t.prototype.isIdle=function(){return this.getState()===e.IDLE},t.prototype.isRunning=function(){return this.getState()===e.RUNNING},t.prototype.isStopped=function(){return this.getState()===e.STOPPED},t.prototype.slice=function(){return this.recordPendingSlice()},t.prototype.getCompletedSlices=function(){return Array.from(this._completeSlices)},t.prototype.getCompletedAndPendingSlices=function(){return this._completeSlices.concat([this.getPendingSlice()])},t.prototype.getPendingSlice=function(){return this.calculatePendingSlice()},t.prototype.getTime=function(){return this.caculateStopwatchTime()},t.prototype.reset=function(){this._startSystemTime=this._pendingSliceStartStopwatchTime=this._stopSystemTime=void 0,this._stopDuration=0,this._completeSlices=[]},t.prototype.start=function(t){if(void 0===t&&(t=!1),t&&this.reset(),void 0!==this._stopSystemTime){var e=(n=this.getSystemTime())-this._stopSystemTime;this._stopDuration+=e,this._stopSystemTime=void 0}else if(void 0===this._startSystemTime){var n=this.getSystemTime();this._startSystemTime=n,this._pendingSliceStartStopwatchTime=0}},t.prototype.stop=function(t){if(void 0===t&&(t=!1),void 0===this._startSystemTime)return 0;var e=this.getSystemTimeOfCurrentStopwatchTime();return t&&this.recordPendingSlice(this.caculateStopwatchTime(e)),this._stopSystemTime=e,this.getTime()},t.prototype.calculatePendingSlice=function(t){return void 0===this._pendingSliceStartStopwatchTime?Object.freeze({startTime:0,endTime:0,duration:0}):(void 0===t&&(t=this.getTime()),Object.freeze({startTime:this._pendingSliceStartStopwatchTime,endTime:t,duration:t-this._pendingSliceStartStopwatchTime}))},t.prototype.caculateStopwatchTime=function(t){return void 0===this._startSystemTime?0:(void 0===t&&(t=this.getSystemTimeOfCurrentStopwatchTime()),t-this._startSystemTime-this._stopDuration)},t.prototype.getSystemTimeOfCurrentStopwatchTime=function(){return void 0===this._stopSystemTime?this.getSystemTime():this._stopSystemTime},t.prototype.recordPendingSlice=function(t){if(void 0!==this._pendingSliceStartStopwatchTime){void 0===t&&(t=this.getTime());var e=this.calculatePendingSlice(t);return this._pendingSliceStartStopwatchTime=e.endTime,this._completeSlices.push(e),e}return this.calculatePendingSlice()},t}();t.Stopwatch=n,function(t){t.IDLE="IDLE",t.RUNNING="RUNNING",t.STOPPED="STOPPED"}(e||(e={})),t.setDefaultSystemTimeGetter=function(t){void 0===t&&(t=Date.now),i=t};var i=Date.now}(stopwatch||(stopwatch={})),function(t){var e=function(){function e(){this.showLog=!1,this._frameKey="frame",this._logKey="log",this.markers=[],this.stopwacth=new stopwatch.Stopwatch,this._markerNameToIdMap=new Map,this._logs=new Array(2);for(var e=0;e=e.logSnapDuration&&(l.logs[r].snapMin=l.logs[r].min,l.logs[r].snapMax=l.logs[r].max,l.logs[r].snapAvg=l.logs[r].avg,l.logs[r].samples=0)):(l.logs[r].min=h,l.logs[r].max=h,l.logs[r].avg=h,l.logs[r].initialized=!0)}s.markCount=o.nestCount,s.nestCount=o.nestCount}t.stopwacth.reset(),t.stopwacth.start()}})},e.prototype.beginMark=function(t,n,i){var r=this;void 0===i&&(i=0),new LockUtils(this._frameKey).lock().then(function(){if(i<0||i>=e.maxBars)throw new Error("barIndex argument out of range");var o=r._curLog.bars[i];if(o.markCount>=e.maxSamples)throw new Error("exceeded sample count. either set larger number to timeruler.maxsaple or lower sample count");if(o.nestCount>=e.maxNestCall)throw new Error("exceeded nest count. either set larger number to timeruler.maxnestcall or lower nest calls");var s=r._markerNameToIdMap.get(t);isNaN(s)&&(s=r.markers.length,r._markerNameToIdMap.set(t,s)),o.markerNests[o.nestCount++]=o.markCount,o.markers[o.markCount].markerId=s,o.markers[o.markCount].color=n,o.markers[o.markCount].beginTime=r.stopwacth.getTime(),o.markers[o.markCount].endTime=-1})},e.prototype.endMark=function(t,n){var i=this;void 0===n&&(n=0),new LockUtils(this._frameKey).lock().then(function(){if(n<0||n>=e.maxBars)throw new Error("barIndex argument out of range");var r=i._curLog.bars[n];if(r.nestCount<=0)throw new Error("call beginMark method before calling endMark method");var o=i._markerNameToIdMap.get(t);if(isNaN(o))throw new Error("Marker "+t+" is not registered. Make sure you specifed same name as you used for beginMark method");var s=r.markerNests[--r.nestCount];if(r.markers[s].markerId!=o)throw new Error("Incorrect call order of beginMark/endMark method. beginMark(A), beginMark(B), endMark(B), endMark(A) But you can't called it like beginMark(A), beginMark(B), endMark(A), endMark(B).");r.markers[s].endTime=i.stopwacth.getTime()})},e.prototype.getAverageTime=function(t,n){if(t<0||t>=e.maxBars)throw new Error("barIndex argument out of range");var i=0,r=this._markerNameToIdMap.get(n);return r&&(i=this.markers[r].logs[t].avg),i},e.prototype.resetLog=function(){var t=this;new LockUtils(this._logKey).lock().then(function(){var e=parseInt(egret.localStorage.getItem(t._logKey),10);e+=1,egret.localStorage.setItem(t._logKey,e.toString()),t.markers.forEach(function(t){for(var e=0;e0&&(i+=e.barHeight+2*e.barPadding,r=Math.max(r,t.markers[t.markCount-1].endTime))});var o=this.sampleFrames*(1/60*1e3);this._frameAdjust=r>o?Math.max(0,this._frameAdjust)+1:Math.min(0,this._frameAdjust)-1,Math.max(this._frameAdjust)>e.autoAdjustDelay&&(this.sampleFrames=Math.min(e.maxSampleFrames,this.sampleFrames),this.sampleFrames=Math.max(this.targetSampleFrames,r/(1/60*1e3)+1),this._frameAdjust=0);t.y,e.barHeight}},e.prototype.onGraphicsDeviceReset=function(){var n=new t.Layout;this._position=n.place(new t.Vector2(this.width,e.barHeight),0,.01,t.Alignment.bottomCenter).location},e.maxBars=8,e.maxSamples=256,e.maxNestCall=32,e.barHeight=8,e.maxSampleFrames=4,e.logSnapDuration=120,e.barPadding=2,e.autoAdjustDelay=30,e}();t.TimeRuler=e;var n=function(){return function(){this.bars=new Array(e.maxBars),this.bars.fill(new i,0,e.maxBars)}}();t.FrameLog=n;var i=function(){return function(){this.markers=new Array(e.maxSamples),this.markCount=0,this.markerNests=new Array(e.maxNestCall),this.nestCount=0,this.markers.fill(new r,0,e.maxSamples),this.markerNests.fill(0,0,e.maxNestCall)}}();t.MarkerCollection=i;var r=function(){return function(){this.markerId=0,this.beginTime=0,this.endTime=0,this.color=0}}();t.Marker=r;var o=function(){return function(t){this.logs=new Array(e.maxBars),this.name=t,this.logs.fill(new s,0,e.maxBars)}}();t.MarkerInfo=o;var s=function(){return function(){this.snapMin=0,this.snapMax=0,this.snapAvg=0,this.min=0,this.max=0,this.avg=0,this.samples=0,this.color=0,this.initialized=!1}}();t.MarkerLog=s}(es||(es={})); \ No newline at end of file diff --git a/source/gulpfile.js b/source/gulpfile.js index 7f85a5b2..941e0520 100644 --- a/source/gulpfile.js +++ b/source/gulpfile.js @@ -8,10 +8,10 @@ const tsProject = ts.createProject('tsconfig.json'); gulp.task('buildJs', () => { return tsProject.src() .pipe(tsProject()) - .js.pipe(inject.replace('var framework;', '')) - .pipe(inject.prepend('window.framework = {};\n')) + .js.pipe(inject.replace('var es;', '')) + .pipe(inject.prepend('window.es = {};\n')) .pipe(inject.replace('var __extends =', 'window.__extends =')) - .pipe(minify({ ext: { min: ".min.js" } })) + .pipe(minify({ext: {min: ".min.js"}})) .pipe(gulp.dest('./bin')); }); diff --git a/source/lib/wxgame.d.ts b/source/lib/wxgame.d.ts new file mode 100644 index 00000000..b8adb9dd --- /dev/null +++ b/source/lib/wxgame.d.ts @@ -0,0 +1,3945 @@ +/** + * IOS及安卓不支持: + * globalCompositeOperation不支持以下值:source-in source-out destination-atop lighter copy + * isPointInPath 不支持 + */ +declare class WxRenderingContext extends CanvasRenderingContext2D { +} + +/** + * IOS及安卓不支持: + * pixelStorei 当第一个参数是 gl.UNPACK_COLORSPACE_CONVERSION_WEBGL 时不支持 + * compressedTexImage2D不支持 + * compressedTexSubImage2D不支持 + * 安卓不支持: + * getExtension + * getSupportedExtensions + */ +declare class WxWebGLRenderingContext extends WebGLRenderingContext { + /** + * 将一个Canvas对应的Texture绑定到WebGL上下文。(目前该方法仅支持 iOS 6.6.6 以上版本,Android/开发者工具暂不支持。) + * 示例:gl.wxBindCanvasTexture(gl.TEXTURE_2D, canvas) + * @param texture WebGL的纹理类型枚举值 + * @param canvas 需要绑定为Texture的Canvas + */ + wxBindCanvasTexture(texture: number, canvas: Canvas): void; +} + +declare class WxPerformance { + /** + * 时间戳 + */ + now(): number; +} + +declare class Canvas { + /** + * 画布的宽度 + */ + width: number; + /** + * 画布的高度 + */ + height: number; + /** + * 将当前 Canvas 保存为一个临时文件,并生成相应的临时文件路径。 + */ + toTempFilePath(p: wx.types.ToTempFileParams): void; + /** + * toTempFilePath 的同步版本 + */ + toTempFilePathSync(p: wx.types.ToTempFileSyncParams): string; + /** + * 获取画布对象的绘图上下文 + * @param contextType 上下文类型 + * @param contextAttributes webgl 上下文属性,仅当 contextType 为 webgl 时有效 + */ + getContext(contextType: "2d" | "webgl", contextAttributes?: wx.types.RenderingContextConfig): WxRenderingContext | WxWebGLRenderingContext; + /** + * 把画布上的绘制内容以一个 data URI 的格式返回 + */ + toDataURL(): string; +} + +declare class Stats { + /** + * 文件的类型和存取的权限,对应 POSIX stat.st_mode + */ + mode: string; + /** + * 文件大小,单位:B,对应 POSIX stat.st_size + */ + size: number; + /** + * 文件最近一次被存取或被执行的时间,UNIX 时间戳,对应 POSIX stat.st_atime + */ + lastAccessedTime: number; + /** + * 文件最后一次被修改的时间,UNIX 时间戳,对应 POSIX stat.st_mtime + */ + lastModifiedTime: number; + + /** + * 判断当前文件是否一个目录 + */ + isDirectory(): boolean; + /** + * 判断当前文件是否一个普通文件 + */ + isFile(): boolean; +} + +/** + * 日志管理类,最多保存5M的日志内容,超过5M后,旧的日志内容会被删除。 + * 对于小程序,用户可以通过使用 button 组件的 open-type="feedback" 来上传打印的日志。 + * 对于小游戏,用户可以通过使用 wx.createFeedbackButton 来创建上传打印的日志的按钮。 + * 开发者可以通过小程序管理后台左侧菜单“反馈管理”页面查看相关打印日志。 + * 基础库默认会把 App、Page 的生命周期函数和 wx 命名空间下的函数调用写入日志。 + */ +declare class LogManager { + /** + * 写debug日志 + * @param args 要记录的日志内容 + */ + debug(... args: any[]): void; + + /** + * 写info日志 + * @param args 要记录的日志内容 + */ + info(... args: any[]): void; + + /** + * 写log日志 + * @param args 要记录的日志内容 + */ + log(... args: any[]): void; + + /** + * 写warn日志 + * @param args 要记录的日志内容 + */ + warn(... args: any[]): void; +} + +declare class FileSystemManager { + /** + * 重命名文件,可以把文件从 oldPath 移动到 newPath + */ + rename(param: wx.types.RenameParams): void; + /** + * FileSystemManager.rename 的同步版本 + * @param oldPath 源文件路径,可以是普通文件或目录 + * @param newPath 新文件路径 + * @throws 指定源文件或目标文件没有写权限 + * @throws 源文件不存在,或目标文件路径的上层目录不存在 + */ + renameSync(oldPath: string, newPath: string): void; + + /** + * 删除目录 + */ + rmdir(param: wx.types.RmdirParams): void; + /** + * rmdir 的同步版本 + * @param dirPath 要删除的目录路径 + * @param recursive 是否递归删除目录。如果为 true,则删除该目录和该目录下的所有子目录以及文件。 + * @throws 目录不存在, 目录不为空, 指定的 dirPath 路径没有写权限 + */ + rmdirSync(dirPath: string, recursive?: boolean): void; + + /** + * 读取目录内文件列表 + */ + readdir(param: wx.types.ReaddirParams): void; + /** + * readdir的同步版本 + * @param dirPath 要读取的目录路径 + * @throws 目录不存在 + * @throws dirPath 不是目录 + * @throws 指定的 filePath 路径没有读权限 + */ + readdirSync(dirPath: string): ReadonlyArray; + + /** + * 创建目录 + */ + mkdir(param: wx.types.MkdirParams): void; + /** + * mkdir 的同步版本 + * @param dirPath 创建的目录路径 + * @param recursive 是否在递归创建该目录的上级目录后再创建该目录。如果对应的上级目录已经存在,则不创建该上级目录。如 dirPath 为 a/b/c/d 且 recursive 为 true,将创建 a 目录,再在 a 目录下创建 b 目录,以此类推直至创建 a/b/c 目录下的 d 目录。 + * @throws 上级目录不存在 + * @throws 指定的 filePath 路径没有写权限 + * @throws 有同名文件或目录 + */ + mkdirSync(dirPath: string, recursive?: boolean): void; + + /** + * 解链文件 + */ + unlink(param: wx.types.UnlinkParams): void; + /** + * unlink 的同步版本 + * @param filePath 要解链的文件路径 + * @throws 指定的 path 路径没有读权限 + * @throws 文件不存在 + * @throws 传入的 filePath 是一个目录 + */ + unlinkSync(filePath: string): void; + + /** + * 解压文件 + */ + unzip(param: wx.types.UnzipParams): void; + + /** + * 读取本地文件内容 + */ + readFile(param: wx.types.ReadfileParams): void; + /** + * readFile 的同步版本,读取并返回指定路径的文件的原始二进制内容 + * @param filePath 要读取的文件的路径 + * @throws 指定的 filePath 所在目录不存在 + * @throws 指定的 filePath 路径没有读权限 + */ + readFileSync(filePath: string): ArrayBuffer; + /** + * readFile 的同步版本,读取并按指定字符编码返回字符串 + * @param filePath 要读取的文件的路径 + * @param encoding 指定读取文件的字符编码 + * @throws 指定的 filePath 所在目录不存在 + * @throws 指定的 filePath 路径没有读权限 + */ + readFileSync(filePath: string, encoding: wx.types.FileContentEncoding): string; + + /** + * 获取文件 Stats 对象 + */ + stat(param: wx.types.StatParams): void; + /** + * stat 的同步版本 + * @param path 文件/目录路径 + * @throws 指定的 path 路径没有读权限 + * @throws 文件不存在 + */ + statSync(path: string): Stats; + + /** + * 写文件 + */ + writeFile(param: wx.types.WritefileParams): void; + /** + * writeFile 的同步版本,写入二进制原始文件数据 + * @param filePath 要写入的文件路径 + * @param data 要写入的二进制数据 + * @throws 指定的 filePath 所在目录不存在 + * @throws 指定的 filePath 路径没有写权限 + */ + writeFileSync(filePath: string, data: ArrayBuffer): void; + /** + * writeFile 的同步版本,写入文本字符串数据至文件 + * @param filePath 要写入的文件路径 + * @param data 要写入的文本内容 + * @param encoding 指定写入的文本的字符编码格式 + * @throws 指定的 filePath 所在目录不存在 + * @throws 指定的 filePath 路径没有写权限 + */ + writeFileSync(filePath: string, data: string, encoding: wx.types.FileContentEncoding): void; + + /** + * 判断文件/目录是否存在 + */ + access(param: wx.types.AccessfileParams): void; + /** + * access的同步版本 + * @param path 要判断是否存在的文件/目录路径 + * @throws 文件/目录不存在 + */ + accessSync(path: string): void; + + /** + * 复制文件 + */ + copyFile(param: wx.types.CopyfileParams): void; + /** + * copyFile 的同步版本 + * @param srcPath 源文件路径,只可以是普通文件 + * @param destPath 目标文件路径 + * @throws 指定目标文件路径没有写权限 + * @throws 源文件不存在,或目标文件路径的上层目录不存在 + */ + copyFileSync(srcPath: string, destPath: string): void; + + /** + * 获取该小程序下已保存的本地缓存文件列表 + * @param res.fileList.filePath 本地路径 + * @param res.fileList.size 本地文件大小,以字节为单位 + * @param res.fileList.createTime 文件创建时间 + */ + getSavedFileList(param: wx.types.CallbacksWithType): void; + + /** + * 获取该小程序下的 本地临时文件 或 本地缓存文件 信息 + */ + getFileInfo(param: wx.types.FileinfoParams): void; + + /** + * 删除该小程序下已保存的本地缓存文件(新版本应使用unlink) + */ + removeSavedFile(param: wx.types.RemovefileParams): void; + + /** + * 保存临时文件到本地。此接口会移动临时文件,因此调用成功后,tempFilePath 将不可用。 + */ + saveFile(param: wx.types.SavefileParams): void; + /** + * saveFile的同步版本 + * @param tempFilePath 临时存储文件路径 + * @param filePath 要存储的文件路径 + * @throws 指定的 tempFilePath 找不到文件 + * @throws 指定的 filePath 路径没有写权限 + * @throws 上级目录不存在 + */ + saveFileSync(tempFilePath: string, filePath?: string): string; + + /** + * 在文件结尾追加内容 + */ + appendFile(param: wx.types.AppendfileParams): void; + /** + * appendFile的同步版本 + * @param filePath 要追加内容的文件路径 + * @param data 要追加的文本或二进制数据 + * @param encoding 指定写入文件的字符编码 + * @throws 指定的 filePath 文件不存在 + * @throws 指定的 filePath 是一个已经存在的目录 + * @throws 指定的 filePath 路径没有写权限 + * @throws 指定的 filePath 是一个已经存在的目录 + */ + appendFileSync(filePath: string, data: string | ArrayBuffer, encoding: wx.types.FileContentEncoding): void; +} + +declare class DownloadTask { + /** + * 中断下载任务 + */ + abort(): void; + /** + * 监听下载进度变化事件 + * @param res.progress 下载进度百分比,值为0至100 + * @param res.totalBytesWritten 已经下载的数据长度,单位 Bytes + * @param res.totalBytesExpectedToWrite 预期需要下载的数据总长度,单位 Bytes + */ + onProgressUpdate(callback: (res: { progress: number, totalBytesWritten: number, totalBytesExpectedToWrite: number }) => void): void; +} + +declare class RequestTask { + /** + * 中断请求任务 + */ + abort(): void; +} + +declare class SocketTask { + /** + * 通过WebSocket发送数据 + */ + send(param: wx.types.SocketSendParams): void; + /** + * 关闭WebSocket连接 + */ + close(param: wx.types.SocketCloseParams): void; + /** + * 监听WebSocket 连接打开事件 + */ + onOpen(callback: wx.types.SocketOpenCallback): void; + /** + * 监听WebSocket 连接关闭事件 + */ + onClose(callback: () => void): void; + /** + * 监听WebSocket 错误事件 + */ + onError(callback: wx.types.SocketErrorCallback): void; + /** + * 监听WebSocket 接受到服务器的消息事件 + */ + onMessage(callback: wx.types.SocketMessageCallback): void; +} + +/** + * 一个 UDP Socket 实例,默认使用 IPv4 协议。 + * 错误码: + * -1 系统错误 + * -2 socket接口错误 + * -3 发送失败,无接口权限 + * 1 发送失败,参数错误,address不合法 + * 2 发送失败,参数错误,port不合法 + */ +declare class UDPSocket { + /** + * 绑定一个系统随机分配的可用端口,或绑定一个指定的端口号 + * @param port 需要绑定的端口号,不指定时使用随机端口 + * @returns 绑定成功的端口号 + */ + bind(port?: number): number; + + /** + * 向指定的 IP 和 port 发送消息 + */ + send(param: wx.types.UDPSendParams): void; + + /** + * 关闭 UDP Socket 实例,相当于销毁。 在关闭之后,UDP Socket 实例不能再发送消息,每次调用 UDPSocket.send 将会触发错误事件, + * 并且 message 事件回调函数也不会再执行。在 UDPSocket 实例被创建后将被 Native 强引用,保证其不被 GC。在 UDPSocket.close 后 + * 将解除对其的强引用,让 UDPSocket 实例遵从 GC。 + */ + close(): void; + + /** + * 设置监听关闭事件回调 + * @param callback 关闭事件的回调函数 + */ + onClose(callback: () => void): void; + + /** + * 清除监听关闭事件回调 + * @param callback 之前监听的函数 + */ + offClose(callback: () => void): void; + + /** + * 监听错误事件 + * @param callback 错误回调函数 + */ + onError(callback: (res: { + /** + * 错误信息 + */ + errMsg: string; + }) => void): void; + + /** + * 取消监听错误事件 + * @param callback 之前设置的错误回调函数 + */ + offError(callback: (res: { + /** + * 错误信息 + */ + errMsg: string; + }) => void): void; + + /** + * 监听开始监听数据包消息的事件 + * @param callback 回调函数 + */ + onListening(callback: () => void): void; + + /** + * 取消监听开始监听数据包消息的事件 + * @param callback 之前设置的回调函数 + */ + offListening(callback: () => void): void; + + /** + * 监听收到消息的事件 + * @param callback 回调函数 + */ + onMessage(callback: (res: wx.types.UDPMessage) => void): void; + + /** + * 取消监听收到消息的事件 + * @param callback 之前设置的回调函数 + */ + offMessage(callback: (res: wx.types.UDPMessage) => void): void; +} + +declare class UploadTask { + /** + * 中断上传任务 + */ + abort(): void; + /** + * 监听上传进度变化事件 + * @param callback.res.progress 上传进度百分比 + * @param callback.res.totalBytesSent 已经上传的数据长度,单位 Bytes + * @param callback.res.totalBytesExpectedToSend 预期需要上传的数据总长度,单位 Bytes + */ + onProgressUpdate(callback: (res: { progress: number, totalBytesSent: number, totalBytesExpectedToSend: number }) => void): void; +} + +declare class KVData { + key: string; + value: string; +} + +declare class UserGameData { + /** + * 用户的微信头像 url + */ + avatarUrl: string; + /** + * 用户的微信昵称 + */ + nickname: string; + /** + * 用户的openid + */ + openid: string; + /** + * 用户的托管 KV 数据列表 + */ + KVDataList: ReadonlyArray; +} + +declare class CreatedButton { + type: wx.types.ButtonType; + text: string; + image: string; + style: wx.types.ButtonStyle; + show(): void; + hide(): void; + onTap(callback: (res?: any) => void): void; // res参数会被具体按钮的API定义覆盖为具体信息 + offTap(callback: (res?: any) => void): void; + destroy(): void; +} +declare class UserInfoButton extends CreatedButton { + onTap(callback: (res: { + /** + * 用户信息对象,不包含 openid 等敏感信息 + */ + userInfo: wx.types.UserInfo, + /** + * 不包括敏感信息的原始数据字符串,用于计算签名 + */ + rawData: string, + /** + * 使用 sha1( rawData + sessionkey ) 得到字符串,用于校验用户信息,参考文档signature(https://mp.weixin.qq.com/debug/wxagame/dev/tutorial/open-ability/http-signature.html?t=201822) + */ + signature: string, + /** + * 包括敏感数据在内的完整用户信息的加密数据,详见加密数据解密算法(https://mp.weixin.qq.com/debug/wxagame/dev/tutorial/open-ability/signature.html?t=201822) + */ + encryptedData: string, + /** + * 加密算法的初始向量,详见加密数据解密算法(https://mp.weixin.qq.com/debug/wxagame/dev/tutorial/open-ability/signature.html?t=201822) + */ + iv: string, + errMsg: string + }) => void): void; +} +declare class OpenSettingButton extends CreatedButton { + onTap(callback: () => void): void; + offTap(callback: () => void): void; +} +declare class GameClubButton extends CreatedButton { + icon: wx.types.GameClubButtonIcon; + onTap(callback: (res: { + errMsg: string; + }) => void): void; +} +declare class FeedbackButton extends CreatedButton { + onTap(callback: (res: { + errMsg: string; + }) => void): void; +} + +declare class OpenDataContext { + /** + * 开放数据域和主域共享的 sharedCanvas,注意在开放数据域内时getContext只能使用2d模式 + */ + canvas: Canvas; + /** + * 向开放数据域发送消息 + * @param message 要发送的消息,message 中及嵌套对象中 key 的 value 只能是 primitive value。即 number、string、boolean、null、undefined。 + */ + postMessage(message: any): void; +} + +declare class LoadSubpackageTask { + /** + * 监听分包加载进度变化事件 + * @param callback.res.progress 分包下载进度百分比 + * @param callback.res.totalBytesWritten 已经下载的数据长度,单位 Bytes + * @param callback.res.totalBytesExpectedToWrite 预期需要下载的数据总长度,单位 Bytes + */ + onProgressUpdate(callback: (res: { progress: number, totalBytesWritten: number, totalBytesExpectedToWrite: number }) => void): void; +} + +declare class UpdateManager { + /** + * 应用更新包并重启 + */ + applyUpdate(): void; + /** + * 监听检查更新结果回调 + */ + onCheckForUpdate(callback: () => void): void; + /** + * 监听更新包下载成功回调 + */ + onUpdateReady(callback: () => void): void; + /** + * 监听更新包下载失败回调 + */ + onUpdateFailed(callback: () => void): void; +} + +declare class WxWorker { + /** + * 向主线程或Worker线程发送的消息。 + * @param message 需要发送的消息,必须是一个可序列化的 JavaScript 对象。 + */ + postMessage(message: any): void; + /** + * 结束当前 worker 线程,仅限在主线程 worker 对象上调用。 + */ + terminate(): void; + /** + * 监听接收主线程/Worker 线程向当前线程发送的消息 + * @param callback.res.message 接收主线程/Worker 线程向当前线程发送的消息 + */ + onMessage(callback: (res: { message: any }) => void): void; +} + +/** + * InnerAudioContext 实例,可通过 wx.createInnerAudioContext 接口获取实例。 + */ +declare class InnerAudioContext { + /** + * 音频资源的地址 + */ + src: string; + /** + * 是否自动播放 + */ + autoplay: boolean; + /** + * 是否循环播放 + */ + loop: boolean; + /** + * 是否遵循系统静音开关,当此参数为 false 时,即使用户打开了静音开关,也能继续发出声音 + */ + obeyMuteSwitch: boolean; + /** + * 当前音频的长度,单位 s。只有在当前有合法的 src 时返回 + */ + readonly duration: number; + /** + * 当前音频的播放位置,单位 s。只有在当前有合法的 src 时返回,时间不取整,保留小数点后 6 位 + */ + readonly currentTime: number; + /** + * 当前是是否暂停或停止状态,true 表示暂停或停止,false 表示正在播放 + */ + paused: boolean; + /** + * 音频缓冲的时间点,仅保证当前播放时间点到此时间点内容已缓冲 + */ + readonly buffered: number; + /** + * 音量。范围 0~1。 + */ + volume: number; + + /** + * 播放 + */ + play(): void; + /** + * 暂停。暂停后的音频再播放会从暂停处开始播放 + */ + pause(): void; + /** + * 停止。停止后的音频再播放会从头开始播放。 + */ + stop(): void; + /** + * 跳转到指定位置,单位 s + * @param position 跳转的时间 + */ + seek(position: number): void; + /** + * 销毁当前实例 + */ + destroy(): void; + /** + * 监听音频进入可以播放状态的事件 + */ + onCanplay(callback: () => void): void; + /** + * 取消监听音频进入可以播放状态的事件 + */ + offCanplay(callback: () => void): void; + /** + * 监听音频播放事件 + */ + onPlay(callback: () => void): void; + /** + * 取消监听音频播放事件 + */ + offPlay(callback: () => void): void; + /** + * 监听音频暂停事件 + */ + onPause(callback: () => void): void; + /** + * 取消监听音频暂停事件 + */ + offPause(callback: () => void): void; + /** + * 监听音频停止事件 + */ + onStop(callback: () => void): void; + /** + * 取消监听音频停止事件 + */ + offStop(callback: () => void): void; + /** + * 监听音频自然播放至结束的事件 + */ + onEnded(callback: () => void): void; + /** + * 取消监听音频自然播放至结束的事件 + */ + offEnded(callback: () => void): void; + /** + * 监听音频播放进度更新事件 + */ + onTimeUpdate(callback: () => void): void; + /** + * 取消监听音频播放进度更新事件 + */ + offTimeUpdate(callback: () => void): void; + /** + * 监听音频播放错误事件 + */ + onError(callback: () => void): void; + /** + * 取消监听音频播放错误事件 + */ + offError(callback: () => void): void; + /** + * 监听音频加载中事件,当音频因为数据不足,需要停下来加载时会触发 + */ + onWaiting(callback: () => void): void; + /** + * 取消监听音频加载中事件,当音频因为数据不足,需要停下来加载时会触发 + */ + offWaiting(callback: () => void): void; + /** + * 监听音频进行跳转操作的事件 + */ + onSeeking(callback: () => void): void; + /** + * 取消监听音频进行跳转操作的事件 + */ + offSeeking(callback: () => void): void; + /** + * 监听音频完成跳转操作的事件 + */ + onSeeked(callback: () => void): void; + /** + * 取消监听音频完成跳转操作的事件 + */ + offSeeked(callback: () => void): void; +} + +declare class RecorderManager { + /** + * 开始录音 + */ + start(param: { + /** + * 录音的时长,单位 ms,最大值 600000(10 分钟),默认值60000(1 分钟) + */ + duration?: number, + /** + * 采样率 + */ + sampleRate: 8000 | 11025 | 12000 | 16000 | 22050 | 24000 | 32000 | 44100 | 48000, + /** + * 录音通道数 + */ + numberOfChannels: 1 | 2, + /** + * 编码码率 + */ + encodeBitRate: number, + /** + * 音频格式 + */ + format: "mp3" | "aac", + /** + * 指定帧大小,单位 KB。传入 frameSize 后,每录制指定帧大小的内容后,会回调录制的文件内容,不指定则不会回调 + */ + frameSize: number, + /** + * 指定录音的音频源,可通过 wx.getAvailableAudioSources() 获取当前可用的音频源,默认值auto + */ + audioSource?: wx.types.AudioSourceType + }): void; + /** + * 暂停录音 + */ + pause(): void; + /** + * 继续录音 + */ + resume(): void; + /** + * 停止录音 + */ + stop(): void; + /** + * 监听录音开始事件 + */ + onStart(callback: () => void): void; + /** + * 监听录音继续事件 + */ + onResume(callback: () => void): void; + /** + * 监听录音暂停事件 + */ + onPause(callback: () => void): void; + /** + * 监听录音结束事件 + * @param callback.res.tempFilePath 录音文件的临时路径 + */ + onStop(callback: (res: { tempFilePath: string }) => void): void; + /** + * 监听已录制完指定帧大小的文件事件。如果设置了 frameSize,则会回调此事件。 + * @param callback.res.frameBuffer 录音分片数据 + * @param callback.res.isLastFrame 当前帧是否正常录音结束前的最后一帧 + */ + onFrameRecorded(callback: (res: { frameBuffer: ArrayBuffer, isLastFrame: boolean }) => void): void; + /** + * 监听录音错误事件 + */ + onError(callback: (res: { errMsg: string }) => void): void; +} + +declare class ImageFile { + /** + * 本地文件路径 + */ + path: string; + /** + * 本地文件大小,单位 B + */ + size: number; +} + +declare class Video { + /** + * 视频的左上角横坐标 + */ + x: number; + /** + * 视频的左上角纵坐标 + */ + y: number; + /** + * 视频的宽度,默认值300 + */ + width: number; + /** + * 默认值150 + */ + height: number; + /** + * 视频的资源地址 + */ + src: string; + /** + * 视频的封面 + */ + poster: string; + /** + * 视频的初始播放位置,单位为 s 秒,默认值0 + */ + initialTime: number; + /** + * 视频的播放速率,有效值有 0.5、0.8、1.0、1.25、1.5默认值1.0 + */ + playbackRate: number; + /** + * 视频是否为直播,默认值0 + */ + live?: number; + /** + * 视频的缩放模式 + * fill - 填充,视频拉伸填满整个容器,不保证保持原有长宽比例 + * contain - 包含,保持原有长宽比例。保证视频尺寸一定可以在容器里面放得下。因此,可能会有部分空白 + * cover - 覆盖,保持原有长宽比例。保证视频尺寸一定大于容器尺寸,宽度和高度至少有一个和容器一致。因此,视频有部分会看不见 + */ + objectFit: "contain" | "cover" | "fill"; + /** + * 视频是否显示控件,默认true + */ + controls: boolean; + /** + * 视频是否自动播放,默认false + */ + autoplay: boolean; + /** + * 视频是否是否循环播放,默认值false + */ + loop: boolean; + /** + * 视频是否禁音播放,默认值false + */ + muted: boolean; + + /** + * 视频开始缓冲时触发的回调函数 + */ + onwaiting: () => void; + /** + * 视频开始播放时触发的回调函数 + */ + onplay: () => void; + /** + * 视频暂停时触发的回调函数 + */ + onpause: () => void; + /** + * 视频播放到末尾时触发的回调函数 + */ + onended: () => void; + /** + * 每当视频播放进度更新时触发的回调函数 + */ + ontimeupdate: () => void; + /** + * 视频发生错误时触发的回调函数 + */ + onerror: () => void; + + /** + * 销毁视频 + */ + destroy(): void; + /** + * 监听视频缓冲事件 + */ + onWaiting(callback: () => void): void; + /** + * 取消监听视频缓冲事件 + */ + offWaiting(callback: () => void): void; + + /** + * 监听视频播放事件 + */ + onPlay(callback: () => void): void; + /** + * 取消监听视频播放事件 + */ + offPlay(callback: () => void): void; + /** + * 监听视频暂停事件 + */ + onPause(callback: () => void): void; + /** + * 取消监听视频暂停事件 + */ + offPause(callback: () => void): void; + /** + * 监听视频播放到末尾事件 + */ + onEnded(callback: () => void): void; + /** + * 取消监听视频播放到末尾事件 + */ + offEnded(callback: () => void): void; + /** + * 监听视频播放进度更新事件 + * @param callback.res.position 当前的播放位置,单位为秒 + * @param callback.res.duration 视频的总时长,单位为秒 + */ + onTimeUpdate(callback: (res: { position: number, duration: number }) => void): void; + /** + * 取消监听视频播放进度更新事件 + */ + offTimeUpdate(callback: (res: { position: number, duration: number }) => void): void; + /** + * 监听视频错误事件 + * @param callback.res.errMsg 错误信息,有如下值 + * MEDIA_ERR_NETWORK - 当下载时发生错误 + * MEDIA_ERR_DECODE - 当解码时发生错误 + * MEDIA_ERR_SRC_NOT_SUPPORTED - video 的 src 属性是不支持的资源类型 + */ + onError(callback: (res: { errMsg: string }) => void): void; + /** + * 取消监听视频错误事件 + */ + offError(callback: (res: { errMsg: string }) => void): void; + + /** + * 播放视频 + */ + play(): Promise; + /** + * 暂停视频 + */ + pause(): Promise; + /** + * 停止视频 + */ + stop(): Promise; + /** + * 视频跳转 + * @param time 视频跳转到指定位置,单位为 s 秒 + */ + seek(time: number): Promise; + + /** + * 视频全屏 + */ + requestFullScreen(): Promise; + + /** + * 视频退出全屏 + */ + exitFullScreen(): Promise; +} +/** + * 相机对象 + */ +declare class Camera { + /** + * 相机的左上角横坐标 + */ + x: number; + + /** + * 相机的左上角纵坐标 + */ + y: number; + + /** + * 相机的宽度 + */ + width: number; + + /** + * 相机的高度 + */ + height: number; + + /** + * 摄像头朝向 + */ + devicePosition: "front" | "back"; + + /** + * 闪光灯状态 + */ + flash: "auto" | "on" | "off"; + + /** + * 帧数据图像尺寸 + */ + size: "small" | "medium" | "large"; + + /** + * 拍照,可指定质量,成功则返回图片 + * @param quality 图片质量 + */ + takePhoto(quality?: "high" | "normal" | "low"): Promise<{ + /** + * 临时图片路径 + */ + tempImagePath: string, + /** + * 图片宽度 + */ + width: string, + /** + * 图片高度 + */ + height: string + }>; + + /** + * 开始录像 + */ + startRecord(): Promise; + + /** + * 结束录像,成功则返回封面与视频 + * @param compressed 是否压缩录制视频 + */ + stopRecord(compressed: boolean): Promise<{ + /** + * 临时视频路径 + */ + tempThumbPath: string, + /** + * 临时封面路径 + */ + tempVideoPath: string + }>; + + /** + * 监听用户不允许授权使用摄像头的情况 + * @param callback 回调函数 + */ + onAuthCancel(callback: () => void): void; + + /** + * 监听摄像头非正常终止事件,如退出后台等情况 + * @param callback 回调函数 + */ + onStop(callback: () => void): void; + + /** + * 监听摄像头实时帧数据 + */ + onCameraFrame(callback: (res: { + /** + * 图像数据矩形的宽度 + */ + width: number, + /** + * 图像数据矩形的高度 + */ + height: number, + /** + * 图像像素点数据,一维数组,每四项表示一个像素点的 rgba + */ + data: ArrayBuffer + }) => void): void; + + /** + * 开启监听帧数据 + */ + listenFrameChange(): void; + + /** + * 关闭监听帧数据 + */ + closeFrameChange(): void; + + /** + * 销毁相机 + */ + destroy(): void; +} +/** + * banner 广告组件。banner 广告组件是一个原生组件,层级比上屏 Canvas 高,会覆盖在上屏 Canvas 上。banner 广告组件默认是隐藏的,需要调用 BannerAd.show() 将其显示。banner 广告会根据开发者设置的宽度进行等比缩放,缩放后的尺寸将通过 BannerAd.onResize() 事件中提供。 + */ +declare class BannerAd { + /** + * 广告单元 id + */ + adUnitId: string; + /** + * banner 广告组件的样式。style 上的属性的值仅为开发者设置的值,banner 广告会根据开发者设置的宽度进行等比缩放,缩放后的真实尺寸需要通过 BannerAd.onResize() 事件获得。 + */ + style: wx.types.AdStyle; + + /** + * 显示 banner 广告。 + */ + show(): Promise; + /** + * 隐藏 banner 广告 + */ + hide(): void; + /** + * 销毁 banner 广告 + */ + destroy(): void; + /** + * 监听 banner 广告缩放 + */ + onResize(callback: (res: { width: number, height: number }) => void): void; + /** + * 取消监听隐藏 banner 广告缩放 + */ + offResize(callback: (res: { width: number, height: number }) => void): void; + /** + * 监听banner 广告加载事件 + */ + onLoad(callback: () => void): void; + /** + * 取消监听banner 广告加载事件 + */ + offLoad(callback: () => void): void; + /** + * 监听banner 广告错误事件 + */ + onError(callback: (res: { errMsg: string }) => void): void; + /** + * 取消监听banner 广告错误事件 + */ + offError(callback: (res: { errMsg: string }) => void): void; +} + +declare class InterstitialAd extends BannerAd { + /** + * 加载视频广告 + */ + load(): Promise; + /** + * 监听用户点击 关闭广告 按钮的事件 + */ + onClose(callback: (res: { isEnded: boolean }) => void): void; + /** + * 监听用户点击 关闭广告 按钮的事件 + */ + offClose(callback: (res: { isEnded: boolean }) => void): void; +} + +declare class RewardedVideoAd extends InterstitialAd { +} + +// --定时器 +declare function clearTimeout(timeoutID: number): void; +declare function clearInterval(intervalID: number): void; +declare function setTimeout(fn: () => void, delay: number, ...rest: any[]): number; +declare function setInterval(fn: () => void, delay: number, ...rest: any[]): number; + +// --渲染 +declare function cancelAnimationFrame(requestID: number): void; +declare function requestAnimationFrame(callback: () => void): number; + +declare namespace wx { + namespace types { + interface Callbacks { + success?: () => void; + fail?: () => void; + complete?: () => void; + } + + interface CallbacksWithType { + success?: (res: T) => void; + fail?: () => void; + complete?: () => void; + } + + interface CallbacksWithType2 { + success?: (res: T) => void; + fail?: (res: F) => void; + complete?: () => void; + } + + interface RenderingContextConfig { + /** + * 表示是否抗锯齿 + */ + antialias?: boolean; + /** + * 表示是否绘图完成后是否保留绘图缓冲区 + */ + preserveDrawingBuffer?: boolean; + /** + * 抗锯齿样本数。最小值为 2,最大不超过系统限制数量,仅 iOS 支持 + */ + antialiasSamples?: number; + } + + interface ToTempFileSyncParams { + /** + * 截取 canvas 的左上角横坐标 + */ + x?: number; + /** + * 截取 canvas 的左上角纵坐标 + */ + y?: number; + /** + * 截取 canvas 的宽度 + */ + width?: number; + /** + * 截取 canvas 的高度 + */ + height?: number; + /** + * 目标文件的宽度,会将截取的部分拉伸或压缩至该数值 + */ + destWidth?: number; + /** + * 目标文件的高度,会将截取的部分拉伸或压缩至该数值 + */ + destHeight?: number; + /** + * 目标文件的类型 + */ + fileType?: "jpg" | "png"; + /** + * jpg图片的质量,仅当 fileType 为 jpg 时有效。取值范围为 0.0(最低)- 1.0(最高),不含 0。不在范围内时当作 1.0 + */ + quality?: number; + } + + interface ToTempFileParams extends ToTempFileSyncParams { + success?: (res: { tempFilePath: string }) => void; + fail?: () => void; + complete?: () => void; + } + + interface RenameParams { + oldPath: string; + newPath: string; + success?: () => void; + fail?: (res: { errMsg: string }) => void; + complete?: () => void; + } + + interface RmdirParams { + dirPath: string; + recursive?: boolean; + success?: () => void; + fail?: (res: { errMsg: string }) => void; + complete?: () => void; + } + + interface ReaddirParams { + dirPath: string; + success?: (res: { files: ReadonlyArray }) => void; + fail?: (res: { errMsg: string }) => void; + complete?: () => void; + } + + interface MkdirParams { + dirPath: string; + recursive?: boolean; + success?: () => void; + fail?: (res: { errMsg: string }) => void; + complete?: () => void; + } + + type FileContentEncoding = "ascii" | "base64" | "binary" | "hex" | "ucs2" | "ucs-2" | "utf16le" | "utf-16le" | "utf-8" | "utf8" | "latin1"; + + interface ReadfileParams { + filePath: string; + encoding?: FileContentEncoding; + success?: (res: { data: string | ArrayBuffer }) => void; + fail?: (res: { errMsg: string }) => void; + complete?: () => void; + } + + interface StatParams { + path: string; + success?: (res: { stat: Stats }) => void; + fail?: (res: { errMsg: string }) => void; + complete?: () => void; + } + + interface WritefileParams { + filePath: string; + data: string | ArrayBuffer; + encoding?: FileContentEncoding; + success?: () => void; + fail?: (res: { errMsg: string }) => void; + complete?: () => void; + } + + interface UnlinkParams { + filePath: string; + success?: () => void; + fail?: (res: { errMsg: string }) => void; + complete?: () => void; + } + + interface UnzipParams { + zipFilePath: string; + targetPath: string; + success?: () => void; + fail?: (res: { errMsg: string }) => void; + complete?: () => void; + } + + interface AccessfileParams { + path: string; + success?: () => void; + fail?: (res: { errMsg: string }) => void; + complete?: () => void; + } + + interface SavedfileList { + fileList: { + filePath: string; + size: number; + createTime: number; + }; + } + + interface CopyfileParams { + srcPath: string; + destPath: string; + success?: () => void; + fail?: (res: { errMsg: string }) => void; + complete?: () => void; + } + + interface FileinfoParams { + filePath: string; + success?: (res: { size: number, digest: string }) => void; + fail?: (res: { errMsg: string }) => void; + complete?: () => void; + } + + interface RemovefileParams { + filePath: string; + success?: () => void; + fail?: () => void; + complete?: () => void; + } + + interface SavefileParams { + tempFilePath: string; + filePath?: string; + success?: (res: { savedFilePath: string }) => void; + fail?: (res: { errMsg: string }) => void; + complete?: () => void; + } + + interface AppendfileParams { + filePath: string; + data: string | ArrayBuffer; + encoding?: FileContentEncoding; + success?: () => void; + fail?: (res: { errMsg: string }) => void; + complete?: () => void; + } + + interface LineHeightParams { + fontStyle?: "normal" | "italic"; + fontWeight?: "normal" | "bold"; + fontSize?: number; + fontFamily: string; + text: string; + success?: (res: { lineHeight: number }) => void; + fail?: () => void; + complete?: () => void; + } + + interface Image { + src: string; + width: number; + height: number; + onload: () => void; + onerror: (e?: any) => void; + } + + // --启动参数 + interface LaunchOption { + /** + * 场景值 + */ + scene: number; + /** + * 启动参数 + */ + query: any; + /** + * 当前小游戏是否被显示在聊天顶部 + */ + isSticky: boolean; + /** + * 票据 + */ + shareTicket: string; + } + + // --系统信息 + interface SystemInfo { + /** + * 手机品牌 + */ + brand: string; + /** + * 手机型号 + */ + model: string; + /** + * 设备像素比 + */ + pixelRatio: number; + /** + * 屏幕宽度 + */ + screenWidth: number; + /** + * 屏幕高度 + */ + screenHeight: number; + /** + * 可使用窗口宽度 + */ + windowWidth: number; + /** + * 可使用窗口高度 + */ + windowHeight: number; + /** + * 微信设置的语言 + */ + language: string; + /** + * 微信版本号 + */ + version: string; + /** + * 操作系统版本 + */ + system: string; + /** + * 客户端平台 + */ + platform: string; + /** + * 用户字体大小设置。以“我-设置-通用-字体大小”中的设置为准,单位 px。 + */ + fontSizeSetting: string; + /** + * 客户端基础库版本 + */ + SDKVersion: string; + /** + * 性能等级 + */ + benchmarkLevel: number; + /** + * 电量,范围 1 - 100 + */ + battery: number; + /** + * wifi 信号强度,范围 0 - 4 + */ + wifiSignal: number; + } + + // --触摸对象 + interface Touch { + /** + * Touch 对象的唯一标识符,只读属性。一次触摸动作(我们值的是手指的触摸)在平面上移动的整个过程中, 该标识符不变。可以根据它来判断跟踪的是否是同一次触摸过程。 + */ + identifier: number; + /** + * 触点相对于整体页面的 X 轴距离。 + */ + pageX: number; + /** + * 触点相对于整体页面的 Y 轴距离。 + */ + pageY: number; + /** + * 触点相对于游戏窗口的 X 轴距离。 + */ + clientX: number; + /** + * 触点相对于游戏窗口的 Y 轴距离。 + */ + clientY: number; + } + + interface TouchData { + /** + * 当前事件的类型 + */ + type: string; + /** + * 当前所有触摸点的列表 + */ + touches: ReadonlyArray; + /** + * 触发此次事件的触摸点列表 + */ + changedTouches: ReadonlyArray; + /** + * 事件触发时的时间戳 + */ + timeStamp: number; + } + + // --iBeacon(TODO) + /** + * 停止搜索附近的 iBeacon 设备 + */ + function stopBeaconDiscovery(param: any): void; + /** + * 开始搜索附近的 iBeacon 设备 + */ + function startBeaconDiscovery(param: any): void; + /** + * 监听 iBeacon 设备更新事件,仅能注册一个监听 + */ + function onBeaconUpdate(callback: any): void; + /** + * 监听 iBeacon 服务状态变化事件,仅能注册一个监听 + */ + function onBeaconServiceChange(callback: any): void; + /** + * 取消监听 iBeacon 设备更新事件 + */ + function offBeaconUpdate(callback: any): void; + /** + * 取消监听 iBeacon 服务状态变化事件 + */ + function offBeaconServiceChange(callback: any): void; + /** + * 获取所有已搜索到的 iBeacon 设备 + */ + function getBeacons(param: any): void; + /* + IBeaconInfo + 属性 + string uuid + iBeacon 设备广播的 uuid + string major + iBeacon 设备的主 id + string minor + iBeacon 设备的次 id + number proximity + 表示设备距离的枚举值 + number accuracy + iBeacon 设备的距离 + number rssi + 表示设备的信号强度 + */ + + // --低功耗蓝牙(TODO) + function writeBLECharacteristicValue(): void; + function readBLECharacteristicValue(): void; + function onBLEConnectionStateChange(): void; + function onBLECharacteristicValueChange(): void; + function notifyBLECharacteristicValueChange(): void; + function getBLEDeviceServices(): void; + function getBLEDeviceCharacteristics(): void; + function createBLEConnection(): void; + function closeBLEConnection(): void; + + // --蓝牙(TODO) + function stopBluetoothDevicesDiscovery(): void; + function startBluetoothDevicesDiscovery(): void; + function openBluetoothAdapter(): void; + function onBluetoothDeviceFound(): void; + function onBluetoothAdapterStateChange(): void; + function getConnectedBluetoothDevices(): void; + function getBluetoothDevices(): void; + function getBluetoothAdapterState(): void; + function closeBluetoothAdapter(): void; + + // --电量 + interface BatteryInfo { + /** + * 设备电量,范围 1 - 100 + */ + level: string; + /** + * 是否正在充电 + */ + isCharging: boolean; + } + + // --剪切板 + interface ClipboardData { + data: string; + } + + interface SetClipboardDataParams { + success?: () => void; + fail?: () => void; + complete?: () => void; + data: string; + } + + interface SetKeepScreenOnParams { + success?: () => void; + fail?: () => void; + complete?: () => void; + keepScreenOn: boolean; + } + + interface SetScreenBrightnessParams { + success?: () => void; + fail?: () => void; + complete?: () => void; + /** + * 屏幕亮度值,范围 0 ~ 1,0 最暗,1 最亮 + */ + value: number; + } + + interface DownfileParams { + url: string; + /** + * 在指定filePath之后success回调中将不会有res.tempFilePath路径值,下载的文件会直接写入filePath指定的路径(有写入权限的情况下,根目录请使用wx.env.USER_DATA_PATH,路径文件夹必须存在,否则写入失败) + */ + filePath?: string; + /** + * HTTP 请求的 Header,Header 中不能设置 Referer + */ + header?: { [key: string]: string }; + /** + * res.tempFilePath 临时文件路径。如果没传入 filePath 指定文件存储路径,则下载后的文件会存储到一个临时文件 + * res.statusCode 开发者服务器返回的 HTTP 状态码 + */ + success?: (res: { tempFilePath?: string, statusCode: number }) => void; + fail?: (res: { errMsg: string }) => void; + complete?: () => void; + } + + type NetworkType = "wifi" | "2g" | "3g" | "4g" | "any" | "none"; + + type RequestMethod = "GET" | "HEAD" | "POST" | "PUT" | "DELETE" | "TRACE" | "CONNECT"; + + interface RequestParams { + /** + * 开发者服务器接口地址 + */ + url: string; + /** + * 请求的参数 + */ + data?: string | { [key: string]: any }; + /** + * 设置请求的 header,header 中不能设置 Referer + */ + header?: { [name: string]: string }; + /** + * HTTP 请求方法 + */ + method?: RequestMethod; + /** + * 返回的数据格式 + */ + dataType?: "json" | "arraybuffer"; + /** + * res.data usually can be string or ArrayBuffer + */ + success?: (res: { data: any, statusCode: number, header?: { [key: string]: string } }) => void; + fail?: () => void; + complete?: () => void; + } + + interface SocketSendParams { + data: string | ArrayBuffer; + success?: () => void; + fail?: () => void; + complete?: () => void; + } + interface SocketConnectParams { + url: string; + protocols?: string[]; + header?: { [key: string]: string }; + method?: RequestMethod; + success?: () => void; + fail?: () => void; + complete?: () => void; + } + interface SocketCloseParams { + /** + * 一个数字值表示关闭连接的状态号,表示连接被关闭的原因。如果这个参数没有被指定,默认的取值是1000 (表示正常连接关闭) + */ + code?: number; + /** + * 一个可读的字符串,表示连接被关闭的原因。这个字符串必须是不长于123字节的UTF-8 文本(不是字符) + */ + reason?: string; + success?: () => void; + fail?: () => void; + complete?: () => void; + } + + type SocketOpenCallback = (res: { header?: { [key: string]: string } }) => void; + type SocketMessageCallback = (res: { data: string | ArrayBuffer }) => void; + type SocketErrorCallback = (res: { errMsg: string }) => void; + + interface UDPSendParams { + /** + * 要发消息的地址。可以是一个和本机同网段的 IP 地址,也可以是在安全域名列表内的域名地址 + */ + address: string; + /** + * 要发送消息的端口号 + */ + port: number; + /** + * 要发送的数据 + */ + message: string | ArrayBuffer; + /** + * 发送数据的偏移量,仅当 message 为 ArrayBuffer 类型时有效,默认值0 + */ + offset?: number; + /** + * 发送数据的长度,仅当 message 为 ArrayBuffer 类型时有效,默认值message.byteLength + */ + length?: number; + } + interface UDPMessage { + /** + * 收到的消息 + */ + message: ArrayBuffer; + /** + * 消息来源的结构化信息 + */ + remoteInfo: { + /** + * 发送消息的 socket 的地址 + */ + address: string; + /** + * 使用的协议族,为 IPv4 或者 IPv6 + */ + family: string; + /** + * 端口号 + */ + port: number; + /** + * message 的大小,单位:字节 + */ + size: number; + }; + } + + /** + * wx.getUserInfo的旧版本API参数,随时会被删除,不推荐使用 + */ + interface OldUserInfoParam { + /** + * 是否带上登录态信息。当 withCredentials 为 true 时,要求此前有调用过 wx.login 且登录态尚未过期,此时返回的数据会包含 encryptedData, iv 等敏感信息;当 withCredentials 为 false 时,不要求有登录态,返回的数据不包含 encryptedData, iv 等敏感信息。 + */ + withCredentials?: boolean; + /** + * 显示用户信息的语言 + */ + lang?: "en" | "zh_CN" | "zh_TW"; + success?: (res: { + /** + * 用户信息对象,不包含 openid 等敏感信息 + */ + userInfo: UserInfo, + /** + * 不包括敏感信息的原始数据字符串,用于计算签名 + */ + rawData: string, + /** + * 使用 sha1( rawData + sessionkey ) 得到字符串,用于校验用户信息,参考文档signature(https://mp.weixin.qq.com/debug/wxagame/dev/tutorial/open-ability/http-signature.html?t=201822) + */ + signature: string, + /** + * 包括敏感数据在内的完整用户信息的加密数据,详见加密数据解密算法(https://mp.weixin.qq.com/debug/wxagame/dev/tutorial/open-ability/signature.html?t=201822) + */ + encryptedData: string, + /** + * 加密算法的初始向量,详见加密数据解密算法(https://mp.weixin.qq.com/debug/wxagame/dev/tutorial/open-ability/signature.html?t=201822) + */ + iv: string, + errMsg: string + }) => void; + fail?: () => void; + complete?: () => void; + } + + /** + * 新版本wx.getUserInfo的参数,需要在开放数据域内调用 + */ + interface NewUserInfoParam { + /** + * 要获取信息的用户的 openId 数组,如果要获取当前用户信息,则将数组中的一个元素设为 'selfOpenId' + */ + openIdList?: string[]; + /** + * 显示用户信息的语言 + */ + lang?: "en" | "zh_CN" | "zh_TW"; + success?: (res: { data: ReadonlyArray }) => void; + fail?: () => void; + complete?: () => void; + } + + interface UserInfo { + language: string; + nickName: string; + avatarUrl: string; + /** + * 0:未知、1:男、2:女 + */ + gender: 0 | 1 | 2; + country: string; + province: string; + city: string; + } + + type ButtonType = "text" | "image"; + interface ButtonStyle { + left?: number; + top?: number; + width?: number; + height?: number; + /** + * 格式#ff0000 + */ + backgroundColor?: string; + /** + * 格式#ff0000 + */ + borderColor?: string; + borderWidth?: number; + borderRadius?: number; + textAlign?: "left" | "center" | "right"; + fontSize?: number; + lineHeight?: number; + } + + type GameClubButtonIcon = "green" | "white" | "dark" | "light"; + + // --设置 + interface AuthSetting { + /** + * 用户信息,对应接口 wx.getUserInfo + */ + "scope.userInfo"?: boolean; + /** + * 地理位置,对应接口 wx.getLocation wx.chooseLocation + */ + "scope.userLocation"?: boolean; + /** + * 通讯地址,对应接口 wx.chooseAddress + */ + "scope.address"?: boolean; + /** + * 发票抬头,对应接口 wx.chooseInvoiceTitle + */ + "scope.invoiceTitle"?: boolean; + /** + * 微信运动步数,对应接口 wx.getWeRunData + */ + "scope.werun"?: boolean; + /** + * 录音功能,对应接口 wx.startRecord + */ + "scope.record"?: boolean; + /** + * 保存到相册 wx.saveImageToPhotosAlbum, wx.saveVideoToPhotosAlbum + */ + "scope.writePhotosAlbum"?: boolean; + /** + * 摄像头 wx.camera + */ + "scope.camera"?: boolean; + } + + interface SetStorageParams { + key: string; + data: any; + success?: () => void; + fail?: () => void; + complete?: () => void; + } + interface RemoveStorageParams { + key: string; + success?: () => void; + fail?: () => void; + complete?: () => void; + } + interface GetStorageParams { + key: string; + success?: (res: { data: any }) => void; + fail?: () => void; + complete?: () => void; + } + + interface StorageInfo { + /** + * 当前 storage 中所有的 key + */ + keys: ReadonlyArray; + /** + * 当前占用的空间大小, 单位 KB + */ + currentSize: number; + /** + * 限制的空间大小,单位 KB + */ + limitSize: number; + } + + interface ShareOption { + /** + * 转发标题,不传则默认使用当前小游戏的昵称。 + */ + title?: string; + /** + * 转发显示图片的链接,可以是网络图片路径或本地图片文件路径或相对代码包根目录的图片文件路径。显示图片长宽比是 5:4 + */ + imageUrl?: string; + /** + * 查询字符串,必须是 key1=val1&key2=val2 的格式。从这条转发消息进入后,可通过 wx.getLaunchOptionsSync() 或 wx.onShow 获取启动参数中的 query。 + */ + query?: string; + } + + interface AccelerometerParams { + interval: "game" | "ui" | "normal"; + success?: () => void; + fail?: () => void; + complete?: () => void; + } + + type AudioSourceType = "auto" | "buildInMic" | "headsetMic" | "mic" | "camcorder"; + + interface AdStyle { + /** + * 广告组件的左上角横坐标 + */ + left: number; + /** + * banner 广告组件的左上角纵坐标 + */ + top: number; + /** + * banner 广告组件的宽度。最小 300,最大至 屏幕宽度(屏幕宽度可以通过 wx.getSystemInfoSync() 获取)。 + */ + width: number; + /** + * banner 广告组件的高度 + */ + height: number; + /** + * banner 广告组件经过缩放后真实的宽度 + */ + realWidth: number; + /** + * banner 广告组件经过缩放后真实的高度 + */ + realHeight: number; + } + } + + /** + * 创建一个画布对象。首次调用创建的是显示在屏幕上的画布,之后调用创建的都是离屏画布。 + */ + function createCanvas(): Canvas; + + /** + * 只有开放数据域能调用,获取主域和开放数据域共享的 sharedCanvas + */ + function getSharedCanvas(): Canvas; + + /** + * 创建一个图片对象 + */ + function createImage(): types.Image; + + /** + * 获取一行文本的行高 + * @param p 字体参数 + */ + function getTextLineHeight(p: types.LineHeightParams): number; + + /** + * 加载自定义字体文件 + * @param path 字体文件路径。可以是代码包文件路径,也可以是 wxfile:// 协议的本地文件路径。 + */ + function loadFont(path: string): string; + + /** + * 可以修改渲染帧率。默认渲染帧率为 60 帧每秒。修改后,requestAnimationFrame 的回调频率会发生改变。 + * @param fps 帧率,有效范围 1 - 60。 + */ + function setPreferredFramesPerSecond(fps: number): void; + + // --生命周期 + function exitMiniProgram(cb?: types.Callbacks): void; + function getLaunchOptionsSync(): types.LaunchOption; + function onHide(cb: () => void): void; + function offHide(cb: () => void): void; + function onShow(cb: (res: { scene: string, query: any, shareTicket: string }) => void): void; + function offShow(cb: (res: { scene: string, query: any, shareTicket: string }) => void): void; + + // --系统信息 + function getSystemInfo(cb: types.CallbacksWithType): void; + function getSystemInfoSync(): types.SystemInfo; + + /** + * 监听音频中断结束,在收到 onAudioInterruptionBegin 事件之后,小程序内所有音频会暂停,收到此事件之后才可再次播放成功 + */ + function onAudioInterruptionEnd(cb: () => void): void; + /** + * 取消监听音频中断结束,在收到 onAudioInterruptionBegin 事件之后,小程序内所有音频会暂停,收到此事件之后才可再次播放成功 + */ + function offAudioInterruptionEnd(cb: () => void): void; + /** + * 监听音频因为受到系统占用而被中断开始,以下场景会触发此事件:闹钟、电话、FaceTime 通话、微信语音聊天、微信视频聊天。此事件触发后,小程序内所有音频会暂停。 + */ + function onAudioInterruptionBegin(cb: () => void): void; + /** + * 取消监听音频因为受到系统占用而被中断开始,以下场景会触发此事件:闹钟、电话、FaceTime 通话、微信语音聊天、微信视频聊天。此事件触发后,小程序内所有音频会暂停。 + */ + function offAudioInterruptionBegin(cb: () => void): void; + /** + * 监听全局错误事件 + */ + function onError(cb: (res: { message: string, stack: string }) => void): void; + function offError(cb: (res: { message: string, stack: string }) => void): void; + + // --触摸事件 + /** + * 监听开始始触摸事件 + */ + function onTouchStart(cb: (res: types.TouchData) => void): void; + function offTouchStart(cb: (res: types.TouchData) => void): void; + /** + * 监听触点移动事件 + */ + function onTouchMove(cb: (res: types.TouchData) => void): void; + function offTouchMove(cb: (res: types.TouchData) => void): void; + /** + * 监听触摸结束事件 + */ + function onTouchEnd(cb: (res: types.TouchData) => void): void; + function offTouchEnd(cb: (res: types.TouchData) => void): void; + /** + * 监听触点失效事件 + */ + function onTouchCancel(cb: (res: types.TouchData) => void): void; + function offTouchCancel(cb: (res: types.TouchData) => void): void; + + // --加速计 + /** + * 监听加速度数据,频率:5次/秒,接口调用后会自动开始监听,可使用 wx.stopAccelerometer 停止监听。 + */ + function onAccelerometerChange(cb: (res: { x: number, y: number, z: number }) => void): void; + /** + * 开始监听加速度数据。 + */ + function startAccelerometer(cb: types.AccelerometerParams): void; + /** + * 停止监听加速度数据。 + */ + function stopAccelerometer(cb?: types.Callbacks): void; + + // --电量 + /** + * 获取设备电量。同步 API wx.getBatteryInfoSync 在 iOS 上不可用。 + */ + function getBatteryInfo(cb: types.CallbacksWithType): void; + /** + * IOS上这个同步API无法使用 + */ + function getBatteryInfoSync(): types.BatteryInfo; + + // --剪贴板 + /** + * 取得系统剪贴板的内容 + */ + function getClipboardData(cb: types.CallbacksWithType): void; + /** + * 设置系统剪贴板的内容 + */ + function setClipboardData(p: types.SetClipboardDataParams): void; + + // --罗盘 + /** + * 监听罗盘数据,频率:5 次/秒,接口调用后会自动开始监听,可使用 wx.stopCompass 停止监听。 + * @param cb.res.direction 面对的方向度数 + */ + function onCompassChange(cb: (res: { direction: number }) => void): void; + /** + * 开始监听罗盘数据 + */ + function startCompass(cb?: types.Callbacks): void; + /** + * 停止监听罗盘数据 + */ + function stopCompass(cb?: types.Callbacks): void; + + // --网络 + /** + * 获取网络类型 + */ + function getNetworkType(cb: types.CallbacksWithType<{ isConnected: boolean, networkType: types.NetworkType }>): void; + /** + * 监听网络状态变化事件 + */ + function onNetworkStatusChange(cb: (res: { + /** + * 当前是否有网络链接 + */ + isConnected: boolean, + /** + * none - 无网络, any - Android 下不常见的网络类型 + */ + networkType: types.NetworkType + }) => void): void; + + // --屏幕 + /** + * 获取屏幕亮度 + */ + function getScreenBrightness(cb: types.CallbacksWithType<{ value: number }>): void; + /** + * 设置是否保持常亮状态。仅在当前小程序生效,离开小程序后设置失效。 + */ + function setKeepScreenOn(p: types.SetKeepScreenOnParams): void; + /** + * 设置屏幕亮度 + */ + function setScreenBrightness(p: types.SetScreenBrightnessParams): void; + + // --转屏 + /** + * 监听横竖屏切换事件 + */ + function onDeviceOrientationChange(callback: (res: { value: string }) => void): void; + /** + * 取消监听横竖屏切换事件 + */ + function offDeviceOrientationChange(callback: (res: { value: string }) => void): void; + + // --设备方向 + /** + * 停止监听设备方向的变化。 + */ + function stopDeviceMotionListening(cb?: types.Callbacks): void; + /** + * 开始监听设备方向的变化 + */ + function startDeviceMotionListening(param: { + /** + * 开始监听设备方向的变化。默认值normal, + * game - 适用于更新游戏的回调频率,在 20ms/次 左右 + * ui - 适用于更新 UI 的回调频率,在 60ms/次 左右 + * normal - 普通的回调频率,在 200ms/次 左右 + */ + interval: "game" | "ui" | "normal" + } & types.Callbacks): void; + /** + * 监听设备方向变化事件。频率根据 wx.startDeviceMotionListening() 的 interval 参数。可以使用 wx.stopDeviceMotionListening() 停止监听。 + */ + function onDeviceMotionChange(callback: (res: { + /** + * 当 手机坐标 X/Y 和 地球 X/Y 重合时,绕着 Z 轴转动的夹角为 alpha,范围值为 [0, 2*PI)。逆时针转动为正。 + */ + alpha: number, + /** + * 当手机坐标 Y/Z 和地球 Y/Z 重合时,绕着 X 轴转动的夹角为 beta。范围值为 [-1*PI, PI) 。顶部朝着地球表面转动为正。也有可能朝着用户为正。 + */ + beta: number, + /** + * 当手机 X/Z 和地球 X/Z 重合时,绕着 Y 轴转动的夹角为 gamma。范围值为 [-1*PI/2, PI/2)。右边朝着地球表面转动为正。 + */ + gamma: number + }) => void): void; + /** + * 取消监听设备方向变化事件,参数为空,则取消所有的事件监听。 + * @param callback 之前添加过的监听回调函数,如果不指定,则清空所有 + */ + function offDeviceMotionChange(callback?: any): void; + + // --陀螺仪 + /** + * 停止监听陀螺仪数据 + */ + function stopGyroscope(cb?: types.Callbacks): void; + /** + * 开始监听陀螺仪数据。 + */ + function startGyroscope(param: { + /** + * 开始监听设备方向的变化。默认值normal, + * game - 适用于更新游戏的回调频率,在 20ms/次 左右 + * ui - 适用于更新 UI 的回调频率,在 60ms/次 左右 + * normal - 普通的回调频率,在 200ms/次 左右 + */ + interval: "game" | "ui" | "normal" + } & types.Callbacks): void; + /** + * 监听陀螺仪数据变化事件。频率根据 wx.startGyroscope() 的 interval 参数。可以使用 wx.stopGyroscope() 停止监听。 + * @param callback 监听函数 + */ + function onGyroscopeChange(callback: (res: { + /** + * x 轴的角速度 + */ + x: number, + /** + * y 轴的角速度 + */ + y: number, + /** + * z 轴的角速度 + */ + z: number + }) => void): void; + /** + * 取消监听陀螺仪数据变化事件。 + * @param callback 之前监听的回调函数 + */ + function offGyroscopeChange(callback: any): void; + + // --振动 + /** + * 使手机发生较短时间的振动(15 ms) + */ + function vibrateShort(cb?: types.Callbacks): void; + /** + * 使手机发生较长时间的振动(400 ms) + */ + function vibrateLong(cb?: types.Callbacks): void; + + // --文件系统 + function getFileSystemManager(): FileSystemManager; + + // --推荐弹窗 + /** + * 创建小游戏推荐弹窗组件。请通过 wx.getSystemInfoSync() 返回对象的 SDKVersion 判断基础库版本号 >= 2.7.5 后再使用该 API。每次调用该方法都会返回一个全新的实例。 + */ + function createGamePortal(param: { + /** + * 推荐单元 id + */ + adUnitId: string + }): any /* GamePortal */; // TODO: GamePortal + /** + * 创建小游戏推荐icon组件。请通过 wx.getSystemInfoSync() 返回对象的 SDKVersion 判断基础库版本号 >= 2.8.2 后再使用该 API。每次调用该方法都会返回一个全新的实例。 + */ + function createGameIcon(param: { + /** + * 推荐单元 id + */ + adUnitId: string, + /** + * 游戏icon的数量,请注意,正式版下面渲染出来的icon数量会小于等于count,请注册做好样式兼容 + */ + count: number, + /** + * 数组的每一项可以针对对应的icon设置位置和样式等信息,style的每一项称为styleItem + */ + style: ReadonlyArray<{ + /** + * 游戏名称是否隐藏 + */ + appNameHidden: boolean, + /** + * 游戏名称的颜色色值 + */ + color: string, + /** + * 游戏icon的宽高值 + */ + size: number, + /** + * 游戏icon的border尺寸 + */ + borderWidth: number, + /** + * 游戏icon的border颜色色值 + */ + borderColor: string, + /** + * 游戏icon的X轴坐标 + */ + left: number, + /** + * 游戏icon的Y轴坐标 + */ + top: number + }> + }): any /* GameIcon */; // TODO: GameIcon + /** + * 创建小游戏推荐banner组件。请通过 wx.getSystemInfoSync() 返回对象的 SDKVersion 判断基础库版本号 >= 2.7.5 后再使用该 API。每次调用该方法都会返回一个全新的实例。 + */ + function createGameBanner(param: { + /** + * 推荐单元 id + */ + adUnitId: string, + /** + * 小游戏推荐banner组件样式 + */ + style: { + /** + * 小游戏推荐banner组件左上角横坐标 + */ + left: number, + /** + * 小游戏推荐banner组件左上角纵坐标 + */ + top: number + } + }): any /* GameBanner */; // TODO: GameBanner + + // --游戏对局回放 + /** + * 获取全局唯一的游戏画面录制对象 + */ + function getGameRecorder(): any /* GameRecorder */; // TODO: GameRecorder + /** + * 创建游戏对局回放分享按钮,返回一个单例对象。按钮在被用户点击后会发起对最近一次录制完成的游戏对局回放的分享。 + */ + function createGameRecorderShareButton(): any /* GameRecorderShareButton */; // TODO: GameRecorderShareButton + + // --第三方平台 + /** + * 获取第三方平台自定义的数据字段。 + * Tips: 本接口暂时无法通过 wx.canIUse 判断是否兼容,开发者需要自行判断 wx.getExtConfig 是否存在来兼容,示例: + * if (wx.getExtConfig) { + * wx.getExtConfig({ + * success (res) { + * console.log(res.extConfig) + * } + * }) + * } + */ + function getExtConfig(callbacks: types.CallbacksWithType<{ + /** + * 第三方平台自定义的数据 + */ + extConfig: any + }>): void; + /** + * wx.getExtConfig 的同步版本。 + */ + function getExtConfigSync(): any; + + /** + * 系统环境变量 + */ + const env: { + /** + * 用户下载数据根目录 + */ + USER_DATA_PATH: string + }; + + // --位置 + /** + * 获取当前的地理位置、速度。当用户离开小程序后,此接口无法调用;当用户点击“显示在聊天顶部”时,此接口可继续调用。 + */ + function getLocation(param: { + /** + * wgs84 返回 gps 坐标,gcj02 返回可用于 wx.openLocation 的坐标 + */ + type?: "wgs84" | "gcj02", + /** + * 传入 true 会返回高度信息,由于获取高度需要较高精确度,会减慢接口返回速度 >= 1.6.0 + */ + altitude?: boolean, + success?: (res: { + /** + * 纬度,范围为 -90~90,负数表示南纬 + */ + latitude: number, + /** + * 经度,范围为 -180~180,负数表示西经 + */ + longitude: number, + /** + * 速度,单位 m/s + */ + speed: number, + /** + * 位置的精确度 + */ + accuracy: number, + /** + * 高度,单位 m + */ + altitude: number, + /** + * 垂直精度,单位 m(Android 无法获取,返回 0) + */ + verticalAccuracy: number, + /** + * 水平精度,单位 m + */ + horizontalAccuracy: number + }) => void, + fail?: () => void, + complete?: () => void + }): void; + + // --网络 + /** + * 下载文件 + */ + function downloadFile(param: types.DownfileParams): DownloadTask; + + // --发起请求 + function request(param: types.RequestParams): RequestTask; + + // --websocket + /** + * 创建一个 WebSocket 连接。最多同时存在 5 个 WebSocket 连接。 + */ + function connectSocket(param: types.SocketConnectParams): SocketTask; + /** + * 关闭WebSocket + */ + function closeSocket(param: types.SocketCloseParams): void; + /** + * 监听WebSocket 连接打开事件 + */ + function onSocketOpen(callback: types.SocketOpenCallback): void; + /** + * 监听WebSocket 连接关闭事件 + */ + function onSocketClose(callback: () => void): void; + /** + * 监听WebSocket 接受到服务器的消息事件 + */ + function onSocketMessage(callback: types.SocketMessageCallback): void; + /** + * 监听WebSocket 错误事件 + */ + function onSocketError(callback: types.SocketErrorCallback): void; + /** + * 通过 WebSocket 连接发送数据,需要先 wx.connectSocket,并在 wx.onSocketOpen 回调之后才能发送。 + */ + function sendSocketMessage(param: types.SocketSendParams): void; + + // --UDP通信 + /** + * 创建一个 UDP Socket 实例 + */ + function createUDPSocket(): UDPSocket; + + // --上传 + function uploadFile(param: { + /** + * 开发者服务器地址 + */ + url: string, + /** + * 要上传文件资源的路径 + */ + filePath: string, + /** + * 文件对应的 key,开发者在服务端可以通过这个 key 获取文件的二进制内容 + */ + name: string, + /** + * HTTP 请求 Header,Header 中不能设置 Referer + */ + header?: { [key: string]: string }, + /** + * HTTP 请求中其他额外的 form data + */ + formData?: { [key: string]: any }, + success?: (res: { data: string, statusCode: number }) => void, + fail?: () => void, + complete?: () => void + }): UploadTask; + + // --开放数据 + /** + * 拉取当前用户所有同玩好友的托管数据。该接口只可在开放数据域下使用 + */ + function getFriendCloudStorage(param: { + /** + * 要拉取的 key 列表 + */ + keyList: string[], + success?: (res: { data: ReadonlyArray }) => void, + fail?: () => void, + complete?: () => void + }): void; + /** + * 获取当前用户托管数据当中对应 key 的数据。该接口只可在开放数据域下使用 + */ + function getUserCloudStorage(param: { + /** + * 要拉取的 key 列表 + */ + keyList: string[], + success?: (res: { KVDataList: ReadonlyArray }) => void, + fail?: () => void, + complete?: () => void + }): void; + + /** + * 在无须用户授权的情况下,批量获取用户信息。该接口只在开放数据域下可用 + * 请注意!!旧版本的该接口已过期,微信不允许主动弹出授权框,旧版本API会被逐渐作废,请使用wx.createUserInfoButton或在隔离数据区取得用户信息 + * 如使用旧接口取得用户信息,withCredentials 为 true 时需要先调用 wx.login 接口。需要用户授权 scope.userInfo + */ + function getUserInfo(param: types.NewUserInfoParam | types.OldUserInfoParam): void; + /** + * 在小游戏是通过群分享卡片打开的情况下,可以通过调用该接口获取群同玩成员的游戏数据。该接口只可在开放数据域下使用。 + */ + function getGroupCloudStorage(param: { + /** + * 群分享对应的 shareTicket + */ + shareTicket: string, + /** + * 要拉取的 key 列表 + */ + keyList: string[], + success?: (res: { data: ReadonlyArray }) => void, + fail?: () => void, + complete?: () => void + }): void; + /** + * 删除用户托管数据当中对应 key 的数据。 + */ + function removeUserCloudStorage(param: { + /** + * 要删除掉 key 列表 + */ + keyList: string[], + success?: () => void, + fail?: () => void, + complete?: () => void + }): void; + /** + * 对用户托管数据进行写数据操作,允许同时写多组 KV 数据。 + * 托管数据的限制 + * > 每个openid所标识的微信用户在每个游戏上托管的数据不能超过128个key-value对。 + * > 上报的key-value列表当中每一项的key+value长度都不能超过1K(1024)字节。 + * > 上报的key-value列表当中每一个key长度都不能超过128字节。 + */ + function setUserCloudStorage(param: { + /** + * 要修改的 KV 数据列表 + */ + KVDataList: ReadonlyArray, + success?: () => void, + fail?: () => void, + complete?: () => void + }): void; + /** + * 监听成功修改好友的互动型托管数据事件,该接口在游戏主域使用 + * @param callback 事件发生的回调函数,只有一个参数为 wx.modifyFriendInteractiveStorage 传入的 key + */ + function onInteractiveStorageModified(callback: (key: string) => void): void; + /** + * 修改好友的互动型托管数据,该接口只可在开放数据域下使用,示例代码: + * wx.modifyFriendInteractiveStorage({ + * key: '1', + * opNum: 1, + * operation: 'add', + * toUser: '', // 好友的 openId + * title: '送你 10 个金币,赶快打开游戏看看吧', // 2.9.0 支持 + * imageUrl: 'image/xxx' // 2.9.0 支持 + * }); + * + * 赠送动作的校验: + * 调用该接口需要上传 JSServer 函数 "checkInteractiveData",该函数可用于执行赠送动作的校验逻辑,校验通过后返回结果表示本次赠送是否合法。只有 checkInteractiveData 返回了 {ret: true},此次修改才会成功。 + * + * 使用模板规则进行交互: + * 每次调用该接口会弹窗询问用户是否确认执行该操作,2.9.0 之后版本,需要在 game.json 中设置 modifyFriendInteractiveStorageTemplates 来定制交互的文案。 + * modifyFriendInteractiveStorageTemplates是一个模板数组,每一个模板需要有 key, action, object 参数,还有一个可选参数 ratio,详细说明见示例配置: + * { + * "modifyFriendInteractiveStorageTemplates": [ + * { + * "key": "1", // 这个 key 与接口中同名参数相对应,不同的 key 对应不同的模板 + * "action": "赠送", // 互动行为 + * "object": "金币", // 互动物品 + * "ratio": 10 // 物品比率,opNum * ratio 代表物品个数 + * } + * ] + * } + * 最后生成的文案为 "确认 ${action} ${nickname} ${object}?",或者 "确认 ${action} ${nickname} ${object} x ${opNum * ratio}?" + * + * 使用自定义文案进行交互: + * 2.7.7 之后,2.9.0 之前的版本,文案通过 game.json 的 modifyFriendInteractiveStorageConfirmWording 字段配置。 配置内容可包含 nickname 变量,用 ${nickname} 表示,实际调用时会被替换成好友的昵称。示例配置: + * { + * "modifyFriendInteractiveStorageConfirmWording": "确认送给${nickname}一个体力?" + * } + * 2.9.0 之后,在 modifyFriendInteractiveStorageTemplates 和 modifyFriendInteractiveStorageConfirmWording 都存在的情况下,会优先使用前者。 + */ + function modifyFriendInteractiveStorage(param: { + /** + * 需要修改的数据的 key,目前可以为 '1' - '50' + */ + key: string, + /** + * 需要修改的数值,目前只能为 1 + */ + opNum: number, + /** + * 修改类型 + */ + operation: "add", + /** + * 目标好友的 openId + */ + toUser?: string + /** + * 分享标题,如果设置了这个值,则在交互成功后自动询问用户是否分享给好友(需要配置模板规则) + */ + title?: string + /** + * 分享图片地址,详见 wx.shareMessageToFriend 同名参数(需要配置模板规则) + */ + imageUrl?: string, + /** + * 分享图片 ID,详见 wx.shareMessageToFriend 同名参数(需要配置模板规则) + */ + imageUrlId?: string, + /** + * 是否静默修改(不弹框),静默修改需要用户通过快捷分享消息卡片进入才有效,代表分享反馈操作,无需填写 toUser,直接修改分享者与被分享者交互数据 + * 默认值false + */ + quiet?: boolean, + success?: () => void; + fail?: (res: { + /** + * 错误信息 + */ + errMsg: string, + /** + * 错误码 + * -17006 非好友关系 + * -17007 非法的 toUser openId + * -17008 非法的 key + * -17009 非法的 operation + * -17010 非法的操作数 + * -17011 JSServer 校验写操作失败 + */ + errCode: number + }) => void; + complete?: () => void; + }): void; + /** + * 获取当前用户互动型托管数据对应 key 的数据 + */ + function getUserInteractiveStorage(param: { + /** + * 要获取的 key 列表 + */ + keyList: string[] + } & types.CallbacksWithType2<{ + /** + * 加密数据,包含互动型托管数据的值。解密后的结果为一个 KVDataList,每一项为一个 KVData。 用户数据的签名验证和加解密 + */ + encryptedData: string, + /** + * 敏感数据对应的云 ID,开通云开发的小程序才会返回,可通过云调用直接获取开放数据,详细见云调用直接获取开放数据 + */ + cloudID: string + }, { + /** + * 错误信息 + */ + errMsg: string, + /** + * 错误码 + * -17008 非法的 key + */ + errCode: number + }>): void; + /** + * 获取可能对游戏感兴趣的未注册的好友名单。每次调用最多可获得 5 个好友,此接口只能在开放数据域中使用 + */ + function getPotentialFriendList(callback: types.CallbacksWithType<{ + /** + * 可能对游戏感兴趣的未注册好友名单 + */ + list: ReadonlyArray<{ + /** + * 用户的微信头像 url + */ + avatarUrl: string, + /** + * 用户的微信昵称 + */ + nickname: string, + /** + * 用户 openid + */ + openid: string + }> + }>): void; + + // --登录 + /** + * 通过 wx.login 接口获得的用户登录态拥有一定的时效性。用户越久未使用小程序,用户登录态越有可能失效。反之如果用户一直在使用小程序,则用户登录态一直保持有效。具体时效逻辑由微信维护,对开发者透明。开发者只需要调用 wx.checkSession 接口检测当前用户登录态是否有效。登录态过期后开发者可以再调用 wx.login 获取新的用户登录态。 + */ + function checkSession(cb: types.Callbacks): void; + /** + * 调用接口获取登录凭证(code)进而换取用户登录态信息,包括用户的唯一标识(openid) 及本次登录的 会话密钥(session_key)等。用户数据的加解密通讯需要依赖会话密钥完成。 + */ + function login(cb: types.CallbacksWithType<{ + /** + * 用户登录凭证(有效期五分钟)。开发者需要在开发者服务器后台调用 code2accessToken,使用 code 换取 openid 和 session_key 等信息 + */ + code: string + }>): void; + + // --防沉迷 + /** + * 根据用户当天游戏时间判断用户是否需要休息 + */ + function checkIsUserAdvisedToRest(param: { + /** + * 今天已经玩游戏的时间,单位:秒 + */ + todayPlayedTime: number, + success?: (res: { + /** + * 是否建议用户休息 + */ + result: boolean + }) => void, + fail?: () => void, + complete?: () => void + }): void; + + // --小程序跳转 + /** + * 打开另一个小程序 + * @param param 跳转参数 + */ + function navigateToMiniProgram(param: { + /** + * 要打开的小程序 appId + */ + appId: string, + /** + * 打开的页面路径,如果为空则打开首页。path 中 ? 后面的部分会成为 query,在小程序的 App.onLaunch、App.onShow + * 和 Page.onLoad 的回调函数或小游戏的 wx.onShow 回调函数、wx.getLaunchOptionsSync 中可以获取到 query 数据。 + * 对于小游戏,可以只传入 query 部分,来实现传参效果,如:传入 "?foo=bar"。 + */ + path?: string, + /** + * 需要传递给目标小程序的数据,目标小程序可在 App.onLaunch,App.onShow 中获取到这份数据。如果跳转的是小游戏,可以在 wx.onShow、wx.getLaunchOptionsSync 中可以获取到这份数据数据。 + */ + extraData?: any, + /** + * 要打开的小程序版本。仅在当前小程序为开发版或体验版时此参数有效。如果当前小程序是正式版,则打开的小程序必定是正式版。默认值release + * develop 开发版 + * trial 体验版 + * release 正式版 + */ + envVersion?: "develop" | "trial" | "release" + } & types.Callbacks): void; + + // --用户信息 + function createUserInfoButton(param: { + /** + * 按钮类型 + */ + type: types.ButtonType, + /** + * 按钮上的文本,仅当 type 为 text 时有效 + */ + text?: string, + /** + * 按钮的背景图片,仅当 type 为 image 时有效 + */ + image?: string, + /** + * 按钮的样式 + */ + style?: types.ButtonStyle, + /** + * 是否带上登录态信息。当 withCredentials 为 true 时,要求此前有调用过 wx.login 且登录态尚未过期,此时返回的数据会包含 encryptedData, iv 等敏感信息;当 withCredentials 为 false 时,不要求有登录态,返回的数据不包含 encryptedData, iv 等敏感信息。 + */ + withCredentials?: boolean, + lang?: "en" | "zh_CN" | "zh_TW" + }): UserInfoButton; + + // --设置 + /** + * 创建打开设置页面的按钮 + */ + function createOpenSettingButton(param: { + /** + * 按钮类型 + */ + type: types.ButtonType, + /** + * 按钮上的文本,仅当 type 为 text 时有效 + */ + text?: string, + /** + * 按钮的背景图片,仅当 type 为 image 时有效 + */ + image?: string, + /** + * 按钮的样式 + */ + style?: types.ButtonStyle + }): OpenSettingButton; + /** + * 获取用户的当前设置。返回值中只会出现小程序已经向用户请求过的权限。 + */ + function getSetting(p: types.CallbacksWithType<{ authSetting: types.AuthSetting }>): void; + /** + * 调起客户端小程序设置界面,返回用户设置的操作结果。设置界面只会出现小程序已经向用户请求过的权限。 + * @deprecated + */ + function openSetting(p: types.CallbacksWithType<{ authSetting: types.AuthSetting }>): void; + + // --微信运动 + /** + * 获取用户过去三十天微信运动步数,需要先调用 wx.login 接口。需要用户授权 scope.werun。 + */ + function getWeRunData(p: types.CallbacksWithType<{ + /** + * 包括敏感数据在内的完整用户信息的加密数据,详细见加密数据解密算法 + */ + encryptedData: string, + /** + * 加密算法的初始向量 + */ + iv: string + }>): void; + + // --卡券 + /** + * 查看微信卡包中的卡券。只有通过 认证 的小程序或文化互动类目的小游戏才能使用。更多文档请参考:微信卡券接口文档(https://mp.weixin.qq.com/cgi-bin/announce?action=getannouncement&key=1490190158&version=1&lang=zh_CN&platform=2) + */ + function openCard(param: { + /** + * 需要打开的卡券列表 + */ + cardList: ReadonlyArray<{ + /** + * 卡券 ID + */ + cardId: string, + /** + * 由 wx.addCard 的返回对象中的加密 code 通过解密后得到,解密请参照:code 解码接口(https://developers.weixin.qq.com/doc/offiaccount/Cards_and_Offer/Coupons-Mini_Program_Start_Up.html) + */ + code: string + }> + } & types.CallbacksWithType): void; // TODO: success回调里的res的结构官方文档没写 + /** + * 批量添加卡券。只有通过 认证 的小程序或文化互动类目的小游戏才能使用。更多文档请参考 微信卡券接口文档(https://mp.weixin.qq.com/cgi-bin/announce?action=getannouncement&key=1490190158&version=1&lang=zh_CN&platform=2)。 + */ + function addCard(param: { + /** + * 需要添加的卡券列表 + */ + cardList: ReadonlyArray<{ + /** + * 卡券 ID + */ + cardId: string, + /** + * 卡券的扩展参数。需将 CardExt 对象 JSON 序列化为字符串传入 + */ + cardExt: string + }> + } & types.CallbacksWithType<{ + /** + * 卡券添加结果列表 + */ + cardList: ReadonlyArray<{ + /** + * 加密 code,为用户领取到卡券的code加密后的字符串,解密请参照:code 解码接口 + */ + code: string, + /** + * 用户领取到卡券的 ID + */ + cardId: string, + /** + * 卡券的扩展参数,值为一个 JSON 字符串 + */ + cardExt: string, + /** + * 是否成功 + */ + isSuccess: boolean + }> + }>): void; + + // --授权 + /** + * 提前向用户发起授权请求。调用后会立刻弹窗询问用户是否同意授权小程序使用某项功能或获取用户的某些数据,但不会实际调用对应接口。如果用户之前已经同意授权,则不会出现弹窗,直接返回成功。 + */ + function authorize(param: { + /** + * 需要获取权限的 scope + */ + scope: string, + success?: () => void, + fail?: () => void, + complete?: () => void + }): void; + + // --游戏圈 + /** + * 创建游戏圈按钮。游戏圈按钮被点击后会跳转到小游戏的游戏圈。更多关于游戏圈的信息见 游戏圈使用指南 + */ + function createGameClubButton(param: { + type: types.ButtonType, + text?: string, + image?: string, + style?: types.ButtonStyle, + /** + * 游戏圈按钮的图标,仅当 object.type 参数为 image 时有效 + */ + icon?: types.GameClubButtonIcon + }): GameClubButton; + + // --意见反馈 + /** + * 用户点击后打开意见反馈页面的按钮 + */ + function createFeedbackButton(param: { + type: types.ButtonType, + text?: string, + image?: string, + style?: types.ButtonStyle + }): FeedbackButton; + + // --客服消息 + /** + * 进入客服会话,要求在用户发生过至少一次 touch 事件后才能调用。后台接入方式与小程序一致,详见 客服消息接入 + */ + function openCustomerServiceConversation(param: { + /** + * 会话来源 + */ + sessionFrom?: string, + /** + * 是否显示会话内消息卡片,设置此参数为 true,用户进入客服会话之后会收到一个消息卡片,通过以下三个参数设置卡片的内容 + */ + showMessageCard?: boolean, + /** + * 会话内消息卡片标题 + */ + sendMessageTitle?: string, + /** + * 会话内消息卡片路径 + */ + sendMessagePath?: string, + /** + * 会话内消息卡片图片路径 + */ + sendMessageImg?: string, + success?: () => void, + fail?: () => void, + complete?: () => void + }): void; + + // --开放数据域 + /** + * 获取开放数据域 + */ + function getOpenDataContext(): OpenDataContext; + /** + * 监听主域发送的消息 + */ + function onMessage(callback: (data: any) => void): void; + + // --转发 + /** + * 获取转发详细信息 + */ + function getShareInfo(param: { + shareTicket: string, + success?: (res: { + /** + * 错误信息 + */ + errMsg: string, + /** + * 包括敏感数据在内的完整转发信息的加密数据 + */ + encryptedData: string, + /** + * 加密算法的初始向量 + */ + iv: string + }) => void, + fail?: () => void, + complete?: () => void + }): void; + /** + * 隐藏转发按钮 + */ + function hideShareMenu(cb?: types.Callbacks): void; + /** + * 监听用户点击右上角菜单的“转发”按钮时触发的事件 + */ + function onShareAppMessage(cb: () => types.ShareOption): void; + /** + * 取消监听用户点击右上角菜单的“转发”按钮时触发的事件 + */ + function offShareAppMessage(cb: () => types.ShareOption): void; + /** + * 显示当前页面的转发按钮 + */ + function showShareMenu(param?: { + /** + * 是否使用带 shareTicket 的转发 + */ + withShareTicket: boolean, + success?: () => void, + fail?: () => void, + complete?: () => void + }): void; + /** + * 主动拉起转发,进入选择通讯录界面。 + */ + function shareAppMessage(param: types.ShareOption): void; + /** + * 设置 wx.shareMessageToFriend 接口 query 字段的值 + * @param param 设置参数 + * @returns 是否设置成功 + */ + function setMessageToFriendQuery(param: { + /** + * 需要传递的代表场景的数字,需要在 0 - 50 之间 + */ + shareMessageToFriendScene: number; + }): boolean; + /** + * 给指定的好友分享游戏信息,该接口只可在开放数据域下使用 + * 定向分享不允许直接在开放数据域设置 query 参数 需要设置时请参见游戏域 wx.setMessageToFriendQuery 接口 + * @param param 分享参数 + */ + function shareMessageToFriend(param: { + /** + * 发送对象的 openId + */ + openId: string, + /** + * 转发标题,不传则默认使用当前小游戏的昵称。 + */ + title?: string, + /** + * 转发显示图片的链接,可以是网络图片路径或本地图片文件路径或相对代码包根目录的图片文件路径。显示图片长宽比是 5:4 + */ + imageUrl?: string + /** + * 审核通过的图片 ID,详见 使用审核通过的转发图片(https://developers.weixin.qq.com/minigame/dev/guide/open-ability/sh + * are/share.html#%E4%BD%BF%E7%94%A8%E5%AE%A1%E6%A0%B8%E9%80%9A%E8%BF%87%E7%9A%84%E8%BD%AC%E5%8F%91%E5%9B%BE%E7%89%87) + */ + imageUrlId?: string + }): void; + /** + * 更新转发属性 + */ + function updateShareMenu(param: { + /** + * 是否使用带 shareTicket 的转发详情 + */ + withShareTicket: boolean, + success?: () => void, + fail?: () => void, + complete?: () => void + }): void; + + // --性能 + /** + * 获取性能管理器 + */ + function getPerformance(): WxPerformance; + /** + * 加快触发 JavaScriptCore Garbage Collection(垃圾回收),GC 时机是由 JavaScriptCore 来控制的,并不能保证调用后马上触发 GC。 + */ + function triggerGC(): void; + /** + * 监听内存不足告警 + * @param callback.res.level 内存告警等级,只有 Android 才有,对应系统宏定义: + * 10 TRIM_MEMORY_RUNNING_LOW + * 15 TRIM_MEMORY_RUNNING_CRITICAL + */ + function onMemoryWarning(callback: (res: { level: number }) => void): void; + + /** + * 标记自定义场景 + * @param sceneId 在管理后台配置过的场景ID + */ + function markScene(sceneId: number): void; + + // --调试 + function setEnableDebug(p: { + enableDebug: boolean, + success?: () => void, + fail?: () => void, + complete?: () => void + }): void; + + /** + * 获取日志管理器对象 + * @param param 初始化时的参数 + */ + function getLogManager(param?: { + /** + * 取值为0或1,取值为0时会把 App、Page 的生命周期函数和 wx 命名空间下的函数调用写入日志,取值为1则不会。 + * 默认值是 0 + */ + level?: 0 | 1 + }): LogManager; + + // --数据上报 + /** + * 自定义业务数据监控上报接口。 + * 使用前,需要在「小程序管理后台-运维中心-性能监控-业务数据监控」中新建监控事件,配置监控描述与告警类型。每一个监控事件对应唯一的监控ID,开发者最多可以创建128个监控事件。 + * @param name 监控ID,在「小程序管理后台」新建数据指标后获得 + * @param value 上报数值,经处理后会在「小程序管理后台」上展示每分钟的上报总量 + */ + function reportMonitor(name: string, value: number): void; + + // --订阅消息 + /** + * 调起小游戏订阅消息界面,返回用户订阅消息的操作结果。(需要在 touchend 事件的回调中调用) + */ + function requestSubscribeMessage(param: { + /** + * 需要订阅的消息模板的id的集合(注意:iOS客户端7.0.6版本、Android客户端7.0.7版本之后的一次订阅才支持多个模板消息,iOS客户端7.0.5版本、Android客户端7.0.6版本之前的一次订阅 + * 只支持一个模板消息)消息模板id在[微信公众平台(mp.weixin.qq.com)-功能-订阅消息]中配置 + */ + tmplIds: ReadonlyArray; + } & types.CallbacksWithType2<{ + /** + * 接口调用成功时errMsg值为'requestSubscribeMessage:ok' + */ + errMsg: string; + /** + * [TEMPLATE_ID]是动态的键,即模板id,值包括'accept'、'reject'、'ban'。'accept'表示用户同意订阅该条id对应的模板消息,'reject'表示用户拒绝订阅该条id对应的模板消息,'ban'表示 + * 已被后台封禁。例如 { errMsg: "requestSubscribeMessage:ok", zun-LzcQyW-edafCVvzPkK4de2Rllr1fFpw2A_x0oXE: "accept"} 表示用户同意订阅zun-LzcQyW-edafCVvzPkK4de2Rllr1fFpw2A_x0oXE这条消息 + */ + [TEMPLATE_ID: string]: 'accept' | 'reject' | 'ban' | string; + }, { + /** + * 接口调用失败错误信息 + */ + errMsg: string; + /** + * 接口调用失败错误码 + */ + errCode: number; + }>): void; + + // --数据缓存 + /** + * 清理本地数据缓存 + */ + function clearStorage(param: types.Callbacks): void; + /** + * clearStorage的同步版本 + */ + function clearStorageSync(): void; + /** + * 从本地缓存中异步获取指定 key 的内容 + */ + function getStorage(param: types.GetStorageParams): void; + /** + * getStorage 的同步版本 + */ + function getStorageSync(key: string): any; + /** + * 异步获取当前storage的相关信息 + */ + function getStorageInfo(param: types.CallbacksWithType): void; + /** + * getStorageInfo 的同步版本 + */ + function getStorageInfoSync(): types.StorageInfo; + /** + * 从本地缓存中移除指定 key + */ + function removeStorage(param: types.RemoveStorageParams): void; + /** + * removeStorage 的同步版本 + * @param key 本地缓存中指定的 key + */ + function removeStorageSync(key: string): void; + /** + * 将数据存储在本地缓存中指定的 key 中,会覆盖掉原来该 key 对应的内容。 + */ + function setStorage(param: types.SetStorageParams): void; + /** + * setStorage 的同步版本 + * @param key 本地缓存中指定的 key + * @param data 需要存储的内容 + */ + function setStorageSync(key: string, data: any): void; + + // --分包加载 + /** + * 触发分包加载,详见 分包加载 + */ + function loadSubpackage(param: { + /** + * 分包的名字,可以填 name 或者 root + */ + name: string, + success?: () => void, + fail?: () => void, + complete?: () => void + }): LoadSubpackageTask; + + // --菜单 + /** + * 获取菜单按钮的布局置信息 + */ + function getMenuButtonBoundingClientRect(): { + /** + * 宽度 + */ + width: number, + /** + * 高度 + */ + height: number, + /** + * 上边界坐标 + */ + top: number, + /** + * 右边界坐标 + */ + right: number, + /** + * 下边界坐标 + */ + bottom: number, + /** + * 左边界坐标 + */ + left: number + }; + function setMenuStyle(param: { + /** + * 样式风格 + */ + style: "light" | "dark", + success?: () => void, + fail?: () => void, + complete?: () => void + }): void; + + // --交互 + /** + * 显示消息提示框 + */ + function showToast(param: { + /** + * 提示的内容 + */ + title?: string, + /** + * 图标 + */ + icon?: "success" | "loading", + /** + * 自定义图标的本地路径,image 的优先级高于 icon + */ + image?: string, + /** + * 提示的延迟时间 + */ + duration?: number, + success?: () => void, + fail?: () => void, + complete?: () => void + }): void; + /** + * 隐藏消息提示框 + */ + function hideToast(cb?: types.Callbacks): void; + /** + * 显示模态对话框 + */ + function showModal(param: { + /** + * 提示的标题 + */ + title?: string, + /** + * 提示的内容 + */ + content?: string, + /** + * 是否显示取消按钮,默认true + */ + showCancel?: boolean, + /** + * 取消按钮的文字,最多 4 个字符串 + */ + cancelText?: string, + /** + * 取消按钮的文字颜色,必须是 16 进制格式的颜色字符串,默认值#000000 + */ + cancelColor?: string, + /** + * 确认按钮的文字,最多 4 个字符串 + */ + confirmText?: string, + /** + * 确认按钮的文字颜色,必须是 16 进制格式的颜色字符串,默认值#3cc51f + */ + confirmColor?: string, + success?: (res: { confirm?: boolean, cancel?: boolean }) => void, + fail?: () => void, + complete?: () => void + }): void; + /** + * 显示 loading 提示框, 需主动调用 wx.hideLoading 才能关闭提示框 + */ + function showLoading(prms?: { + /** + * 提示的内容 + */ + title?: string, + /** + * 是否显示透明蒙层 + */ + mask?: boolean, + success?: () => void, + fail?: () => void, + complete?: () => void + }): void; + /** + * 隐藏 loading 提示框 + */ + function hideLoading(cb?: types.Callbacks): void; + /** + * 显示选择器 + */ + function showActionSheet(params: { + /** + * 按钮的文字数组,数组长度最大为 6 + */ + itemList: string[], + /** + * 按钮的文字颜色,默认值#000000 + */ + itemColor?: string, + success?: () => void, + fail?: () => void, + complete?: () => void + }): void; + + // --键盘 + function hideKeyboard(): void; + /** + * 监听键盘输入事件 + * @param callback.res.value 键盘输入的当前值 + */ + function onKeyboardInput(callback: (res: { value: string }) => void): void; + /** + * 取消监听键盘输入事件 + */ + function offKeyboardInput(callback: (res: { value: string }) => void): void; + /** + * 监听用户点击键盘 Confirm 按钮时的事件 + * @param callback.res.value 键盘输入的当前值 + */ + function onKeyboardConfirm(callback: (res: { value: string }) => void): void; + /** + * 取消监听用户点击键盘 Confirm 按钮时的事件 + */ + function offKeyboardConfirm(callback: (res: { value: string }) => void): void; + /** + * 监听监听键盘收起的事件 + * @param callback.res.value 键盘输入的当前值 + */ + function onKeyboardComplete(callback: (res: { value: string }) => void): void; + /** + * 取消监听监听键盘收起的事件 + */ + function offKeyboardComplete(callback: (res: { value: string }) => void): void; + /** + * 显示键盘 + */ + function showKeyboard(param: { + /** + * 键盘输入框显示的默认值 + */ + defaultValue: string, + /** + * 键盘中文本的最大长度 + */ + maxLength?: number, + /** + * 是否为多行输入 + */ + multiple?: boolean, + /** + * 当点击完成时键盘是否收起 + */ + confirmHold?: boolean, + /** + * 键盘右下角 confirm 按钮的类型,只影响按钮的文本内容 + */ + confirmType?: "done" | "next" | "search" | "go" | "send" + }): void; + /** + * 更新键盘,只有当键盘处于拉起状态时才会产生效果 + */ + function updateKeyboard(param: { + /** + * 键盘输入框的当前值 + */ + value: string, + success?: () => void, + fail?: () => void, + complete?: () => void + }): void; + + // --状态栏 + /** + * 当在配置中设置 showStatusBarStyle 时,屏幕顶部会显示状态栏。此接口可以修改状态栏的样式。 + */ + function setStatusBarStyle(param: { + style: "white" | "black", + success?: () => void, + fail?: () => void, + complete?: () => void + }): void; + + // --窗口 + /** + * 监听窗口尺寸变化事件 + */ + function onWindowResize(cb: (res: { windowWidth: number, windowHeight: number }) => void): void; + /** + * 取消监听窗口尺寸变化事件 + */ + function offWindowResize(cb: (res: { windowWidth: number, windowHeight: number }) => void): void; + + // --更新 + function getUpdateManager(): UpdateManager; + + // --Worker + /** + * 创建一个 Worker 线程,目前限制最多只能创建一个 Worker,创建下一个 Worker 前请调用 Worker.terminate + */ + function createWorker(): WxWorker; + + // --音频 + /** + * 创建一个 InnerAudioContext 实例 + */ + function createInnerAudioContext(): InnerAudioContext; + /** + * 获取当前支持的音频输入源 + */ + function getAvailableAudioSources(param: types.CallbacksWithType<{ + /** + * 音频输入源,每一项对应一种音频输入源 + */ + audioSources: ReadonlyArray + }>): void; + + // --录音 + function getRecorderManager(): RecorderManager; + + // --图片 + /** + * 从本地相册选择图片或使用相机拍照。 + */ + function chooseImage(param: { + count: number, + /** + * 所选的图片的尺寸 + */ + sizeType: ['original'] | ['compressed'] | ['original', 'compressed'], + /** + * 选择图片的来源 + */ + sourceType: ['album'] | ['camera'] | ['album', 'camera'], + success?: (res: { tempFilePaths: ReadonlyArray, tempFiles: ReadonlyArray }) => void, + fail?: () => void, + complete?: () => void + }): void; + /** + * 预览图片,调用之后会在新打开的页面中全屏预览传入的图片,预览的过程中用户可以进行保存图片、发送给朋友等操作 + */ + function previewImage(param: { + /** + * 需要预览的图片链接列表 + */ + urls: string[], + /** + * 当前显示图片的链接,默认为urls的第一张 + */ + current?: string, + success?: () => void, + fail?: () => void, + complete?: () => void + }): void; + /** + * 保存图片到系统相册。需要用户授权 scope.writePhotosAlbum + */ + function saveImageToPhotosAlbum(param: { + /** + * 图片文件路径,可以是临时文件路径也可以是永久文件路径,不支持网络图片路径 + */ + filePath: string, + success?: () => void, + fail?: () => void, + complete?: () => void + }): void; + + // --视频 + function createVideo(param: { + /** + * 视频的左上角横坐标 + */ + x?: number, + /** + * 视频的左上角纵坐标 + */ + y?: number, + /** + * 视频的宽度,默认值300 + */ + width?: number, + /** + * 默认值150 + */ + height?: number, + /** + * 视频的资源地址 + */ + src: string, + /** + * 视频的封面 + */ + poster?: string, + /** + * 视频的初始播放位置,单位为 s 秒,默认值0 + */ + initialTime?: number, + /** + * 视频的播放速率,有效值有 0.5、0.8、1.0、1.25、1.5默认值1.0 + */ + playbackRate?: number, + /** + * 视频是否为直播,默认值0 + */ + live?: number, + /** + * 视频的缩放模式 + * fill - 填充,视频拉伸填满整个容器,不保证保持原有长宽比例 + * contain - 包含,保持原有长宽比例。保证视频尺寸一定可以在容器里面放得下。因此,可能会有部分空白 + * cover - 覆盖,保持原有长宽比例。保证视频尺寸一定大于容器尺寸,宽度和高度至少有一个和容器一致。因此,视频有部分会看不见 + */ + objectFit?: "contain" | "cover" | "fill", + /** + * 视频是否显示控件,默认true + */ + controls?: boolean, + /** + * 视频是否自动播放,默认false + */ + autoplay?: boolean, + /** + * 视频是否是否循环播放,默认值false + */ + loop?: boolean, + /** + * 视频是否禁音播放,默认值false + */ + muted?: boolean + }): Video; + + // --相机 + /** + * 创建相机 + * @param param 创建相机所需的初始化信息 + */ + function createCamera(param?: types.Callbacks & { + /** + * 相机的左上角横坐标,默认值0 + */ + x?: number; + /** + * 相机的左上角纵坐标,默认值0 + */ + y?: number; + /** + * 相机的宽度,默认值300 + */ + width?: number; + /** + * 相机的高度,默认值150 + */ + height?: number; + /** + * 摄像头朝向,值为 front, back,默认值back + */ + devicePosition?: "front" | "back"; + /** + * 闪光灯,值为 auto, on, off,默认值auto + */ + flash?: "auto" | "on" | "off"; + /** + * 帧数据图像尺寸,值为 small, medium, large,默认值small + */ + size?: "small" | "medium" | "large"; + }): Camera; + + // -- VoIP + /** + * 更新实时语音静音设置 + * @param param 静音设置 + */ + function updateVoIPChatMuteConfig(param: types.Callbacks & { + /** + * 静音设置 + */ + muteConfig: { + /** + * 是否静音麦克风,默认值false + */ + muteMicrophone?: boolean, + /** + * 是否静音耳机,默认值false + */ + muteEarphone?: boolean + } + }): void; + /** + * 监听实时语音通话成员通话状态变化事件。有成员开始/停止说话时触发回调 + * @param callback 实时语音通话成员通话状态变化事件的回调函数 + */ + function onVoIPChatSpeakersChanged(callback: (res: { + /** + * 还在实时语音通话中的成员 openId 名单 + */ + openIdList: ReadonlyArray, + /** + * 错误码 + */ + errCode: number, + /** + * 调用结果(错误原因) + */ + errMsg: string + }) => void): void; + /** + * 取消监听实时语音通话成员通话状态变化事件。 + * @param callback 之前监听的回调函数 + */ + function offVoIPChatSpeakersChanged(callback: any): void; + /** + * 监听实时语音通话成员在线状态变化事件。有成员加入/退出通话时触发回调 + * @param callback 实时语音通话成员在线状态变化事件的回调函数 + */ + function onVoIPChatMembersChanged(callback: (res: { + /** + * 还在实时语音通话中的成员 openId 名单 + */ + openIdList: ReadonlyArray, + /** + * 错误码 + */ + errCode: number, + /** + * 调用结果(错误原因) + */ + errMsg: string + }) => void): void; + /** + * 取消监听实时语音通话成员在线状态变化事件。 + * @param callback 之前监听的回调函数 + */ + function offVoIPChatMembersChanged(callback: any): void; + /** + * 监听被动断开实时语音通话事件。包括小游戏切入后端时断开 + * @param callback 被动断开实时语音通话事件的回调函数 + */ + function onVoIPChatInterrupted(callback: (res: { + /** + * 错误码 + */ + errCode: number, + /** + * 调用结果(错误原因) + */ + errMsg: string + }) => void): void; + /** + * 取消监听被动断开实时语音通话事件。 + * @param callback 之前监听的回调函数 + */ + function offVoIPChatInterrupted(callback: any): void; + /** + * 加入 (创建) 实时语音通话,更多信息可见:实时语音指南(https://developers.weixin.qq.com/minigame/dev/guide/open-ability/voip-chat.html) + * 错误码 + * -1 当前已在房间内 + * -2 录音设备被占用,可能是当前正在使用微信内语音通话或系统通话 + * -3 加入会话期间退出(可能是用户主动退出,或者退后台、来电等原因),因此加入失败 + * -1000 系统错误 + * @param param 加入语音聊天时的初始化参数 + */ + function joinVoIPChat(param: types.CallbacksWithType<{ + /** + * 在此通话中的成员 openId 名单 + */ + openIdList: ReadonlyArray, + /** + * 错误码 + */ + errCode: number, + /** + * 调用结果 + */ + errMsg: string + }> & { + /** + * 签名,用于验证小游戏的身份 + */ + signature: string, + /** + * 验证所需的随机字符串 + */ + nonceStr: string, + /** + * 验证所需的时间戳 + */ + timeStamp: number, + /** + * 小游戏内此房间/群聊的 ID。同一时刻传入相同 groupId 的用户会进入到同个实时语音房间。 + */ + groupId: string, + /** + * 静音设置 + */ + muteConfig?: { + /** + * 是否静音麦克风,默认值false + */ + muteMicrophone?: boolean, + /** + * 是否静音耳机,默认值false + */ + muteEarphone?: boolean + } + }): void; + /** + * 退出(销毁)实时语音通话 + */ + function exitVoIPChat(callbacks?: types.Callbacks): void; + + // --广告 + /** + * 创建 banner 广告组件。请通过 wx.getSystemInfoSync() 返回对象的 SDKVersion 判断基础库版本号 >= 2.0.4 后再使用该 API。同时,开发者工具上暂不支持调试该 API,请直接在真机上进行调试。 + */ + function createBannerAd(param: { + /** + * 广告单元 id + */ + adUnitId: string, + /** + * banner 广告组件的样式 + */ + style: types.AdStyle + }): BannerAd; + /** + * 创建激励视频广告组件。请通过 wx.getSystemInfoSync() 返回对象的 SDKVersion 判断基础库版本号 >= 2.0.4 后再使用该 API。同时,开发者工具上暂不支持调试该 API,请直接在真机上进行调试。 + */ + function createRewardedVideoAd(param: { + /** + * 广告单元 id + */ + adUnitId: string + }): RewardedVideoAd; + /** + * 创建插屏广告组件。请通过 wx.getSystemInfoSync() 返回对象的 SDKVersion 判断基础库版本号后再使用该 API。每次调用该方法创建插屏广告都会返回一个全新的实例(小程序端的插屏广告实例不允许跨页面使用)。 + */ + function createInterstitialAd(param: { + /** + * 广告单元 id + */ + adUnitId: string + }): InterstitialAd; + + // --虚拟支付 + /** + * 发起米大师支付 + */ + function requestMidasPayment(param: { + /** + * 支付的类型,不同的支付类型有各自额外要传的附加参数。 + * game - 购买游戏币 + */ + mode: "game", + /** + * 环境配置,默认值0 + * 0 - 米大师正式环境 + * 1 - 米大师沙箱环境 + */ + env?: 0 | 1, + /** + * 在米大师侧申请的应用 id + */ + offerId: string, + /** + * 币种 + */ + currencyType: "CNY", + /** + * 申请接入时的平台,platform 与应用id有关。 + */ + platform?: "android", + /** + * 购买数量。mode=game 时必填。购买数量。详见 buyQuantity 限制说明。 + * mode为game(购买游戏币)时,buyQuantity不可任意填写。需满足 buyQuantity * 游戏币单价 = 限定的价格等级。如:游戏币单价为 0.1 元,一次购买最少数量是 10。 + * 有效价格等级如下: + * 价格等级(单位:人民币) + * 1 + * 3 + * 6 + * 8 + * 12 + * 18 + * 25 + * 30 + * 40 + * 45 + * 50 + * 60 + * 68 + * 73 + * 78 + * 88 + * 98 + * 108 + * 118 + * 128 + * 148 + * 168 + * 188 + * 198 + * 328 + * 648 + */ + buyQuantity?: number, + /** + * 分区 ID + */ + zoneId?: string, + success?: () => void, + /** + * @param res.errCode 有如下值: + * -1 系统失败 + * -2 支付取消 + * -15001 虚拟支付接口错误码,缺少参数 + * -15002 虚拟支付接口错误码,参数不合法 + * -15003 虚拟支付接口错误码,订单重复 + * -15004 虚拟支付接口错误码,后台错误 + * -15006 虚拟支付接口错误码,appId 权限被封禁 + * -15006 虚拟支付接口错误码,货币类型不支持 + * -15007 虚拟支付接口错误码,订单已支付 + * 1 虚拟支付接口错误码,用户取消支付 + * 2 虚拟支付接口错误码,客户端错误, 判断到小程序在用户处于支付中时,又发起了一笔支付请求 + * 3 虚拟支付接口错误码,Android 独有错误:用户使用 Google Play 支付,而手机未安装 Google Play + * 4 虚拟支付接口错误码,用户操作系统支付状态异常 + * 5 虚拟支付接口错误码,操作系统错误 + * 6 虚拟支付接口错误码,其他错误 + * 1000 参数错误 + * 1003 米大师 Portal 错误 + */ + fail?: (res: { errMsg: string, errCode: number }) => void, + complete?: () => void + }): void; +} \ No newline at end of file diff --git a/source/src/AI/Pathfinding/AStar/AStarPathfinder.ts b/source/src/AI/Pathfinding/AStar/AStarPathfinder.ts index d2155c9c..692d87a2 100644 --- a/source/src/AI/Pathfinding/AStar/AStarPathfinder.ts +++ b/source/src/AI/Pathfinding/AStar/AStarPathfinder.ts @@ -1,89 +1,103 @@ /// -/** - * 计算路径给定的IAstarGraph和开始/目标位置 - */ -class AStarPathfinder { - public static search(graph: IAstarGraph, start: T, goal: T){ - let foundPath = false; - let cameFrom = new Map(); - cameFrom.set(start, start); +module es { + /** + * 计算路径给定的IAstarGraph和开始/目标位置 + */ + export class AStarPathfinder { + /** + * 尽可能从开始到目标找到一条路径。如果没有找到路径,则返回null。 + * @param graph + * @param start + * @param goal + */ + public static search(graph: IAstarGraph, start: T, goal: T) { + let foundPath = false; + let cameFrom = new Map(); + cameFrom.set(start, start); - let costSoFar = new Map(); - let frontier = new PriorityQueue>(1000); - frontier.enqueue(new AStarNode(start), 0); + let costSoFar = new Map(); + let frontier = new PriorityQueue>(1000); + frontier.enqueue(new AStarNode(start), 0); - costSoFar.set(start, 0); + costSoFar.set(start, 0); - while (frontier.count > 0){ - let current = frontier.dequeue(); + while (frontier.count > 0) { + let current = frontier.dequeue(); - if (JSON.stringify(current.data) == JSON.stringify(goal)){ - foundPath = true; - break; + if (JSON.stringify(current.data) == JSON.stringify(goal)) { + foundPath = true; + break; + } + + graph.getNeighbors(current.data).forEach(next => { + let newCost = costSoFar.get(current.data) + graph.cost(current.data, next); + if (!this.hasKey(costSoFar, next) || newCost < costSoFar.get(next)) { + costSoFar.set(next, newCost); + let priority = newCost + graph.heuristic(next, goal); + frontier.enqueue(new AStarNode(next), priority); + cameFrom.set(next, current.data); + } + }); } - graph.getNeighbors(current.data).forEach(next => { - let newCost = costSoFar.get(current.data) + graph.cost(current.data, next); - if (!this.hasKey(costSoFar, next) || newCost < costSoFar.get(next)){ - costSoFar.set(next, newCost); - let priority = newCost + graph.heuristic(next, goal); - frontier.enqueue(new AStarNode(next), priority); - cameFrom.set(next, current.data); - } - }); + return foundPath ? this.recontructPath(cameFrom, start, goal) : null; } - return foundPath ? this.recontructPath(cameFrom, start, goal) : null; + /** + * 从cameFrom字典重新构造路径 + * @param cameFrom + * @param start + * @param goal + */ + public static recontructPath(cameFrom: Map, start: T, goal: T): T[] { + let path = []; + let current = goal; + path.push(goal); + + while (current != start) { + current = this.getKey(cameFrom, current); + path.push(current); + } + + path.reverse(); + + return path; + } + + private static hasKey(map: Map, compareKey: T) { + let iterator = map.keys(); + let r: IteratorResult; + while (r = iterator.next() , !r.done) { + if (JSON.stringify(r.value) == JSON.stringify(compareKey)) + return true; + } + + return false; + } + + private static getKey(map: Map, compareKey: T) { + let iterator = map.keys(); + let valueIterator = map.values(); + let r: IteratorResult; + let v: IteratorResult; + while (r = iterator.next(), v = valueIterator.next(), !r.done) { + if (JSON.stringify(r.value) == JSON.stringify(compareKey)) + return v.value; + } + + return null; + } } - private static hasKey(map: Map, compareKey: T){ - let iterator = map.keys(); - let r: IteratorResult; - while (r = iterator.next() , !r.done) { - if (JSON.stringify(r.value) == JSON.stringify(compareKey)) - return true; + /** + * 使用PriorityQueue需要的额外字段将原始数据封装在一个小类中 + */ + export class AStarNode extends PriorityQueueNode { + public data: T; + + constructor(data: T) { + super(); + this.data = data; } - - return false; - } - - private static getKey(map: Map, compareKey: T){ - let iterator = map.keys(); - let valueIterator = map.values(); - let r: IteratorResult; - let v: IteratorResult; - while (r = iterator.next(), v = valueIterator.next(), !r.done) { - if (JSON.stringify(r.value) == JSON.stringify(compareKey)) - return v.value; - } - - return null; - } - - public static recontructPath(cameFrom: Map, start: T, goal: T): T[]{ - let path = []; - let current = goal; - path.push(goal); - - while (current != start){ - current = this.getKey(cameFrom, current); - path.push(current); - } - - path.reverse(); - - return path; } } - -/** - * 使用PriorityQueue需要的额外字段将原始数据封装在一个小类中 - */ -class AStarNode extends PriorityQueueNode { - public data: T; - - constructor(data: T){ - super(); - this.data = data; - } -} \ No newline at end of file diff --git a/source/src/AI/Pathfinding/AStar/AstarGridGraph.ts b/source/src/AI/Pathfinding/AStar/AstarGridGraph.ts index d815f19d..844c07b4 100644 --- a/source/src/AI/Pathfinding/AStar/AstarGridGraph.ts +++ b/source/src/AI/Pathfinding/AStar/AstarGridGraph.ts @@ -1,67 +1,74 @@ -/** - * 基本静态网格图与A*一起使用 - * 将walls添加到walls HashSet,并将加权节点添加到weightedNodes - */ -class AstarGridGraph implements IAstarGraph { - public dirs: Vector2[] = [ - new Vector2(1, 0), - new Vector2(0, -1), - new Vector2(-1, 0), - new Vector2(0, 1) - ]; - - public walls: Vector2[] = []; - public weightedNodes: Vector2[] = []; - public defaultWeight: number = 1; - public weightedNodeWeight = 5; - - private _width; - private _height; - private _neighbors: Vector2[] = new Array(4); - - constructor(width: number, height: number){ - this._width = width; - this._height = height; - } - +module es { /** - * 确保节点在网格图的边界内 - * @param node + * 基本静态网格图与A*一起使用 + * 将walls添加到walls HashSet,并将加权节点添加到weightedNodes */ - public isNodeInBounds(node: Vector2): boolean { - return 0 <= node.x && node.x < this._width && 0 <= node.y && node.y < this._height; + export class AstarGridGraph implements IAstarGraph { + public dirs: Vector2[] = [ + new Vector2(1, 0), + new Vector2(0, -1), + new Vector2(-1, 0), + new Vector2(0, 1) + ]; + + public walls: Vector2[] = []; + public weightedNodes: Vector2[] = []; + public defaultWeight: number = 1; + public weightedNodeWeight = 5; + + private _width; + private _height; + private _neighbors: Vector2[] = new Array(4); + + constructor(width: number, height: number) { + this._width = width; + this._height = height; + } + + /** + * 确保节点在网格图的边界内 + * @param node + */ + public isNodeInBounds(node: Vector2): boolean { + return 0 <= node.x && node.x < this._width && 0 <= node.y && node.y < this._height; + } + + /** + * 检查节点是否可以通过。walls是不可逾越的。 + * @param node + */ + public isNodePassable(node: Vector2): boolean { + return !this.walls.firstOrDefault(wall => JSON.stringify(wall) == JSON.stringify(node)); + } + + /** + * 调用AStarPathfinder.search的快捷方式 + * @param start + * @param goal + */ + public search(start: Vector2, goal: Vector2) { + return AStarPathfinder.search(this, start, goal); + } + + public getNeighbors(node: Vector2): Vector2[] { + this._neighbors.length = 0; + + this.dirs.forEach(dir => { + let next = new Vector2(node.x + dir.x, node.y + dir.y); + if (this.isNodeInBounds(next) && this.isNodePassable(next)) + this._neighbors.push(next); + }); + + return this._neighbors; + } + + public cost(from: Vector2, to: Vector2): number { + return this.weightedNodes.find((p) => JSON.stringify(p) == JSON.stringify(to)) ? this.weightedNodeWeight : this.defaultWeight; + } + + public heuristic(node: Vector2, goal: Vector2) { + return Math.abs(node.x - goal.x) + Math.abs(node.y - goal.y); + } + } - - /** - * 检查节点是否可以通过。墙壁是不可逾越的。 - * @param node - */ - public isNodePassable(node: Vector2): boolean { - return !this.walls.firstOrDefault(wall => JSON.stringify(wall) == JSON.stringify(node)); - } - - public search(start: Vector2, goal: Vector2){ - return AStarPathfinder.search(this, start, goal); - } - - public getNeighbors(node: Vector2): Vector2[] { - this._neighbors.length = 0; - - this.dirs.forEach(dir => { - let next = new Vector2(node.x + dir.x, node.y + dir.y); - if (this.isNodeInBounds(next) && this.isNodePassable(next)) - this._neighbors.push(next); - }); - - return this._neighbors; - } - - public cost(from: Vector2, to: Vector2): number { - return this.weightedNodes.find((p)=> JSON.stringify(p) == JSON.stringify(to)) ? this.weightedNodeWeight : this.defaultWeight; - } - - public heuristic(node: Vector2, goal: Vector2) { - return Math.abs(node.x - goal.x) + Math.abs(node.y - goal.y); - } - -} \ No newline at end of file +} diff --git a/source/src/AI/Pathfinding/AStar/IAstarGraph.ts b/source/src/AI/Pathfinding/AStar/IAstarGraph.ts index 3630e3e1..839edb41 100644 --- a/source/src/AI/Pathfinding/AStar/IAstarGraph.ts +++ b/source/src/AI/Pathfinding/AStar/IAstarGraph.ts @@ -1,5 +1,26 @@ -interface IAstarGraph { - getNeighbors(node: T): Array; - cost(from: T, to: T): number; - heuristic(node: T, goal: T); -} \ No newline at end of file +module es { + /** + * graph的接口,可以提供给AstarPathfinder.search方法 + */ + export interface IAstarGraph { + /** + * getNeighbors方法应该返回从传入的节点可以到达的任何相邻节点 + * @param node + */ + getNeighbors(node: T): Array; + + /** + * 计算从从from到to的成本 + * @param from + * @param to + */ + cost(from: T, to: T): number; + + /** + * 计算从node到to的启发式。参见WeightedGridGraph了解常用的Manhatten方法。 + * @param node + * @param goal + */ + heuristic(node: T, goal: T); + } +} diff --git a/source/src/AI/Pathfinding/AStar/PriorityQueue.ts b/source/src/AI/Pathfinding/AStar/PriorityQueue.ts index 5c40272a..ae315fa4 100644 --- a/source/src/AI/Pathfinding/AStar/PriorityQueue.ts +++ b/source/src/AI/Pathfinding/AStar/PriorityQueue.ts @@ -1,150 +1,236 @@ -class PriorityQueue { - private _numNodes: number; - private _nodes: T[]; - private _numNodesEverEnqueued; +module es { + /** + * 使用堆实现最小优先级队列 O(1)复杂度 + * 这种查找速度比使用字典快5-10倍 + * 但是,由于IPriorityQueue.contains()是许多寻路算法中调用最多的方法,因此尽可能快地实现它对于我们的应用程序非常重要。 + */ + export class PriorityQueue { + private _numNodes: number; + private _nodes: T[]; + private _numNodesEverEnqueued; - constructor(maxNodes: number) { - this._numNodes = 0; - this._nodes = new Array(maxNodes + 1); - this._numNodesEverEnqueued = 0; - } + /** + * 实例化一个新的优先级队列 + * @param maxNodes 允许加入队列的最大节点(执行此操作将导致undefined的行为) + */ + constructor(maxNodes: number) { + this._numNodes = 0; + this._nodes = new Array(maxNodes + 1); + this._numNodesEverEnqueued = 0; + } - public clear() { - this._nodes.splice(1, this._numNodes); - this._numNodes = 0; - } + /** + * 返回队列中的节点数。 + * O(1)复杂度 + */ + public get count() { + return this._numNodes; + } - public get count() { - return this._numNodes; - } + /** + * 返回可同时进入此队列的最大项数。一旦你达到这个数字(即。一旦Count == MaxSize),尝试加入另一个项目将导致undefined的行为 + * O(1)复杂度 + */ + public get maxSize() { + return this._nodes.length - 1; + } - public contains(node: T): boolean { - return (this._nodes[node.queueIndex] == node); - } + /** + * 从队列中删除每个节点。 + * O(n)复杂度 所有尽可能少调用该方法 + */ + public clear() { + this._nodes.splice(1, this._numNodes); + this._numNodes = 0; + } - public enqueue(node: T, priority: number) { - node.priority = priority; - this._numNodes++; - this._nodes[this._numNodes] = node; - node.queueIndex = this._numNodes; - node.insertionIndex = this._numNodesEverEnqueued++; - this.cascadeUp(this._nodes[this._numNodes]); - } + /** + * 返回(在O(1)中)给定节点是否在队列中 + * O (1)复杂度 + * @param node + */ + public contains(node: T): boolean { + if (!node) { + console.error("node cannot be null"); + return false; + } - public dequeue(): T { - let returnMe = this._nodes[1]; - this.remove(returnMe); - return returnMe; - } + if (node.queueIndex < 0 || node.queueIndex >= this._nodes.length) { + console.error("node.QueueIndex has been corrupted. Did you change it manually? Or add this node to another queue?"); + return false; + } - public remove(node: T) { - if (node.queueIndex == this._numNodes) { - this._nodes[this._numNodes] = null; + return (this._nodes[node.queueIndex] == node); + } + + /** + * 将节点放入优先队列 较低的值放在前面 先入先出 + * 如果队列已满,则结果undefined。如果节点已经加入队列,则结果undefined。 + * O(log n) + * @param node + * @param priority + */ + public enqueue(node: T, priority: number) { + node.priority = priority; + this._numNodes++; + this._nodes[this._numNodes] = node; + node.queueIndex = this._numNodes; + node.insertionIndex = this._numNodesEverEnqueued++; + this.cascadeUp(this._nodes[this._numNodes]); + } + + /** + * 删除队列头(具有最小优先级的节点;按插入顺序断开连接),并返回它。如果队列为空,结果undefined + * O(log n) + */ + public dequeue(): T { + let returnMe = this._nodes[1]; + this.remove(returnMe); + return returnMe; + } + + /** + * 从队列中删除一个节点。节点不需要是队列的头。如果节点不在队列中,则结果未定义。如果不确定,首先检查Contains() + * O(log n) + * @param node + */ + public remove(node: T) { + if (node.queueIndex == this._numNodes) { + this._nodes[this._numNodes] = null; + this._numNodes--; + return; + } + + let formerLastNode = this._nodes[this._numNodes]; + this.swap(node, formerLastNode); + delete this._nodes[this._numNodes]; this._numNodes--; - return; + + this.onNodeUpdated(formerLastNode); } - let formerLastNode = this._nodes[this._numNodes]; - this.swap(node, formerLastNode); - delete this._nodes[this._numNodes]; - this._numNodes--; + /** + * 检查以确保队列仍然处于有效状态。用于测试/调试队列。 + */ + public isValidQueue(): boolean { + for (let i = 1; i < this._nodes.length; i++) { + if (this._nodes[i]) { + let childLeftIndex = 2 * i; + if (childLeftIndex < this._nodes.length && this._nodes[childLeftIndex] && + this.hasHigherPriority(this._nodes[childLeftIndex], this._nodes[i])) + return false; - this.onNodeUpdated(formerLastNode); - } - - public isValidQueue(): boolean { - for (let i = 1; i < this._nodes.length; i++) { - if (this._nodes[i]) { - let childLeftIndex = 2 * i; - if (childLeftIndex < this._nodes.length && this._nodes[childLeftIndex] && - this.hasHigherPriority(this._nodes[childLeftIndex], this._nodes[i])) - return false; - - let childRightIndex = childLeftIndex + 1; - if (childRightIndex < this._nodes.length && this._nodes[childRightIndex] && - this.hasHigherPriority(this._nodes[childRightIndex], this._nodes[i])) - return false; - } - } - - return true; - } - - private onNodeUpdated(node: T) { - let parentIndex = Math.floor(node.queueIndex / 2); - let parentNode = this._nodes[parentIndex]; - - if (parentIndex > 0 && this.hasHigherPriority(node, parentNode)) { - this.cascadeUp(node); - } else { - this.cascadeDown(node); - } - } - - private cascadeDown(node: T) { - let newParent: T; - let finalQueueIndex = node.queueIndex; - while (true) { - newParent = node; - let childLeftIndex = 2 * finalQueueIndex; - - if (childLeftIndex > this._numNodes) { - node.queueIndex = finalQueueIndex; - this._nodes[finalQueueIndex] = node; - break; - } - - let childLeft = this._nodes[childLeftIndex]; - if (this.hasHigherPriority(childLeft, newParent)) { - newParent = childLeft; - } - - let childRightIndex = childLeftIndex + 1; - if (childRightIndex <= this._numNodes) { - let childRight = this._nodes[childRightIndex]; - if (this.hasHigherPriority(childRight, newParent)) { - newParent = childRight; + let childRightIndex = childLeftIndex + 1; + if (childRightIndex < this._nodes.length && this._nodes[childRightIndex] && + this.hasHigherPriority(this._nodes[childRightIndex], this._nodes[i])) + return false; } } - if (newParent != node) { - this._nodes[finalQueueIndex] = newParent; + return true; + } - let temp = newParent.queueIndex; - newParent.queueIndex = finalQueueIndex; - finalQueueIndex = temp; + private onNodeUpdated(node: T) { + // 将更新后的节点按适当的方式向上或向下冒泡 + let parentIndex = Math.floor(node.queueIndex / 2); + let parentNode = this._nodes[parentIndex]; + + if (parentIndex > 0 && this.hasHigherPriority(node, parentNode)) { + this.cascadeUp(node); } else { - node.queueIndex = finalQueueIndex; - this._nodes[finalQueueIndex] = node; - break; + // 注意,如果parentNode == node(即节点是根),则将调用CascadeDown。 + this.cascadeDown(node); } } - } - private cascadeUp(node: T) { - let parent = Math.floor(node.queueIndex / 2); - while (parent >= 1) { - let parentNode = this._nodes[parent]; - if (this.hasHigherPriority(parentNode, node)) - break; + private cascadeDown(node: T) { + // 又名Heapify-down + let newParent: T; + let finalQueueIndex = node.queueIndex; + while (true) { + newParent = node; + let childLeftIndex = 2 * finalQueueIndex; - this.swap(node, parentNode); + // 检查左子节点的优先级是否高于当前节点 + if (childLeftIndex > this._numNodes) { + // 这可以放在循环之外,但是我们必须检查newParent != node两次 + node.queueIndex = finalQueueIndex; + this._nodes[finalQueueIndex] = node; + break; + } - parent = Math.floor(node.queueIndex / 2); + let childLeft = this._nodes[childLeftIndex]; + if (this.hasHigherPriority(childLeft, newParent)) { + newParent = childLeft; + } + + // 检查右子节点的优先级是否高于当前节点或左子节点 + let childRightIndex = childLeftIndex + 1; + if (childRightIndex <= this._numNodes) { + let childRight = this._nodes[childRightIndex]; + if (this.hasHigherPriority(childRight, newParent)) { + newParent = childRight; + } + } + + // 如果其中一个子节点具有更高(更小)的优先级,则交换并继续级联 + if (newParent != node) { + // 将新的父节点移动到它的新索引 + // 节点将被移动一次,这样做比调用Swap()少一个赋值操作。 + this._nodes[finalQueueIndex] = newParent; + + let temp = newParent.queueIndex; + newParent.queueIndex = finalQueueIndex; + finalQueueIndex = temp; + } else { + // 参见上面的笔记 + node.queueIndex = finalQueueIndex; + this._nodes[finalQueueIndex] = node; + break; + } + } + } + + /** + * 当没有内联时,性能会稍微好一些 + * @param node + */ + private cascadeUp(node: T) { + // 又名Heapify-up + let parent = Math.floor(node.queueIndex / 2); + while (parent >= 1) { + let parentNode = this._nodes[parent]; + if (this.hasHigherPriority(parentNode, node)) + break; + + // 节点具有较低的优先级值,因此将其向上移动到堆中 + // 出于某种原因,使用Swap()比使用单独的操作更快,如CascadeDown() + this.swap(node, parentNode); + + parent = Math.floor(node.queueIndex / 2); + } + } + + private swap(node1: T, node2: T) { + // 交换节点 + this._nodes[node1.queueIndex] = node2; + this._nodes[node2.queueIndex] = node1; + + // 交换他们的indicies + let temp = node1.queueIndex; + node1.queueIndex = node2.queueIndex; + node2.queueIndex = temp; + } + + /** + * 如果higher的优先级高于lower,则返回true,否则返回false。 + * 注意,调用HasHigherPriority(节点,节点)(即。两个参数为同一个节点)将返回false + * @param higher + * @param lower + */ + private hasHigherPriority(higher: T, lower: T) { + return (higher.priority < lower.priority || + (higher.priority == lower.priority && higher.insertionIndex < lower.insertionIndex)); } } - - private swap(node1: T, node2: T) { - this._nodes[node1.queueIndex] = node2; - this._nodes[node2.queueIndex] = node1; - - let temp = node1.queueIndex; - node1.queueIndex = node2.queueIndex; - node2.queueIndex = temp; - } - - private hasHigherPriority(higher: T, lower: T) { - return (higher.priority < lower.priority || - (higher.priority == lower.priority && higher.insertionIndex < lower.insertionIndex)); - } -} \ No newline at end of file +} diff --git a/source/src/AI/Pathfinding/AStar/PriorityQueueNode.ts b/source/src/AI/Pathfinding/AStar/PriorityQueueNode.ts index 44edbc9e..29c86e2c 100644 --- a/source/src/AI/Pathfinding/AStar/PriorityQueueNode.ts +++ b/source/src/AI/Pathfinding/AStar/PriorityQueueNode.ts @@ -1,14 +1,16 @@ -class PriorityQueueNode { - /** - * 插入此节点的优先级。在将节点添加到队列之前必须设置 - */ - public priority: number = 0; - /** - * 由优先级队列使用-不要编辑此值。表示插入节点的顺序 - */ - public insertionIndex: number = 0; - /** - * 由优先级队列使用-不要编辑此值。表示队列中的当前位置 - */ - public queueIndex: number = 0; -} \ No newline at end of file +module es { + export class PriorityQueueNode { + /** + * 插入此节点的优先级。在将节点添加到队列之前必须设置 + */ + public priority: number = 0; + /** + * 由优先级队列使用-不要编辑此值。表示插入节点的顺序 + */ + public insertionIndex: number = 0; + /** + * 由优先级队列使用-不要编辑此值。表示队列中的当前位置 + */ + public queueIndex: number = 0; + } +} diff --git a/source/src/AI/Pathfinding/BreadthFirst/BreadthFirstPathfinder.ts b/source/src/AI/Pathfinding/BreadthFirst/BreadthFirstPathfinder.ts index 429af42c..c352fea3 100644 --- a/source/src/AI/Pathfinding/BreadthFirst/BreadthFirstPathfinder.ts +++ b/source/src/AI/Pathfinding/BreadthFirst/BreadthFirstPathfinder.ts @@ -1,41 +1,43 @@ -/** - * 计算路径给定的IUnweightedGraph和开始/目标位置 - */ -class BreadthFirstPathfinder { - public static search(graph: IUnweightedGraph, start: T, goal: T): T[]{ - let foundPath = false; - let frontier = []; - frontier.unshift(start); +module es { + /** + * 计算路径给定的IUnweightedGraph和开始/目标位置 + */ + export class BreadthFirstPathfinder { + public static search(graph: IUnweightedGraph, start: T, goal: T): T[] { + let foundPath = false; + let frontier = []; + frontier.unshift(start); - let cameFrom = new Map(); - cameFrom.set(start, start); + let cameFrom = new Map(); + cameFrom.set(start, start); - while (frontier.length > 0){ - let current = frontier.shift(); - if (JSON.stringify(current) == JSON.stringify(goal)){ - foundPath = true; - break; + while (frontier.length > 0) { + let current = frontier.shift(); + if (JSON.stringify(current) == JSON.stringify(goal)) { + foundPath = true; + break; + } + + graph.getNeighbors(current).forEach(next => { + if (!this.hasKey(cameFrom, next)) { + frontier.unshift(next); + cameFrom.set(next, current); + } + }); } - graph.getNeighbors(current).forEach(next => { - if (!this.hasKey(cameFrom, next)){ - frontier.unshift(next); - cameFrom.set(next, current); - } - }); + return foundPath ? AStarPathfinder.recontructPath(cameFrom, start, goal) : null; } - return foundPath ? AStarPathfinder.recontructPath(cameFrom, start, goal) : null; - } + private static hasKey(map: Map, compareKey: T) { + let iterator = map.keys(); + let r: IteratorResult; + while (r = iterator.next() , !r.done) { + if (JSON.stringify(r.value) == JSON.stringify(compareKey)) + return true; + } - private static hasKey(map: Map, compareKey: T){ - let iterator = map.keys(); - let r: IteratorResult; - while (r = iterator.next() , !r.done) { - if (JSON.stringify(r.value) == JSON.stringify(compareKey)) - return true; + return false; } - - return false; } -} \ No newline at end of file +} diff --git a/source/src/AI/Pathfinding/BreadthFirst/IUnweightedGraph.ts b/source/src/AI/Pathfinding/BreadthFirst/IUnweightedGraph.ts index 26a6af36..7e53339c 100644 --- a/source/src/AI/Pathfinding/BreadthFirst/IUnweightedGraph.ts +++ b/source/src/AI/Pathfinding/BreadthFirst/IUnweightedGraph.ts @@ -1,7 +1,9 @@ -interface IUnweightedGraph{ - /** - * getNeighbors方法应该返回从传入的节点可以到达的任何相邻节点。 - * @param node - */ - getNeighbors(node: T): T[]; -} \ No newline at end of file +module es { + export interface IUnweightedGraph { + /** + * getNeighbors方法应该返回从传入的节点可以到达的任何相邻节点。 + * @param node + */ + getNeighbors(node: T): T[]; + } +} diff --git a/source/src/AI/Pathfinding/BreadthFirst/UnweightedGraph.ts b/source/src/AI/Pathfinding/BreadthFirst/UnweightedGraph.ts index e37120bc..fb841a61 100644 --- a/source/src/AI/Pathfinding/BreadthFirst/UnweightedGraph.ts +++ b/source/src/AI/Pathfinding/BreadthFirst/UnweightedGraph.ts @@ -1,16 +1,18 @@ -/** - * 一个未加权图的基本实现。所有的边都被缓存。这种类型的图最适合于非基于网格的图。 - * 作为边添加的任何节点都必须在边字典中有一个条目作为键。 - */ -class UnweightedGraph implements IUnweightedGraph { - public edges: Map = new Map(); +module es { + /** + * 一个未加权图的基本实现。所有的边都被缓存。这种类型的图最适合于非基于网格的图。 + * 作为边添加的任何节点都必须在边字典中有一个条目作为键。 + */ + export class UnweightedGraph implements IUnweightedGraph { + public edges: Map = new Map(); - public addEdgesForNode(node: T, edges: T[]){ - this.edges.set(node, edges); - return this; - } + public addEdgesForNode(node: T, edges: T[]) { + this.edges.set(node, edges); + return this; + } - public getNeighbors(node: T){ - return this.edges.get(node); + public getNeighbors(node: T) { + return this.edges.get(node); + } } -} \ No newline at end of file +} diff --git a/source/src/AI/Pathfinding/BreadthFirst/UnweightedGridGraph.ts b/source/src/AI/Pathfinding/BreadthFirst/UnweightedGridGraph.ts index f769f398..e0516a93 100644 --- a/source/src/AI/Pathfinding/BreadthFirst/UnweightedGridGraph.ts +++ b/source/src/AI/Pathfinding/BreadthFirst/UnweightedGridGraph.ts @@ -1,61 +1,63 @@ /// -/** - * 基本的未加权网格图形用于BreadthFirstPathfinder - */ -class UnweightedGridGraph implements IUnweightedGraph { - private static readonly CARDINAL_DIRS: Vector2[] = [ - new Vector2(1, 0), - new Vector2(0, -1), - new Vector2(-1, 0), - new Vector2(0, -1) - ]; +module es { + /** + * 基本的未加权网格图形用于BreadthFirstPathfinder + */ + export class UnweightedGridGraph implements IUnweightedGraph { + private static readonly CARDINAL_DIRS: Vector2[] = [ + new Vector2(1, 0), + new Vector2(0, -1), + new Vector2(-1, 0), + new Vector2(0, -1) + ]; - private static readonly COMPASS_DIRS = [ - new Vector2(1, 0), - new Vector2(1, -1), - new Vector2(0, -1), - new Vector2(-1, -1), - new Vector2(-1, 0), - new Vector2(-1, 1), - new Vector2(0, 1), - new Vector2(1, 1), - ]; + private static readonly COMPASS_DIRS = [ + new Vector2(1, 0), + new Vector2(1, -1), + new Vector2(0, -1), + new Vector2(-1, -1), + new Vector2(-1, 0), + new Vector2(-1, 1), + new Vector2(0, 1), + new Vector2(1, 1), + ]; - public walls: Vector2[] = []; + public walls: Vector2[] = []; - private _width: number; - private _hegiht: number; + private _width: number; + private _hegiht: number; - private _dirs: Vector2[]; - private _neighbors: Vector2[] = new Array(4); + private _dirs: Vector2[]; + private _neighbors: Vector2[] = new Array(4); - constructor(width: number, height: number, allowDiagonalSearch: boolean = false) { - this._width = width; - this._hegiht = height; - this._dirs = allowDiagonalSearch ? UnweightedGridGraph.COMPASS_DIRS : UnweightedGridGraph.CARDINAL_DIRS; + constructor(width: number, height: number, allowDiagonalSearch: boolean = false) { + this._width = width; + this._hegiht = height; + this._dirs = allowDiagonalSearch ? UnweightedGridGraph.COMPASS_DIRS : UnweightedGridGraph.CARDINAL_DIRS; + } + + public isNodeInBounds(node: Vector2): boolean { + return 0 <= node.x && node.x < this._width && 0 <= node.y && node.y < this._hegiht; + } + + public isNodePassable(node: Vector2): boolean { + return !this.walls.firstOrDefault(wall => JSON.stringify(wall) == JSON.stringify(node)); + } + + public getNeighbors(node: Vector2) { + this._neighbors.length = 0; + + this._dirs.forEach(dir => { + let next = new Vector2(node.x + dir.x, node.y + dir.y); + if (this.isNodeInBounds(next) && this.isNodePassable(next)) + this._neighbors.push(next); + }); + + return this._neighbors; + } + + public search(start: Vector2, goal: Vector2): Vector2[] { + return BreadthFirstPathfinder.search(this, start, goal); + } } - - public isNodeInBounds(node: Vector2): boolean { - return 0 <= node.x && node.x < this._width && 0 <= node.y && node.y < this._hegiht; - } - - public isNodePassable(node: Vector2): boolean { - return !this.walls.firstOrDefault(wall => JSON.stringify(wall) == JSON.stringify(node)); - } - - public getNeighbors(node: Vector2) { - this._neighbors.length = 0; - - this._dirs.forEach(dir => { - let next = new Vector2(node.x + dir.x, node.y + dir.y); - if (this.isNodeInBounds(next) && this.isNodePassable(next)) - this._neighbors.push(next); - }); - - return this._neighbors; - } - - public search(start: Vector2, goal: Vector2): Vector2[] { - return BreadthFirstPathfinder.search(this, start, goal); - } -} \ No newline at end of file +} diff --git a/source/src/AI/Pathfinding/Dijkstra/IWeightedGraph.ts b/source/src/AI/Pathfinding/Dijkstra/IWeightedGraph.ts index 7ce1e30e..60e743ce 100644 --- a/source/src/AI/Pathfinding/Dijkstra/IWeightedGraph.ts +++ b/source/src/AI/Pathfinding/Dijkstra/IWeightedGraph.ts @@ -1,14 +1,16 @@ -interface IWeightedGraph{ - /** - * - * @param node - */ - getNeighbors(node: T): T[]; +module es { + export interface IWeightedGraph { + /** + * + * @param node + */ + getNeighbors(node: T): T[]; - /** - * - * @param from - * @param to - */ - cost(from: T, to: T): number; -} \ No newline at end of file + /** + * + * @param from + * @param to + */ + cost(from: T, to: T): number; + } +} diff --git a/source/src/AI/Pathfinding/Dijkstra/WeightedGridGraph.ts b/source/src/AI/Pathfinding/Dijkstra/WeightedGridGraph.ts index 474535c1..3392d5b1 100644 --- a/source/src/AI/Pathfinding/Dijkstra/WeightedGridGraph.ts +++ b/source/src/AI/Pathfinding/Dijkstra/WeightedGridGraph.ts @@ -1,67 +1,69 @@ /// -/** - * 支持一种加权节点的基本网格图 - */ -class WeightedGridGraph implements IWeightedGraph { - public static readonly CARDINAL_DIRS = [ - new Vector2(1, 0), - new Vector2(0, -1), - new Vector2(-1, 0), - new Vector2(0, 1) - ]; +module es { + /** + * 支持一种加权节点的基本网格图 + */ + export class WeightedGridGraph implements IWeightedGraph { + public static readonly CARDINAL_DIRS = [ + new Vector2(1, 0), + new Vector2(0, -1), + new Vector2(-1, 0), + new Vector2(0, 1) + ]; - private static readonly COMPASS_DIRS = [ - new Vector2(1, 0), - new Vector2(1, -1), - new Vector2(0, -1), - new Vector2(-1, -1), - new Vector2(-1, 0), - new Vector2(-1, 1), - new Vector2(0, 1), - new Vector2(1, 1), - ]; + private static readonly COMPASS_DIRS = [ + new Vector2(1, 0), + new Vector2(1, -1), + new Vector2(0, -1), + new Vector2(-1, -1), + new Vector2(-1, 0), + new Vector2(-1, 1), + new Vector2(0, 1), + new Vector2(1, 1), + ]; - public walls: Vector2[] = []; - public weightedNodes: Vector2[] = []; - public defaultWeight = 1; - public weightedNodeWeight = 5; + public walls: Vector2[] = []; + public weightedNodes: Vector2[] = []; + public defaultWeight = 1; + public weightedNodeWeight = 5; - private _width: number; - private _height: number; - private _dirs: Vector2[]; - private _neighbors: Vector2[] = new Array(4); + private _width: number; + private _height: number; + private _dirs: Vector2[]; + private _neighbors: Vector2[] = new Array(4); - constructor(width: number, height: number, allowDiagonalSearch: boolean = false){ - this._width = width; - this._height = height; - this._dirs = allowDiagonalSearch ? WeightedGridGraph.COMPASS_DIRS : WeightedGridGraph.CARDINAL_DIRS; + constructor(width: number, height: number, allowDiagonalSearch: boolean = false) { + this._width = width; + this._height = height; + this._dirs = allowDiagonalSearch ? WeightedGridGraph.COMPASS_DIRS : WeightedGridGraph.CARDINAL_DIRS; + } + + public isNodeInBounds(node: Vector2) { + return 0 <= node.x && node.x < this._width && 0 <= node.y && node.y < this._height; + } + + public isNodePassable(node: Vector2): boolean { + return !this.walls.firstOrDefault(wall => JSON.stringify(wall) == JSON.stringify(node)); + } + + public search(start: Vector2, goal: Vector2) { + return WeightedPathfinder.search(this, start, goal); + } + + public getNeighbors(node: Vector2): Vector2[] { + this._neighbors.length = 0; + + this._dirs.forEach(dir => { + let next = new Vector2(node.x + dir.x, node.y + dir.y); + if (this.isNodeInBounds(next) && this.isNodePassable(next)) + this._neighbors.push(next); + }); + + return this._neighbors; + } + + public cost(from: Vector2, to: Vector2): number { + return this.weightedNodes.find(t => JSON.stringify(t) == JSON.stringify(to)) ? this.weightedNodeWeight : this.defaultWeight; + } } - - public isNodeInBounds(node: Vector2){ - return 0 <= node.x && node.x < this._width && 0 <= node.y && node.y < this._height; - } - - public isNodePassable(node: Vector2): boolean { - return !this.walls.firstOrDefault(wall => JSON.stringify(wall) == JSON.stringify(node)); - } - - public search(start: Vector2, goal: Vector2){ - return WeightedPathfinder.search(this, start, goal); - } - - public getNeighbors(node: Vector2): Vector2[]{ - this._neighbors.length = 0; - - this._dirs.forEach(dir => { - let next = new Vector2(node.x + dir.x, node.y + dir.y); - if (this.isNodeInBounds(next) && this.isNodePassable(next)) - this._neighbors.push(next); - }); - - return this._neighbors; - } - - public cost(from: Vector2, to: Vector2): number{ - return this.weightedNodes.find(t => JSON.stringify(t) == JSON.stringify(to)) ? this.weightedNodeWeight : this.defaultWeight; - } -} \ No newline at end of file +} diff --git a/source/src/AI/Pathfinding/Dijkstra/WeightedPathfinder.ts b/source/src/AI/Pathfinding/Dijkstra/WeightedPathfinder.ts index 1150e696..0e10e293 100644 --- a/source/src/AI/Pathfinding/Dijkstra/WeightedPathfinder.ts +++ b/source/src/AI/Pathfinding/Dijkstra/WeightedPathfinder.ts @@ -1,83 +1,85 @@ -class WeightedNode extends PriorityQueueNode { - public data: T; +module es { + export class WeightedNode extends PriorityQueueNode { + public data: T; - constructor(data: T){ - super(); - this.data = data; + constructor(data: T) { + super(); + this.data = data; + } } -} -class WeightedPathfinder { - public static search(graph: IWeightedGraph, start: T, goal: T){ - let foundPath = false; + export class WeightedPathfinder { + public static search(graph: IWeightedGraph, start: T, goal: T) { + let foundPath = false; - let cameFrom = new Map(); - cameFrom.set(start, start); + let cameFrom = new Map(); + cameFrom.set(start, start); - let costSoFar = new Map(); - let frontier = new PriorityQueue>(1000); - frontier.enqueue(new WeightedNode(start), 0); + let costSoFar = new Map(); + let frontier = new PriorityQueue>(1000); + frontier.enqueue(new WeightedNode(start), 0); - costSoFar.set(start, 0); + costSoFar.set(start, 0); - while (frontier.count > 0){ - let current = frontier.dequeue(); - - if (JSON.stringify(current.data) == JSON.stringify(goal)){ - foundPath = true; - break; + while (frontier.count > 0) { + let current = frontier.dequeue(); + + if (JSON.stringify(current.data) == JSON.stringify(goal)) { + foundPath = true; + break; + } + + graph.getNeighbors(current.data).forEach(next => { + let newCost = costSoFar.get(current.data) + graph.cost(current.data, next); + if (!this.hasKey(costSoFar, next) || newCost < costSoFar.get(next)) { + costSoFar.set(next, newCost); + let priprity = newCost; + frontier.enqueue(new WeightedNode(next), priprity); + cameFrom.set(next, current.data); + } + }); } - graph.getNeighbors(current.data).forEach(next => { - let newCost = costSoFar.get(current.data) + graph.cost(current.data, next); - if (!this.hasKey(costSoFar, next) || newCost < costSoFar.get(next)){ - costSoFar.set(next, newCost); - let priprity = newCost; - frontier.enqueue(new WeightedNode(next), priprity); - cameFrom.set(next, current.data); - } - }); - } - - return foundPath ? this.recontructPath(cameFrom, start, goal) : null; - } - - private static hasKey(map: Map, compareKey: T){ - let iterator = map.keys(); - let r: IteratorResult; - while (r = iterator.next() , !r.done) { - if (JSON.stringify(r.value) == JSON.stringify(compareKey)) - return true; + return foundPath ? this.recontructPath(cameFrom, start, goal) : null; } - return false; - } + public static recontructPath(cameFrom: Map, start: T, goal: T): T[] { + let path = []; + let current = goal; + path.push(goal); - private static getKey(map: Map, compareKey: T){ - let iterator = map.keys(); - let valueIterator = map.values(); - let r: IteratorResult; - let v: IteratorResult; - while (r = iterator.next(), v = valueIterator.next(), !r.done) { - if (JSON.stringify(r.value) == JSON.stringify(compareKey)) - return v.value; + while (current != start) { + current = this.getKey(cameFrom, current); + path.push(current); + } + + path.reverse(); + + return path; } - return null; - } + private static hasKey(map: Map, compareKey: T) { + let iterator = map.keys(); + let r: IteratorResult; + while (r = iterator.next() , !r.done) { + if (JSON.stringify(r.value) == JSON.stringify(compareKey)) + return true; + } - public static recontructPath(cameFrom: Map, start: T, goal: T): T[]{ - let path = []; - let current = goal; - path.push(goal); - - while (current != start){ - current = this.getKey(cameFrom, current); - path.push(current); + return false; } - path.reverse(); + private static getKey(map: Map, compareKey: T) { + let iterator = map.keys(); + let valueIterator = map.values(); + let r: IteratorResult; + let v: IteratorResult; + while (r = iterator.next(), v = valueIterator.next(), !r.done) { + if (JSON.stringify(r.value) == JSON.stringify(compareKey)) + return v.value; + } - return path; + return null; + } } -} \ No newline at end of file +} diff --git a/source/src/Debug/Debug.ts b/source/src/Debug/Debug.ts new file mode 100644 index 00000000..be5abb28 --- /dev/null +++ b/source/src/Debug/Debug.ts @@ -0,0 +1,24 @@ +module es { + export class Debug { + private static _debugDrawItems: DebugDrawItem[] = []; + + public static drawHollowRect(rectanle: Rectangle, color: number, duration = 0) { + this._debugDrawItems.push(new DebugDrawItem(rectanle, color, duration)); + } + + public static render() { + if (this._debugDrawItems.length > 0) { + let debugShape = new egret.Shape(); + if (Core.scene) { + Core.scene.addChild(debugShape); + } + + for (let i = this._debugDrawItems.length - 1; i >= 0; i--) { + let item = this._debugDrawItems[i]; + if (item.draw(debugShape)) + this._debugDrawItems.removeAt(i); + } + } + } + } +} diff --git a/source/src/Debug/DebugDefaults.ts b/source/src/Debug/DebugDefaults.ts index 9b79445c..febc8a01 100644 --- a/source/src/Debug/DebugDefaults.ts +++ b/source/src/Debug/DebugDefaults.ts @@ -1,4 +1,6 @@ -class DebugDefaults { - public static verletParticle = 0xDC345E; - public static verletConstraintEdge = 0x433E36; -} \ No newline at end of file +module es { + export class DebugDefaults { + public static verletParticle = 0xDC345E; + public static verletConstraintEdge = 0x433E36; + } +} diff --git a/source/src/Debug/DebugDrawItem.ts b/source/src/Debug/DebugDrawItem.ts new file mode 100644 index 00000000..cb57f5b3 --- /dev/null +++ b/source/src/Debug/DebugDrawItem.ts @@ -0,0 +1,49 @@ +module es { + export enum DebugDrawType { + line, + hollowRectangle, + pixel, + text + } + + export class DebugDrawItem { + public rectangle: Rectangle; + public color: number; + public duration: number; + public drawType: DebugDrawType; + public text: string; + public start: Vector2; + public end: Vector2; + public x: number; + public y: number; + public size: number; + + constructor(rectangle: Rectangle, color: number, duration: number) { + this.rectangle = rectangle; + this.color = color; + this.duration = duration; + this.drawType = DebugDrawType.hollowRectangle; + } + + public draw(shape: egret.Shape): boolean { + switch (this.drawType) { + case DebugDrawType.line: + DrawUtils.drawLine(shape, this.start, this.end, this.color); + break; + case DebugDrawType.hollowRectangle: + DrawUtils.drawHollowRect(shape, this.rectangle, this.color); + break; + case DebugDrawType.pixel: + DrawUtils.drawPixel(shape, new Vector2(this.x, this.y), this.color, this.size); + break; + case DebugDrawType.text: + break; + } + + this.duration -= Time.deltaTime; + return this.duration < 0; + } + } +} + + diff --git a/source/src/ECS/Component.ts b/source/src/ECS/Component.ts index a365bab7..2959113e 100644 --- a/source/src/ECS/Component.ts +++ b/source/src/ECS/Component.ts @@ -1,75 +1,137 @@ -abstract class Component extends egret.DisplayObjectContainer { - public entity: Entity; - private _enabled: boolean = true; - public updateInterval: number = 1; - /** 允许用户为实体存入信息 */ - public userData: any; +module es { + /** + * 执行顺序 + * - onAddedToEntity + * - OnEnabled + * + * 删除执行顺序 + * - onRemovedFromEntity + */ + export abstract class Component extends egret.HashObject { + /** + * 此组件附加的实体 + */ + public entity: Entity; + /** + * 更新该组件的时间间隔。这与实体的更新间隔无关。 + */ + public updateInterval: number = 1; - public get enabled(){ - return this.entity ? this.entity.enabled && this._enabled : this._enabled; - } - - public set enabled(value: boolean){ - this.setEnabled(value); - } - - public setEnabled(isEnabled: boolean){ - if (this._enabled != isEnabled){ - this._enabled = isEnabled; - - if (this._enabled){ - this.onEnabled(); - }else{ - this.onDisabled(); - } + /** + * 快速访问 this.entity.transform + */ + public get transform(): Transform { + return this.entity.transform; } - return this; + private _enabled: boolean = true; + + /** + * 如果组件和实体都已启用,则为。当启用该组件时,将调用该组件的生命周期方法。状态的改变会导致调用onEnabled/onDisable。 + */ + public get enabled() { + return this.entity ? this.entity.enabled && this._enabled : this._enabled; + } + + /** + * 如果组件和实体都已启用,则为。当启用该组件时,将调用该组件的生命周期方法。状态的改变会导致调用onEnabled/onDisable。 + * @param value + */ + public set enabled(value: boolean) { + this.setEnabled(value); + } + + private _updateOrder = 0; + + /** 更新此实体上组件的顺序 */ + public get updateOrder() { + return this._updateOrder; + } + + /** 更新此实体上组件的顺序 */ + public set updateOrder(value: number) { + this.setUpdateOrder(value); + } + + /** + * 当此组件已分配其实体,但尚未添加到实体的活动组件列表时调用。有用的东西,如物理组件,需要访问转换来修改碰撞体的属性。 + */ + public initialize() { + } + + /** + * 在提交所有挂起的组件更改后,将该组件添加到场景时调用。此时,设置了实体字段和实体。场景也设定好了。 + */ + public onAddedToEntity() { + } + + /** + * 当此组件从其实体中移除时调用。在这里做所有的清理工作。 + */ + public onRemovedFromEntity() { + } + + /** + * 当实体的位置改变时调用。这允许组件知道它们由于父实体的移动而移动了。 + * @param comp + */ + public onEntityTransformChanged(comp: transform.Component) { + } + + /** + * + */ + public debugRender() { + } + + /** + *当父实体或此组件启用时调用 + */ + public onEnabled() { + } + + /** + * 禁用父实体或此组件时调用 + */ + public onDisabled() { + } + + /** + * 当该组件启用时每帧进行调用 + */ + public update() { + } + + public setEnabled(isEnabled: boolean) { + if (this._enabled != isEnabled) { + this._enabled = isEnabled; + + if (this._enabled) { + this.onEnabled(); + } else { + this.onDisabled(); + } + } + + return this; + } + + public setUpdateOrder(updateOrder: number) { + if (this._updateOrder != updateOrder) { + this._updateOrder = updateOrder; + } + + return this; + } + + /** + * 创建此组件的克隆 + */ + public clone(): Component { + let component = ObjectUtils.clone(this); + component.entity = null; + + return component; + } } - - public initialize(){ - } - - public onAddedToEntity(){ - - } - - public onRemovedFromEntity(){ - - } - - public onEnabled(){ - - } - - public onDisabled(){ - - } - - public update(){ - - } - - public debugRender(){ - - } - - /** - * 当实体的位置改变时调用。这允许组件知道它们由于父实体的移动而移动了。 - * @param comp - */ - public onEntityTransformChanged(comp: TransformComponent){ - - } - - /** 内部使用 运行时不应该调用 */ - public registerComponent(){ - this.entity.componentBits.set(ComponentTypeManager.getIndexFor(this), false); - this.entity.scene.entityProcessors.onComponentAdded(this.entity); - } - - public deregisterComponent(){ - this.entity.componentBits.set(ComponentTypeManager.getIndexFor(this)); - this.entity.scene.entityProcessors.onComponentRemoved(this.entity); - } -} \ No newline at end of file +} diff --git a/source/src/ECS/Components/Camera.ts b/source/src/ECS/Components/Camera.ts index 9a1f7e68..4c3c67f0 100644 --- a/source/src/ECS/Components/Camera.ts +++ b/source/src/ECS/Components/Camera.ts @@ -1,235 +1,484 @@ -/// -class Camera extends Component { - private _zoom; - private _origin: Vector2 = Vector2.zero; - - private _minimumZoom = 0.3; - private _maximumZoom = 3; - - private _position: Vector2 = Vector2.zero; - /** - * 如果相机模式为cameraWindow 则会进行缓动移动 - * 该值为移动速度 - */ - public followLerp = 0.1; - public deadzone: Rectangle = new Rectangle(); - /** 锁定偏移量 默认中心 */ - public focusOffset: Vector2 = new Vector2(); - /** 是否地图锁定 如果锁定则需要设置mapSize属性 */ - public mapLockEnabled: boolean = false; - /** 设置地图大小 默认从0 0左上角开始 只需要输入地图宽高 */ - public mapSize: Vector2 = new Vector2(); - /** 跟随的实体 设置后镜头将锁定目标为中心 */ - public targetEntity: Entity; - private _worldSpaceDeadZone: Rectangle = new Rectangle(); - private _desiredPositionDelta: Vector2 = new Vector2(); - private _targetCollider: Collider; - /** 相机模式 */ - public cameraStyle: CameraStyle = CameraStyle.lockOn; - - public get zoom(){ - if (this._zoom == 0) - return 1; - - if (this._zoom < 1) - return MathHelper.map(this._zoom, this._minimumZoom, 1, -1, 0); - - return MathHelper.map(this._zoom, 1, this._maximumZoom, 0, 1); +module es { + export enum CameraStyle { + lockOn, + cameraWindow, } - public set zoom(value: number){ - this.setZoom(value); + export class CameraInset { + public left: number = 0; + public right: number = 0; + public top: number = 0; + public bottom: number = 0; } - public get minimumZoom(){ - return this._minimumZoom; - } + export class Camera extends Component { + public _inset: CameraInset = new CameraInset(); + public _areMatrixedDirty: boolean = true; + public _areBoundsDirty: boolean = true; + public _isProjectionMatrixDirty = true; + /** + * 如果相机模式为cameraWindow 则会进行缓动移动 + * 该值为移动速度 + */ + public followLerp = 0.1; + /** + * 在cameraWindow模式下,宽度/高度被用做边界框,允许在不移动相机的情况下移动 + * 在lockOn模式下,只使用deadZone的x/y值 你可以通过直接setCenteredDeadzone重写它来自定义deadZone + */ + public deadzone: Rectangle = new Rectangle(); + /** + * 相机聚焦于屏幕中心的偏移 + */ + public focusOffset: Vector2 = Vector2.zero; + /** + * 如果为true 相机位置则不会超出地图矩形(0, 0, mapwidth, mapheight) + */ + public mapLockEnabled: boolean = false; + /** + * 當前地圖映射的寬度和高度 + */ + public mapSize: Vector2 = Vector2.zero; + public _targetEntity: Entity; + public _targetCollider: Collider; + public _desiredPositionDelta: Vector2 = new Vector2(); + public _cameraStyle: CameraStyle; + public _worldSpaceDeadZone: Rectangle = new Rectangle(); - public set minimumZoom(value: number){ - this.setMinimumZoom(value); - } + constructor(targetEntity: Entity = null, cameraStyle: CameraStyle = CameraStyle.lockOn) { + super(); - public get maximumZoom(){ - return this._maximumZoom; - } - - public set maximumZoom(value: number){ - this.setMaximumZoom(value); - } - - public get origin(){ - return this._origin; - } - - public set origin(value: Vector2){ - if (this._origin != value){ - this._origin = value; - } - } - - public get position(){ - return this._position; - } - - public set position(value: Vector2){ - this._position = value; - } - - public get x(){ - return this._position.x; - } - public set x(value: number){ - this._position.x = value; - } - public get y(){ - return this._position.y; - } - public set y(value: number){ - this._position.y = value; - } - - constructor() { - super(); - - this.width = SceneManager.stage.stageWidth; - this.height = SceneManager.stage.stageHeight; - this.setZoom(0); - } - - public onSceneSizeChanged(newWidth: number, newHeight: number){ - let oldOrigin = this._origin; - this.origin = new Vector2(newWidth / 2, newHeight / 2); - - this.entity.position = Vector2.add(this.entity.position, Vector2.subtract(this._origin, oldOrigin)); - } - - public setMinimumZoom(minZoom: number): Camera{ - if (this._zoom < minZoom) - this._zoom = this.minimumZoom; - - this._minimumZoom = minZoom; - return this; - } - - public setMaximumZoom(maxZoom: number): Camera { - if (this._zoom > maxZoom) - this._zoom = maxZoom; - - this._maximumZoom = maxZoom; - return this; - } - - public setZoom(zoom: number): Camera{ - let newZoom = MathHelper.clamp(zoom, -1, 1); - if (newZoom == 0){ - this._zoom = 1; - } else if(newZoom < 0){ - this._zoom = MathHelper.map(newZoom, -1, 0, this._minimumZoom, 1); - } else { - this._zoom = MathHelper.map(newZoom, 0, 1, 1, this._maximumZoom); + this._targetEntity = targetEntity; + this._cameraStyle = cameraStyle; + this.setZoom(0); } - SceneManager.scene.scaleX = this._zoom; - SceneManager.scene.scaleY = this._zoom; - return this; - } - - public setRotation(rotation: number): Camera { - SceneManager.scene.rotation = rotation; - return this; - } - - public setPosition(position: Vector2){ - this.entity.position = position; - - return this; - } - - public follow(targetEntity: Entity, cameraStyle: CameraStyle = CameraStyle.cameraWindow){ - this.targetEntity = targetEntity; - this.cameraStyle = cameraStyle; - let cameraBounds = new Rectangle(0, 0, SceneManager.stage.stageWidth, SceneManager.stage.stageHeight); - - switch (this.cameraStyle){ - case CameraStyle.cameraWindow: - let w = cameraBounds.width / 6; - let h = cameraBounds.height / 3; - this.deadzone = new Rectangle((cameraBounds.width - w) / 2, (cameraBounds.height - h) / 2, w, h); - break; - case CameraStyle.lockOn: - this.deadzone = new Rectangle(cameraBounds.width / 2, cameraBounds.height / 2, 10, 10); - break; + /** + * 对entity.transform.position的快速访问 + */ + public get position() { + return this.entity.transform.position; } - } - public update(){ - let cameraBounds = new Rectangle(0, 0, SceneManager.stage.stageWidth, SceneManager.stage.stageHeight); - let halfScreen = Vector2.multiply(new Vector2(cameraBounds.width, cameraBounds.height), new Vector2(0.5)); - this._worldSpaceDeadZone.x = this.position.x - halfScreen.x + this.deadzone.x + this.focusOffset.x; - this._worldSpaceDeadZone.y = this.position.y - halfScreen.y + this.deadzone.y + this.focusOffset.y; - this._worldSpaceDeadZone.width = this.deadzone.width; - this._worldSpaceDeadZone.height = this.deadzone.height; - - if (this.targetEntity) - this.updateFollow(); - - this.position = Vector2.lerp(this.position, Vector2.add(this.position, this._desiredPositionDelta), this.followLerp); - this.entity.roundPosition(); - - if (this.mapLockEnabled){ - this.position = this.clampToMapSize(this.position); - this.entity.roundPosition(); + /** + * 对entity.transform.position的快速访问 + * @param value + */ + public set position(value: Vector2) { + this.entity.transform.position = value; } - } - private clampToMapSize(position: Vector2){ - let cameraBounds = new Rectangle(0, 0, SceneManager.stage.stageWidth, SceneManager.stage.stageHeight); - let halfScreen = Vector2.multiply(new Vector2(cameraBounds.width, cameraBounds.height), new Vector2(0.5)); - let cameraMax = new Vector2(this.mapSize.x - halfScreen.x, this.mapSize.y - halfScreen.y); + /** + * 对entity.transform.rotation的快速访问 + */ + public get rotation(): number { + return this.entity.transform.rotation; + } - return Vector2.clamp(position, halfScreen, cameraMax); - } + /** + * 对entity.transform.rotation的快速访问 + * @param value + */ + public set rotation(value: number) { + this.entity.transform.rotation = value; + } - private updateFollow(){ - this._desiredPositionDelta.x = this._desiredPositionDelta.y = 0; + public _zoom; - if (this.cameraStyle == CameraStyle.lockOn){ - let targetX = this.targetEntity.position.x; - let targetY = this.targetEntity.position.y; + /** + * 缩放值应该在-1和1之间、然后将该值从minimumZoom转换为maximumZoom。 + * 允许你设置适当的最小/最大值,然后使用更直观的-1到1的映射来更改缩放 + */ + public get zoom() { + if (this._zoom == 0) + return 1; - if (this._worldSpaceDeadZone.x > targetX) - this._desiredPositionDelta.x = targetX - this._worldSpaceDeadZone.x; - else if(this._worldSpaceDeadZone.x < targetX) - this._desiredPositionDelta.x = targetX - this._worldSpaceDeadZone.x; + if (this._zoom < 1) + return MathHelper.map(this._zoom, this._minimumZoom, 1, -1, 0); - if (this._worldSpaceDeadZone.y < targetY) - this._desiredPositionDelta.y = targetY - this._worldSpaceDeadZone.y; - else if(this._worldSpaceDeadZone.y > targetY) - this._desiredPositionDelta.y = targetY - this._worldSpaceDeadZone.y; - } else { - if (!this._targetCollider){ - this._targetCollider = this.targetEntity.getComponent(Collider); - if (!this._targetCollider) - return; + return MathHelper.map(this._zoom, 1, this._maximumZoom, 0, 1); + } + + /** + * 缩放值应该在-1和1之间、然后将该值从minimumZoom转换为maximumZoom。 + * 允许你设置适当的最小/最大值,然后使用更直观的-1到1的映射来更改缩放 + * @param value + */ + public set zoom(value: number) { + this.setZoom(value); + } + + public _minimumZoom = 0.3; + + /** + * 相机变焦可以达到的最小非缩放值(0-number.max)。默认为0.3 + */ + public get minimumZoom() { + return this._minimumZoom; + } + + /** + * 相机变焦可以达到的最小非缩放值(0-number.max)。默认为0.3 + * @param value + */ + public set minimumZoom(value: number) { + this.setMinimumZoom(value); + } + + public _maximumZoom = 3; + + /** + * 相机变焦可以达到的最大非缩放值(0-number.max)。默认为3 + */ + public get maximumZoom() { + return this._maximumZoom; + } + + /** + * 相机变焦可以达到的最大非缩放值(0-number.max)。默认为3 + * @param value + */ + public set maximumZoom(value: number) { + this.setMaximumZoom(value); + } + + public _bounds: Rectangle = new Rectangle(); + + /** + * 相机的世界-空间边界 + */ + public get bounds() { + if (this._areMatrixedDirty) + this.updateMatrixes(); + + if (this._areBoundsDirty) { + // 旋转或非旋转的边界都需要左上角和右下角 + let topLeft = this.screenToWorldPoint(new Vector2(this._inset.left, this._inset.top)); + let bottomRight = this.screenToWorldPoint(new Vector2(Core.graphicsDevice.viewport.width - this._inset.right, + Core.graphicsDevice.viewport.height - this._inset.bottom)); + + if (this.entity.transform.rotation != 0) { + // 特别注意旋转的边界。我们需要找到绝对的最小/最大值并从中创建边界 + let topRight = this.screenToWorldPoint(new Vector2(Core.graphicsDevice.viewport.width - this._inset.right, + this._inset.top)); + let bottomLeft = this.screenToWorldPoint(new Vector2(this._inset.left, + Core.graphicsDevice.viewport.height - this._inset.bottom)); + + let minX = Math.min(topLeft.x, bottomRight.x, topRight.x, bottomLeft.x); + let maxX = Math.max(topLeft.x, bottomRight.x, topRight.x, bottomLeft.x); + let minY = Math.min(topLeft.y, bottomRight.y, topRight.y, bottomLeft.y); + let maxY = Math.max(topLeft.y, bottomRight.y, topRight.y, bottomLeft.y); + + this._bounds.location = new Vector2(minX, minY); + this._bounds.width = maxX - minX; + this._bounds.height = maxY - minY; + } else { + this._bounds.location = topLeft; + this._bounds.width = bottomRight.x - topLeft.x; + this._bounds.height = bottomRight.y - topLeft.y; + } + + this._areBoundsDirty = false; } - let targetBounds = this.targetEntity.getComponent(Collider).bounds; - if (!this._worldSpaceDeadZone.containsRect(targetBounds)){ - if (this._worldSpaceDeadZone.left > targetBounds.left) - this._desiredPositionDelta.x = targetBounds.left - this._worldSpaceDeadZone.left; - else if(this._worldSpaceDeadZone.right < targetBounds.right) - this._desiredPositionDelta.x = targetBounds.right - this._worldSpaceDeadZone.right; + return this._bounds; + } - if (this._worldSpaceDeadZone.bottom < targetBounds.bottom) - this._desiredPositionDelta.y = targetBounds.bottom - this._worldSpaceDeadZone.bottom; - else if(this._worldSpaceDeadZone.top > targetBounds.top) - this._desiredPositionDelta.y = targetBounds.top - this._worldSpaceDeadZone.top; + public _transformMatrix: Matrix2D = new Matrix2D().identity(); + + /** + * 用于从世界坐标转换到屏幕 + */ + public get transformMatrix(): Matrix2D { + if (this._areMatrixedDirty) + this.updateMatrixes(); + return this._transformMatrix; + } + + public _inverseTransformMatrix: Matrix2D = new Matrix2D().identity(); + + /** + * 用于从屏幕坐标到世界的转换 + */ + public get inverseTransformMatrix(): Matrix2D { + if (this._areMatrixedDirty) + this.updateMatrixes(); + return this._inverseTransformMatrix; + } + + public _origin: Vector2 = Vector2.zero; + + public get origin() { + return this._origin; + } + + public set origin(value: Vector2) { + if (this._origin != value) { + this._origin = value; + this._areMatrixedDirty = true; } } + + /** + * 当场景渲染目标的大小发生变化时,我们会更新相机的原点并调整它的位置以保持它原来的位置 + * @param newWidth + * @param newHeight + */ + public onSceneSizeChanged(newWidth: number, newHeight: number) { + let oldOrigin = this._origin; + this.origin = new Vector2(newWidth / 2, newHeight / 2); + + this.entity.transform.position = Vector2.add(this.entity.transform.position, Vector2.subtract(this._origin, oldOrigin)); + } + + /** + * 设置用于从视口边缘插入摄像机边界的量 + * @param left + * @param right + * @param top + * @param bottom + */ + public setInset(left: number, right: number, top: number, bottom: number): Camera { + this._inset = new CameraInset(); + this._inset.left = left; + this._inset.right = right; + this._inset.top = top; + this._inset.bottom = bottom; + this._areBoundsDirty = true; + return this; + } + + /** + * 对entity.transform.setPosition快速访问 + * @param position + */ + public setPosition(position: Vector2) { + this.entity.transform.setPosition(position.x, position.y); + return this; + } + + /** + * 对entity.transform.setRotation的快速访问 + * @param rotation + */ + public setRotation(rotation: number): Camera { + this.entity.transform.setRotation(rotation); + return this; + } + + /** + * 设置缩放值,缩放值应该在-1到1之间。然后将该值从minimumZoom转换为maximumZoom + * 允许您设置适当的最小/最大值。使用更直观的-1到1的映射来更改缩放 + * @param zoom + */ + public setZoom(zoom: number): Camera { + let newZoom = MathHelper.clamp(zoom, -1, 1); + if (newZoom == 0) { + this._zoom = 1; + } else if (newZoom < 0) { + this._zoom = MathHelper.map(newZoom, -1, 0, this._minimumZoom, 1); + } else { + this._zoom = MathHelper.map(newZoom, 0, 1, 1, this._maximumZoom); + } + this._areMatrixedDirty = true; + + return this; + } + + /** + * 相机变焦可以达到的最小非缩放值(0-number.max) 默认为0.3 + * @param minZoom + */ + public setMinimumZoom(minZoom: number): Camera { + if (minZoom <= 0) { + console.error("minimumZoom must be greater than zero"); + return; + } + + if (this._zoom < minZoom) + this._zoom = this.minimumZoom; + + this._minimumZoom = minZoom; + return this; + } + + /** + * 相机变焦可以达到的最大非缩放值(0-number.max) 默认为3 + * @param maxZoom + */ + public setMaximumZoom(maxZoom: number): Camera { + if (maxZoom <= 0) { + console.error("maximumZoom must be greater than zero"); + return; + } + + if (this._zoom > maxZoom) + this._zoom = maxZoom; + + this._maximumZoom = maxZoom; + return this; + } + + public onEntityTransformChanged(comp: transform.Component) { + this._areMatrixedDirty = true; + } + + public zoomIn(deltaZoom: number) { + this.zoom += deltaZoom; + } + + public zoomOut(deltaZoom: number) { + this.zoom -= deltaZoom; + } + + /** + * 将一个点从世界坐标转换到屏幕 + * @param worldPosition + */ + public worldToScreenPoint(worldPosition: Vector2): Vector2 { + this.updateMatrixes(); + worldPosition = Vector2.transform(worldPosition, this._transformMatrix); + return worldPosition; + } + + /** + * 将点从屏幕坐标转换为世界坐标 + * @param screenPosition + */ + public screenToWorldPoint(screenPosition: Vector2): Vector2 { + this.updateMatrixes(); + screenPosition = Vector2.transform(screenPosition, this._inverseTransformMatrix); + return screenPosition; + } + + /** + * 返回鼠标在世界空间中的位置 + */ + public mouseToWorldPoint(): Vector2 { + return this.screenToWorldPoint(Input.touchPosition); + } + + public onAddedToEntity() { + this.follow(this._targetEntity, this._cameraStyle); + } + + public update() { + let halfScreen = Vector2.multiply(new Vector2(this.bounds.width, this.bounds.height), new Vector2(0.5)); + this._worldSpaceDeadZone.x = this.position.x - halfScreen.x * Core.scene.scaleX + this.deadzone.x + this.focusOffset.x; + this._worldSpaceDeadZone.y = this.position.y - halfScreen.y * Core.scene.scaleY + this.deadzone.y + this.focusOffset.y; + this._worldSpaceDeadZone.width = this.deadzone.width; + this._worldSpaceDeadZone.height = this.deadzone.height; + + if (this._targetEntity) + this.updateFollow(); + + this.position = Vector2.lerp(this.position, Vector2.add(this.position, this._desiredPositionDelta), this.followLerp); + this.entity.transform.roundPosition(); + + if (this.mapLockEnabled) { + this.position = this.clampToMapSize(this.position); + this.entity.transform.roundPosition(); + } + } + + /** + * 固定相机 永远不会离开地图的可见区域 + * @param position + */ + public clampToMapSize(position: Vector2) { + let halfScreen = Vector2.multiply(new Vector2(this.bounds.width, this.bounds.height), new Vector2(0.5)); + let cameraMax = new Vector2(this.mapSize.x - halfScreen.x, this.mapSize.y - halfScreen.y); + + return Vector2.clamp(position, halfScreen, cameraMax); + } + + public updateFollow() { + this._desiredPositionDelta.x = this._desiredPositionDelta.y = 0; + + if (this._cameraStyle == CameraStyle.lockOn) { + let targetX = this._targetEntity.transform.position.x; + let targetY = this._targetEntity.transform.position.y; + + if (this._worldSpaceDeadZone.x > targetX) + this._desiredPositionDelta.x = targetX - this._worldSpaceDeadZone.x; + else if (this._worldSpaceDeadZone.x < targetX) + this._desiredPositionDelta.x = targetX - this._worldSpaceDeadZone.x; + + if (this._worldSpaceDeadZone.y < targetY) + this._desiredPositionDelta.y = targetY - this._worldSpaceDeadZone.y; + else if (this._worldSpaceDeadZone.y > targetY) + this._desiredPositionDelta.y = targetY - this._worldSpaceDeadZone.y; + } else { + if (!this._targetCollider) { + this._targetCollider = this._targetEntity.getComponent(Collider); + if (!this._targetCollider) + return; + } + + let targetBounds = this._targetEntity.getComponent(Collider).bounds; + if (!this._worldSpaceDeadZone.containsRect(targetBounds)) { + if (this._worldSpaceDeadZone.left > targetBounds.left) + this._desiredPositionDelta.x = targetBounds.left - this._worldSpaceDeadZone.left; + else if (this._worldSpaceDeadZone.right < targetBounds.right) + this._desiredPositionDelta.x = targetBounds.right - this._worldSpaceDeadZone.right; + + if (this._worldSpaceDeadZone.bottom < targetBounds.bottom) + this._desiredPositionDelta.y = targetBounds.bottom - this._worldSpaceDeadZone.bottom; + else if (this._worldSpaceDeadZone.top > targetBounds.top) + this._desiredPositionDelta.y = targetBounds.top - this._worldSpaceDeadZone.top; + } + } + } + + public follow(targetEntity: Entity, cameraStyle: CameraStyle = CameraStyle.cameraWindow) { + this._targetEntity = targetEntity; + this._cameraStyle = cameraStyle; + + switch (this._cameraStyle) { + case CameraStyle.cameraWindow: + let w = this.bounds.width / 6; + let h = this.bounds.height / 3; + this.deadzone = new Rectangle((this.bounds.width - w) / 2, (this.bounds.height - h) / 2, w, h); + break; + case CameraStyle.lockOn: + this.deadzone = new Rectangle(this.bounds.width / 2, this.bounds.height / 2, 10, 10); + break; + } + } + + /** + * 以给定的尺寸设置当前相机边界中心的死区 + * @param width + * @param height + */ + public setCenteredDeadzone(width: number, height: number) { + this.deadzone = new Rectangle((this.bounds.width - width) / 2, (this.bounds.height - height) / 2, width, height); + } + + protected updateMatrixes() { + if (!this._areMatrixedDirty) + return; + + let tempMat: Matrix2D; + this._transformMatrix = Matrix2D.create().translate(-this.entity.transform.position.x, -this.entity.transform.position.y); + + if (this._zoom != 1) { + tempMat = Matrix2D.create().scale(this._zoom, this._zoom); + this._transformMatrix = this._transformMatrix.multiply(tempMat); + } + + if (this.entity.transform.rotation != 0) { + tempMat = Matrix2D.create().rotate(this.entity.transform.rotation); + this._transformMatrix = this._transformMatrix.multiply(tempMat); + } + + tempMat = Matrix2D.create().translate(this._origin.x, this._origin.y); + this._transformMatrix = this._transformMatrix.multiply(tempMat); + + this._inverseTransformMatrix = this._transformMatrix.invert(); + + // 无论何时矩阵改变边界都是无效的 + this._areBoundsDirty = true; + this._areMatrixedDirty = false; + } } } - -enum CameraStyle { - lockOn, - cameraWindow, -} \ No newline at end of file diff --git a/source/src/ECS/Components/ComponentPool.ts b/source/src/ECS/Components/ComponentPool.ts index df1d66f2..8b52e501 100644 --- a/source/src/ECS/Components/ComponentPool.ts +++ b/source/src/ECS/Components/ComponentPool.ts @@ -1,22 +1,24 @@ -class ComponentPool{ - private _cache: T[]; - private _type: any; +module es { + export class ComponentPool { + private _cache: T[]; + private _type: any; - constructor(typeClass: any){ - this._type = typeClass; - this._cache = []; - } + constructor(typeClass: any) { + this._type = typeClass; + this._cache = []; + } - public obtain(): T{ - try { - return this._cache.length > 0 ? this._cache.shift() : new this._type(); - } catch(err){ - throw new Error(this._type + err); + public obtain(): T { + try { + return this._cache.length > 0 ? this._cache.shift() : new this._type(); + } catch (err) { + throw new Error(this._type + err); + } + } + + public free(component: T) { + component.reset(); + this._cache.push(component); } } - - public free(component: T){ - component.reset(); - this._cache.push(component); - } -} \ No newline at end of file +} diff --git a/source/src/ECS/Components/IUpdatableComparer.ts b/source/src/ECS/Components/IUpdatableComparer.ts new file mode 100644 index 00000000..48185319 --- /dev/null +++ b/source/src/ECS/Components/IUpdatableComparer.ts @@ -0,0 +1,10 @@ +module es { + /** + * 用于比较组件更新排序 + */ + export class IUpdatableComparer { + public compare(a: Component, b: Component) { + return a.updateOrder - b.updateOrder; + } + } +} \ No newline at end of file diff --git a/source/src/ECS/Components/Mesh.ts b/source/src/ECS/Components/Mesh.ts index bea8a9c9..9e5c6207 100644 --- a/source/src/ECS/Components/Mesh.ts +++ b/source/src/ECS/Components/Mesh.ts @@ -1,32 +1,25 @@ /// -class Mesh extends RenderableComponent { - private _mesh: egret.Mesh; +module es { + export class Mesh extends RenderableComponent { + private _mesh: egret.Mesh; - constructor(){ - super(); + constructor() { + super(); - this._mesh = new egret.Mesh(); + this._mesh = new egret.Mesh(); + } + + public setTexture(texture: egret.Texture): Mesh { + this._mesh.texture = texture; + this._mesh.$renderNode = new egret.sys.RenderNode(); + + return this; + } + + public reset() { + } + + render(camera: es.Camera) { + } } - - public setTexture(texture: egret.Texture): Mesh{ - this._mesh.texture = texture; - - return this; - } - - public onAddedToEntity(){ - this.addChild(this._mesh); - } - - public onRemovedFromEntity(){ - this.removeChild(this._mesh); - } - - public render(camera: Camera){ - this.x = this.entity.position.x - camera.position.x + camera.origin.x; - this.y = this.entity.position.y - camera.position.y + camera.origin.y; - } - - public reset() { - } -} \ No newline at end of file +} diff --git a/source/src/ECS/Components/Physics/Colliders/BoxCollider.ts b/source/src/ECS/Components/Physics/Colliders/BoxCollider.ts index 14e56800..d8433430 100644 --- a/source/src/ECS/Components/Physics/Colliders/BoxCollider.ts +++ b/source/src/ECS/Components/Physics/Colliders/BoxCollider.ts @@ -1,74 +1,85 @@ /// -class BoxCollider extends Collider { - public get width(){ - return (this.shape as Box).width; - } +module es { + export class BoxCollider extends Collider { + /** + * 零参数构造函数要求RenderableComponent在实体上,这样碰撞器可以在实体被添加到场景时调整自身的大小。 + */ + constructor() { + super(); - public set width(value: number){ - this.setWidth(value); - } - - /** - * 设置BoxCollider的宽度 - * @param width - */ - public setWidth(width: number): BoxCollider{ - this._colliderRequiresAutoSizing = false; - let box = this.shape as Box; - if (width != box.width){ - // 更新框,改变边界,如果我们需要更新物理系统中的边界 - box.updateBox(width, box.height); - if (this.entity && this._isParentEntityAddedToScene) - Physics.updateCollider(this); + // 我们在这里插入一个1x1框作为占位符,直到碰撞器在下一阵被添加到实体并可以获得更精确的自动调整大小数据 + this.shape = new Box(1, 1); + this._colliderRequiresAutoSizing = true; } - return this; - } - - public get height(){ - return (this.shape as Box).height; - } - - public set height(value: number){ - this.setHeight(value); - } - - /** - * 设置BoxCollider的高度 - * @param height - */ - public setHeight(height: number){ - this._colliderRequiresAutoSizing = false; - let box = this.shape as Box; - if (height != box.height){ - // 更新框,改变边界,如果我们需要更新物理系统中的边界 - box.updateBox(box.width, height); - if (this.entity && this._isParentEntityAddedToScene) - Physics.updateCollider(this); - } - } - - /** - * 零参数构造函数要求RenderableComponent在实体上,这样碰撞器可以在实体被添加到场景时调整自身的大小。 - */ - constructor(){ - super(); - - // 我们在这里插入一个1x1框作为占位符,直到碰撞器在下一阵被添加到实体并可以获得更精确的自动调整大小数据 - this.shape = new Box(1, 1); - this._colliderRequiresAutoSizing = true; - } - - public setSize(width: number, height: number){ - this._colliderRequiresAutoSizing = false; - let box = this.shape as Box; - if (width != box.width || height != box.height){ - // 更新框,改变边界,如果我们需要更新物理系统中的边界 - box.updateBox(width, height); - if (this.entity && this._isParentEntityAddedToScene) - Physics.updateCollider(this); + public get width() { + return (this.shape as Box).width; } - return this; + public set width(value: number) { + this.setWidth(value); + } + + public get height() { + return (this.shape as Box).height; + } + + public set height(value: number) { + this.setHeight(value); + } + + /** + * 设置BoxCollider的大小 + * @param width + * @param height + */ + public setSize(width: number, height: number) { + this._colliderRequiresAutoSizing = false; + let box = this.shape as Box; + if (width != box.width || height != box.height) { + // 更新框,改变边界,如果我们需要更新物理系统中的边界 + box.updateBox(width, height); + if (this.entity && this._isParentEntityAddedToScene) + Physics.updateCollider(this); + } + + return this; + } + + /** + * 设置BoxCollider的宽度 + * @param width + */ + public setWidth(width: number): BoxCollider { + this._colliderRequiresAutoSizing = false; + let box = this.shape as Box; + if (width != box.width) { + // 更新框,改变边界,如果我们需要更新物理系统中的边界 + box.updateBox(width, box.height); + if (this.entity && this._isParentEntityAddedToScene) + Physics.updateCollider(this); + } + + return this; + } + + /** + * 设置BoxCollider的高度 + * @param height + */ + public setHeight(height: number) { + this._colliderRequiresAutoSizing = false; + let box = this.shape as Box; + if (height != box.height) { + // 更新框,改变边界,如果我们需要更新物理系统中的边界 + box.updateBox(box.width, height); + if (this.entity && this._isParentEntityAddedToScene) + Physics.updateCollider(this); + } + } + + public toString() { + return `[BoxCollider: bounds: ${this.bounds}]`; + } } -} \ No newline at end of file +} diff --git a/source/src/ECS/Components/Physics/Colliders/CircleCollider.ts b/source/src/ECS/Components/Physics/Colliders/CircleCollider.ts new file mode 100644 index 00000000..3612f6cb --- /dev/null +++ b/source/src/ECS/Components/Physics/Colliders/CircleCollider.ts @@ -0,0 +1,48 @@ +module es { + export class CircleCollider extends Collider { + /** + * 创建一个有半径的圆 + * + * @param radius + */ + constructor(radius?: number) { + super(); + + if (radius) + this._colliderRequiresAutoSizing = true; + // 我们在这里插入一个1px的圆圈作为占位符 + // 直到碰撞器被添加到实体并可以获得更精确的自动调整大小数据的下一帧 + this.shape = new Circle(radius ? radius : 1); + } + + public get radius(): number { + return (this.shape as Circle).radius; + } + + public set radius(value: number) { + this.setRadius(value); + } + + /** + * 设置圆的半径 + * @param radius + */ + public setRadius(radius: number): CircleCollider { + this._colliderRequiresAutoSizing = false; + let circle = this.shape as Circle; + if (radius != circle.radius) { + circle.radius = radius; + circle._originalRadius = radius; + + if (this.entity && this._isParentEntityAddedToScene) + Physics.updateCollider(this); + } + + return this; + } + + public toString() { + return `[CircleCollider: bounds: ${this.bounds}, radius: ${(this.shape as Circle).radius}]` + } + } +} diff --git a/source/src/ECS/Components/Physics/Colliders/Collider.ts b/source/src/ECS/Components/Physics/Colliders/Collider.ts index 40493224..dd53c5c4 100644 --- a/source/src/ECS/Components/Physics/Colliders/Collider.ts +++ b/source/src/ECS/Components/Physics/Colliders/Collider.ts @@ -1,146 +1,238 @@ -abstract class Collider extends Component{ - /** 对撞机的基本形状 */ - public shape: Shape; - /** 在处理冲突时,physicsLayer可以用作过滤器。Flags类有帮助位掩码的方法。 */ - public physicsLayer = 1 << 0; - /** 如果这个碰撞器是一个触发器,它将不会引起碰撞,但它仍然会触发事件 */ - public isTrigger: boolean; - /** - * 这个对撞机在物理系统注册时的边界。 - * 存储这个允许我们始终能够安全地从物理系统中移除对撞机,即使它在试图移除它之前已经被移动了。 - */ - public registeredPhysicsBounds: Rectangle = new Rectangle(); - /** 如果为true,碰撞器将根据附加的变换缩放和旋转 */ - public shouldColliderScaleAndRotateWithTransform = true; - /** 默认为所有层。 */ - public collidesWithLayers = Physics.allLayers; +module es { + export abstract class Collider extends Component { + /** + * 对撞机的基本形状 + */ + public shape: Shape; + /** + * 如果这个碰撞器是一个触发器,它将不会引起碰撞,但它仍然会触发事件 + */ + public isTrigger: boolean; + /** + * 在处理冲突时,physicsLayer可以用作过滤器。Flags类有帮助位掩码的方法 + */ + public physicsLayer = 1 << 0; + /** + * 碰撞器在使用移动器移动时应该碰撞的层 + * 默认为所有层 + */ + public collidesWithLayers = Physics.allLayers; + /** + * 如果为true,碰撞器将根据附加的变换缩放和旋转 + */ + public shouldColliderScaleAndRotateWithTransform = true; + /** + * 这个对撞机在物理系统注册时的边界。 + * 存储这个允许我们始终能够安全地从物理系统中移除对撞机,即使它在试图移除它之前已经被移动了。 + */ + public registeredPhysicsBounds: Rectangle = new Rectangle(); + public _localOffsetLength: number; + public _isPositionDirty: boolean = true; + public _isRotationDirty: boolean = true; + protected _colliderRequiresAutoSizing; + /** + * 标记来跟踪我们的实体是否被添加到场景中 + */ + protected _isParentEntityAddedToScene; + /** + * 标记来记录我们是否注册了物理系统 + */ + protected _isColliderRegistered; - public _localOffsetLength: number; - /** 标记来跟踪我们的实体是否被添加到场景中 */ - protected _isParentEntityAddedToScene; - protected _colliderRequiresAutoSizing; - protected _localOffset: Vector2 = new Vector2(0, 0); - /** 标记来记录我们是否注册了物理系统 */ - protected _isColliderRegistered; + /** + * 镖师碰撞器的绝对位置 + */ + public get absolutePosition(): Vector2 { + return Vector2.add(this.entity.transform.position, this._localOffset); + } - public get bounds(): Rectangle { - // this.shape.recalculateBounds(this); - let bds = this.entity.getBounds(); - return new Rectangle(bds.x, bds.y, bds.width, bds.height); - } + /** + * 封装变换。如果碰撞器没和实体一起旋转 则返回transform.rotation + */ + public get rotation(): number { + if (this.shouldColliderScaleAndRotateWithTransform && this.entity) + return this.entity.transform.rotation; - public get localOffset(){ - return new Vector2(this.x, this.y); - } + return 0; + } - /** - * 将localOffset添加到实体。获取碰撞器的最终位置。这允许您向一个实体添加多个碰撞器并分别定位它们。 - */ - public set localOffset(value: Vector2){ - this.setLocalOffset(value); - } + public get bounds(): Rectangle { + if (this._isPositionDirty || this._isRotationDirty) { + this.shape.recalculateBounds(this); + this._isPositionDirty = this._isRotationDirty = false; + } - public setLocalOffset(offset: Vector2){ - if (this._localOffset != offset){ - this.unregisterColliderWithPhysicsSystem(); - this.$setX(offset.x); - this.$setY(offset.y); - this._localOffsetLength = this._localOffset.length(); + return this.shape.bounds; + } + + protected _localOffset: Vector2 = Vector2.zero; + + /** + * 将localOffset添加到实体。获取碰撞器几何图形的最终位置。 + * 允许向一个实体添加多个碰撞器并分别定位,还允许你设置缩放/旋转 + */ + public get localOffset(): Vector2 { + return this._localOffset; + } + + /** + * 将localOffset添加到实体。获取碰撞器几何图形的最终位置。 + * 允许向一个实体添加多个碰撞器并分别定位,还允许你设置缩放/旋转 + * @param value + */ + public set localOffset(value: Vector2) { + this.setLocalOffset(value); + } + + /** + * 将localOffset添加到实体。获取碰撞器的最终位置。 + * 这允许您向一个实体添加多个碰撞器并分别定位它们。 + * @param offset + */ + public setLocalOffset(offset: Vector2): Collider { + if (this._localOffset != offset) { + this.unregisterColliderWithPhysicsSystem(); + this._localOffset = offset; + this._localOffsetLength = this._localOffset.length(); + this._isPositionDirty = true; + this.registerColliderWithPhysicsSystem(); + } + + return this; + } + + /** + * 如果为true,碰撞器将根据附加的变换缩放和旋转 + * @param shouldColliderScaleAndRotationWithTransform + */ + public setShouldColliderScaleAndRotateWithTransform(shouldColliderScaleAndRotationWithTransform: boolean): Collider { + this.shouldColliderScaleAndRotateWithTransform = shouldColliderScaleAndRotationWithTransform; + this._isPositionDirty = this._isRotationDirty = true; + return this; + } + + public onAddedToEntity() { + if (this._colliderRequiresAutoSizing) { + if (!(this instanceof BoxCollider || this instanceof CircleCollider)) { + console.error("Only box and circle colliders can be created automatically"); + return; + } + + let renderable = this.entity.getComponent(RenderableComponent); + if (renderable) { + let renderableBounds = renderable.bounds; + + // 这里我们需要大小*反尺度,因为当我们自动调整碰撞器的大小时,它需要没有缩放的渲染 + let width = renderableBounds.width / this.entity.scale.x; + let height = renderableBounds.height / this.entity.scale.y; + // 圆碰撞器需要特别注意原点 + if (this instanceof CircleCollider) { + this.radius = Math.max(width, height) * 0.5; + } else { + this.width = width; + this.height = height; + } + + // 获取渲染的中心,将其转移到本地坐标,并使用它作为碰撞器的localOffset + this.localOffset = Vector2.subtract(renderableBounds.center, this.entity.transform.position); + } else { + console.warn("Collider has no shape and no RenderableComponent. Can't figure out how to size it."); + } + } + + this._isParentEntityAddedToScene = true; this.registerColliderWithPhysicsSystem(); } - } - /** - * 父实体会在不同的时间调用它(当添加到场景,启用,等等) - */ - public registerColliderWithPhysicsSystem(){ - // 如果在将我们添加到实体之前更改了origin等属性,则实体可以为null - if (this._isParentEntityAddedToScene && !this._isColliderRegistered){ - Physics.addCollider(this); - this._isColliderRegistered = true; + public onRemovedFromEntity() { + this.unregisterColliderWithPhysicsSystem(); + this._isParentEntityAddedToScene = false; } - } - /** - * 父实体会在不同的时候调用它(从场景中移除,禁用,等等) - */ - public unregisterColliderWithPhysicsSystem(){ - if (this._isParentEntityAddedToScene && this._isColliderRegistered){ - Physics.removeCollider(this); - } - this._isColliderRegistered = false; - } - - /** - * 检查这个形状是否与物理系统中的其他对撞机重叠 - * @param other - */ - public overlaps(other: Collider){ - return this.shape.overlaps(other.shape); - } - - /** - * 检查这个与运动应用的碰撞器(移动向量)是否与碰撞器碰撞。如果是这样,将返回true,并且结果将填充碰撞数据。 - * @param collider - * @param motion - */ - public collidesWith(collider: Collider, motion: Vector2){ - // 改变形状的位置,使它在移动后的位置,这样我们可以检查重叠 - let oldPosition = this.shape.position; - this.shape.position = Vector2.add(this.shape.position, motion); - - let result = this.shape.collidesWithShape(collider.shape); - if (result) - result.collider = collider; - - // 将图形位置返回到检查前的位置 - this.shape.position = oldPosition; - - return result; - } - - public onAddedToEntity(){ - if (this._colliderRequiresAutoSizing){ - if (!(this instanceof BoxCollider)){ - console.error("Only box and circle colliders can be created automatically"); + public onEntityTransformChanged(comp: transform.Component) { + switch (comp) { + case transform.Component.position: + this._isPositionDirty = true; + break; + case transform.Component.scale: + this._isPositionDirty = true; + break; + case transform.Component.rotation: + this._isRotationDirty = true; + break; } - let bounds = this.entity.getBounds(); - let renderbaleBounds = new Rectangle(bounds.x, bounds.y, bounds.width, bounds.height); + if (this._isColliderRegistered) + Physics.updateCollider(this); + } - // 这里我们需要大小*反尺度,因为当我们自动调整碰撞器的大小时,它需要没有缩放的渲染 - let width = renderbaleBounds.width / this.entity.scale.x; - let height = renderbaleBounds.height / this.entity.scale.y; + public onEnabled() { + this.registerColliderWithPhysicsSystem(); + this._isPositionDirty = this._isRotationDirty = true; + } - if (this instanceof BoxCollider){ - let boxCollider = this as BoxCollider; - boxCollider.width = width; - boxCollider.height = height; + public onDisabled() { + this.unregisterColliderWithPhysicsSystem(); + } - // 获取渲染的中心,将其转移到本地坐标,并使用它作为碰撞器的localOffset - this.localOffset = Vector2.subtract(renderbaleBounds.center, this.entity.position); + /** + * 父实体会在不同的时间调用它(当添加到场景,启用,等等) + */ + public registerColliderWithPhysicsSystem() { + // 如果在将我们添加到实体之前更改了origin等属性,则实体可以为null + if (this._isParentEntityAddedToScene && !this._isColliderRegistered) { + Physics.addCollider(this); + this._isColliderRegistered = true; } } - this._isParentEntityAddedToScene = true; - this.registerColliderWithPhysicsSystem(); - } - - public onRemovedFromEntity(){ - this.unregisterColliderWithPhysicsSystem(); - this._isParentEntityAddedToScene = false; - } + /** + * 父实体会在不同的时候调用它(从场景中移除,禁用,等等) + */ + public unregisterColliderWithPhysicsSystem() { + if (this._isParentEntityAddedToScene && this._isColliderRegistered) { + Physics.removeCollider(this); + } + this._isColliderRegistered = false; + } - public onEnabled(){ - this.registerColliderWithPhysicsSystem(); - } + /** + * 检查这个形状是否与物理系统中的其他对撞机重叠 + * @param other + */ + public overlaps(other: Collider): boolean { + return this.shape.overlaps(other.shape); + } - public onDisabled(){ - this.unregisterColliderWithPhysicsSystem(); - } + /** + * 检查这个与运动应用的碰撞器(移动向量)是否与碰撞器碰撞。如果是这样,将返回true,并且结果将填充碰撞数据。 + * @param collider + * @param motion + * @param result + */ + public collidesWith(collider: Collider, motion: Vector2, result: CollisionResult): boolean { + // 改变形状的位置,使它在移动后的位置,这样我们可以检查重叠 + let oldPosition = this.entity.position; + this.entity.position = this.entity.position.add(motion); - public onEntityTransformChanged(comp: TransformComponent){ - if (this._isColliderRegistered) - Physics.updateCollider(this); + let didCollide = this.shape.collidesWithShape(collider.shape, result); + if (didCollide) + result.collider = collider; + + // 将图形位置返回到检查前的位置 + this.entity.position = oldPosition; + + return didCollide; + } + + public clone(): Component { + let collider = ObjectUtils.clone(this); + collider.entity = null; + + if (this.shape) + collider.shape = this.shape.clone(); + + return collider; + } } -} \ No newline at end of file +} diff --git a/source/src/ECS/Components/Physics/Colliders/PolygonCollider.ts b/source/src/ECS/Components/Physics/Colliders/PolygonCollider.ts new file mode 100644 index 00000000..9e6732f4 --- /dev/null +++ b/source/src/ECS/Components/Physics/Colliders/PolygonCollider.ts @@ -0,0 +1,26 @@ +module es { + /** + * 多边形应该以顺时针方式定义 + */ + export class PolygonCollider extends Collider { + /** + * 如果这些点没有居中,它们将以localOffset的差异为居中。 + * @param points + */ + constructor(points: Vector2[]) { + super(); + + // 第一点和最后一点决不能相同。我们想要一个开放的多边形 + let isPolygonClosed = points[0] == points[points.length - 1]; + + // 最后一个移除 + if (isPolygonClosed) + points.splice(points.length - 1, 1); + + let center = Polygon.findPolygonCenter(points); + this.setLocalOffset(center); + Polygon.recenterPolygonVerts(points); + this.shape = new Polygon(points); + } + } +} diff --git a/source/src/ECS/Components/Physics/ITriggerListener.ts b/source/src/ECS/Components/Physics/ITriggerListener.ts index a04f150c..d7585ef3 100644 --- a/source/src/ECS/Components/Physics/ITriggerListener.ts +++ b/source/src/ECS/Components/Physics/ITriggerListener.ts @@ -1,4 +1,23 @@ -interface ITriggerListener { - onTriggerEnter(other: Collider, local: Collider); - onTriggerExit(other: Collider, local: Collider); -} \ No newline at end of file +module es { + /** + * 当添加到组件时,每当实体上的冲突器与另一个组件重叠/退出时,将调用这些方法。 + * ITriggerListener方法将在实现接口的触发器实体上的任何组件上调用。 + * 注意,这个接口只与Mover类一起工作 + */ + export interface ITriggerListener { + /** + * 当碰撞器与触发碰撞器相交时调用。这是在触发碰撞器和触发碰撞器上调用的。 + * 移动必须由Mover/ProjectileMover方法处理,以使其自动工作。 + * @param other + * @param local + */ + onTriggerEnter(other: Collider, local: Collider); + + /** + * 当另一个碰撞器离开触发碰撞器时调用 + * @param other + * @param local + */ + onTriggerExit(other: Collider, local: Collider); + } +} diff --git a/source/src/ECS/Components/Physics/Mover.ts b/source/src/ECS/Components/Physics/Mover.ts index 1c730d62..a13c1132 100644 --- a/source/src/ECS/Components/Physics/Mover.ts +++ b/source/src/ECS/Components/Physics/Mover.ts @@ -1,82 +1,89 @@ -/** - * 辅助类说明了一种处理移动的方法,它考虑了包括触发器在内的所有冲突。 - * ITriggerListener接口用于管理对移动过程中违反的任何触发器的回调。 - * 一个物体只能通过移动器移动。要正确报告触发器的move方法。 - * - * 请注意,多个移动者相互交互将多次调用ITriggerListener。 - */ -class Mover extends Component { - private _triggerHelper: ColliderTriggerHelper; - - public onAddedToEntity(){ - this._triggerHelper = new ColliderTriggerHelper(this.entity); - } - +module es { /** - * 计算修改运动矢量的运动,以考虑移动时可能发生的碰撞 - * @param motion + * 辅助类说明了一种处理移动的方法,它考虑了包括触发器在内的所有冲突。 + * ITriggerListener接口用于管理对移动过程中违反的任何触发器的回调。 + * 一个物体只能通过移动器移动。要正确报告触发器的move方法。 + * + * 请注意,多个移动者相互交互将多次调用ITriggerListener。 */ - public calculateMovement(motion: Vector2){ - let collisionResult = new CollisionResult(); + export class Mover extends Component { + private _triggerHelper: ColliderTriggerHelper; - if (!this.entity.getComponent(Collider) || !this._triggerHelper){ - return null; + public onAddedToEntity() { + this._triggerHelper = new ColliderTriggerHelper(this.entity); } - let colliders: Collider[] = this.entity.getComponents(Collider); - for (let i = 0; i < colliders.length; i ++){ - let collider = colliders[i]; + /** + * 计算修改运动矢量的运动,以考虑移动时可能发生的碰撞 + * @param motion + * @param collisionResult + */ + public calculateMovement(motion: Vector2, collisionResult: CollisionResult): boolean { + if (!this.entity.getComponent(Collider) || !this._triggerHelper) { + return false; + } - // 不检测触发器 - if (collider.isTrigger) - continue; + // 移动所有的非触发碰撞器并获得最近的碰撞 + let colliders: Collider[] = this.entity.getComponents(Collider); + for (let i = 0; i < colliders.length; i++) { + let collider = colliders[i]; - // 获取我们在新位置可能发生碰撞的任何东西 - let bounds = collider.bounds; - bounds.x += motion.x; - bounds.y += motion.y; - let boxcastResult = Physics.boxcastBroadphaseExcludingSelf(collider, bounds, collider.collidesWithLayers); - bounds = boxcastResult.bounds; - let neighbors = boxcastResult.tempHashSet; - - for (let j = 0; j < neighbors.length; j ++){ - let neighbor = neighbors[j]; - // 不检测触发器 - if (neighbor.isTrigger) + // 不检测触发器 在我们移动后会重新访问它 + if (collider.isTrigger) continue; - let _internalcollisionResult = collider.collidesWith(neighbor, motion); - if (_internalcollisionResult){ - // 如果碰撞 则退回之前的移动量 - motion = Vector2.subtract(motion, _internalcollisionResult.minimumTranslationVector); + // 获取我们在新位置可能发生碰撞的任何东西 + let bounds = collider.bounds; + bounds.x += motion.x; + bounds.y += motion.y; + let neighbors = Physics.boxcastBroadphaseExcludingSelf(collider, bounds, collider.collidesWithLayers); - // 如果我们碰到多个对象,为了简单起见,只取第一个。 - if (_internalcollisionResult.collider){ - collisionResult = _internalcollisionResult; + for (let j = 0; j < neighbors.length; j++) { + let neighbor = neighbors[j]; + // 不检测触发器 + if (neighbor.isTrigger) + continue; + + let _internalcollisionResult: CollisionResult = new CollisionResult(); + if (collider.collidesWith(neighbor, motion, _internalcollisionResult)) { + // 如果碰撞 则退回之前的移动量 + motion = motion.subtract(_internalcollisionResult.minimumTranslationVector); + + // 如果我们碰到多个对象,为了简单起见,只取第一个。 + if (_internalcollisionResult.collider != null) { + collisionResult = _internalcollisionResult; + } } } } + + ListPool.free(colliders); + + return collisionResult.collider != null; } - ListPool.free(colliders); + /** + * 将calculatemomovement应用到实体并更新triggerHelper + * @param motion + */ + public applyMovement(motion: Vector2) { + // 移动实体到它的新位置,如果我们有一个碰撞,否则移动全部数量。当碰撞发生时,运动被更新 + this.entity.position = Vector2.add(this.entity.position, motion); - return {collisionResult: collisionResult, motion: motion}; + // 对所有是触发器的碰撞器与所有宽相位碰撞器进行重叠检查。任何重叠都会导致触发事件。 + if (this._triggerHelper) + this._triggerHelper.update(); + } + + /** + * 通过调用calculateMovement和applyMovement来移动考虑碰撞的实体; + * @param motion + * @param collisionResult + */ + public move(motion: Vector2, collisionResult: CollisionResult) { + this.calculateMovement(motion, collisionResult); + this.applyMovement(motion); + return collisionResult.collider != null; + } } - - public applyMovement(motion: Vector2){ - this.entity.position = Vector2.add(this.entity.position, motion); - - if (this._triggerHelper) - this._triggerHelper.update(); - } - - public move(motion: Vector2){ - let movementResult = this.calculateMovement(motion); - let collisionResult = movementResult.collisionResult; - motion = movementResult.motion; - - this.applyMovement(motion); - - return collisionResult; - } -} \ No newline at end of file +} diff --git a/source/src/ECS/Components/Physics/ProjectileMover.ts b/source/src/ECS/Components/Physics/ProjectileMover.ts new file mode 100644 index 00000000..a12d4e87 --- /dev/null +++ b/source/src/ECS/Components/Physics/ProjectileMover.ts @@ -0,0 +1,58 @@ +module es { + /** + * 只向itriggerlistener报告冲突的移动器 + * 该对象将始终移动完整的距离 + */ + export class ProjectileMover extends Component { + private _tempTriggerList: ITriggerListener[] = []; + private _collider: Collider; + + public onAddedToEntity() { + this._collider = this.entity.getComponent(Collider); + if (!this._collider) + console.warn("ProjectileMover has no Collider. ProjectilMover requires a Collider!"); + } + + /** + * 移动考虑碰撞的实体 + * @param motion + */ + public move(motion: Vector2): boolean { + if (!this._collider) + return false; + + let didCollide = false; + + // 获取我们在新位置可能发生碰撞的任何东西 + this.entity.position = Vector2.add(this.entity.position, motion); + + // 获取任何可能在新位置发生碰撞的东西 + let neighbors = Physics.boxcastBroadphase(this._collider.bounds, this._collider.collidesWithLayers); + for (let i = 0; i < neighbors.length; i++) { + let neighbor = neighbors[i]; + if (this._collider.overlaps(neighbor) && neighbor.enabled) { + didCollide = true; + this.notifyTriggerListeners(this._collider, neighbor); + } + } + + return didCollide; + } + + private notifyTriggerListeners(self: Collider, other: Collider) { + // 通知我们重叠的碰撞器实体上的任何侦听器 + other.entity.getComponents("ITriggerListener", this._tempTriggerList); + for (let i = 0; i < this._tempTriggerList.length; i++) { + this._tempTriggerList[i].onTriggerEnter(self, other); + } + this._tempTriggerList.length = 0; + + // 通知此实体上的任何侦听器 + this.entity.getComponents("ITriggerListener", this._tempTriggerList); + for (let i = 0; i < this._tempTriggerList.length; i++) { + this._tempTriggerList[i].onTriggerEnter(other, self); + } + this._tempTriggerList.length = 0; + } + } +} diff --git a/source/src/ECS/Components/PooledComponent.ts b/source/src/ECS/Components/PooledComponent.ts index 91fd8e1d..1d289140 100644 --- a/source/src/ECS/Components/PooledComponent.ts +++ b/source/src/ECS/Components/PooledComponent.ts @@ -1,4 +1,6 @@ -/** 回收实例的组件类型。 */ -abstract class PooledComponent extends Component { - public abstract reset(); -} \ No newline at end of file +module es { + /** 回收实例的组件类型。 */ + export abstract class PooledComponent extends Component { + public abstract reset(); + } +} diff --git a/source/src/ECS/Components/RenderableComponent.ts b/source/src/ECS/Components/RenderableComponent.ts index 9a1940a3..689539d2 100644 --- a/source/src/ECS/Components/RenderableComponent.ts +++ b/source/src/ECS/Components/RenderableComponent.ts @@ -1,56 +1,192 @@ /// -/** - * 所有可渲染组件的基类 - */ -abstract class RenderableComponent extends PooledComponent implements IRenderable { - private _isVisible: boolean; - protected _areBoundsDirty = true; - protected _bounds: Rectangle = new Rectangle(); - protected _localOffset: Vector2 = Vector2.zero; +module es { + /** + * 所有可渲染组件的基类 + */ + export abstract class RenderableComponent extends Component implements IRenderable { + /** + * 用于装载egret显示对象 + */ + public displayObject: egret.DisplayObject = new egret.DisplayObject(); + /** + * 用于着色器处理精灵 + */ + public color: number = 0x000000; + protected _areBoundsDirty = true; - public color: number = 0x000000; + /** + * renderableComponent的宽度 + * 如果你不重写bounds属性则需要实现这个 + */ + public get width() { + return this.bounds.width; + } - public get width(){ - return this.getWidth(); - } + /** + * renderableComponent的高度 + * 如果你不重写bounds属性则需要实现这个 + */ + public get height() { + return this.bounds.height; + } - public get height(){ - return this.getHeight(); - } + protected _localOffset: Vector2 = Vector2.zero; - public get isVisible(){ - return this._isVisible; - } + /** + * 从父实体的偏移量。用于向需要特定定位的实体 + */ + public get localOffset(): Vector2 { + return this._localOffset; + } - public set isVisible(value: boolean){ - this._isVisible = value; + /** + * 从父实体的偏移量。用于向需要特定定位的实体 + * @param value + */ + public set localOffset(value: Vector2) { + this.setLocalOffset(value); + } - if (this._isVisible) - this.onBecameVisible(); - else - this.onBecameInvisible(); - } + protected _renderLayer: number = 0; - public get bounds(): Rectangle{ - return new Rectangle(this.getBounds().x, this.getBounds().y, this.getBounds().width, this.getBounds().height); - } + /** + * 较低的渲染层在前面,较高的在后面 + */ + public get renderLayer(): number { + return this._renderLayer; + } - protected getWidth(){ - return this.bounds.width; - } + public set renderLayer(value: number) { - protected getHeight(){ - return this.bounds.height; - } + } - protected onBecameVisible(){} + protected _bounds: Rectangle = new Rectangle(); - protected onBecameInvisible(){} + /** + * 这个物体的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; + } - public abstract render(camera: Camera); + return this._bounds; + } - public isVisibleFromCamera(camera: Camera): boolean{ - this.isVisible = camera.getBounds().intersects(this.getBounds()); - return this.isVisible; + 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); + + /** + * 如果renderableComponent的边界与camera.bounds相交 返回true + * 用于处理isVisible标志的状态开关 + * 在渲染方法中使用这个方法来决定是否渲染 + * @param camera + */ + public isVisibleFromCamera(camera: Camera): boolean { + 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) { + this.displayObject.x = this.entity.position.x + this.localOffset.x - camera.position.x + camera.origin.x; + this.displayObject.y = this.entity.position.y + this.localOffset.y - camera.position.y + camera.origin.y; + this.displayObject.scaleX = this.entity.scale.x; + this.displayObject.scaleY = this.entity.scale.y; + this.displayObject.rotation = this.entity.rotation; + } + + public toString() { + return `[RenderableComponent] renderLayer: ${this.renderLayer}`; + } + + /** + * 当renderableComponent进入相机框架时调用 + * 如果渲染器不适用isVisibleFromCamera进行剔除检查 这些方法不会被调用 + */ + protected onBecameVisible() { + this.displayObject.visible = this.isVisible; + } + + /** + * 当renderableComponent离开相机框架时调用 + * 如果渲染器不适用isVisibleFromCamera进行剔除检查 这些方法不会被调用 + */ + protected onBecameInvisible() { + this.displayObject.visible = this.isVisible; + } } } \ No newline at end of file diff --git a/source/src/ECS/Components/ScrollingSpriteRenderer.ts b/source/src/ECS/Components/ScrollingSpriteRenderer.ts index f2e1ba30..4dda18f6 100644 --- a/source/src/ECS/Components/ScrollingSpriteRenderer.ts +++ b/source/src/ECS/Components/ScrollingSpriteRenderer.ts @@ -1,37 +1,38 @@ /// -class ScrollingSpriteRenderer extends TiledSpriteRenderer { - public scrollSpeedX = 15; - public scroolSpeedY = 0; - private _scrollX = 0; - private _scrollY = 0; +module es { + export class ScrollingSpriteRenderer extends TiledSpriteRenderer { + /** + * x自动滚动速度(以像素/s为单位) + */ + public scrollSpeedX = 15; + /** + * 自动滚动的y速度(以像素/s为单位) + */ + public scroolSpeedY = 0; - public update(){ - this._scrollX += this.scrollSpeedX * Time.deltaTime; - this._scrollY += this.scroolSpeedY * Time.deltaTime; - this.sourceRect.x = this._scrollX; - this.sourceRect.y = this._scrollY; + public get textureScale(): Vector2 { + return this._textureScale; + } + + public set textureScale(value: Vector2){ + this._textureScale = value; + + // 重新计算我们的inverseTextureScale和源矩形大小 + this._inverseTexScale = new Vector2(1 / this._textureScale.x, 1 / this._textureScale.y); + } + + private _scrollX = 0; + private _scrollY = 0; + + constructor(sprite: Sprite) { + super(sprite); + } + + public update() { + this._scrollX += this.scrollSpeedX * Time.deltaTime; + this._scrollY += this.scroolSpeedY * Time.deltaTime; + this._sourceRect.x = this._scrollX; + this._sourceRect.y = this._scrollY; + } } - - public render(camera: Camera) { - if (!this.sprite) - return; - - super.render(camera); - - let renderTexture = new egret.RenderTexture(); - let cacheBitmap = new egret.DisplayObjectContainer(); - cacheBitmap.removeChildren(); - cacheBitmap.addChild(this.leftTexture); - cacheBitmap.addChild(this.rightTexture); - - this.leftTexture.x = this.sourceRect.x; - this.rightTexture.x = this.sourceRect.x - this.sourceRect.width; - this.leftTexture.y = this.sourceRect.y; - this.rightTexture.y = this.sourceRect.y; - - cacheBitmap.cacheAsBitmap = true; - renderTexture.drawToTexture(cacheBitmap, new egret.Rectangle(0, 0, this.sourceRect.width, this.sourceRect.height)); - - this.bitmap.texture = renderTexture; - } -} \ No newline at end of file +} diff --git a/source/src/ECS/Components/Sprite.ts b/source/src/ECS/Components/Sprite.ts index b9c2f7a8..19c54fb4 100644 --- a/source/src/ECS/Components/Sprite.ts +++ b/source/src/ECS/Components/Sprite.ts @@ -1,24 +1,26 @@ -class Sprite { - public texture2D: egret.Texture; - public readonly sourceRect: Rectangle; - public readonly center: Vector2; - public origin: Vector2; - public readonly uvs: Rectangle = new Rectangle(); +module es { + 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; + 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 + 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; + this.uvs.x = sourceRect.x * inverseTexW; + this.uvs.y = sourceRect.y * inverseTexH; + this.uvs.width = sourceRect.width * inverseTexW; + this.uvs.height = sourceRect.height * inverseTexH; + } } -} \ No newline at end of file +} diff --git a/source/src/ECS/Components/SpriteAnimation.ts b/source/src/ECS/Components/SpriteAnimation.ts index 15ee5ea3..b5f81b75 100644 --- a/source/src/ECS/Components/SpriteAnimation.ts +++ b/source/src/ECS/Components/SpriteAnimation.ts @@ -1,9 +1,11 @@ -class SpriteAnimation { - public readonly sprites: Sprite[]; - public readonly frameRate: number; +module es { + export class SpriteAnimation { + public readonly sprites: Sprite[]; + public readonly frameRate: number; - constructor(sprites: Sprite[], frameRate: number){ - this.sprites = sprites; - this.frameRate = frameRate; + constructor(sprites: Sprite[], frameRate: number) { + this.sprites = sprites; + this.frameRate = frameRate; + } } -} \ No newline at end of file +} diff --git a/source/src/ECS/Components/SpriteAnimator.ts b/source/src/ECS/Components/SpriteAnimator.ts index 1c6c802b..6d649bf6 100644 --- a/source/src/ECS/Components/SpriteAnimator.ts +++ b/source/src/ECS/Components/SpriteAnimator.ts @@ -1,104 +1,84 @@ /// -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; +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, } - private _animations: Map = new Map(); - private _elapsedTime: number = 0; - private _loopMode: LoopMode; - - constructor(sprite?: Sprite){ - super(); - - if (sprite) this.setSprite(sprite); + export enum State { + none, + running, + paused, + completed, } - /** - * 添加一个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; - } + 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; - /** - * 以给定的名称放置动画。如果没有指定循环模式,则默认为循环 - * @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; + constructor(sprite?: Sprite) { + super(sprite); + } - this.sprite = this.currentAnimation.sprites[0]; - this._elapsedTime = 0; - this._loopMode = loopMode ? loopMode : LoopMode.loop; - } + /** + * 检查当前动画是否正在运行 + */ + public get isRunning(): boolean { + return this.animationState == State.running; + } - /** - * 检查动画是否正在播放(即动画是活动的)。它可能仍然处于暂停状态) - * @param name - */ - public isAnimationActive(name: string): boolean{ - return this.currentAnimation && this.currentAnimationName == name; - } + private _animations: Map = new Map(); - /** - * 暂停动画 - */ - public pause(){ - this.animationState = State.paused; - } + /** 提供对可用动画列表的访问 */ + public get animations() { + return this._animations; + } - /** - * 继续动画 - */ - public unPause(){ - this.animationState = State.running; - } + public update() { + if (this.animationState != State.running || !this.currentAnimation) return; - /** - * 停止当前动画并将其设为null - */ - public stop(){ - this.currentAnimation = null; - this.currentAnimationName = null; - this.currentFrame = 0; - this.animationState = State.none; - } + let animation = this.currentAnimation; + let secondsPerFrame = 1 / (animation.frameRate * this.speed); + let iterationDuration = secondsPerFrame * animation.sprites.length; - public update(){ - if (this.animationState != State.running || !this.currentAnimation) return; + this._elapsedTime += Time.deltaTime; + let time = Math.abs(this._elapsedTime); - 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){ + // 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; @@ -109,34 +89,76 @@ class SpriteAnimator extends SpriteRenderer { // 弄清楚我们在哪个坐标系上 let i = Math.floor(time / secondsPerFrame); let n = animation.sprites.length; - if (n > 2 && (this._loopMode == LoopMode.pingPong || this._loopMode == LoopMode.pingPongOnce)){ + 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{ + } else { this.currentFrame = i % n; } this.sprite = animation.sprites[this.currentFrame]; + } + + /** + * 添加一个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; + } } } - -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, -} \ No newline at end of file diff --git a/source/src/ECS/Components/SpriteRenderer.ts b/source/src/ECS/Components/SpriteRenderer.ts index 09238e97..30d37dd2 100644 --- a/source/src/ECS/Components/SpriteRenderer.ts +++ b/source/src/ECS/Components/SpriteRenderer.ts @@ -1,62 +1,131 @@ -class SpriteRenderer extends RenderableComponent { - private _sprite: Sprite; - protected bitmap: egret.Bitmap; +module es { + import Bitmap = egret.Bitmap; - /** 应该由这个精灵显示的精灵 */ - public get sprite(): Sprite{ - return this._sprite; - } - /** 应该由这个精灵显示的精灵 */ - public set sprite(value: Sprite){ - this.setSprite(value); - } - - public setSprite(sprite: Sprite): SpriteRenderer{ - this.removeChildren(); - this._sprite = sprite; - if (this._sprite) { - this.anchorOffsetX = this._sprite.origin.x / this._sprite.sourceRect.width; - this.anchorOffsetY = this._sprite.origin.y / this._sprite.sourceRect.height; + 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)); } - this.bitmap = new egret.Bitmap(sprite.texture2D); - this.addChild(this.bitmap); - return this; - } + 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; + } + } - public setColor(color: number): SpriteRenderer{ - let colorMatrix = [ - 1, 0, 0, 0, 0, - 0, 1, 0, 0, 0, - 0, 0, 1, 0, 0, - 0, 0, 0, 1, 0 - ]; - colorMatrix[0] = Math.floor(color / 256 / 256) / 255; - colorMatrix[6] = Math.floor(color / 256 % 256) / 255; - colorMatrix[12] = color % 256 / 255; - let colorFilter = new egret.ColorMatrixFilter(colorMatrix); - this.filters = [colorFilter]; + return this._bounds; + } - return this; - } + /** + * 用归一化方法设置原点 + * 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); + } - public isVisibleFromCamera(camera: Camera): boolean{ - this.isVisible = new Rectangle(0, 0, this.stage.stageWidth, this.stage.stageHeight).intersects(this.bounds); - this.visible = this.isVisible; - return this.isVisible; - } + /** + * 用归一化方法设置原点 + * 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)); + } - /** 渲染处理 在每个模块中处理各自的渲染逻辑 */ - public render(camera: Camera){ - this.x = -camera.position.x + camera.origin.x; - this.y = -camera.position.y + camera.origin.y; - } + protected _origin: Vector2; - public onRemovedFromEntity(){ - if (this.parent) - this.parent.removeChild(this); - } + /** + * 精灵的原点。这是在设置精灵时自动设置的 + */ + public get origin(): Vector2 { + return this._origin; + } - public reset(){ + /** + * 精灵的原点。这是在设置精灵时自动设置的 + * @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); + + this.displayObject.x = this.entity.position.x - this.origin.x + this.localOffset.x - camera.position.x + camera.origin.x; + this.displayObject.y = this.entity.position.y - this.origin.y + this.localOffset.y - camera.position.y + camera.origin.y; + } } } + diff --git a/source/src/ECS/Components/TiledSpriteRenderer.ts b/source/src/ECS/Components/TiledSpriteRenderer.ts index e5b097f4..2b0fb8fb 100644 --- a/source/src/ECS/Components/TiledSpriteRenderer.ts +++ b/source/src/ECS/Components/TiledSpriteRenderer.ts @@ -1,57 +1,113 @@ /// -/** - * 滚动由两张图片组合而成 - */ -class TiledSpriteRenderer extends SpriteRenderer { - protected sourceRect: Rectangle; - protected leftTexture: egret.Bitmap; - protected rightTexture: egret.Bitmap; +module es { + import Bitmap = egret.Bitmap; - public get scrollX() { - return this.sourceRect.x; + /** + * 滚动由两张图片组合而成 + */ + 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 = this._sprite.sourceRect.width * this._inverseTexScale.x; + this._sourceRect.height = 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; + } + + protected _sourceRect: Rectangle = new Rectangle(); + protected _textureScale = Vector2.one; + protected _inverseTexScale = Vector2.one; + + constructor(sprite: Sprite) { + super(sprite); + + this._sourceRect = sprite.sourceRect; + + let bitmap = this.displayObject as Bitmap; + bitmap.$fillMode = egret.BitmapFillMode.REPEAT; + } + + public render(camera: es.Camera) { + let bitmap = this.displayObject as Bitmap; + bitmap.width = this.width; + bitmap.height = this.height; + + super.render(camera); + } } - public set scrollX(value: number) { - this.sourceRect.x = value; - } - public get scrollY() { - return this.sourceRect.y; - } - public set scrollY(value: number) { - this.sourceRect.y = value; - } - - constructor(sprite: Sprite) { - super(); - - this.leftTexture = new egret.Bitmap(); - this.rightTexture = new egret.Bitmap(); - this.leftTexture.texture = sprite.texture2D; - this.rightTexture.texture = sprite.texture2D; - - this.setSprite(sprite); - this.sourceRect = sprite.sourceRect; - } - - public render(camera: Camera) { - if (!this.sprite) - return; - - super.render(camera); - - let renderTexture = new egret.RenderTexture(); - let cacheBitmap = new egret.DisplayObjectContainer(); - cacheBitmap.removeChildren(); - cacheBitmap.addChild(this.leftTexture); - cacheBitmap.addChild(this.rightTexture); - - this.leftTexture.x = this.sourceRect.x; - this.rightTexture.x = this.sourceRect.x - this.sourceRect.width; - this.leftTexture.y = this.sourceRect.y; - this.rightTexture.y = this.sourceRect.y; - - cacheBitmap.cacheAsBitmap = true; - renderTexture.drawToTexture(cacheBitmap, new egret.Rectangle(0, 0, this.sourceRect.width, this.sourceRect.height)); - - this.bitmap.texture = renderTexture; - } -} \ No newline at end of file +} diff --git a/source/src/ECS/Core.ts b/source/src/ECS/Core.ts new file mode 100644 index 00000000..2e07ea4f --- /dev/null +++ b/source/src/ECS/Core.ts @@ -0,0 +1,230 @@ +module es { + /** + * 全局核心类 + */ + export class Core extends egret.DisplayObjectContainer { + /** + * 核心发射器。只发出核心级别的事件 + */ + public static emitter: Emitter; + /** + * 全局访问图形设备 + */ + public static graphicsDevice: GraphicsDevice; + /** + * 全局内容管理器加载任何应该停留在场景之间的资产 + */ + public static content: ContentManager; + /** + * 简化对内部类的全局内容实例的访问 + */ + public static _instance: Core; + public _nextScene: Scene; + public _sceneTransition: SceneTransition; + /** + * 全局访问系统 + */ + public _globalManagers: GlobalManager[] = []; + + constructor() { + super(); + + Core._instance = this; + Core.emitter = new Emitter(); + Core.content = new ContentManager(); + + this.addEventListener(egret.Event.ADDED_TO_STAGE, this.onAddToStage, this); + } + + /** + * 提供对单例/游戏实例的访问 + * @constructor + */ + public static get Instance() { + return this._instance; + } + + public _scene: Scene; + + /** + * 当前活动的场景。注意,如果设置了该设置,在更新结束之前场景实际上不会改变 + */ + public static get scene() { + if (!this._instance) + return null; + return this._instance._scene; + } + + /** + * 当前活动的场景。注意,如果设置了该设置,在更新结束之前场景实际上不会改变 + * @param value + */ + public static set scene(value: Scene) { + if (!value) { + console.error("场景不能为空"); + return; + } + + if (this._instance._scene == null) { + this._instance._scene = value; + this._instance.addChild(value); + this._instance._scene.begin(); + Core.Instance.onSceneChanged(); + } else { + this._instance._nextScene = value; + } + } + + /** + * 临时运行SceneTransition,允许一个场景过渡到另一个平滑的自定义效果。 + * @param sceneTransition + */ + public static startSceneTransition(sceneTransition: T): T { + if (this._instance._sceneTransition) { + console.warn("在前一个场景完成之前,不能开始一个新的场景转换。"); + return; + } + + this._instance._sceneTransition = sceneTransition; + return sceneTransition; + } + + /** + * 添加一个全局管理器对象,它的更新方法将调用场景前的每一帧。 + * @param manager + */ + public static registerGlobalManager(manager: es.GlobalManager) { + this._instance._globalManagers.push(manager); + manager.enabled = true; + } + + /** + * 删除全局管理器对象 + * @param manager + */ + public static unregisterGlobalManager(manager: es.GlobalManager) { + this._instance._globalManagers.remove(manager); + manager.enabled = false; + } + + /** + * 获取类型为T的全局管理器 + * @param type + */ + public static getGlobalManager(type): T { + for (let i = 0; i < this._instance._globalManagers.length; i++) { + if (this._instance._globalManagers[i] instanceof type) + return this._instance._globalManagers[i] as T; + } + return null; + } + + public onOrientationChanged() { + Core.emitter.emit(CoreEvents.OrientationChanged); + } + + public async draw() { + if (this._sceneTransition) { + this._sceneTransition.preRender(); + + // 如果我们有场景转换的特殊处理。我们要么渲染场景过渡,要么渲染场景 + if (this._scene && !this._sceneTransition.hasPreviousSceneRender) { + this._scene.render(); + this._scene.postRender(); + await this._sceneTransition.onBeginTransition(); + } else if (this._sceneTransition) { + if (this._scene && this._sceneTransition.isNewSceneLoaded) { + this._scene.render(); + this._scene.postRender(); + } + + this._sceneTransition.render(); + } + } else if (this._scene) { + this._scene.render(); + + Debug.render(); + + // 如果我们没有一个活跃的场景转换,就像平常一样渲染 + this._scene.postRender(); + } + } + + public startDebugUpdate() { + TimeRuler.Instance.startFrame(); + TimeRuler.Instance.beginMark("update", 0x00FF00); + } + + public endDebugUpdate() { + TimeRuler.Instance.endMark("update"); + } + + /** + * 在一个场景结束后,下一个场景开始之前调用 + */ + public onSceneChanged() { + Core.emitter.emit(CoreEvents.SceneChanged); + Time.sceneChanged(); + } + + /** + * 当屏幕大小发生改变时调用 + */ + protected onGraphicsDeviceReset() { + Core.emitter.emit(CoreEvents.GraphicsDeviceReset); + } + + protected initialize() { + } + + protected async update() { + // this.startDebugUpdate(); + + // 更新我们所有的系统管理器 + Time.update(egret.getTimer()); + + if (this._scene) { + for (let i = this._globalManagers.length - 1; i >= 0; i--) { + if (this._globalManagers[i].enabled) + this._globalManagers[i].update(); + } + + // 仔细阅读: + // 当场景转换发生时,我们不会更新场景 + // -除非是不改变场景的场景转换(没有理由不更新) + // -或者它是一个已经切换到新场景的场景转换(新场景需要做它自己的事情) + if (!this._sceneTransition || + (this._sceneTransition && (!this._sceneTransition.loadsNewScene || this._sceneTransition.isNewSceneLoaded))) { + this._scene.update(); + } + + if (this._nextScene) { + this.removeChild(this._scene); + this._scene.end(); + + this._scene = this._nextScene; + this._nextScene = null; + this.onSceneChanged(); + + this.addChild(this._scene); + await this._scene.begin(); + } + } + + // this.endDebugUpdate(); + + await this.draw(); + } + + private onAddToStage() { + Core.graphicsDevice = new GraphicsDevice(); + + this.addEventListener(egret.Event.RESIZE, this.onGraphicsDeviceReset, this); + this.addEventListener(egret.StageOrientationEvent.ORIENTATION_CHANGE, this.onOrientationChanged, this); + this.addEventListener(egret.Event.ENTER_FRAME, this.update, this); + + Input.initialize(); + this.initialize(); + } + } +} diff --git a/source/src/ECS/CoreEvents.ts b/source/src/ECS/CoreEvents.ts new file mode 100644 index 00000000..074469e9 --- /dev/null +++ b/source/src/ECS/CoreEvents.ts @@ -0,0 +1,16 @@ +module es { + export enum CoreEvents { + /** + * 在图形设备重置时触发。当这种情况发生时,任何渲染目标或其他内容的VRAM将被擦除,需要重新生成 + */ + GraphicsDeviceReset, + /** + * 当场景发生变化时触发 + */ + SceneChanged, + /** + * 当设备方向改变时触发 + */ + OrientationChanged, + } +} diff --git a/source/src/ECS/Entity.ts b/source/src/ECS/Entity.ts index ed56b187..8ba689ac 100644 --- a/source/src/ECS/Entity.ts +++ b/source/src/ECS/Entity.ts @@ -1,223 +1,436 @@ -class Entity extends egret.DisplayObjectContainer { - private static _idGenerator: number; +module es { + export class Entity { + public static _idGenerator: number; - public name: string; - public readonly id: number; - /** 当前实体所属的场景 */ - public scene: Scene; - /** 当前附加到此实体的所有组件的列表 */ - public readonly components: ComponentList; - private _updateOrder: number = 0; - private _enabled: boolean = true; - public _isDestoryed: boolean; - private _tag: number = 0; + /** + * 当前实体所属的场景 + */ + public scene: Scene; + /** + * 实体名称。用于在场景范围内搜索实体 + */ + public name: string; + /** + * 此实体的唯一标识 + */ + public readonly id: number; + /** + * 封装实体的位置/旋转/缩放,并允许设置一个高层结构 + */ + public readonly transform: Transform; + /** + * 当前附加到此实体的所有组件的列表 + */ + public readonly components: ComponentList; + /** + * 指定应该调用这个entity update方法的频率。1表示每一帧,2表示每一帧,以此类推 + */ + public updateInterval: number = 1; + public componentBits: BitSet; - public componentBits: BitSet; + constructor(name: string) { + this.components = new ComponentList(this); + this.transform = new Transform(this); + this.name = name; + this.id = Entity._idGenerator++; - public get isDestoryed(){ - return this._isDestoryed; - } - - public get position(){ - return new Vector2(this.x, this.y); - } - - public set position(value: Vector2){ - this.$setX(value.x); - this.$setY(value.y); - this.onEntityTransformChanged(TransformComponent.position); - } - - public get scale(){ - return new Vector2(this.scaleX, this.scaleY); - } - - public set scale(value: Vector2){ - this.$setScaleX(value.x); - this.$setScaleY(value.y); - this.onEntityTransformChanged(TransformComponent.scale); - } - - public set rotation(value: number){ - this.$setRotation(value); - this.onEntityTransformChanged(TransformComponent.rotation); - } - - public get enabled(){ - return this._enabled; - } - - public set enabled(value: boolean){ - this.setEnabled(value); - } - - public setEnabled(isEnabled: boolean){ - if (this._enabled != isEnabled){ - this._enabled = isEnabled; + this.componentBits = new BitSet(); } - return this; - } + public _isDestroyed: boolean; - public get tag(){ - return this._tag; - } + /** + * 如果调用了destroy,那么在下一次处理实体之前这将一直为true + */ + public get isDestroyed() { + return this._isDestroyed; + } - public set tag(value: number){ - this.setTag(value); - } + private _tag: number = 0; - public get stage(){ - if (!this.scene) - return null; - - return this.scene.stage; - } + /** + * 你可以随意使用。稍后可以使用它来查询场景中具有特定标记的所有实体 + */ + public get tag(): number { + return this._tag; + } - constructor(name: string){ - super(); - this.name = name; - this.components = new ComponentList(this); - this.id = Entity._idGenerator ++; + /** + * 你可以随意使用。稍后可以使用它来查询场景中具有特定标记的所有实体 + * @param value + */ + public set tag(value: number) { + this.setTag(value); + } - this.componentBits = new BitSet(); - } + private _enabled: boolean = true; - public get updateOrder(){ - return this._updateOrder; - } + /** + * 启用/禁用实体。当禁用碰撞器从物理系统和组件中移除时,方法将不会被调用 + */ + public get enabled() { + return this._enabled; + } - public set updateOrder(value: number){ - this.setUpdateOrder(value); - } + /** + * 启用/禁用实体。当禁用碰撞器从物理系统和组件中移除时,方法将不会被调用 + * @param value + */ + public set enabled(value: boolean) { + this.setEnabled(value); + } - public roundPosition(){ - this.position = Vector2Ext.round(this.position); - } + private _updateOrder: number = 0; - public setUpdateOrder(updateOrder: number){ - if (this._updateOrder != updateOrder){ - this._updateOrder = updateOrder; - if (this.scene){ - + /** + * 更新此实体的顺序。updateOrder还用于对scene.entities上的标签列表进行排序 + */ + public get updateOrder() { + return this._updateOrder; + } + + /** + * 更新此实体的顺序。updateOrder还用于对scene.entities上的标签列表进行排序 + * @param value + */ + public set updateOrder(value: number) { + this.setUpdateOrder(value); + } + + public get parent(): Transform { + return this.transform.parent; + } + + public set parent(value: Transform) { + this.transform.setParent(value); + } + + public get childCount() { + return this.transform.childCount; + } + + public get position(): Vector2 { + return this.transform.position; + } + + public set position(value: Vector2) { + this.transform.setPosition(value.x, value.y); + } + + public get localPosition(): Vector2 { + return this.transform.localPosition; + } + + public set localPosition(value: Vector2) { + this.transform.setLocalPosition(value); + } + + public get rotation(): number { + return this.transform.rotation; + } + + public set rotation(value: number) { + this.transform.setRotation(value); + } + + public get rotationDegrees(): number { + return this.transform.rotationDegrees; + } + + public set rotationDegrees(value: number) { + this.transform.setRotationDegrees(value); + } + + public get localRotation(): number { + return this.transform.localRotation; + } + + public set localRotation(value: number) { + this.transform.setLocalRotation(value); + } + + public get localRotationDegrees(): number { + return this.transform.localRotationDegrees; + } + + public set localRotationDegrees(value: number) { + this.transform.setLocalRotationDegrees(value); + } + + public get scale(): Vector2 { + return this.transform.scale; + } + + public set scale(value: Vector2) { + this.transform.setScale(value); + } + + public get localScale(): Vector2 { + return this.transform.localScale; + } + + public set localScale(value: Vector2) { + this.transform.setLocalScale(value); + } + + public get worldInverseTransform(): Matrix2D { + return this.transform.worldInverseTransform; + } + + public get localToWorldTransform(): Matrix2D { + return this.transform.localToWorldTransform; + } + + public get worldToLocalTransform(): Matrix2D { + return this.transform.worldToLocalTransform; + } + + public onTransformChanged(comp: transform.Component) { + // 通知我们的子项改变了位置 + this.components.onEntityTransformChanged(comp); + } + + /** + * 设置实体的标记 + * @param tag + */ + public setTag(tag: number): Entity { + if (this._tag != tag) { + // 我们只有在已经有场景的情况下才会调用entityTagList。如果我们还没有场景,我们会被添加到entityTagList + if (this.scene) + this.scene.entities.removeFromTagList(this); + this._tag = tag; + if (this.scene) + this.scene.entities.addToTagList(this); } return this; } - } - public setTag(tag: number): Entity{ - if (this._tag != tag){ - if (this.scene){ - this.scene.entities.removeFromTagList(this); + /** + * 设置实体的启用状态。当禁用碰撞器从物理系统和组件中移除时,方法将不会被调用 + * @param isEnabled + */ + public setEnabled(isEnabled: boolean) { + if (this._enabled != isEnabled) { + this._enabled = isEnabled; + + if (this._enabled) + this.components.onEntityEnabled(); + else + this.components.onEntityDisabled(); } - this._tag = tag; - if (this.scene){ - this.scene.entities.addToTagList(this); + + return this; + } + + /** + * 设置此实体的更新顺序。updateOrder还用于对scene.entities上的标签列表进行排序 + * @param updateOrder + */ + public setUpdateOrder(updateOrder: number) { + if (this._updateOrder != updateOrder) { + this._updateOrder = updateOrder; + if (this.scene) { + this.scene.entities.markEntityListUnsorted(); + this.scene.entities.markTagUnsorted(this.tag); + } + + return this; } } - return this; - } + /** + * 从场景中删除实体并销毁所有子元素 + */ + public destroy() { + this._isDestroyed = true; + this.scene.entities.remove(this); + this.transform.parent = null; - public attachToScene(newScene: Scene){ - this.scene = newScene; - newScene.entities.add(this); - this.components.registerAllComponents(); - - for (let i = 0; i < this.numChildren; i ++){ - (this.getChildAt(i) as Component).entity.attachToScene(newScene); - } - } - - public detachFromScene(){ - this.scene.entities.remove(this); - this.components.deregisterAllComponents(); - - for (let i = 0; i < this.numChildren; i ++) - (this.getChildAt(i) as Component).entity.detachFromScene(); - } - - public addComponent(component: T): T{ - component.entity = this; - this.components.add(component); - this.addChild(component); - component.initialize(); - return component; - } - - public hasComponent(type){ - return this.components.getComponent(type, false) != null; - } - - public getOrCreateComponent(type: T){ - let comp = this.components.getComponent(type, true); - if (!comp){ - comp = this.addComponent(type); + // 销毁所有子项 + for (let i = this.transform.childCount - 1; i >= 0; i--) { + let child = this.transform.getChild(i); + child.entity.destroy(); + } } - return comp; - } + /** + * 将实体从场景中分离。下面的生命周期方法将被调用在组件上:OnRemovedFromEntity + */ + public detachFromScene() { + this.scene.entities.remove(this); + this.components.deregisterAllComponents(); - public getComponent(type): T{ - return this.components.getComponent(type, false) as T; - } - - public getComponents(typeName: string | any, componentList?){ - return this.components.getComponents(typeName, componentList); - } - - private onEntityTransformChanged(comp: TransformComponent){ - this.components.onEntityTransformChanged(comp); - } - - public removeComponentForType(type){ - let comp = this.getComponent(type); - if (comp){ - this.removeComponent(comp); - return true; + for (let i = 0; i < this.transform.childCount; i++) + this.transform.getChild(i).entity.detachFromScene(); } - return false; - } + /** + * 将一个先前分离的实体附加到一个新的场景 + * @param newScene + */ + public attachToScene(newScene: Scene) { + this.scene = newScene; + newScene.entities.add(this); + this.components.registerAllComponents(); - public removeComponent(component: Component){ - this.components.remove(component); - } - - public removeAllComponents(){ - for (let i = 0; i < this.components.count; i ++){ - this.removeComponent(this.components.buffer[i]); + for (let i = 0; i < this.transform.childCount; i++) { + this.transform.getChild(i).entity.attachToScene(newScene); + } } - } - public update(){ - this.components.update(); - } + /** + * 创建此实体的深层克隆。子类可以重写此方法来复制任何自定义字段。 + * 当重写时,应该调用CopyFrom方法,它将为您克隆所有组件、碰撞器和转换子组件。 + * 注意克隆的实体不会被添加到任何场景中!你必须自己添加它们! + * @param position + */ + public clone(position: Vector2 = new Vector2()): Entity { + let entity = new Entity(this.name + "(clone)"); + entity.copyFrom(this); + entity.transform.position = position; - public onAddedToScene(){ + return entity; + } - } + /** + * 在提交了所有挂起的实体更改后,将此实体添加到场景时调用 + */ + public onAddedToScene() { + } - public onRemovedFromScene(){ - if (this._isDestoryed) - this.components.removeAllComponents(); - } + /** + * 当此实体从场景中删除时调用 + */ + public onRemovedFromScene() { + // 如果已经被销毁了,移走我们的组件。如果我们只是分离,我们需要保持我们的组件在实体上。 + if (this._isDestroyed) + this.components.removeAllComponents(); + } - public destroy(){ - this._isDestoryed = true; - this.scene.entities.remove(this); - this.removeChildren(); + /** + * 每帧进行调用进行更新组件 + */ + public update() { + this.components.update(); + } - for (let i = this.numChildren - 1; i >= 0; i --){ - let child = this.getChildAt(i); - (child as Component).entity.destroy(); + /** + * 将组件添加到组件列表中。返回组件。 + * @param component + */ + public addComponent(component: T): T { + component.entity = this; + this.components.add(component); + component.initialize(); + return component; + } + + /** + * 获取类型T的第一个组件并返回它。如果没有找到组件,则返回null。 + * @param type + */ + public getComponent(type): T { + return this.components.getComponent(type, false) as T; + } + + /** + * 检查实体是否具有该组件 + * @param type + */ + public hasComponent(type) { + return this.components.getComponent(type, false) != null; + } + + /** + * 获取类型T的第一个组件并返回它。如果没有找到组件,将创建组件。 + * @param type + */ + public getOrCreateComponent(type: T) { + let comp = this.components.getComponent(type, true); + if (!comp) { + comp = this.addComponent(type); + } + + return comp; + } + + /** + * 获取typeName类型的所有组件,但不使用列表分配 + * @param typeName + * @param componentList + */ + public getComponents(typeName: string | any, componentList?) { + return this.components.getComponents(typeName, componentList); + } + + /** + * 从组件列表中删除组件 + * @param component + */ + public removeComponent(component: Component) { + this.components.remove(component); + } + + /** + * 从组件列表中删除类型为T的第一个组件 + * @param type + */ + public removeComponentForType(type) { + let comp = this.getComponent(type); + if (comp) { + this.removeComponent(comp); + return true; + } + + return false; + } + + /** + * 从实体中删除所有组件 + */ + public removeAllComponents() { + for (let i = 0; i < this.components.count; i++) { + this.removeComponent(this.components.buffer[i]); + } + } + + public compareTo(other: Entity): number { + let compare = this._updateOrder - other._updateOrder; + if (compare == 0) + compare = this.id - other.id; + return compare; + } + + public toString(): string { + return `[Entity: name: ${this.name}, tag: ${this.tag}, enabled: ${this.enabled}, depth: ${this.updateOrder}]`; + } + + /** + * 将实体的属性、组件和碰撞器复制到此实例 + * @param entity + */ + protected copyFrom(entity: Entity) { + this.tag = entity.tag; + this.updateInterval = entity.updateInterval; + this.updateOrder = entity.updateOrder; + this.enabled = entity.enabled; + + this.transform.scale = entity.transform.scale; + this.transform.rotation = entity.transform.rotation; + + for (let i = 0; i < entity.components.count; i++) + this.addComponent(entity.components.buffer[i].clone()); + for (let i = 0; i < entity.components._componentsToAdd.length; i++) + this.addComponent(entity.components._componentsToAdd[i].clone()); + + for (let i = 0; i < entity.transform.childCount; i++) { + let child = entity.transform.getChild(i).entity; + let childClone = child.clone(); + childClone.transform.copyFrom(child.transform); + childClone.transform.parent = this.transform; + } } } } - -enum TransformComponent { - rotation, - scale, - position -} \ No newline at end of file diff --git a/source/src/ECS/Scene.ts b/source/src/ECS/Scene.ts index 9bf9100e..63ce0c9d 100644 --- a/source/src/ECS/Scene.ts +++ b/source/src/ECS/Scene.ts @@ -1,213 +1,355 @@ -/** 场景 */ -class Scene extends egret.DisplayObjectContainer { - public camera: Camera; - public readonly entities: EntityList; - public readonly renderableComponents: RenderableComponentList; - public readonly content: ContentManager; - public enablePostProcessing = true; +module es { + /** 场景 */ + export class Scene extends egret.DisplayObjectContainer { + /** + * 默认场景摄像机 + */ + public camera: Camera; + /** + * 场景特定内容管理器。使用它来加载仅由这个场景需要的任何资源。如果你有全局/多场景资源,你可以使用SceneManager.content。 + * contentManager来加载它们,因为Nez不会卸载它们。 + */ + public readonly content: ContentManager; + /** + * 全局切换后处理器 + */ + public enablePostProcessing = true; + /** + * 这个场景中的实体列表 + */ + public readonly entities: EntityList; + /** + * 管理当前在场景实体上的所有可呈现组件的列表 + */ + public readonly renderableComponents: RenderableComponentList; + /** + * 管理所有实体处理器 + */ + public readonly entityProcessors: EntityProcessorList; - private _renderers: Renderer[] = []; - private _postProcessors: PostProcessor[] = []; - private _didSceneBegin; + public _renderers: Renderer[] = []; + public readonly _postProcessors: PostProcessor[] = []; + public _didSceneBegin; - public readonly entityProcessors: EntityProcessorList; + constructor() { + super(); + this.entities = new EntityList(this); + this.renderableComponents = new RenderableComponentList(); + this.content = new ContentManager(); - constructor() { - super(); - this.entityProcessors = new EntityProcessorList(); - this.renderableComponents = new RenderableComponentList(); - this.entities = new EntityList(this); - this.content = new ContentManager(); - this.width = SceneManager.stage.stageWidth; - this.height = SceneManager.stage.stageHeight; + this.entityProcessors = new EntityProcessorList(); - this.addEventListener(egret.Event.ACTIVATE, this.onActive, this); - this.addEventListener(egret.Event.DEACTIVATE, this.onDeactive, this); - } + this.initialize(); + } - public createEntity(name: string) { - let entity = new Entity(name); - entity.position = new Vector2(0, 0); - return this.addEntity(entity); - } + /** + * 辅助器,创建一个场景与DefaultRenderer附加并准备使用 + */ + public static createWithDefaultRenderer() { + let scene = new Scene(); + scene.addRenderer(new DefaultRenderer()); + return scene; + } - public addEntity(entity: Entity) { - this.entities.add(entity); - entity.scene = this; - this.addChild(entity); + /** + * 在场景子类中重写这个并在这里进行加载。在场景设置好之后,在调用begin之前,从构造器中调用。 + */ + public initialize() { + } - for (let i = 0; i < entity.numChildren; i++) - this.addEntity((entity.getChildAt(i) as Component).entity); + /** + * 在场景子类中重写这个。当SceneManager将此场景设置为活动场景时,将调用此操作。 + */ + public async onStart() { + } - return entity; - } + /** + * 在场景子类中重写这个,并在这里做任何必要的卸载。当SceneManager从活动槽中删除此场景时调用。 + */ + public unload() { + } - public destroyAllEntities() { - for (let i = 0; i < this.entities.count; i++) { - this.entities.buffer[i].destroy(); - } - } - public findEntity(name: string): Entity { - return this.entities.findEntity(name); - } + /** + * 在场景子类中重写这个,当该场景当获得焦点时调用 + */ + public onActive() { + } - /** - * 在场景中添加一个EntitySystem处理器 - * @param processor 处理器 - */ - public addEntityProcessor(processor: EntitySystem) { - processor.scene = this; - this.entityProcessors.add(processor); - return processor; - } + /** + * 在场景子类中重写这个,当该场景当失去焦点时调用 + */ + public onDeactive() { + } - public removeEntityProcessor(processor: EntitySystem) { - this.entityProcessors.remove(processor); - } - - public getEntityProcessor(): T { - return this.entityProcessors.getProcessor(); - } - - public addRenderer(renderer: T) { - this._renderers.push(renderer); - this._renderers.sort(); - - renderer.onAddedToScene(this); - - return renderer; - } - - public getRenderer(type): T { - for (let i = 0; i < this._renderers.length; i++) { - if (this._renderers[i] instanceof type) - return this._renderers[i] as T; - } - - return null; - } - - public removeRenderer(renderer: Renderer) { - this._renderers.remove(renderer); - renderer.unload(); - } - - public begin() { - if (SceneManager.sceneTransition){ - SceneManager.stage.addChildAt(this, SceneManager.stage.numChildren - 1); - }else{ - SceneManager.stage.addChild(this); - } - - if (this._renderers.length == 0) { - this.addRenderer(new DefaultRenderer()); - console.warn("场景开始时没有渲染器 自动添加DefaultRenderer以保证能够正常渲染"); - } - /** 初始化默认相机 */ - this.camera = this.createEntity("camera").getOrCreateComponent(new Camera()); - - Physics.reset(); - - if (this.entityProcessors) - this.entityProcessors.begin(); - - this.camera.onSceneSizeChanged(this.stage.stageWidth, this.stage.stageHeight); - - this._didSceneBegin = true; - this.onStart(); - } - - public end() { - this._didSceneBegin = false; - - this.removeEventListener(egret.Event.DEACTIVATE, this.onDeactive, this); - this.removeEventListener(egret.Event.ACTIVATE, this.onActive, this); - - for (let i = 0; i < this._renderers.length; i++) { - this._renderers[i].unload(); - } - - for (let i = 0; i < this._postProcessors.length; i++) { - this._postProcessors[i].unload(); - } - - this.entities.removeAllEntities(); - this.removeChildren(); - - Physics.clear(); - - this.camera = null; - this.content.dispose(); - - if (this.entityProcessors) - this.entityProcessors.end(); - - this.unload(); - - if (this.parent) - this.parent.removeChild(this); - } - - protected async onStart() { - - } - - /** 场景激活 */ - protected onActive() { - - } - - /** 场景失去焦点 */ - protected onDeactive() { - - } - - protected unload() { } - - public update() { - this.entities.updateLists(); - - if (this.entityProcessors) - this.entityProcessors.update() - - this.entities.update(); - - if (this.entityProcessors) - this.entityProcessors.lateUpdate(); - - this.renderableComponents.updateList(); - } - - public postRender() { - let enabledCounter = 0; - if (this.enablePostProcessing) { - for (let i = 0; i < this._postProcessors.length; i++) { - if (this._postProcessors[i].enable) { - let isEven = MathHelper.isEven(enabledCounter); - enabledCounter ++; - - this._postProcessors[i].process(); + public async begin() { + if (this._renderers.length == 0) { + this.addRenderer(new DefaultRenderer()); + console.warn("场景开始时没有渲染器 自动添加DefaultRenderer以保证能够正常渲染"); } - } - } - } - public render() { - for (let i = 0; i < this._renderers.length; i++) { - this._renderers[i].render(this); - } - } + this.camera = this.createEntity("camera").getOrCreateComponent(new Camera()); - public addPostProcessor(postProcessor: T): T{ - this._postProcessors.push(postProcessor); - this._postProcessors.sort(); - postProcessor.onAddedToScene(this); + Physics.reset(); - if (this._didSceneBegin){ - postProcessor.onSceneBackBufferSizeChanged(this.stage.stageWidth, this.stage.stageHeight); - } + if (this.entityProcessors) + this.entityProcessors.begin(); - return postProcessor; - } + this.addEventListener(egret.Event.ACTIVATE, this.onActive, this); + this.addEventListener(egret.Event.DEACTIVATE, this.onDeactive, this); + this.camera.onSceneSizeChanged(this.stage.stageWidth, this.stage.stageHeight); + + this._didSceneBegin = true; + this.onStart(); + } + + public end() { + this._didSceneBegin = false; + + this.removeEventListener(egret.Event.DEACTIVATE, this.onDeactive, this); + this.removeEventListener(egret.Event.ACTIVATE, this.onActive, this); + + for (let i = 0; i < this._renderers.length; i++) { + this._renderers[i].unload(); + } + + for (let i = 0; i < this._postProcessors.length; i++) { + this._postProcessors[i].unload(); + } + + this.entities.removeAllEntities(); + this.removeChildren(); + + this.camera = null; + this.content.dispose(); + + if (this.entityProcessors) + this.entityProcessors.end(); + + if (this.parent) + this.parent.removeChild(this); + + this.unload(); + } + + public update() { + // 更新我们的列表,以防它们有任何变化 + this.entities.updateLists(); + + // 更新我们的实体解析器 + if (this.entityProcessors) + this.entityProcessors.update(); + + // 更新我们的实体组 + this.entities.update(); + + if (this.entityProcessors) + this.entityProcessors.lateUpdate(); + + // 我们在实体之后更新我们的呈现。如果添加了任何新的渲染,请进行更新 + this.renderableComponents.updateList(); + } + + public render() { + if (this._renderers.length == 0) { + console.error("there are no renderers in the scene!"); + return; + } + + for (let i = 0; i < this._renderers.length; i++) { + this._renderers[i].render(this); + } + } + + /** + * 现在的任何后处理器都要完成它的处理 + * 只有在SceneTransition请求渲染时,它才会有一个值。 + */ + public postRender() { + if (this.enablePostProcessing) { + for (let i = 0; i < this._postProcessors.length; i++) { + if (this._postProcessors[i].enabled) { + this._postProcessors[i].process(); + } + } + } + } + + /** + * 为场景添加一个渲染器 + * @param renderer + */ + public addRenderer(renderer: T) { + this._renderers.push(renderer); + this._renderers.sort(); + + renderer.onAddedToScene(this); + + return renderer; + } + + /** + * 获取类型为T的第一个渲染器 + * @param type + */ + public getRenderer(type): T { + for (let i = 0; i < this._renderers.length; i++) { + if (this._renderers[i] instanceof type) + return this._renderers[i] as T; + } + + return null; + } + + /** + * 从场景中移除渲染器 + * @param renderer + */ + public removeRenderer(renderer: Renderer) { + if (!this._renderers.contains(renderer)) + return; + this._renderers.remove(renderer); + renderer.unload(); + } + + /** + * 添加一个后处理器到场景。设置场景字段并调用后处理器。onAddedToScene使后处理器可以使用场景ContentManager加载资源。 + * @param postProcessor + */ + public addPostProcessor(postProcessor: T): T { + this._postProcessors.push(postProcessor); + this._postProcessors.sort(); + postProcessor.onAddedToScene(this); + + if (this._didSceneBegin) { + postProcessor.onSceneBackBufferSizeChanged(this.stage.stageWidth, this.stage.stageHeight); + } + + return postProcessor; + } + + /** + * 获取类型为T的第一个后处理器 + * @param type + */ + public getPostProcessor(type): T { + for (let i = 0; i < this._postProcessors.length; i++) { + if (this._postProcessors[i] instanceof type) + return this._postProcessors[i] as T; + } + + return null; + } + + /** + * 删除一个后处理程序。注意,在删除时不会调用unload,因此如果不再需要PostProcessor,请确保调用unload来释放资源。 + * @param postProcessor + */ + public removePostProcessor(postProcessor: PostProcessor) { + if (!this._postProcessors.contains(postProcessor)) + return; + + this._postProcessors.remove(postProcessor); + postProcessor.unload(); + } + + /** + * 将实体添加到此场景,并返回它 + * @param name + */ + public createEntity(name: string) { + let entity = new Entity(name); + return this.addEntity(entity); + } + + /** + * 在场景的实体列表中添加一个实体 + * @param entity + */ + public addEntity(entity: Entity) { + if (this.entities.buffer.contains(entity)) + console.warn(`You are attempting to add the same entity to a scene twice: ${entity}`); + this.entities.add(entity); + entity.scene = this; + + for (let i = 0; i < entity.transform.childCount; i++) + this.addEntity(entity.transform.getChild(i).entity); + + return entity; + } + + /** + * 从场景中删除所有实体 + */ + public destroyAllEntities() { + for (let i = 0; i < this.entities.count; i++) { + this.entities.buffer[i].destroy(); + } + } + + /** + * 搜索并返回第一个具有名称的实体 + * @param name + */ + public findEntity(name: string): Entity { + return this.entities.findEntity(name); + } + + /** + * 返回具有给定标记的所有实体 + * @param tag + */ + public findEntitiesWithTag(tag: number): Entity[] { + return this.entities.entitiesWithTag(tag); + } + + /** + * 返回类型为T的所有实体 + * @param type + */ + public entitiesOfType(type): T[] { + return this.entities.entitiesOfType(type); + } + + /** + * 返回第一个启用加载的类型为T的组件 + * @param type + */ + public findComponentOfType(type): T { + return this.entities.findComponentOfType(type); + } + + /** + * 返回类型为T的所有已启用已加载组件的列表 + * @param type + */ + public findComponentsOfType(type): T[] { + return this.entities.findComponentsOfType(type); + } + + /** + * 在场景中添加一个EntitySystem处理器 + * @param processor 处理器 + */ + public addEntityProcessor(processor: EntitySystem) { + processor.scene = this; + this.entityProcessors.add(processor); + return processor; + } + + /** + * 从场景中删除EntitySystem处理器 + * @param processor + */ + public removeEntityProcessor(processor: EntitySystem) { + this.entityProcessors.remove(processor); + } + + /** + * 获取EntitySystem处理器 + */ + public getEntityProcessor(): T { + return this.entityProcessors.getProcessor(); + } + } } \ No newline at end of file diff --git a/source/src/ECS/SceneManager.ts b/source/src/ECS/SceneManager.ts deleted file mode 100644 index 53294375..00000000 --- a/source/src/ECS/SceneManager.ts +++ /dev/null @@ -1,101 +0,0 @@ -/** 运行时的场景管理。 */ -class SceneManager { - private static _scene: Scene; - private static _nextScene: Scene; - public static sceneTransition: SceneTransition; - public static stage: egret.Stage; - - constructor(stage: egret.Stage) { - stage.addEventListener(egret.Event.ENTER_FRAME, SceneManager.update, this); - - SceneManager.stage = stage; - SceneManager.initialize(stage); - } - - public static get scene() { - return this._scene; - } - public static set scene(value: Scene) { - if (!value) - throw new Error("场景不能为空"); - - if (this._scene == null) { - this._scene = value; - this._scene.begin(); - } else { - this._nextScene = value; - } - } - - public static initialize(stage: egret.Stage) { - Input.initialize(stage); - } - - public static update() { - Time.update(egret.getTimer()); - - if (SceneManager._scene) { - for (let i = GlobalManager.globalManagers.length - 1; i >= 0; i--) { - if (GlobalManager.globalManagers[i].enabled) - GlobalManager.globalManagers[i].update(); - } - - if (!SceneManager.sceneTransition || - (SceneManager.sceneTransition && (!SceneManager.sceneTransition.loadsNewScene || SceneManager.sceneTransition.isNewSceneLoaded))) { - SceneManager._scene.update(); - } - - if (SceneManager._nextScene) { - SceneManager._scene.end(); - - for (let i = 0; i < SceneManager._scene.entities.buffer.length; i++) { - let entity = SceneManager._scene.entities.buffer[i]; - entity.destroy(); - } - - SceneManager._scene = SceneManager._nextScene; - SceneManager._nextScene = null; - - SceneManager._scene.begin(); - } - } - - SceneManager.render(); - } - - public static render() { - if (this.sceneTransition){ - this.sceneTransition.preRender(); - - if (this._scene && !this.sceneTransition.hasPreviousSceneRender){ - this._scene.render(); - this._scene.postRender(); - this.sceneTransition.onBeginTransition(); - } else if (this.sceneTransition) { - if (this._scene && this.sceneTransition.isNewSceneLoaded) { - this._scene.render(); - this._scene.postRender(); - } - - this.sceneTransition.render(); - } - } else if (this._scene) { - this._scene.render(); - this._scene.postRender(); - } - } - - /** - * 临时运行SceneTransition,允许一个场景过渡到另一个平滑的自定义效果。 - * @param sceneTransition - */ - public static startSceneTransition(sceneTransition: T): T { - if (this.sceneTransition) { - console.warn("在前一个场景完成之前,不能开始一个新的场景转换。"); - return; - } - - this.sceneTransition = sceneTransition; - return sceneTransition; - } -} \ No newline at end of file diff --git a/source/src/ECS/Systems/EntityProcessingSystem.ts b/source/src/ECS/Systems/EntityProcessingSystem.ts index 5eebfedf..15022a35 100644 --- a/source/src/ECS/Systems/EntityProcessingSystem.ts +++ b/source/src/ECS/Systems/EntityProcessingSystem.ts @@ -1,32 +1,34 @@ /// -/** - * 基本实体处理系统。将其用作处理具有特定组件的许多实体的基础 - */ -abstract class EntityProcessingSystem extends EntitySystem { - constructor(matcher: Matcher) { - super(matcher); - } - - +module es { /** - * 处理特定的实体 - * @param entity + * 基本实体处理系统。将其用作处理具有特定组件的许多实体的基础 */ - public abstract processEntity(entity: Entity); + export abstract class EntityProcessingSystem extends EntitySystem { + constructor(matcher: Matcher) { + super(matcher); + } - public lateProcessEntity(entity: Entity) { + /** + * 处理特定的实体 + * @param entity + */ + public abstract processEntity(entity: Entity); + + public lateProcessEntity(entity: Entity) { + + } + + /** + * 遍历这个系统的所有实体并逐个处理它们 + * @param entities + */ + protected process(entities: Entity[]) { + entities.forEach(entity => this.processEntity(entity)); + } + + protected lateProcess(entities: Entity[]) { + entities.forEach(entity => this.lateProcessEntity(entity)); + } } - - /** - * 遍历这个系统的所有实体并逐个处理它们 - * @param entities - */ - protected process(entities: Entity[]) { - entities.forEach(entity => this.processEntity(entity)); - } - - protected lateProcess(entities: Entity[]) { - entities.forEach(entity => this.lateProcessEntity(entity)); - } -} \ No newline at end of file +} diff --git a/source/src/ECS/Systems/EntitySystem.ts b/source/src/ECS/Systems/EntitySystem.ts index 8ec9cdc6..a3e0c94a 100644 --- a/source/src/ECS/Systems/EntitySystem.ts +++ b/source/src/ECS/Systems/EntitySystem.ts @@ -1,79 +1,83 @@ -class EntitySystem { - private _scene: Scene; - private _entities: Entity[] = []; - private _matcher: Matcher; +module es { + export class EntitySystem { + private _entities: Entity[] = []; - public get matcher(){ - return this._matcher; + constructor(matcher?: Matcher) { + this._matcher = matcher ? matcher : Matcher.empty(); + } + + private _scene: Scene; + + public get scene() { + return this._scene; + } + + public set scene(value: Scene) { + this._scene = value; + this._entities = []; + } + + private _matcher: Matcher; + + public get matcher() { + return this._matcher; + } + + public initialize() { + + } + + public onChanged(entity: Entity) { + let contains = this._entities.contains(entity); + let interest = this._matcher.IsIntersted(entity); + + if (interest && !contains) + this.add(entity); + else if (!interest && contains) + this.remove(entity); + } + + public add(entity: Entity) { + this._entities.push(entity); + this.onAdded(entity); + } + + public onAdded(entity: Entity) { + } + + public remove(entity: Entity) { + this._entities.remove(entity); + this.onRemoved(entity); + } + + public onRemoved(entity: Entity) { + + } + + public update() { + this.begin(); + this.process(this._entities); + } + + public lateUpdate() { + this.lateProcess(this._entities); + this.end(); + } + + protected begin() { + + } + + protected process(entities: Entity[]) { + + } + + protected lateProcess(entities: Entity[]) { + + } + + protected end() { + + } } - - public get scene(){ - return this._scene; - } - - public set scene(value: Scene){ - this._scene = value; - this._entities = []; - } - - constructor(matcher?: Matcher){ - this._matcher = matcher ? matcher : Matcher.empty(); - } - - public initialize(){ - - } - - public onChanged(entity: Entity){ - let contains = this._entities.contains(entity); - let interest = this._matcher.IsIntersted(entity); - - if (interest && !contains) - this.add(entity); - else if(!interest && contains) - this.remove(entity); - } - - public add(entity: Entity){ - this._entities.push(entity); - this.onAdded(entity); - } - - public onAdded(entity: Entity){ - } - - public remove(entity: Entity){ - this._entities.remove(entity); - this.onRemoved(entity); - } - - public onRemoved(entity: Entity){ - - } - - public update(){ - this.begin(); - this.process(this._entities); - } - - public lateUpdate(){ - this.lateProcess(this._entities); - this.end(); - } - - protected begin(){ - - } - - protected process(entities: Entity[]){ - - } - - protected lateProcess(entities: Entity[]){ - - } - - protected end(){ - - } -} \ No newline at end of file +} diff --git a/source/src/ECS/Systems/PassiveSystem.ts b/source/src/ECS/Systems/PassiveSystem.ts index 97fbd0d1..f6285f3c 100644 --- a/source/src/ECS/Systems/PassiveSystem.ts +++ b/source/src/ECS/Systems/PassiveSystem.ts @@ -1,11 +1,13 @@ -abstract class PassiveSystem extends EntitySystem { - public onChanged(entity: Entity){ +module es { + export abstract class PassiveSystem extends EntitySystem { + public onChanged(entity: Entity) { - } + } - protected process(entities: Entity[]){ - // 我们用我们自己的不考虑实体的基本实体系统来代替 - this.begin(); - this.end(); + protected process(entities: Entity[]) { + // 我们用我们自己的不考虑实体的基本实体系统来代替 + this.begin(); + this.end(); + } } -} \ No newline at end of file +} diff --git a/source/src/ECS/Systems/ProcessingSystem.ts b/source/src/ECS/Systems/ProcessingSystem.ts index 39a4eb9e..d09a8ef6 100644 --- a/source/src/ECS/Systems/ProcessingSystem.ts +++ b/source/src/ECS/Systems/ProcessingSystem.ts @@ -1,15 +1,17 @@ /** 用于协调其他系统的通用系统基类 */ -abstract class ProcessingSystem extends EntitySystem { - public onChanged(entity: Entity){ +module es { + export abstract class ProcessingSystem extends EntitySystem { + public onChanged(entity: Entity) { + } + + /** 处理我们的系统 每帧调用 */ + public abstract processSystem(); + + protected process(entities: Entity[]) { + this.begin(); + this.processSystem(); + this.end(); + } } - - protected process(entities: Entity[]){ - this.begin(); - this.processSystem(); - this.end(); - } - - /** 处理我们的系统 每帧调用 */ - public abstract processSystem(); -} \ No newline at end of file +} diff --git a/source/src/ECS/Transform.ts b/source/src/ECS/Transform.ts new file mode 100644 index 00000000..6151919f --- /dev/null +++ b/source/src/ECS/Transform.ts @@ -0,0 +1,507 @@ +module transform { + export enum Component { + position, + scale, + rotation, + } +} + +module es { + import HashObject = egret.HashObject; + + export enum DirtyType { + clean, + positionDirty, + scaleDirty, + rotationDirty, + } + + export class Transform extends HashObject { + /** 与此转换关联的实体 */ + public readonly entity: Entity; + public hierarchyDirty: DirtyType; + public _localDirty: boolean; + public _localPositionDirty: boolean; + public _localScaleDirty: boolean; + public _localRotationDirty: boolean; + public _positionDirty: boolean; + public _worldToLocalDirty: boolean; + public _worldInverseDirty: boolean; + /** + * 值会根据位置、旋转和比例自动重新计算 + */ + public _localTransform: Matrix2D = Matrix2D.create(); + /** + * 值将自动从本地和父矩阵重新计算。 + */ + public _worldTransform = Matrix2D.create().identity(); + public _rotationMatrix: Matrix2D = Matrix2D.create(); + public _translationMatrix: Matrix2D = Matrix2D.create(); + public _scaleMatrix: Matrix2D = Matrix2D.create(); + public _children: Transform[]; + + constructor(entity: Entity) { + super(); + this.entity = entity; + this.scale = Vector2.one; + this._children = []; + } + + /** + * 这个转换的所有子元素 + */ + public get childCount() { + return this._children.length; + } + + /** + * 变换在世界空间的旋转度 + */ + public get rotationDegrees(): number { + return MathHelper.toDegrees(this._rotation); + } + + /** + * 变换在世界空间的旋转度 + * @param value + */ + public set rotationDegrees(value: number) { + this.setRotation(MathHelper.toRadians(value)); + } + + /** + * 旋转相对于父变换旋转的角度 + */ + public get localRotationDegrees(): number { + return MathHelper.toDegrees(this._localRotation); + } + + /** + * 旋转相对于父变换旋转的角度 + * @param value + */ + public set localRotationDegrees(value: number) { + this.localRotation = MathHelper.toRadians(value); + } + + public get localToWorldTransform(): Matrix2D { + this.updateTransform(); + return this._worldTransform; + } + + public _parent: Transform; + + /** + * 获取此转换的父转换 + */ + public get parent() { + return this._parent; + } + + /** + * 设置此转换的父转换 + * @param value + */ + public set parent(value: Transform) { + this.setParent(value); + } + + public _worldToLocalTransform = Matrix2D.create().identity(); + + public get worldToLocalTransform(): Matrix2D { + if (this._worldToLocalDirty) { + if (!this.parent) { + this._worldToLocalTransform = Matrix2D.create().identity(); + } else { + this.parent.updateTransform(); + this._worldToLocalTransform = this.parent._worldTransform.invert(); + } + + this._worldToLocalDirty = false; + } + + return this._worldToLocalTransform; + } + + public _worldInverseTransform = Matrix2D.create().identity(); + + public get worldInverseTransform(): Matrix2D { + this.updateTransform(); + if (this._worldInverseDirty) { + this._worldInverseTransform = this._worldTransform.invert(); + this._worldInverseDirty = false; + } + + return this._worldInverseTransform; + } + + public _position: Vector2 = Vector2.zero; + + /** + * 变换在世界空间中的位置 + */ + public get position(): Vector2 { + this.updateTransform(); + if (this._positionDirty) { + if (!this.parent) { + this._position = this._localPosition; + } else { + this.parent.updateTransform(); + this._position = Vector2Ext.transformR(this._localPosition, this.parent._worldTransform); + } + + this._positionDirty = false; + } + + return this._position; + } + + /** + * 变换在世界空间中的位置 + * @param value + */ + public set position(value: Vector2) { + this.setPosition(value.x, value.y); + } + + public _scale: Vector2 = Vector2.one; + + /** + * 变换在世界空间的缩放 + */ + public get scale(): Vector2 { + this.updateTransform(); + return this._scale; + } + + /** + * 变换在世界空间的缩放 + * @param value + */ + public set scale(value: Vector2) { + this.setScale(value); + } + + public _rotation: number = 0; + + /** + * 在世界空间中以弧度旋转的变换 + */ + public get rotation(): number { + this.updateTransform(); + return this._rotation; + } + + /** + * 变换在世界空间的旋转度 + * @param value + */ + public set rotation(value: number) { + this.setRotation(value); + } + + public _localPosition: Vector2 = Vector2.zero; + + /** + * 转换相对于父转换的位置。如果转换没有父元素,则与transform.position相同 + */ + public get localPosition(): Vector2 { + this.updateTransform(); + return this._localPosition; + } + + /** + * 转换相对于父转换的位置。如果转换没有父元素,则与transform.position相同 + * @param value + */ + public set localPosition(value: Vector2) { + this.setLocalPosition(value); + } + + public _localScale: Vector2 = Vector2.one; + + /** + * 转换相对于父元素的比例。如果转换没有父元素,则与transform.scale相同 + */ + public get localScale(): Vector2 { + this.updateTransform(); + return this._localScale; + } + + /** + * 转换相对于父元素的比例。如果转换没有父元素,则与transform.scale相同 + * @param value + */ + public set localScale(value: Vector2) { + this.setLocalScale(value); + } + + public _localRotation: number = 0; + + /** + * 相对于父变换的旋转,变换的旋转。如果转换没有父元素,则与transform.rotation相同 + */ + public get localRotation(): number { + this.updateTransform(); + return this._localRotation; + } + + /** + * 相对于父变换的旋转,变换的旋转。如果转换没有父元素,则与transform.rotation相同 + * @param value + */ + public set localRotation(value: number) { + this.setLocalRotation(value); + } + + /** + * 返回在索引处的转换子元素 + * @param index + */ + public getChild(index: number): Transform { + return this._children[index]; + } + + /** + * 设置此转换的父转换 + * @param parent + */ + public setParent(parent: Transform): Transform { + if (this._parent.equals(parent)) + return this; + + if (!this._parent) { + this._parent._children.remove(this); + this._parent._children.push(this); + } + + this._parent = parent; + this.setDirty(DirtyType.positionDirty); + + return this; + } + + /** + * 设置转换在世界空间中的位置 + * @param x + * @param y + */ + public setPosition(x: number, y: number): Transform { + let position = new Vector2(x, y); + if (position.equals(this._position)) + return this; + + this._position = position; + if (this.parent) { + this.localPosition = Vector2Ext.transformR(this._position, this._worldToLocalTransform); + } else { + this.localPosition = position; + } + this._positionDirty = false; + + return this; + } + + /** + * 设置转换相对于父转换的位置。如果转换没有父元素,则与transform.position相同 + * @param localPosition + */ + public setLocalPosition(localPosition: Vector2): Transform { + if (localPosition.equals(this._localPosition)) + return this; + + this._localPosition = localPosition; + this._localDirty = this._positionDirty = this._localPositionDirty = this._localRotationDirty = this._localScaleDirty = true; + this.setDirty(DirtyType.positionDirty); + + return this; + } + + + /** + * 设置变换在世界空间的旋转度 + * @param radians + */ + public setRotation(radians: number): Transform { + this._rotation = radians; + if (this.parent) { + this.localRotation = this.parent.rotation + radians; + } else { + this.localRotation = radians; + } + + return this; + } + + /** + * 设置变换在世界空间的旋转度 + * @param degrees + */ + public setRotationDegrees(degrees: number): Transform { + return this.setRotation(MathHelper.toRadians(degrees)); + } + + /** + * 旋转精灵的顶部,使其朝向位置 + * @param pos + */ + public lookAt(pos: Vector2) { + let sign = this.position.x > pos.x ? -1 : 1; + let vectorToAlignTo = Vector2.normalize(Vector2.subtract(this.position, pos)); + this.rotation = sign * Math.acos(Vector2.dot(vectorToAlignTo, Vector2.unitY)); + } + + /** + * 相对于父变换的旋转设置变换的旋转。如果转换没有父元素,则与transform.rotation相同 + * @param radians + */ + public setLocalRotation(radians: number) { + this._localRotation = radians; + this._localDirty = this._positionDirty = this._localPositionDirty = this._localRotationDirty = this._localScaleDirty = true; + this.setDirty(DirtyType.rotationDirty); + + return this; + } + + /** + * 相对于父变换的旋转设置变换的旋转。如果转换没有父元素,则与transform.rotation相同 + * @param degrees + */ + public setLocalRotationDegrees(degrees: number): Transform { + return this.setLocalRotation(MathHelper.toRadians(degrees)); + } + + /** + * 设置变换在世界空间中的缩放 + * @param scale + */ + public setScale(scale: Vector2): Transform { + this._scale = scale; + if (this.parent) { + this.localScale = Vector2.divide(scale, this.parent._scale); + } else { + this.localScale = scale; + } + return this; + } + + /** + * 设置转换相对于父对象的比例。如果转换没有父元素,则与transform.scale相同 + * @param scale + */ + public setLocalScale(scale: Vector2): Transform { + this._localScale = scale; + this._localDirty = this._positionDirty = this._localScaleDirty = true; + this.setDirty(DirtyType.scaleDirty); + + return this; + } + + /** + * 对精灵坐标进行四舍五入 + */ + public roundPosition() { + this.position = this._position.round(); + } + + public updateTransform() { + if (this.hierarchyDirty != DirtyType.clean) { + if (this.parent) + this.parent.updateTransform(); + + if (this._localDirty) { + if (this._localPositionDirty) { + this._translationMatrix = Matrix2D.create().translate(this._localPosition.x, this._localPosition.y); + this._localPositionDirty = false; + } + + if (this._localRotationDirty) { + this._rotationMatrix = Matrix2D.create().rotate(this._localRotation); + this._localRotationDirty = false; + } + + if (this._localScaleDirty) { + this._scaleMatrix = Matrix2D.create().scale(this._localScale.x, this._localScale.y); + this._localScaleDirty = false; + } + + this._localTransform = this._scaleMatrix.multiply(this._rotationMatrix); + this._localTransform = this._localTransform.multiply(this._translationMatrix); + + if (!this.parent) { + this._worldTransform = this._localTransform; + this._rotation = this._localRotation; + this._scale = this._localScale; + this._worldInverseDirty = true; + } + + this._localDirty = false; + } + + if (this.parent) { + this._worldTransform = this._localTransform.multiply(this.parent._worldTransform); + + this._rotation = this._localRotation + this.parent._rotation; + this._scale = Vector2.multiply(this.parent._scale, this._localScale); + this._worldInverseDirty = true; + } + + this._worldToLocalDirty = true; + this._positionDirty = true; + this.hierarchyDirty = DirtyType.clean; + } + } + + public setDirty(dirtyFlagType: DirtyType) { + if ((this.hierarchyDirty & dirtyFlagType) == 0) { + this.hierarchyDirty |= dirtyFlagType; + + switch (dirtyFlagType) { + case es.DirtyType.positionDirty: + this.entity.onTransformChanged(transform.Component.position); + break; + case es.DirtyType.rotationDirty: + this.entity.onTransformChanged(transform.Component.rotation); + break; + case es.DirtyType.scaleDirty: + this.entity.onTransformChanged(transform.Component.scale); + break; + } + + if (!this._children) + this._children = []; + + // 告诉子项发生了变换 + for (let i = 0; i < this._children.length; i++) + this._children[i].setDirty(dirtyFlagType); + } + } + + /** + * 从另一个transform属性进行拷贝 + * @param transform + */ + public copyFrom(transform: Transform) { + this._position = transform.position; + this._localPosition = transform._localPosition; + this._rotation = transform._rotation; + this._localRotation = transform._localRotation; + this._scale = transform._scale; + this._localScale = transform._localScale; + + this.setDirty(DirtyType.positionDirty); + this.setDirty(DirtyType.rotationDirty); + this.setDirty(DirtyType.scaleDirty); + } + + public toString(): string { + return `[Transform: parent: ${this.parent}, position: ${this.position}, rotation: ${this.rotation}, + scale: ${this.scale}, localPosition: ${this._localPosition}, localRotation: ${this._localRotation}, + localScale: ${this._localScale}]`; + } + + public equals(other: Transform) { + return other.hashCode == this.hashCode; + } + } +} \ No newline at end of file diff --git a/source/src/ECS/Utils/BitSet.ts b/source/src/ECS/Utils/BitSet.ts index d75c2f35..8ec94a8b 100644 --- a/source/src/ECS/Utils/BitSet.ts +++ b/source/src/ECS/Utils/BitSet.ts @@ -1,133 +1,135 @@ -/** - * 这个类可以从两方面来考虑。你可以把它看成一个位向量或者一组非负整数。这个名字有点误导人。 - * - * 它是由一个位向量实现的,但同样可以把它看成是一个非负整数的集合;集合中的每个整数由对应索引处的集合位表示。该结构的大小由集合中的最大整数决定。 - */ -class BitSet{ - private static LONG_MASK: number = 0x3f; - private _bits: number[]; +module es { + /** + * 这个类可以从两方面来考虑。你可以把它看成一个位向量或者一组非负整数。这个名字有点误导人。 + * + * 它是由一个位向量实现的,但同样可以把它看成是一个非负整数的集合;集合中的每个整数由对应索引处的集合位表示。该结构的大小由集合中的最大整数决定。 + */ + export class BitSet { + private static LONG_MASK: number = 0x3f; + private _bits: number[]; - constructor(nbits: number = 64){ - let length = nbits >> 6; - if ((nbits & BitSet.LONG_MASK) != 0) - length ++; + constructor(nbits: number = 64) { + let length = nbits >> 6; + if ((nbits & BitSet.LONG_MASK) != 0) + length++; - this._bits = new Array(length); - } + this._bits = new Array(length); + } - public and(bs: BitSet){ - let max = Math.min(this._bits.length, bs._bits.length); - let i; - for (let i = 0; i < max; ++i) - this._bits[i] &= bs._bits[i]; + public and(bs: BitSet) { + let max = Math.min(this._bits.length, bs._bits.length); + let i; + for (let i = 0; i < max; ++i) + this._bits[i] &= bs._bits[i]; - while (i < this._bits.length) - this._bits[i ++] = 0; - } + while (i < this._bits.length) + this._bits[i++] = 0; + } - public andNot(bs: BitSet){ - let i = Math.min(this._bits.length, bs._bits.length); - while(--i >= 0) - this._bits[i] &= ~bs._bits[i]; - } + public andNot(bs: BitSet) { + let i = Math.min(this._bits.length, bs._bits.length); + while (--i >= 0) + this._bits[i] &= ~bs._bits[i]; + } - public cardinality(): number{ - let card = 0; - for (let i = this._bits.length - 1; i >= 0; i --){ - let a = this._bits[i]; + public cardinality(): number { + let card = 0; + for (let i = this._bits.length - 1; i >= 0; i--) { + let a = this._bits[i]; - if (a == 0) - continue; + if (a == 0) + continue; - if (a == -1){ - card += 64; - continue; + if (a == -1) { + card += 64; + continue; + } + + a = ((a >> 1) & 0x5555555555555555) + (a & 0x5555555555555555); + a = ((a >> 2) & 0x3333333333333333) + (a & 0x3333333333333333); + let b = ((a >> 32) + a); + b = ((b >> 4) & 0x0f0f0f0f) + (b & 0x0f0f0f0f); + b = ((b >> 8) & 0x00ff00ff) + (b & 0x00ff00ff); + card += ((b >> 16) & 0x0000ffff) + (b & 0x0000ffff); } - a = ((a >> 1) & 0x5555555555555555) + (a & 0x5555555555555555); - a = ((a >> 2) & 0x3333333333333333) + (a & 0x3333333333333333); - let b = ((a >> 32) + a); - b = ((b >> 4) & 0x0f0f0f0f) + (b & 0x0f0f0f0f); - b = ((b >> 8) & 0x00ff00ff) + (b & 0x00ff00ff); - card += ((b >> 16) & 0x0000ffff) + (b & 0x0000ffff); + return card; } - return card; - } + public clear(pos?: number) { + if (pos != undefined) { + let offset = pos >> 6; + this.ensure(offset); + this._bits[offset] &= ~(1 << pos); + } else { + for (let i = 0; i < this._bits.length; i++) + this._bits[i] = 0; + } + } - public clear(pos?: number){ - if (pos != undefined){ + public get(pos: number): boolean { let offset = pos >> 6; - this.ensure(offset); - this._bits[offset] &= ~(1 << pos); - }else{ - for (let i = 0; i < this._bits.length; i ++) - this._bits[i] = 0; - } - } - - private ensure(lastElt: number){ - if (lastElt >= this._bits.length){ - let nd = new Number[lastElt + 1]; - nd = this._bits.copyWithin(0, 0, this._bits.length); - this._bits = nd; - } - } - - public get(pos: number): boolean{ - let offset = pos >> 6; - if (offset >= this._bits.length) - return false; - - return (this._bits[offset] & (1 << pos)) != 0; - } - - public intersects(set: BitSet){ - let i = Math.min(this._bits.length, set._bits.length); - while (--i >= 0){ - if ((this._bits[i] & set._bits[i]) != 0) - return true; - } - - return false; - } - - public isEmpty(): boolean{ - for (let i = this._bits.length - 1; i >= 0; i --){ - if (this._bits[i]) + if (offset >= this._bits.length) return false; + + return (this._bits[offset] & (1 << pos)) != 0; } - return true; - } + public intersects(set: BitSet) { + let i = Math.min(this._bits.length, set._bits.length); + while (--i >= 0) { + if ((this._bits[i] & set._bits[i]) != 0) + return true; + } - public nextSetBit(from: number){ - let offset = from >> 6; - let mask = 1 << from; - while (offset < this._bits.length){ - let h = this._bits[offset]; - do { - if ((h & mask) != 0) - return from; - - mask <<= 1; - from ++; - } while (mask != 0); - - mask = 1; - offset ++; + return false; } - return -1; - } + public isEmpty(): boolean { + for (let i = this._bits.length - 1; i >= 0; i--) { + if (this._bits[i]) + return false; + } - public set(pos: number, value: boolean = true){ - if (value){ - let offset = pos >> 6; - this.ensure(offset); - this._bits[offset] |= 1 << pos; - }else{ - this.clear(pos); + return true; + } + + public nextSetBit(from: number) { + let offset = from >> 6; + let mask = 1 << from; + while (offset < this._bits.length) { + let h = this._bits[offset]; + do { + if ((h & mask) != 0) + return from; + + mask <<= 1; + from++; + } while (mask != 0); + + mask = 1; + offset++; + } + + return -1; + } + + public set(pos: number, value: boolean = true) { + if (value) { + let offset = pos >> 6; + this.ensure(offset); + this._bits[offset] |= 1 << pos; + } else { + this.clear(pos); + } + } + + private ensure(lastElt: number) { + if (lastElt >= this._bits.length) { + let nd = new Number[lastElt + 1]; + nd = this._bits.copyWithin(0, 0, this._bits.length); + this._bits = nd; + } } } -} \ No newline at end of file +} diff --git a/source/src/ECS/Utils/ComponentList.ts b/source/src/ECS/Utils/ComponentList.ts index bdb60bdf..1194ebab 100644 --- a/source/src/ECS/Utils/ComponentList.ts +++ b/source/src/ECS/Utils/ComponentList.ts @@ -1,186 +1,271 @@ -class ComponentList { - private _entity: Entity; - private _components: Component[] = []; - private _componentsToAdd: Component[] = []; - private _componentsToRemove: Component[] = []; - private _tempBufferList: Component[] = []; +/// +module es { + export class ComponentList { + /** + * 组件列表的全局updateOrder排序 + */ + public static compareUpdatableOrder: IUpdatableComparer = new IUpdatableComparer(); + public _entity: Entity; - constructor(entity: Entity){ - this._entity = entity; - } + /** + * 添加到实体的组件列表 + */ + public _components: Component[] = []; + /** + * 添加到此框架的组件列表。用来对组件进行分组,这样我们就可以同时进行加工 + */ + public _componentsToAdd: Component[] = []; + /** + * 标记要删除此框架的组件列表。用来对组件进行分组,这样我们就可以同时进行加工 + */ + public _componentsToRemove: Component[] = []; + public _tempBufferList: Component[] = []; + /** + * 用于确定是否需要对该框架中的组件进行排序的标志 + */ + public _isComponentListUnsorted: boolean; - public get count(){ - return this._components.length; - } - - public get buffer(){ - return this._components; - } - - public add(component: Component){ - this._componentsToAdd.push(component); - } - - public remove(component: Component){ - if (this._componentsToAdd.contains(component)){ - this._componentsToAdd.remove(component); - return; + constructor(entity: Entity) { + this._entity = entity; } - this._componentsToRemove.push(component); - } - - public removeAllComponents(){ - for (let i = 0; i < this._components.length; i ++){ - this.handleRemove(this._components[i]); + public get count() { + return this._components.length; } - this._components.length = 0; - this._componentsToAdd.length = 0; - this._componentsToRemove.length = 0; - } - - public deregisterAllComponents(){ - for (let i = 0; i < this._components.length; i ++){ - let component = this._components[i]; - - if (component instanceof RenderableComponent) - this._entity.scene.renderableComponents.remove(component); - - this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component), false); - this._entity.scene.entityProcessors.onComponentRemoved(this._entity); + public get buffer() { + return this._components; } - } - public registerAllComponents(){ - for (let i = 0; i < this._components.length; i ++){ - let component = this._components[i]; - - if (component instanceof RenderableComponent) - this._entity.scene.renderableComponents.add(component); - - this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component)); - this._entity.scene.entityProcessors.onComponentAdded(this._entity); + public markEntityListUnsorted() { + this._isComponentListUnsorted = true; } - } - public updateLists(){ - if (this._componentsToRemove.length > 0){ - for (let i = 0; i < this._componentsToRemove.length; i ++){ - this.handleRemove(this._componentsToRemove[i]); - this._components.remove(this._componentsToRemove[i]); + public add(component: Component) { + this._componentsToAdd.push(component); + } + + public remove(component: Component) { + if (this._componentsToRemove.contains(component)) + console.warn(`You are trying to remove a Component (${component}) that you already removed`); + + // 这可能不是一个活动的组件,所以我们必须注意它是否还没有被处理,它可能正在同一帧中被删除 + if (this._componentsToAdd.contains(component)) { + this._componentsToAdd.remove(component); + return; } + this._componentsToRemove.push(component); + } + + /** + * 立即从组件列表中删除所有组件 + */ + public removeAllComponents() { + for (let i = 0; i < this._components.length; i++) { + this.handleRemove(this._components[i]); + } + + this._components.length = 0; + this._componentsToAdd.length = 0; this._componentsToRemove.length = 0; } - if (this._componentsToAdd.length > 0){ - for (let i = 0, count = this._componentsToAdd.length; i < count; i ++){ - let component = this._componentsToAdd[i]; - if (component instanceof RenderableComponent) + public deregisterAllComponents() { + for (let i = 0; i < this._components.length; i++) { + let component = this._components[i]; + + // 处理渲染层列表 + if (component instanceof RenderableComponent) { + this._entity.scene.removeChild(component.displayObject); + this._entity.scene.renderableComponents.remove(component); + } + + + this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component), false); + this._entity.scene.entityProcessors.onComponentRemoved(this._entity); + } + } + + public registerAllComponents() { + for (let i = 0; i < this._components.length; i++) { + let component = this._components[i]; + + if (component instanceof RenderableComponent) { + this._entity.scene.addChild(component.displayObject); this._entity.scene.renderableComponents.add(component); + } + this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component)); this._entity.scene.entityProcessors.onComponentAdded(this._entity); - - this._components.push(component); - this._tempBufferList.push(component); } + } - this._componentsToAdd.length = 0; - - for (let i = 0; i < this._tempBufferList.length; i++){ - let component = this._tempBufferList[i]; - component.onAddedToEntity(); - - if (component.enabled){ - component.onEnabled(); + /** + * 处理任何需要删除或添加的组件 + */ + public updateLists() { + if (this._componentsToRemove.length > 0) { + for (let i = 0; i < this._componentsToRemove.length; i++) { + this.handleRemove(this._componentsToRemove[i]); + this._components.remove(this._componentsToRemove[i]); } + + this._componentsToRemove.length = 0; } - this._tempBufferList.length = 0; - } - } + if (this._componentsToAdd.length > 0) { + for (let i = 0, count = this._componentsToAdd.length; i < count; i++) { + let component = this._componentsToAdd[i]; + if (component instanceof RenderableComponent) { + this._entity.scene.addChild(component.displayObject); + this._entity.scene.renderableComponents.add(component); + } - public onEntityTransformChanged(comp: TransformComponent){ - for (let i = 0; i < this._components.length; i ++){ - if (this._components[i].enabled) - this._components[i].onEntityTransformChanged(comp); + + this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component)); + this._entity.scene.entityProcessors.onComponentAdded(this._entity); + + this._components.push(component); + this._tempBufferList.push(component); + } + + // 在调用onAddedToEntity之前清除,以防添加更多组件 + this._componentsToAdd.length = 0; + this._isComponentListUnsorted = true; + + // 现在所有的组件都添加到了场景中,我们再次循环并调用onAddedToEntity/onEnabled + for (let i = 0; i < this._tempBufferList.length; i++) { + let component = this._tempBufferList[i]; + component.onAddedToEntity(); + + // enabled检查实体和组件 + if (component.enabled) { + component.onEnabled(); + } + } + + this._tempBufferList.length = 0; + } + + if (this._isComponentListUnsorted) { + this._components.sort(ComponentList.compareUpdatableOrder.compare); + this._isComponentListUnsorted = false; + } } - for (let i = 0; i < this._componentsToAdd.length; i ++){ - if (this._componentsToAdd[i].enabled) - this._componentsToAdd[i].onEntityTransformChanged(comp); - } - } + public handleRemove(component: Component) { + // 处理渲染层列表 + if (component instanceof RenderableComponent) { + this._entity.scene.removeChild(component.displayObject); + this._entity.scene.renderableComponents.remove(component); + } - private handleRemove(component: Component){ - if (component instanceof RenderableComponent) - this._entity.scene.renderableComponents.remove(component); - this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component), false); - this._entity.scene.entityProcessors.onComponentRemoved(this._entity); + this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component), false); + this._entity.scene.entityProcessors.onComponentRemoved(this._entity); - component.onRemovedFromEntity(); - component.entity = null; - } - - public getComponent(type, onlyReturnInitializedComponents: boolean): T{ - for (let i = 0; i < this._components.length; i ++){ - let component = this._components[i]; - if (component instanceof type) - return component as T; + component.onRemovedFromEntity(); + component.entity = null; } - if (!onlyReturnInitializedComponents){ - for (let i = 0; i < this._componentsToAdd.length; i ++){ - let component = this._componentsToAdd[i]; + + /** + * 获取类型T的第一个组件并返回它 + * 可以选择跳过检查未初始化的组件(尚未调用onAddedToEntity方法的组件) + * 如果没有找到组件,则返回null。 + * @param type + * @param onlyReturnInitializedComponents + */ + public getComponent(type, onlyReturnInitializedComponents: boolean): T { + for (let i = 0; i < this._components.length; i++) { + let component = this._components[i]; if (component instanceof type) return component as T; } + + // 我们可以选择检查挂起的组件,以防addComponent和getComponent在同一个框架中被调用 + if (!onlyReturnInitializedComponents) { + for (let i = 0; i < this._componentsToAdd.length; i++) { + let component = this._componentsToAdd[i]; + if (component instanceof type) + return component as T; + } + } + + return null; } - return null; - } + /** + * 获取T类型的所有组件,但不使用列表分配 + * @param typeName + * @param components + */ + public getComponents(typeName: string | any, components?) { + if (!components) + components = []; - public getComponents(typeName: string | any, components?){ - if (!components) - components = []; + for (let i = 0; i < this._components.length; i++) { + let component = this._components[i]; + if (typeof (typeName) == "string") { + if (egret.is(component, typeName)) { + components.push(component); + } + } else { + if (component instanceof typeName) { + components.push(component); + } + } + } - for (let i = 0; i < this._components.length; i ++){ - let component = this._components[i]; - if (typeof(typeName) == "string"){ - if (egret.is(component, typeName)){ - components.push(component); - } - }else{ - if (component instanceof typeName){ - components.push(component); + for (let i = 0; i < this._componentsToAdd.length; i++) { + let component = this._componentsToAdd[i]; + if (typeof (typeName) == "string") { + if (egret.is(component, typeName)) { + components.push(component); + } + } else { + if (component instanceof typeName) { + components.push(component); + } } } + + return components; + } + + public update() { + this.updateLists(); + for (let i = 0; i < this._components.length; i++) { + let updatableComponent = this._components[i]; + + if (updatableComponent.enabled && + (updatableComponent.updateInterval == 1 || + Time.frameCount % updatableComponent.updateInterval == 0)) + updatableComponent.update(); + } } - for (let i = 0; i < this._componentsToAdd.length; i ++){ - let component = this._componentsToAdd[i]; - if (typeof(typeName) == "string"){ - if (egret.is(component, typeName)){ - components.push(component); - } - }else{ - if (component instanceof typeName){ - components.push(component); - } + public onEntityTransformChanged(comp: transform.Component) { + for (let i = 0; i < this._components.length; i++) { + if (this._components[i].enabled) + this._components[i].onEntityTransformChanged(comp); + } + + for (let i = 0; i < this._componentsToAdd.length; i++) { + if (this._componentsToAdd[i].enabled) + this._componentsToAdd[i].onEntityTransformChanged(comp); } } - return components; - } + public onEntityEnabled() { + for (let i = 0; i < this._components.length; i++) + this._components[i].onEnabled(); + } - public update(){ - this.updateLists(); - for (let i = 0; i < this._components.length; i ++){ - let component = this._components[i]; - if (component.enabled && (component.updateInterval == 1 || Time.frameCount % component.updateInterval == 0)) - component.update(); + public onEntityDisabled() { + for (let i = 0; i < this._components.length; i++) + this._components[i].onDisabled(); } } -} \ No newline at end of file +} diff --git a/source/src/ECS/Utils/ComponentTypeManager.ts b/source/src/ECS/Utils/ComponentTypeManager.ts index f8ca330c..fc8c5409 100644 --- a/source/src/ECS/Utils/ComponentTypeManager.ts +++ b/source/src/ECS/Utils/ComponentTypeManager.ts @@ -1,18 +1,20 @@ -class ComponentTypeManager{ - private static _componentTypesMask: Map = new Map(); +module es { + export class ComponentTypeManager { + private static _componentTypesMask: Map = new Map(); - public static add(type){ - if (!this._componentTypesMask.has(type)) - this._componentTypesMask[type] = this._componentTypesMask.size; - } - - public static getIndexFor(type){ - let v = -1; - if (!this._componentTypesMask.has(type)){ - this.add(type); - v = this._componentTypesMask.get(type); + public static add(type) { + if (!this._componentTypesMask.has(type)) + this._componentTypesMask[type] = this._componentTypesMask.size; } - return v; + public static getIndexFor(type) { + let v = -1; + if (!this._componentTypesMask.has(type)) { + this.add(type); + v = this._componentTypesMask.get(type); + } + + return v; + } } -} \ No newline at end of file +} diff --git a/source/src/ECS/Utils/EntityList.ts b/source/src/ECS/Utils/EntityList.ts index 1aae3886..d00cbb2b 100644 --- a/source/src/ECS/Utils/EntityList.ts +++ b/source/src/ECS/Utils/EntityList.ts @@ -1,134 +1,285 @@ -class EntityList{ - public scene: Scene; - private _entitiesToRemove: Entity[] = []; - private _entitiesToAdded: Entity[] = []; - private _tempEntityList: Entity[] = []; - private _entities: Entity[] = []; - private _entityDict: Map = new Map(); - private _unsortedTags: number[] = []; +module es { + export class EntityList { + public scene: Scene; + /** + * 添加到场景中的实体列表 + */ + public _entities: Entity[] = []; + /** + * 添加到此框架的实体列表。用于对实体进行分组,以便我们可以同时处理它们 + */ + public _entitiesToAdded: Entity[] = []; + /** + * 标记要删除此框架的实体列表。用于对实体进行分组,以便我们可以同时处理它们 + */ + public _entitiesToRemove: Entity[] = []; + /** + * 用于确定是否需要在此框架中对实体进行排序的标志 + */ + public _isEntityListUnsorted: boolean; + /** + * 通过标签跟踪实体,便于检索 + */ + public _entityDict: Map = new Map(); + public _unsortedTags: number[] = []; + /** + * 在updateLists中用于双缓冲区,以便可以在其他地方修改原始列表 + */ + public _tempEntityList: Entity[] = []; - constructor(scene: Scene){ - this.scene = scene; - } - - public get count(){ - return this._entities.length; - } - - public get buffer(){ - return this._entities; - } - - public add(entity: Entity){ - if (this._entitiesToAdded.indexOf(entity) == -1) - this._entitiesToAdded.push(entity); - } - - public remove(entity: Entity){ - if (this._entitiesToAdded.contains(entity)){ - this._entitiesToAdded.remove(entity); - return; + constructor(scene: Scene) { + this.scene = scene; } - if (!this._entitiesToRemove.contains(entity)) - this._entitiesToRemove.push(entity); - } - - public findEntity(name: string){ - for (let i = 0; i < this._entities.length; i ++){ - if (this._entities[i].name == name) - return this._entities[i]; + public get count() { + return this._entities.length; } - return this._entitiesToAdded.firstOrDefault(entity => entity.name == name); - } - - public getTagList(tag: number){ - let list = this._entityDict.get(tag); - if (!list){ - list = []; - this._entityDict.set(tag, list); + public get buffer() { + return this._entities; } - return this._entityDict.get(tag); - } - - public addToTagList(entity: Entity){ - let list = this.getTagList(entity.tag); - if (!list.contains(entity)){ - list.push(entity); - this._unsortedTags.push(entity.tag); - } - } - - public removeFromTagList(entity: Entity){ - let list = this._entityDict.get(entity.tag); - if (list){ - list.remove(entity); - } - } - - public update(){ - for (let i = 0; i < this._entities.length; i++){ - let entity = this._entities[i]; - if (entity.enabled) - entity.update(); - } - } - - public removeAllEntities(){ - this._entitiesToAdded.length = 0; - - this.updateLists(); - - for (let i = 0; i < this._entities.length; i ++){ - this._entities[i]._isDestoryed = true; - this._entities[i].onRemovedFromScene(); - this._entities[i].scene = null; + public markEntityListUnsorted() { + this._isEntityListUnsorted = true; } - this._entities.length = 0; - this._entityDict.clear(); - } - - public updateLists(){ - if (this._entitiesToRemove.length > 0){ - let temp = this._entitiesToRemove; - this._entitiesToRemove = this._tempEntityList; - this._tempEntityList = temp; - this._tempEntityList.forEach(entity => { - this._entities.remove(entity); - entity.scene = null; - - this.scene.entityProcessors.onEntityRemoved(entity); - }); - - this._tempEntityList.length = 0; + public markTagUnsorted(tag: number) { + this._unsortedTags.push(tag); } - if (this._entitiesToAdded.length > 0){ - let temp = this._entitiesToAdded; - this._entitiesToAdded = this._tempEntityList; - this._tempEntityList = temp; - this._tempEntityList.forEach(entity => { - if (!this._entities.contains(entity)){ - this._entities.push(entity); - entity.scene = this.scene; - - this.scene.entityProcessors.onEntityAdded(entity) - } - }); - - this._tempEntityList.forEach(entity => entity.onAddedToScene()); - this._tempEntityList.length = 0; + /** + * 将实体添加到列表中。所有生命周期方法将在下一帧中被调用。 + * @param entity + */ + public add(entity: Entity) { + if (this._entitiesToAdded.indexOf(entity) == -1) + this._entitiesToAdded.push(entity); } - if (this._unsortedTags.length > 0){ - this._unsortedTags.forEach(tag => { - this._entityDict.get(tag).sort(); - }); + /** + * 从列表中删除一个实体。所有生命周期方法将在下一帧中被调用。 + * @param entity + */ + public remove(entity: Entity) { + if (!this._entitiesToRemove.contains(entity)) { + console.warn(`You are trying to remove an entity (${entity.name}) that you already removed`); + return; + } + // 防止在同一帧中添加或删除实体 + if (this._entitiesToAdded.contains(entity)) { + this._entitiesToAdded.remove(entity); + return; + } + + if (!this._entitiesToRemove.contains(entity)) + this._entitiesToRemove.push(entity); + } + + /** + * 从实体列表中删除所有实体 + */ + public removeAllEntities() { this._unsortedTags.length = 0; + this._entitiesToAdded.length = 0; + this._isEntityListUnsorted = false; + + // 为什么我们要在这里更新列表?主要用于处理场景切换前分离的实体。 + // 它们仍然在_entitiesToRemove列表中,该列表将由更新列表处理。 + this.updateLists(); + + for (let i = 0; i < this._entities.length; i++) { + this._entities[i]._isDestroyed = true; + this._entities[i].onRemovedFromScene(); + this._entities[i].scene = null; + } + + this._entities.length = 0; + this._entityDict.clear(); + } + + /** + * 检查该实体当前是否由此EntityList管理 + * @param entity + */ + public contains(entity: Entity): boolean { + return this._entities.contains(entity) || this._entitiesToAdded.contains(entity); + } + + public getTagList(tag: number) { + let list = this._entityDict.get(tag); + if (!list) { + list = []; + this._entityDict.set(tag, list); + } + + return this._entityDict.get(tag); + } + + public addToTagList(entity: Entity) { + let list = this.getTagList(entity.tag); + if (!list.contains(entity)) { + list.push(entity); + this._unsortedTags.push(entity.tag); + } + } + + public removeFromTagList(entity: Entity) { + let list = this._entityDict.get(entity.tag); + if (list) { + list.remove(entity); + } + } + + public update() { + for (let i = 0; i < this._entities.length; i++) { + let entity = this._entities[i]; + if (entity.enabled && (entity.updateInterval == 1 || Time.frameCount % entity.updateInterval == 0)) + entity.update(); + } + } + + public updateLists() { + if (this._entitiesToRemove.length > 0) { + let temp = this._entitiesToRemove; + this._entitiesToRemove = this._tempEntityList; + this._tempEntityList = temp; + this._tempEntityList.forEach(entity => { + this.removeFromTagList(entity); + + this._entities.remove(entity); + entity.onRemovedFromScene(); + entity.scene = null; + + this.scene.entityProcessors.onEntityRemoved(entity); + }); + + this._tempEntityList.length = 0; + } + + if (this._entitiesToAdded.length > 0) { + let temp = this._entitiesToAdded; + this._entitiesToAdded = this._tempEntityList; + this._tempEntityList = temp; + this._tempEntityList.forEach(entity => { + if (!this._entities.contains(entity)) { + this._entities.push(entity); + entity.scene = this.scene; + + this.addToTagList(entity); + + this.scene.entityProcessors.onEntityAdded(entity) + } + }); + + // 现在所有实体都被添加到场景中,我们再次循环并调用onAddedToScene + this._tempEntityList.forEach(entity => entity.onAddedToScene()); + this._tempEntityList.length = 0; + this._isEntityListUnsorted = true; + } + + if (this._isEntityListUnsorted) { + this._entities.sort(); + this._isEntityListUnsorted = false; + } + + if (this._unsortedTags.length > 0) { + this._unsortedTags.forEach(tag => { + this._entityDict.get(tag).sort(); + }); + + this._unsortedTags.length = 0; + } + } + + /** + * 返回找到的第一个实体的名称。如果没有找到,则返回null。 + * @param name + */ + public findEntity(name: string) { + for (let i = 0; i < this._entities.length; i++) { + if (this._entities[i].name == name) + return this._entities[i]; + } + + return this._entitiesToAdded.firstOrDefault(entity => entity.name == name); + } + + /** + * 返回带有标记的所有实体的列表。如果没有实体具有标记,则返回一个空列表。可以通过ListPool.free将返回的列表放回池中。 + * @param tag + */ + public entitiesWithTag(tag: number) { + let list = this.getTagList(tag); + + let returnList = ListPool.obtain(); + for (let i = 0; i < list.length; i++) + returnList.push(list[i]); + + return returnList; + } + + /** + * 返回t类型的所有实体的列表。返回的列表可以通过ListPool.free放回池中。 + * @param type + */ + public entitiesOfType(type): T[] { + let list = ListPool.obtain(); + for (let i = 0; i < this._entities.length; i++) { + if (this._entities[i] instanceof type) + list.push(this._entities[i] as T); + } + this._entitiesToAdded.forEach(entity => { + if (entity instanceof type) + list.push(entity as T); + }); + + return list; + } + + /** + * 返回在类型为T的场景中找到的第一个组件 + * @param type + */ + public findComponentOfType(type): T { + for (let i = 0; i < this._entities.length; i++) { + if (this._entities[i].enabled) { + let comp = this._entities[i].getComponent(type); + if (comp) + return comp; + } + } + + for (let i = 0; i < this._entitiesToAdded.length; i++) { + let entity = this._entitiesToAdded[i]; + if (entity.enabled) { + let comp = entity.getComponent(type); + if (comp) + return comp; + } + } + + return null; + } + + /** + * 返回在类型t的场景中找到的所有组件。返回的列表可以通过ListPool.free放回池中。 + * @param type + */ + public findComponentsOfType(type): T[] { + let comps = ListPool.obtain(); + for (let i = 0; i < this._entities.length; i++) { + if (this._entities[i].enabled) + this._entities[i].getComponents(type, comps); + } + + for (let i = 0; i < this._entitiesToAdded.length; i++) { + let entity = this._entitiesToAdded[i]; + if (entity.enabled) + entity.getComponents(type, comps); + } + + return comps; } } -} \ No newline at end of file +} diff --git a/source/src/ECS/Utils/EntityProcessorList.ts b/source/src/ECS/Utils/EntityProcessorList.ts index eedd5fdd..f816a573 100644 --- a/source/src/ECS/Utils/EntityProcessorList.ts +++ b/source/src/ECS/Utils/EntityProcessorList.ts @@ -1,69 +1,71 @@ -class EntityProcessorList { - private _processors: EntitySystem[] = []; +module es { + export class EntityProcessorList { + private _processors: EntitySystem[] = []; - public add(processor: EntitySystem){ - this._processors.push(processor); - } - - public remove(processor: EntitySystem){ - this._processors.remove(processor); - } - - public onComponentAdded(entity: Entity){ - this.notifyEntityChanged(entity); - } - - public onComponentRemoved(entity: Entity){ - this.notifyEntityChanged(entity); - } - - public onEntityAdded(entity: Entity){ - this.notifyEntityChanged(entity); - } - - public onEntityRemoved(entity: Entity){ - this.removeFromProcessors(entity); - } - - protected notifyEntityChanged(entity: Entity){ - for (let i = 0; i < this._processors.length; i ++){ - this._processors[i].onChanged(entity); - } - } - - protected removeFromProcessors(entity: Entity){ - for (let i = 0; i < this._processors.length; i ++){ - this._processors[i].remove(entity); - } - } - - public begin(){ - - } - - public update(){ - for (let i = 0; i < this._processors.length; i++){ - this._processors[i].update(); - } - } - - public lateUpdate(){ - for (let i = 0; i < this._processors.length; i ++){ - this._processors[i].lateUpdate(); - } - } - - public end(){ - - } - - public getProcessor(): T{ - for (let i = 0; i < this._processors.length; i ++){ - let processor = this._processors[i]; - if (processor instanceof EntitySystem) - return processor as T; + public add(processor: EntitySystem) { + this._processors.push(processor); } - return null; + public remove(processor: EntitySystem) { + this._processors.remove(processor); + } + + public onComponentAdded(entity: Entity) { + this.notifyEntityChanged(entity); + } + + public onComponentRemoved(entity: Entity) { + this.notifyEntityChanged(entity); + } + + public onEntityAdded(entity: Entity) { + this.notifyEntityChanged(entity); + } + + public onEntityRemoved(entity: Entity) { + this.removeFromProcessors(entity); + } + + public begin() { + + } + + public update() { + for (let i = 0; i < this._processors.length; i++) { + this._processors[i].update(); + } + } + + public lateUpdate() { + for (let i = 0; i < this._processors.length; i++) { + this._processors[i].lateUpdate(); + } + } + + public end() { + + } + + public getProcessor(): T { + for (let i = 0; i < this._processors.length; i++) { + let processor = this._processors[i]; + if (processor instanceof EntitySystem) + return processor as T; + } + + return null; + } + + protected notifyEntityChanged(entity: Entity) { + for (let i = 0; i < this._processors.length; i++) { + this._processors[i].onChanged(entity); + } + } + + protected removeFromProcessors(entity: Entity) { + for (let i = 0; i < this._processors.length; i++) { + this._processors[i].remove(entity); + } + } } -} \ No newline at end of file +} diff --git a/source/src/ECS/Utils/Matcher.ts b/source/src/ECS/Utils/Matcher.ts index c827d0b3..06a6960a 100644 --- a/source/src/ECS/Utils/Matcher.ts +++ b/source/src/ECS/Utils/Matcher.ts @@ -1,62 +1,64 @@ -class Matcher{ - protected allSet = new BitSet(); - protected exclusionSet = new BitSet(); - protected oneSet = new BitSet(); +module es { + export class Matcher { + protected allSet = new BitSet(); + protected exclusionSet = new BitSet(); + protected oneSet = new BitSet(); - public static empty(){ - return new Matcher(); - } - - public getAllSet(){ - return this.allSet; - } - - public getExclusionSet(){ - return this.exclusionSet; - } - - public getOneSet(){ - return this.oneSet; - } - - public IsIntersted(e: Entity){ - if (!this.allSet.isEmpty()){ - for (let i = this.allSet.nextSetBit(0); i >= 0; i = this.allSet.nextSetBit(i + 1)){ - if (!e.componentBits.get(i)) - return false; - } + public static empty() { + return new Matcher(); } - if (!this.exclusionSet.isEmpty() && this.exclusionSet.intersects(e.componentBits)) - return false; + public getAllSet() { + return this.allSet; + } - if (!this.oneSet.isEmpty() && !this.oneSet.intersects(e.componentBits)) - return false; + public getExclusionSet() { + return this.exclusionSet; + } - return true; + public getOneSet() { + return this.oneSet; + } + + public IsIntersted(e: Entity) { + if (!this.allSet.isEmpty()) { + for (let i = this.allSet.nextSetBit(0); i >= 0; i = this.allSet.nextSetBit(i + 1)) { + if (!e.componentBits.get(i)) + return false; + } + } + + if (!this.exclusionSet.isEmpty() && this.exclusionSet.intersects(e.componentBits)) + return false; + + if (!this.oneSet.isEmpty() && !this.oneSet.intersects(e.componentBits)) + return false; + + return true; + } + + public all(...types: any[]): Matcher { + types.forEach(type => { + this.allSet.set(ComponentTypeManager.getIndexFor(type)); + }); + + return this; + } + + public exclude(...types: any[]) { + types.forEach(type => { + this.exclusionSet.set(ComponentTypeManager.getIndexFor(type)); + }); + + return this; + } + + public one(...types: any[]) { + types.forEach(type => { + this.oneSet.set(ComponentTypeManager.getIndexFor(type)); + }); + + return this; + } } - - public all(...types: any[]): Matcher{ - types.forEach(type => { - this.allSet.set(ComponentTypeManager.getIndexFor(type)); - }); - - return this; - } - - public exclude(...types: any[]){ - types.forEach(type => { - this.exclusionSet.set(ComponentTypeManager.getIndexFor(type)); - }); - - return this; - } - - public one(...types: any[]){ - types.forEach(type => { - this.oneSet.set(ComponentTypeManager.getIndexFor(type)); - }); - - return this; - } -} \ No newline at end of file +} diff --git a/source/src/ECS/Utils/ObjectUtils.ts b/source/src/ECS/Utils/ObjectUtils.ts new file mode 100644 index 00000000..a0f95e2b --- /dev/null +++ b/source/src/ECS/Utils/ObjectUtils.ts @@ -0,0 +1,19 @@ +class ObjectUtils { + /** + * 对象深度拷贝 + * @param p any 源对象 + * @param c any 目标对象, 不传则返回新对象, 传则合并属性, 相同名字的属性则会覆盖 + */ + public static clone(p: any, c: T = null): T { + var c = c || {}; + for (let i in p) { + if (typeof p[i] === 'object') { + c[i] = p[i] instanceof Array ? [] : {}; + this.clone(p[i], c[i]); + } else { + c[i] = p[i]; + } + } + return c; + } +} \ No newline at end of file diff --git a/source/src/ECS/Utils/RenderableComponentList.ts b/source/src/ECS/Utils/RenderableComponentList.ts index df443385..74746f76 100644 --- a/source/src/ECS/Utils/RenderableComponentList.ts +++ b/source/src/ECS/Utils/RenderableComponentList.ts @@ -1,22 +1,101 @@ -class RenderableComponentList { - private _components: IRenderable[] = []; - public get count(){ - return this._components.length; - } +/// +module es { + export class RenderableComponentList { + /** + * IRenderable列表的全局updatePrder排序 + */ + public static compareUpdatableOrder = new RenderableComparer(); + /** + * 添加到实体的组件列表 + */ + public _components: IRenderable[] = []; + /** + * 通过渲染层跟踪组件,便于检索 + */ + public _componentsByRenderLayer: Map = new Map(); + public _unsortedRenderLayers: number[] = []; + public _componentsNeedSort: boolean = true; - public get buffer(){ - return this._components; - } + public get count() { + return this._components.length; + } - public add(component: IRenderable){ - this._components.push(component); - } + public get buffer() { + return this._components; + } - public remove(component: IRenderable){ - this._components.remove(component); - } + public add(component: IRenderable) { + this._components.push(component); + this.addToRenderLayerList(component, component.renderLayer); + } - public updateList(){ + public remove(component: IRenderable) { + this._components.remove(component); + this._componentsByRenderLayer.get(component.renderLayer).remove(component); + } + public updateRenderableRenderLayer(component: IRenderable, oldRenderLayer: number, newRenderLayer: number) { + // 需要注意的是,如果渲染层在组件update之前发生了改变 + if (this._componentsByRenderLayer.has(oldRenderLayer) && this._componentsByRenderLayer.get(oldRenderLayer).contains(component)) { + this._componentsByRenderLayer.get(oldRenderLayer).remove(component); + this.addToRenderLayerList(component, newRenderLayer); + } + } + + /** + * 将渲染层排序标志弄脏,让所有组件重新排序 + * @param renderLayer + */ + public setRenderLayerNeedsComponentSort(renderLayer: number) { + if (!this._unsortedRenderLayers.contains(renderLayer)) + this._unsortedRenderLayers.push(renderLayer); + this._componentsNeedSort = true; + } + + public setNeedsComponentSort() { + this._componentsNeedSort = true; + } + + public addToRenderLayerList(component: IRenderable, renderLayer: number) { + let list = this.componentsWithRenderLayer(renderLayer); + if (!list.contains(component)) { + console.warn("Component renderLayer list already contains this component"); + return; + } + + list.push(component); + if (!this._unsortedRenderLayers.contains(renderLayer)) + this._unsortedRenderLayers.push(renderLayer); + this._componentsNeedSort = true; + } + + /** + * 使用给定的渲染层获取所有组件。组件列表是预先排序的 + * @param renderLayer + */ + public componentsWithRenderLayer(renderLayer: number): IRenderable[] { + if (!this._componentsByRenderLayer.get(renderLayer)) { + this._componentsByRenderLayer.set(renderLayer, []); + } + return this._componentsByRenderLayer.get(renderLayer); + } + + public updateList() { + if (this._componentsNeedSort) { + this._components.sort(RenderableComponentList.compareUpdatableOrder.compare); + this._componentsNeedSort = false; + } + + if (this._unsortedRenderLayers.length > 0) { + for (let i = 0, count = this._unsortedRenderLayers.length; i < count; i++) { + let renderLayerComponents = this._componentsByRenderLayer.get(this._unsortedRenderLayers[i]); + if (renderLayerComponents) { + renderLayerComponents.sort(RenderableComponentList.compareUpdatableOrder.compare); + } + } + + this._unsortedRenderLayers.length = 0; + } + } } -} \ No newline at end of file +} diff --git a/source/src/ECS/Utils/StringUtils.ts b/source/src/ECS/Utils/StringUtils.ts new file mode 100644 index 00000000..09d5fd2a --- /dev/null +++ b/source/src/ECS/Utils/StringUtils.ts @@ -0,0 +1,233 @@ +class StringUtils { + /** + * 特殊符号字符串 + */ + private static specialSigns: string[] = [ + '&', '&', + '<', '<', + '>', '>', + '"', '"', + "'", ''', + '®', '®', + '©', '©', + '™', '™', + ]; + + /** + * 匹配中文字符 + * @param str 需要匹配的字符串 + * @return + */ + public static matchChineseWord(str: string): string[] { + //中文字符的unicode值[\u4E00-\u9FA5] + let patternA: RegExp = /[\u4E00-\u9FA5]+/gim; + return str.match(patternA); + } + + /** + * 去除字符串左端的空白字符 + * @param target 目标字符串 + * @return + */ + public static lTrim(target: string): string { + let startIndex: number = 0; + while (this.isWhiteSpace(target.charAt(startIndex))) { + startIndex++; + } + return target.slice(startIndex, target.length); + } + + /** + * 去除字符串右端的空白字符 + * @param target 目标字符串 + * @return + */ + public static rTrim(target: string): string { + let endIndex: number = target.length - 1; + while (this.isWhiteSpace(target.charAt(endIndex))) { + endIndex--; + } + return target.slice(0, endIndex + 1); + } + + /** + * 返回一个去除2段空白字符的字符串 + * @param target + * @return 返回一个去除2段空白字符的字符串 + */ + public static trim(target: string): string { + if (target == null) { + return null; + } + return this.rTrim(this.lTrim(target)); + } + + /** + * 返回该字符是否为空白字符 + * @param str + * @return 返回该字符是否为空白字符 + */ + public static isWhiteSpace(str: string): boolean { + if (str == " " || str == "\t" || str == "\r" || str == "\n") + return true; + return false; + } + + /** + * 返回执行替换后的字符串 + * @param mainStr 待查找字符串 + * @param targetStr 目标字符串 + * @param replaceStr 替换字符串 + * @param caseMark 是否忽略大小写 + * @return 返回执行替换后的字符串 + */ + public static replaceMatch(mainStr: string, targetStr: string, + replaceStr: string, caseMark: boolean = false): string { + let len: number = mainStr.length; + let tempStr: string = ""; + let isMatch: boolean = false; + let tempTarget: string = caseMark == true ? targetStr.toLowerCase() : targetStr; + for (let i: number = 0; i < len; i++) { + isMatch = false; + if (mainStr.charAt(i) == tempTarget.charAt(0)) { + if (mainStr.substr(i, tempTarget.length) == tempTarget) { + isMatch = true; + } + } + if (isMatch) { + tempStr += replaceStr; + i = i + tempTarget.length - 1; + } else { + tempStr += mainStr.charAt(i); + } + } + return tempStr; + } + + /** + * 用html实体换掉字符窜中的特殊字符 + * @param str 需要替换的字符串 + * @param reversion 是否翻转替换:将转义符号替换为正常的符号 + * @return 换掉特殊字符后的字符串 + */ + public static htmlSpecialChars(str: string, reversion: boolean = false): string { + let len: number = this.specialSigns.length; + for (let i: number = 0; i < len; i += 2) { + let from: string; + let to: string; + from = this.specialSigns[i]; + to = this.specialSigns[i + 1]; + if (reversion) { + let temp: string = from; + from = to; + to = temp; + } + str = this.replaceMatch(str, from, to); + } + return str; + } + + + /** + * 给数字字符前面添 "0" + * + *
+     *
+     * trace( StringFormat.zfill('1') );
+     * // 01
+     *
+     * trace( StringFormat.zfill('16', 5) );
+     * // 00016
+     *
+     * trace( StringFormat.zfill('-3', 3) );
+     * // -03
+     *
+     * 
+ * + * @param str 要进行处理的字符串 + * @param width 处理后字符串的长度, + * 如果str.length >= width,将不做任何处理直接返回原始的str。 + * @return + * + */ + public static zfill(str: string, width: number = 2): string { + if (!str) { + return str; + } + width = Math.floor(width); + let slen: number = str.length; + if (slen >= width) { + return str; + } + + let negative: boolean = false; + if (str.substr(0, 1) == '-') { + negative = true; + str = str.substr(1); + } + + let len: number = width - slen; + for (let i: number = 0; i < len; i++) { + str = '0' + str; + } + + if (negative) { + str = '-' + str; + } + + return str; + } + + + /** + * 翻转字符串 + * @param str 字符串 + * @return 翻转后的字符串 + */ + public static reverse(str: string): string { + if (str.length > 1) + return this.reverse(str.substring(1)) + str.substring(0, 1); + else + return str; + } + + + /** + * 截断某段字符串 + * @param str 目标字符串 + * @param start 需要截断的起始索引 + * @param len 截断长度 + * @param order 顺序,true从字符串头部开始计算,false从字符串尾巴开始结算。 + * @return 截断后的字符串 + */ + public static cutOff(str: string, start: number, + len: number, order: boolean = true): string { + start = Math.floor(start); + len = Math.floor(len); + let length: number = str.length; + if (start > length) start = length; + let s: number = start; + let e: number = start + len; + let newStr: string; + if (order) { + newStr = str.substring(0, s) + str.substr(e, length); + } else { + s = length - 1 - start - len; + e = s + len; + newStr = str.substring(0, s + 1) + str.substr(e + 1, length); + } + return newStr; + } + + /**{0} 字符替换 */ + public static strReplace(str: string, rStr: string[]): string { + let i: number = 0, len: number = rStr.length; + for (; i < len; i++) { + if (rStr[i] == null || rStr[i] == "") { + rStr[i] = "无"; + } + str = str.replace("{" + i + "}", rStr[i]); + } + return str + } +} \ No newline at end of file diff --git a/source/src/ECS/Utils/TextureUtils.ts b/source/src/ECS/Utils/TextureUtils.ts new file mode 100644 index 00000000..f1a6f4f4 --- /dev/null +++ b/source/src/ECS/Utils/TextureUtils.ts @@ -0,0 +1,151 @@ +module es { + /** + * 纹理帮助类 + */ + export class TextureUtils { + public static sharedCanvas: HTMLCanvasElement; + public static sharedContext: CanvasRenderingContext2D; + + public static convertImageToCanvas(texture: egret.Texture, rect?: egret.Rectangle): HTMLCanvasElement { + if (!this.sharedCanvas) { + this.sharedCanvas = egret.sys.createCanvas(); + this.sharedContext = this.sharedCanvas.getContext("2d"); + } + + let w = texture.$getTextureWidth(); + let h = texture.$getTextureHeight(); + if (!rect) { + rect = egret.$TempRectangle; + rect.x = 0; + rect.y = 0; + rect.width = w; + rect.height = h; + } + + rect.x = Math.min(rect.x, w - 1); + rect.y = Math.min(rect.y, h - 1); + rect.width = Math.min(rect.width, w - rect.x); + rect.height = Math.min(rect.height, h - rect.y); + + let iWidth = Math.floor(rect.width); + let iHeight = Math.floor(rect.height); + let surface = this.sharedCanvas; + surface["style"]["width"] = iWidth + "px"; + surface["style"]["height"] = iHeight + "px"; + this.sharedCanvas.width = iWidth; + this.sharedCanvas.height = iHeight; + + if (egret.Capabilities.renderMode == "webgl") { + let renderTexture: egret.RenderTexture; + //webgl下非RenderTexture纹理先画到RenderTexture + if (!(texture).$renderBuffer) { + if (egret.sys.systemRenderer["renderClear"]) { + egret.sys.systemRenderer["renderClear"](); + } + renderTexture = new egret.RenderTexture(); + renderTexture.drawToTexture(new egret.Bitmap(texture)); + } else { + renderTexture = texture; + } + //从RenderTexture中读取像素数据,填入canvas + let pixels = renderTexture.$renderBuffer.getPixels(rect.x, rect.y, iWidth, iHeight); + let x = 0; + let y = 0; + for (let i = 0; i < pixels.length; i += 4) { + this.sharedContext.fillStyle = + 'rgba(' + pixels[i] + + ',' + pixels[i + 1] + + ',' + pixels[i + 2] + + ',' + (pixels[i + 3] / 255) + ')'; + this.sharedContext.fillRect(x, y, 1, 1); + x++; + if (x == iWidth) { + x = 0; + y++; + } + } + + if (!(texture).$renderBuffer) { + renderTexture.dispose(); + } + + return surface; + } else { + let bitmapData = texture; + let offsetX: number = Math.round(bitmapData.$offsetX); + let offsetY: number = Math.round(bitmapData.$offsetY); + let bitmapWidth: number = bitmapData.$bitmapWidth; + let bitmapHeight: number = bitmapData.$bitmapHeight; + let $TextureScaleFactor = Core._instance.stage.textureScaleFactor; + this.sharedContext.drawImage(bitmapData.$bitmapData.source, bitmapData.$bitmapX + rect.x / $TextureScaleFactor, bitmapData.$bitmapY + rect.y / $TextureScaleFactor, + bitmapWidth * rect.width / w, bitmapHeight * rect.height / h, offsetX, offsetY, rect.width, rect.height); + return surface; + } + } + + public static toDataURL(type: string, texture: egret.Texture, rect?: egret.Rectangle, encoderOptions?): string { + try { + let surface = this.convertImageToCanvas(texture, rect); + let result = surface.toDataURL(type, encoderOptions); + return result; + } catch (e) { + egret.$error(1033); + } + return null; + } + + /** + * 有些杀毒软件认为 saveToFile 可能是一个病毒文件 + * @param type + * @param texture + * @param filePath + * @param rect + * @param encoderOptions + */ + public static eliFoTevas(type: string, texture: egret.Texture, filePath: string, rect?: egret.Rectangle, encoderOptions?): void { + let surface = this.convertImageToCanvas(texture, rect); + let result = (surface as any).toTempFilePathSync({ + fileType: type.indexOf("png") >= 0 ? "png" : "jpg" + }); + + wx.getFileSystemManager().saveFile({ + tempFilePath: result, + filePath: `${wx.env.USER_DATA_PATH}/${filePath}`, + success: function (res) { + //todo + } + }); + + return result; + } + + public static getPixel32(texture: egret.Texture, x: number, y: number): number[] { + egret.$warn(1041, "getPixel32", "getPixels"); + return texture.getPixels(x, y); + } + + public static getPixels(texture: egret.Texture, x: number, y: number, width: number = 1, height: number = 1): number[] { + //webgl环境下不需要转换成canvas获取像素信息 + if (egret.Capabilities.renderMode == "webgl") { + let renderTexture: egret.RenderTexture; + //webgl下非RenderTexture纹理先画到RenderTexture + if (!(texture).$renderBuffer) { + renderTexture = new egret.RenderTexture(); + renderTexture.drawToTexture(new egret.Bitmap(texture)); + } else { + renderTexture = texture; + } + //从RenderTexture中读取像素数据 + let pixels = renderTexture.$renderBuffer.getPixels(x, y, width, height); + return pixels; + } + try { + let surface = this.convertImageToCanvas(texture); + let result = this.sharedContext.getImageData(x, y, width, height).data; + return result; + } catch (e) { + egret.$error(1039); + } + } + } +} diff --git a/source/src/ECS/Utils/Time.ts b/source/src/ECS/Utils/Time.ts index 178b0c13..e4acc278 100644 --- a/source/src/ECS/Utils/Time.ts +++ b/source/src/ECS/Utils/Time.ts @@ -1,17 +1,39 @@ -class Time { - public static unscaledDeltaTime; - public static deltaTime: number = 0; - public static timeScale = 1; - public static frameCount = 0;; - - private static _lastTime = 0; +module es { + /** 提供帧定时信息 */ + export class Time { + /** deltaTime的未缩放版本。不受时间尺度的影响 */ + public static unscaledDeltaTime; + /** 前一帧到当前帧的时间增量,按时间刻度进行缩放 */ + public static deltaTime: number = 0; + /** 时间刻度缩放 */ + public static timeScale = 1; + /** 已传递的帧总数 */ + public static frameCount = 0; + /** 自场景加载以来的总时间 */ + public static _timeSinceSceneLoad; + private static _lastTime = 0; - public static update(currentTime: number){ - let dt = (currentTime - this._lastTime) / 1000; - this.deltaTime = dt * this.timeScale; - this.unscaledDeltaTime = dt; - this.frameCount ++; + public static update(currentTime: number) { + let dt = (currentTime - this._lastTime) / 1000; + this.deltaTime = dt * this.timeScale; + this.unscaledDeltaTime = dt; + this._timeSinceSceneLoad += dt; + this.frameCount++; - this._lastTime = currentTime; + this._lastTime = currentTime; + } + + public static sceneChanged() { + this._timeSinceSceneLoad = 0; + } + + /** + * 允许在间隔检查。只应该使用高于delta的间隔值,否则它将始终返回true。 + * @param interval + */ + public static checkEvery(interval: number) { + // 我们减去了delta,因为timeSinceSceneLoad已经包含了这个update ticks delta + return (this._timeSinceSceneLoad / interval) > ((this._timeSinceSceneLoad - this.deltaTime) / interval); + } } -} \ No newline at end of file +} diff --git a/source/src/ECS/Utils/TimeUtils.ts b/source/src/ECS/Utils/TimeUtils.ts new file mode 100644 index 00000000..b8277a80 --- /dev/null +++ b/source/src/ECS/Utils/TimeUtils.ts @@ -0,0 +1,212 @@ +class TimeUtils { + /** + * 计算月份ID + * @param d 指定计算日期 + * @returns 月ID + */ + public static monthId(d: Date = null): number { + d = d ? d : new Date(); + let y = d.getFullYear(); + let m = d.getMonth() + 1; + let g = m < 10 ? "0" : ""; + return parseInt(y + g + m); + } + + /** + * 计算日期ID + * @param d 指定计算日期 + * @returns 日期ID + */ + public static dateId(t: Date = null): number { + t = t ? t : new Date(); + let m: number = t.getMonth() + 1; + let a = m < 10 ? "0" : ""; + let d: number = t.getDate(); + let b = d < 10 ? "0" : ""; + return parseInt(t.getFullYear() + a + m + b + d); + } + + /** + * 计算周ID + * @param d 指定计算日期 + * @returns 周ID + */ + public static weekId(d: Date = null, first: boolean = true): number { + d = d ? d : new Date(); + let c: Date = new Date(); + c.setTime(d.getTime()); + c.setDate(1); + c.setMonth(0);//当年第一天 + + let year: number = c.getFullYear(); + let firstDay: number = c.getDay(); + if (firstDay == 0) { + firstDay = 7; + } + let max: boolean = false; + if (firstDay <= 4) { + max = firstDay > 1; + c.setDate(c.getDate() - (firstDay - 1)); + } else { + c.setDate(c.getDate() + 7 - firstDay + 1); + } + let num: number = this.diffDay(d, c, false); + if (num < 0) { + c.setDate(1); + c.setMonth(0);//当年第一天 + c.setDate(c.getDate() - 1); + return this.weekId(c, false); + } + let week: number = num / 7; + let weekIdx: number = Math.floor(week) + 1; + if (weekIdx == 53) { + c.setTime(d.getTime()); + c.setDate(c.getDate() - 1); + let endDay: number = c.getDay(); + if (endDay == 0) { + endDay = 7; + } + if (first && (!max || endDay < 4)) { + c.setFullYear(c.getFullYear() + 1); + c.setDate(1); + c.setMonth(0);//当年第一天 + return this.weekId(c, false); + } + } + let g: string = weekIdx > 9 ? "" : "0"; + let s: string = year + "00" + g + weekIdx;//加上00防止和月份ID冲突 + return parseInt(s); + } + + /** + * 计算俩日期时间差,如果a比b小,返回负数 + */ + public static diffDay(a: Date, b: Date, fixOne: boolean = false): number { + let x = (a.getTime() - b.getTime()) / 86400000; + return fixOne ? Math.ceil(x) : Math.floor(x); + } + + /** + * 获取本周一 凌晨时间 + */ + public static getFirstDayOfWeek(d?: Date): Date { + d = d ? d : new Date(); + let day = d.getDay() || 7; + return new Date(d.getFullYear(), d.getMonth(), d.getDate() + 1 - day, 0, 0, 0, 0); + } + + /** + * 获取当日凌晨时间 + */ + public static getFirstOfDay(d?: Date): Date { + d = d ? d : new Date(); + d.setHours(0, 0, 0, 0); + return d; + } + + /** + * 获取次日凌晨时间 + */ + public static getNextFirstOfDay(d?: Date): Date { + return new Date(this.getFirstOfDay(d).getTime() + 86400000); + } + + /** + * @returns 2018-12-12 + */ + public static formatDate(date: Date): string { + let y = date.getFullYear(); + let m: any = date.getMonth() + 1; + m = m < 10 ? '0' + m : m; + let d: any = date.getDate(); + d = d < 10 ? ('0' + d) : d; + return y + '-' + m + '-' + d; + } + + /** + * @returns 2018-12-12 12:12:12 + */ + public static formatDateTime(date: Date): string { + let y = date.getFullYear(); + let m: any = date.getMonth() + 1; + m = m < 10 ? ('0' + m) : m; + let d: any = date.getDate(); + d = d < 10 ? ('0' + d) : d; + let h = date.getHours(); + let i: any = date.getMinutes(); + i = i < 10 ? ('0' + i) : i; + let s: any = date.getSeconds(); + s = s < 10 ? ('0' + s) : s; + return y + '-' + m + '-' + d + ' ' + h + ':' + i + ":" + s; + } + + /** + * @returns s 2018-12-12 或者 2018-12-12 12:12:12 + */ + public static parseDate(s: string): Date { + let t = Date.parse(s); + if (!isNaN(t)) { + return new Date(Date.parse(s.replace(/-/g, "/"))); + } else { + return new Date(); + } + } + + /** + * 秒数转换为时间形式。 + * @param time 秒数 + * @param partition 分隔符 + * @param showHour 是否显示小时 + * @return 返回一个以分隔符分割的时, 分, 秒 + * + * 比如: time = 4351; secondToTime(time)返回字符串01:12:31; + */ + public static secondToTime(time: number = 0, partition: string = ":", showHour: boolean = true): string { + let hours: number = Math.floor(time / 3600); + let minutes: number = Math.floor(time % 3600 / 60); + let seconds: number = Math.floor(time % 3600 % 60); + + let h: string = hours.toString(); + let m: string = minutes.toString(); + let s: string = seconds.toString(); + + if (hours < 10) h = "0" + h; + if (minutes < 10) m = "0" + m; + if (seconds < 10) s = "0" + s; + + let timeStr: string; + if (showHour) + timeStr = h + partition + m + partition + s; + else + timeStr = m + partition + s; + + return timeStr; + } + + + /** + * 时间形式转换为毫秒数。 + * @param time 以指定分隔符分割的时间字符串 + * @param partition 分隔符 + * @return 毫秒数显示的字符串 + * @throws Error Exception + * + * 用法1 trace(MillisecondTransform.timeToMillisecond("00:60:00")) + * 输出 3600000 + * + * + * 用法2 trace(MillisecondTransform.timeToMillisecond("00.60.00",".")) + * 输出 3600000 + */ + public static timeToMillisecond(time: string, partition: string = ":"): string { + let _ary: any[] = time.split(partition); + let timeNum: number = 0; + let len: number = _ary.length; + for (let i: number = 0; i < len; i++) { + let n: number = _ary[i]; + timeNum += n * Math.pow(60, (len - 1 - i)); + } + timeNum *= 1000; + return timeNum.toString(); + } +} \ No newline at end of file diff --git a/source/src/Extension.ts b/source/src/Extension.ts index 3a7ce9d4..6d0141c1 100644 --- a/source/src/Extension.ts +++ b/source/src/Extension.ts @@ -3,90 +3,106 @@ declare interface Array { * 获取满足表达式的数组元素索引 * @param predicate 表达式 */ - findIndex(predicate: Function): number; + findIndex(predicate: (c: T)=>boolean): number; + /** * 是否存在满足表达式的数组元素 * @param predicate 表达式 */ - any(predicate: Function): boolean; + any(predicate: (c: T) => boolean): boolean; + /** * 获取满足表达式的第一个或默认数组元素 * @param predicate 表达式 */ - firstOrDefault(predicate: Function): T; + firstOrDefault(predicate: (c: T)=>boolean): T; + /** * 获取满足表达式的第一个数组元素 * @param predicate 表达式 */ - find(predicate: Function): T; + find(predicate: (c: T) => boolean): T; + /** * 筛选满足表达式的数组元素 * @param predicate 表达式 */ - where(predicate: Function): Array; + where(predicate: (c: T) => boolean): Array; + /** * 获取满足表达式的数组元素的计数 * @param predicate 表达式 */ - count(predicate: Function): number; + count(predicate: (c: T) => boolean): number; + /** * 获取满足表达式的数组元素的数组 * @param predicate 表达式 */ - findAll(predicate: Function): Array; + findAll(predicate: (c: T) => boolean): Array; + /** * 是否有获取满足表达式的数组元素 * @param value 值 */ - contains(value): boolean; + contains(value: T): boolean; + /** * 移除满足表达式的数组元素 * @param predicate 表达式 */ - removeAll(predicate: Function): void; + removeAll(predicate: (c: T) => boolean): void; + /** * 移除数组元素 * @param element 数组元素 */ - remove(element): boolean; + remove(element: T): boolean; + /** * 移除特定索引数组元素 * @param index 索引 */ - removeAt(index): void; + removeAt(index: number): void; + /** * 移除范围数组元素 * @param index 开始索引 * @param count 删除的个数 */ - removeRange(index, count): void; + removeRange(index: number, count: number): void; + /** * 获取通过选择器转换的数组 * @param selector 选择器 */ select(selector: Function): Array; + /** * 排序(升序) * @param keySelector key选择器 * @param comparer 比较器 */ orderBy(keySelector: Function, comparer: Function): Array; + /** * 排序(降序) * @param keySelector key选择器 * @param comparer 比较器 */ orderByDescending(keySelector: Function, comparer: Function): Array; + /** * 分组 * @param keySelector key选择器 */ groupBy(keySelector: Function): Array; + /** * 求和 * @param selector 选择器 */ - sum(selector); + sum(selector: Function): number; } Array.prototype.findIndex = function (predicate) { @@ -101,7 +117,7 @@ Array.prototype.findIndex = function (predicate) { } return findIndex(this, predicate); -} +}; Array.prototype.any = function (predicate) { function any(array, predicate) { @@ -109,7 +125,7 @@ Array.prototype.any = function (predicate) { } return any(this, predicate); -} +}; Array.prototype.firstOrDefault = function (predicate) { function firstOrDefault(array, predicate) { @@ -118,7 +134,7 @@ Array.prototype.firstOrDefault = function (predicate) { } return firstOrDefault(this, predicate); -} +}; Array.prototype.find = function (predicate) { function find(array, predicate) { @@ -126,7 +142,7 @@ Array.prototype.find = function (predicate) { } return find(this, predicate); -} +}; Array.prototype.where = function (predicate) { function where(array, predicate) { @@ -138,8 +154,7 @@ Array.prototype.where = function (predicate) { return ret; }, []); - } - else { + } else { let ret = []; for (let i = 0, len = array.length; i < len; i++) { let element = array[i]; @@ -153,7 +168,7 @@ Array.prototype.where = function (predicate) { } return where(this, predicate); -} +}; Array.prototype.count = function (predicate) { function count(array, predicate) { @@ -161,7 +176,7 @@ Array.prototype.count = function (predicate) { } return count(this, predicate); -} +}; Array.prototype.findAll = function (predicate) { function findAll(array, predicate) { @@ -169,11 +184,16 @@ Array.prototype.findAll = function (predicate) { } return findAll(this, predicate); -} +}; Array.prototype.contains = function (value) { function contains(array, value) { for (let i = 0, len = array.length; i < len; i++) { + if (array[i] instanceof egret.HashObject && value instanceof egret.HashObject){ + if ((array[i] as egret.HashObject).hashCode == (value as egret.HashObject).hashCode) + return true; + } + if (array[i] == value) { return true; } @@ -183,7 +203,7 @@ Array.prototype.contains = function (value) { } return contains(this, value); -} +}; Array.prototype.removeAll = function (predicate) { function removeAll(array, predicate) { @@ -198,7 +218,7 @@ Array.prototype.removeAll = function (predicate) { } removeAll(this, predicate); -} +}; Array.prototype.remove = function (element) { function remove(array, element) { @@ -209,14 +229,13 @@ Array.prototype.remove = function (element) { if (index >= 0) { array.splice(index, 1); return true; - } - else { + } else { return false; } } return remove(this, element); -} +}; Array.prototype.removeAt = function (index) { function removeAt(array, index) { @@ -224,7 +243,7 @@ Array.prototype.removeAt = function (index) { } return removeAt(this, index); -} +}; Array.prototype.removeRange = function (index, count) { function removeRange(array, index, count) { @@ -232,7 +251,7 @@ Array.prototype.removeRange = function (index, count) { } return removeRange(this, index, count); -} +}; Array.prototype.select = function (selector) { function select(array, selector) { @@ -241,8 +260,7 @@ Array.prototype.select = function (selector) { ret.push(selector.call(arguments[2], element, index, array)); return ret; }, []); - } - else { + } else { let ret = []; for (let i = 0, len = array.length; i < len; i++) { ret.push(selector.call(arguments[2], array[i], i, array)) @@ -253,17 +271,16 @@ Array.prototype.select = function (selector) { } return select(this, selector); -} +}; Array.prototype.orderBy = function (keySelector, comparer) { function orderBy(array, keySelector, comparer) { array.sort(function (x, y) { - let v1 = keySelector(x) - let v2 = keySelector(y) + let v1 = keySelector(x); + let v2 = keySelector(y); if (comparer) { return comparer(v1, v2); - } - else { + } else { return (v1 > v2) ? 1 : -1; } }); @@ -272,17 +289,16 @@ Array.prototype.orderBy = function (keySelector, comparer) { } return orderBy(this, keySelector, comparer); -} +}; Array.prototype.orderByDescending = function (keySelector, comparer) { function orderByDescending(array, keySelector, comparer) { array.sort(function (x, y) { - let v1 = keySelector(x) - let v2 = keySelector(y) + let v1 = keySelector(x); + let v2 = keySelector(y); if (comparer) { return -comparer(v1, v2); - } - else { + } else { return (v1 < v2) ? 1 : -1; } }); @@ -291,15 +307,17 @@ Array.prototype.orderByDescending = function (keySelector, comparer) { } return orderByDescending(this, keySelector, comparer); -} +}; Array.prototype.groupBy = function (keySelector) { function groupBy(array, keySelector) { if (typeof (array.reduce) === "function") { let keys = []; return array.reduce(function (groups, element, index) { - let key = JSON.stringify(keySelector.call(arguments[1], element, index, array)) - let index2 = keys.findIndex(function (x) { return x === key }); + let key = JSON.stringify(keySelector.call(arguments[1], element, index, array)); + let index2 = keys.findIndex(function (x) { + return x === key; + }); if (index2 < 0) { index2 = keys.push(key) - 1; @@ -312,13 +330,14 @@ Array.prototype.groupBy = function (keySelector) { groups[index2].push(element); return groups; }, []); - } - else { + } else { let groups = []; let keys = []; for (let i = 0, len = array.length; i < len; i++) { let key = JSON.stringify(keySelector.call(arguments[1], array[i], i, array)); - let index = keys.findIndex(function (x) { return x === key }); + let index = keys.findIndex(function (x) { + return x === key; + }); if (index < 0) { index = keys.push(key) - 1; @@ -336,7 +355,7 @@ Array.prototype.groupBy = function (keySelector) { } return groupBy(this, keySelector); -} +}; Array.prototype.sum = function (selector) { function sum(array, selector) { @@ -345,17 +364,14 @@ Array.prototype.sum = function (selector) { if (i == 0) { if (selector) { ret = selector.call(arguments[2], array[i], i, array); + } else { + ret = array[i]; } - else { - ret = array[i] - } - } - else { + } else { if (selector) { ret += selector.call(arguments[2], array[i], i, array); - } - else { - ret += array[i] + } else { + ret += array[i]; } } } @@ -364,4 +380,4 @@ Array.prototype.sum = function (selector) { } return sum(this, selector); -} \ No newline at end of file +}; \ No newline at end of file diff --git a/source/src/Graphics/Effects/GaussianBlurEffect.ts b/source/src/Graphics/Effects/GaussianBlurEffect.ts index 7b9c92a3..087c0ec9 100644 --- a/source/src/Graphics/Effects/GaussianBlurEffect.ts +++ b/source/src/Graphics/Effects/GaussianBlurEffect.ts @@ -1,72 +1,74 @@ -class GaussianBlurEffect extends egret.CustomFilter { - // private static blur_frag = "precision mediump float;\n" + - // "uniform vec2 blur;\n" + - // "uniform sampler2D uSampler;\n" + - // "varying vec2 vTextureCoord;\n" + - // "uniform vec2 uTextureSize;\n" + - // "void main()\n" + - // "{\n " + - // "const int sampleRadius = 5;\n" + - // "const int samples = sampleRadius * 2 + 1;\n" + - // "vec2 blurUv = blur / uTextureSize;\n" + - // "vec4 color = vec4(0, 0, 0, 0);\n" + - // "vec2 uv = vec2(0.0, 0.0);\n" + - // "blurUv /= float(sampleRadius);\n" + - - // "for (int i = -sampleRadius; i <= sampleRadius; i++) {\n" + - // "uv.x = vTextureCoord.x + float(i) * blurUv.x;\n" + - // "uv.y = vTextureCoord.y + float(i) * blurUv.y;\n" + - // "color += texture2D(uSampler, uv);\n" + - // "}\n" + - - // "color /= float(samples);\n" + - // "gl_FragColor = color;\n" + - // "}"; +module es { + export class GaussianBlurEffect extends egret.CustomFilter { + // private static blur_frag = "precision mediump float;\n" + + // "uniform vec2 blur;\n" + + // "uniform sampler2D uSampler;\n" + + // "varying vec2 vTextureCoord;\n" + + // "uniform vec2 uTextureSize;\n" + + // "void main()\n" + + // "{\n " + + // "const int sampleRadius = 5;\n" + + // "const int samples = sampleRadius * 2 + 1;\n" + + // "vec2 blurUv = blur / uTextureSize;\n" + + // "vec4 color = vec4(0, 0, 0, 0);\n" + + // "vec2 uv = vec2(0.0, 0.0);\n" + + // "blurUv /= float(sampleRadius);\n" + - private static blur_frag = "precision mediump float;\n" + - "uniform sampler2D uSampler;\n" + - "uniform float screenWidth;\n" + - "uniform float screenHeight;\n" + + // "for (int i = -sampleRadius; i <= sampleRadius; i++) {\n" + + // "uv.x = vTextureCoord.x + float(i) * blurUv.x;\n" + + // "uv.y = vTextureCoord.y + float(i) * blurUv.y;\n" + + // "color += texture2D(uSampler, uv);\n" + + // "}\n" + - "float normpdf(in float x, in float sigma)\n" + - "{\n" + - "return 0.39894*exp(-0.5*x*x/(sigma*sigma))/sigma;\n" + - "}\n" + + // "color /= float(samples);\n" + + // "gl_FragColor = color;\n" + + // "}"; - "void main()\n" + - "{\n" + - "vec3 c = texture2D(uSampler, gl_FragCoord.xy / vec2(screenWidth, screenHeight).xy).rgb;\n" + + private static blur_frag = "precision mediump float;\n" + + "uniform sampler2D uSampler;\n" + + "uniform float screenWidth;\n" + + "uniform float screenHeight;\n" + - "const int mSize = 11;\n" + - "const int kSize = (mSize - 1)/2;\n" + - "float kernel[mSize];\n" + - "vec3 final_colour = vec3(0.0);\n" + + "float normpdf(in float x, in float sigma)\n" + + "{\n" + + "return 0.39894*exp(-0.5*x*x/(sigma*sigma))/sigma;\n" + + "}\n" + - "float sigma = 7.0;\n" + - "float z = 0.0;\n" + - "for (int j = 0; j <= kSize; ++j)\n" + - "{\n" + - "kernel[kSize+j] = kernel[kSize-j] = normpdf(float(j),sigma);\n" + - "}\n" + - - "for (int j = 0; j < mSize; ++j)\n" + - "{\n" + - "z += kernel[j];\n" + - "}\n" + + "void main()\n" + + "{\n" + + "vec3 c = texture2D(uSampler, gl_FragCoord.xy / vec2(screenWidth, screenHeight).xy).rgb;\n" + - "for (int i = -kSize; i <= kSize; ++i)\n" + - "{\n" + - "for (int j = -kSize; j <= kSize; ++j)\n" + - "{\n" + - "final_colour += kernel[kSize+j]*kernel[kSize+i]*texture2D(uSampler, (gl_FragCoord.xy+vec2(float(i),float(j))) / vec2(screenWidth, screenHeight).xy).rgb;\n" + - "}\n}\n" + - "gl_FragColor = vec4(final_colour/(z*z), 1.0);\n" + - "}"; + "const int mSize = 11;\n" + + "const int kSize = (mSize - 1)/2;\n" + + "float kernel[mSize];\n" + + "vec3 final_colour = vec3(0.0);\n" + - constructor(){ - super(PostProcessor.default_vert, GaussianBlurEffect.blur_frag,{ - screenWidth: SceneManager.stage.stageWidth, - screenHeight: SceneManager.stage.stageHeight - }); + "float sigma = 7.0;\n" + + "float z = 0.0;\n" + + "for (int j = 0; j <= kSize; ++j)\n" + + "{\n" + + "kernel[kSize+j] = kernel[kSize-j] = normpdf(float(j),sigma);\n" + + "}\n" + + + "for (int j = 0; j < mSize; ++j)\n" + + "{\n" + + "z += kernel[j];\n" + + "}\n" + + + "for (int i = -kSize; i <= kSize; ++i)\n" + + "{\n" + + "for (int j = -kSize; j <= kSize; ++j)\n" + + "{\n" + + "final_colour += kernel[kSize+j]*kernel[kSize+i]*texture2D(uSampler, (gl_FragCoord.xy+vec2(float(i),float(j))) / vec2(screenWidth, screenHeight).xy).rgb;\n" + + "}\n}\n" + + "gl_FragColor = vec4(final_colour/(z*z), 1.0);\n" + + "}"; + + constructor() { + super(PostProcessor.default_vert, GaussianBlurEffect.blur_frag, { + screenWidth: Core.graphicsDevice.viewport.width, + screenHeight: Core.graphicsDevice.viewport.height + }); + } } -} \ No newline at end of file +} diff --git a/source/src/Graphics/Effects/PolygonLightEffect.ts b/source/src/Graphics/Effects/PolygonLightEffect.ts index 84d38be7..0b5c7377 100644 --- a/source/src/Graphics/Effects/PolygonLightEffect.ts +++ b/source/src/Graphics/Effects/PolygonLightEffect.ts @@ -1,34 +1,36 @@ -class PolygonLightEffect extends egret.CustomFilter { - private static vertSrc = "attribute vec2 aVertexPosition;\n" + - "attribute vec2 aTextureCoord;\n" + +module es { + export class PolygonLightEffect extends egret.CustomFilter { + private static vertSrc = "attribute vec2 aVertexPosition;\n" + + "attribute vec2 aTextureCoord;\n" + - "uniform vec2 projectionVector;\n" + + "uniform vec2 projectionVector;\n" + - "varying vec2 vTextureCoord;\n" + + "varying vec2 vTextureCoord;\n" + - "const vec2 center = vec2(-1.0, 1.0);\n" + + "const vec2 center = vec2(-1.0, 1.0);\n" + - "void main(void) {\n" + - " gl_Position = vec4( (aVertexPosition / projectionVector) + center , 0.0, 1.0);\n" + - " vTextureCoord = aTextureCoord;\n" + - "}"; - private static fragmentSrc = "precision lowp float;\n" + - "varying vec2 vTextureCoord;\n" + - "uniform sampler2D uSampler;\n" + + "void main(void) {\n" + + " gl_Position = vec4( (aVertexPosition / projectionVector) + center , 0.0, 1.0);\n" + + " vTextureCoord = aTextureCoord;\n" + + "}"; + private static fragmentSrc = "precision lowp float;\n" + + "varying vec2 vTextureCoord;\n" + + "uniform sampler2D uSampler;\n" + - "#define SAMPLE_COUNT 15\n" + + "#define SAMPLE_COUNT 15\n" + - "uniform vec2 _sampleOffsets[SAMPLE_COUNT];\n" + - "uniform float _sampleWeights[SAMPLE_COUNT];\n" + + "uniform vec2 _sampleOffsets[SAMPLE_COUNT];\n" + + "uniform float _sampleWeights[SAMPLE_COUNT];\n" + - "void main(void) {\n" + - "vec4 c = vec4(0, 0, 0, 0);\n" + - "for( int i = 0; i < SAMPLE_COUNT; i++ )\n" + - " c += texture2D( uSampler, vTextureCoord + _sampleOffsets[i] ) * _sampleWeights[i];\n" + - "gl_FragColor = c;\n" + - "}"; + "void main(void) {\n" + + "vec4 c = vec4(0, 0, 0, 0);\n" + + "for( int i = 0; i < SAMPLE_COUNT; i++ )\n" + + " c += texture2D( uSampler, vTextureCoord + _sampleOffsets[i] ) * _sampleWeights[i];\n" + + "gl_FragColor = c;\n" + + "}"; - constructor(){ - super(PolygonLightEffect.vertSrc, PolygonLightEffect.fragmentSrc); + constructor() { + super(PolygonLightEffect.vertSrc, PolygonLightEffect.fragmentSrc); + } } -} \ No newline at end of file +} diff --git a/source/src/Graphics/GraphicsCapabilities.ts b/source/src/Graphics/GraphicsCapabilities.ts index f4509bb2..8e1fba29 100644 --- a/source/src/Graphics/GraphicsCapabilities.ts +++ b/source/src/Graphics/GraphicsCapabilities.ts @@ -1,33 +1,31 @@ -class GraphicsCapabilities { - public supportsTextureFilterAnisotropic: boolean; - public supportsNonPowerOfTwo: boolean; - public supportsDepth24: boolean; - public supportsPackedDepthStencil: boolean; - public supportsDepthNonLinear: boolean; - public supportsTextureMaxLevel: boolean; - public supportsS3tc: boolean; - public supportsDxt1: boolean; - public supportsPvrtc: boolean; - public supportsAtitc: boolean; - public supportsFramebufferObjectARB: boolean; +module es { + export class GraphicsCapabilities extends egret.Capabilities { - public initialize(device: GraphicsDevice){ - this.platformInitialize(device); - } + public initialize(device: GraphicsDevice) { + this.platformInitialize(device); + } - private platformInitialize(device: GraphicsDevice){ - let gl: WebGLRenderingContext = new egret.sys.RenderBuffer().context.getInstance(); - this.supportsNonPowerOfTwo = false; - this.supportsTextureFilterAnisotropic = gl.getExtension("EXT_texture_filter_anisotropic") != null; - this.supportsDepth24 = true; - this.supportsPackedDepthStencil = true; - this.supportsDepthNonLinear = false; - this.supportsTextureMaxLevel = true; - this.supportsS3tc = gl.getExtension("WEBGL_compressed_texture_s3tc") != null || - gl.getExtension("WEBGL_compressed_texture_s3tc_srgb") != null; - this.supportsDxt1 = this.supportsS3tc; - this.supportsPvrtc = false; - this.supportsAtitc = gl.getExtension("WEBGL_compressed_texture_astc") != null; - this.supportsFramebufferObjectARB = false; + private platformInitialize(device: GraphicsDevice) { + if (GraphicsCapabilities.runtimeType != egret.RuntimeType.WXGAME) + return; + let capabilities = this; + capabilities["isMobile"] = true; + + let systemInfo = wx.getSystemInfoSync(); + let systemStr = systemInfo.system.toLowerCase(); + if (systemStr.indexOf("ios") > -1) { + capabilities["os"] = "iOS"; + } else if (systemStr.indexOf("android") > -1) { + capabilities["os"] = "Android"; + } + + let language = systemInfo.language; + if (language.indexOf('zh') > -1) { + language = "zh-CN"; + } else { + language = "en-US"; + } + capabilities["language"] = language; + } } -} \ No newline at end of file +} diff --git a/source/src/Graphics/GraphicsDevice.ts b/source/src/Graphics/GraphicsDevice.ts index 6deacb10..9892b045 100644 --- a/source/src/Graphics/GraphicsDevice.ts +++ b/source/src/Graphics/GraphicsDevice.ts @@ -1,10 +1,21 @@ -class GraphicsDevice { - private viewport: Viewport; +module es { + export class GraphicsDevice { + public graphicsCapabilities: GraphicsCapabilities; - public graphicsCapabilities: GraphicsCapabilities; + constructor() { + this.setup(); + this.graphicsCapabilities = new GraphicsCapabilities(); + this.graphicsCapabilities.initialize(this); + } - constructor(){ - this.graphicsCapabilities = new GraphicsCapabilities(); - this.graphicsCapabilities.initialize(this); + private _viewport: Viewport; + + public get viewport(): Viewport { + return this._viewport; + } + + private setup() { + this._viewport = new Viewport(0, 0, Core._instance.stage.stageWidth, Core._instance.stage.stageHeight); + } } -} \ No newline at end of file +} diff --git a/source/src/Graphics/PostProcessing/PostProcessor.ts b/source/src/Graphics/PostProcessing/PostProcessor.ts index a1249150..51f6f3c2 100644 --- a/source/src/Graphics/PostProcessing/PostProcessor.ts +++ b/source/src/Graphics/PostProcessing/PostProcessor.ts @@ -1,58 +1,60 @@ -class PostProcessor { - public enable: boolean; - public effect: egret.Filter; - public scene: Scene; - public shape: egret.Shape; +module es { + export class PostProcessor { + public static default_vert = "attribute vec2 aVertexPosition;\n" + + "attribute vec2 aTextureCoord;\n" + + "attribute vec2 aColor;\n" + - public static default_vert = "attribute vec2 aVertexPosition;\n" + - "attribute vec2 aTextureCoord;\n" + - "attribute vec2 aColor;\n" + - - "uniform vec2 projectionVector;\n" + - //"uniform vec2 offsetVector;\n" + + "uniform vec2 projectionVector;\n" + + //"uniform vec2 offsetVector;\n" + - "varying vec2 vTextureCoord;\n" + - "varying vec4 vColor;\n" + + "varying vec2 vTextureCoord;\n" + + "varying vec4 vColor;\n" + - "const vec2 center = vec2(-1.0, 1.0);\n" + + "const vec2 center = vec2(-1.0, 1.0);\n" + - "void main(void) {\n" + - "gl_Position = vec4( (aVertexPosition / projectionVector) + center , 0.0, 1.0);\n" + - "vTextureCoord = aTextureCoord;\n" + - "vColor = vec4(aColor.x, aColor.x, aColor.x, aColor.x);\n" + - "}"; + "void main(void) {\n" + + "gl_Position = vec4( (aVertexPosition / projectionVector) + center , 0.0, 1.0);\n" + + "vTextureCoord = aTextureCoord;\n" + + "vColor = vec4(aColor.x, aColor.x, aColor.x, aColor.x);\n" + + "}"; + public enabled: boolean; + public effect: egret.Filter; + public scene: Scene; + public shape: egret.Shape; - constructor(effect: egret.Filter = null){ - this.enable = true; - this.effect = effect; - } - - public onAddedToScene(scene: Scene){ - this.scene = scene; - this.shape = new egret.Shape(); - this.shape.graphics.beginFill(0xFFFFFF, 1); - this.shape.graphics.drawRect(0, 0, SceneManager.stage.stageWidth, SceneManager.stage.stageHeight); - this.shape.graphics.endFill(); - scene.addChild(this.shape); - } - - public process(){ - this.drawFullscreenQuad(); - } - - public onSceneBackBufferSizeChanged(newWidth: number, newHeight: number){} - - protected drawFullscreenQuad(){ - this.scene.filters = [this.effect]; - // this.shape.filters = [this.effect]; - } - - public unload(){ - if (this.effect){ - this.effect = null; + constructor(effect: egret.Filter = null) { + this.enabled = true; + this.effect = effect; } - this.scene.removeChild(this.shape); - this.scene = null; + public onAddedToScene(scene: Scene) { + this.scene = scene; + this.shape = new egret.Shape(); + this.shape.graphics.beginFill(0xFFFFFF, 1); + this.shape.graphics.drawRect(0, 0, Core.graphicsDevice.viewport.width, Core.graphicsDevice.viewport.height); + this.shape.graphics.endFill(); + scene.addChild(this.shape); + } + + public process() { + this.drawFullscreenQuad(); + } + + public onSceneBackBufferSizeChanged(newWidth: number, newHeight: number) { + } + + public unload() { + if (this.effect) { + this.effect = null; + } + + this.scene.removeChild(this.shape); + this.scene = null; + } + + protected drawFullscreenQuad() { + this.scene.filters = [this.effect]; + // this.shape.filters = [this.effect]; + } } -} \ No newline at end of file +} diff --git a/source/src/Graphics/PostProcessing/PostProcessors/GaussianBlurPostProcessor.ts b/source/src/Graphics/PostProcessing/PostProcessors/GaussianBlurPostProcessor.ts index 3030b81f..04316920 100644 --- a/source/src/Graphics/PostProcessing/PostProcessors/GaussianBlurPostProcessor.ts +++ b/source/src/Graphics/PostProcessing/PostProcessors/GaussianBlurPostProcessor.ts @@ -1,6 +1,8 @@ -class GaussianBlurPostProcessor extends PostProcessor { - public onAddedToScene(scene: Scene){ - super.onAddedToScene(scene); - this.effect = new GaussianBlurEffect(); +module es { + export class GaussianBlurPostProcessor extends PostProcessor { + public onAddedToScene(scene: Scene) { + super.onAddedToScene(scene); + this.effect = new GaussianBlurEffect(); + } } -} \ No newline at end of file +} diff --git a/source/src/Graphics/Renderers/DefaultRenderer.ts b/source/src/Graphics/Renderers/DefaultRenderer.ts index dd18bd8e..5a839623 100644 --- a/source/src/Graphics/Renderers/DefaultRenderer.ts +++ b/source/src/Graphics/Renderers/DefaultRenderer.ts @@ -1,13 +1,19 @@ /// -class DefaultRenderer extends Renderer { - public render(scene: Scene) { - let cam = this.camera ? this.camera : scene.camera; - this.beginRender(cam); +module es { + export class DefaultRenderer extends Renderer { + constructor() { + super(0, null); + } - for (let i = 0; i < scene.renderableComponents.count; i++){ - let renderable = scene.renderableComponents.buffer[i]; - if (renderable.enabled && renderable.isVisibleFromCamera(cam)) - this.renderAfterStateCheck(renderable, cam); + public render(scene: Scene) { + let cam = this.camera ? this.camera : scene.camera; + this.beginRender(cam); + + for (let i = 0; i < scene.renderableComponents.count; i++) { + let renderable = scene.renderableComponents.buffer[i]; + if (renderable.enabled && renderable.isVisibleFromCamera(cam)) + this.renderAfterStateCheck(renderable, cam); + } } } -} \ No newline at end of file +} diff --git a/source/src/Graphics/Renderers/IRenderable.ts b/source/src/Graphics/Renderers/IRenderable.ts index c19dd59d..fbfbf21c 100644 --- a/source/src/Graphics/Renderers/IRenderable.ts +++ b/source/src/Graphics/Renderers/IRenderable.ts @@ -1,7 +1,47 @@ -interface IRenderable { - bounds: Rectangle; - enabled: boolean; - isVisible: boolean; - isVisibleFromCamera(camera: Camera); - render(camera: Camera); -} \ No newline at end of file +module es { + /** + * 当该接口应用到组件时,它将注册组件以场景渲染器显示 + * 该接口请谨慎实现 + */ + export interface IRenderable { + /** + * 对象的AABB用于相机剔除 + */ + bounds: Rectangle; + /** + * 这个组件是否应该被渲染 + */ + enabled: boolean; + /** + * 较低的渲染层在前面,较高的在后面 + */ + renderLayer: number; + /** + * 可渲染的可见性。状态的改变会调用onBecameVisible/onBecameInvisible方法 + */ + isVisible: boolean; + + /** + * 如果renderableComponent的边界与camera.bounds相交 返回true + * 用于处理isVisible标志的状态开关 + * 在渲染方法中使用这个方法来决定是否渲染 + * @param camera + */ + isVisibleFromCamera(camera: Camera); + + /** + * 由渲染器调用。可以使用摄像机进行剔除 + * @param camera + */ + render(camera: Camera); + } + + /** + * 用于排序IRenderables的比较器 + */ + export class RenderableComparer { + public compare(self: IRenderable, other: IRenderable) { + return other.renderLayer - self.renderLayer; + } + } +} diff --git a/source/src/Graphics/Renderers/PolygonLight/PolyLight.ts b/source/src/Graphics/Renderers/PolygonLight/PolyLight.ts index 0ae9af42..37a2ffa9 100644 --- a/source/src/Graphics/Renderers/PolygonLight/PolyLight.ts +++ b/source/src/Graphics/Renderers/PolygonLight/PolyLight.ts @@ -1,46 +1,50 @@ -class PolyLight extends RenderableComponent { - public power: number; - protected _radius: number; - private _lightEffect; - private _indices: number[] = []; +module es { + export class PolyLight extends RenderableComponent { + public power: number; + private _lightEffect; + private _indices: number[] = []; - public get radius(){ - return this._radius; - } - public set radius(value: number){ - this.setRadius(value); - } + constructor(radius: number, color: number, power: number) { + super(); - constructor(radius: number, color: number, power: number){ - super(); + this.radius = radius; + this.power = power; + this.color = color; + this.computeTriangleIndices(); + } - this.radius = radius; - this.power = power; - this.color = color; - this.computeTriangleIndices(); - } + protected _radius: number; - private computeTriangleIndices(totalTris: number = 20){ - this._indices.length = 0; + public get radius() { + return this._radius; + } - for (let i = 0; i < totalTris; i += 2){ - this._indices.push(0); - this._indices.push(i + 2); - this._indices.push(i + 1); + public set radius(value: number) { + this.setRadius(value); + } + + public setRadius(radius: number) { + if (radius != this._radius) { + this._radius = radius; + this._areBoundsDirty = true; + } + } + + public render(camera: Camera) { + } + + public reset() { + + } + + private computeTriangleIndices(totalTris: number = 20) { + this._indices.length = 0; + + for (let i = 0; i < totalTris; i += 2) { + this._indices.push(0); + this._indices.push(i + 2); + this._indices.push(i + 1); + } } } - - public setRadius(radius: number){ - if (radius != this._radius){ - this._radius = radius; - this._areBoundsDirty = true; - } - } - - public render(camera: Camera) { - } - - public reset(){ - - } -} \ No newline at end of file +} diff --git a/source/src/Graphics/Renderers/Renderer.ts b/source/src/Graphics/Renderers/Renderer.ts index 86b5afec..e761e4a8 100644 --- a/source/src/Graphics/Renderers/Renderer.ts +++ b/source/src/Graphics/Renderers/Renderer.ts @@ -1,38 +1,66 @@ -/** - * 渲染器被添加到场景中并处理所有对RenderableComponent的实际调用 - */ -abstract class Renderer { - /** - * 渲染器用于渲染的摄像机(实际上是用于剔除的变换矩阵和边界) - * 不是必须的 - * Renderer子类可以选择调用beginRender时使用的摄像头 - */ - public camera: Camera; - +module es { /** - * 当渲染器被添加到场景时调用 - * @param scene + * 渲染器被添加到场景中并处理所有对RenderableComponent的实际调用 */ - public onAddedToScene(scene: Scene){} + export abstract class Renderer { + /** + * 渲染器用于渲染的摄像机(实际上是用于剔除的变换矩阵和边界) + * 不是必须的 + * Renderer子类可以选择调用beginRender时使用的摄像头 + */ + public camera: Camera; + /** + * 指定场景调用渲染器的顺序 + */ + public readonly renderOrder: number = 0; - protected beginRender(cam: Camera){ - + protected constructor(renderOrder: number, camera: Camera = null) { + this.camera = camera; + this.renderOrder = renderOrder; + } + + /** + * 当渲染器被添加到场景时调用 + * @param scene + */ + public onAddedToScene(scene: Scene) { + } + + /** + * 当场景结束或渲染器从场景中移除时调用。使用这个进行清理。 + */ + public unload() { + } + + public abstract render(scene: Scene); + + /** + * 当默认场景渲染目标被调整大小和当场景已经开始添加渲染器时调用 + * @param newWidth + * @param newHeight + */ + public onSceneBackBufferSizeChanged(newWidth: number, newHeight: number) { + + } + + public compareTo(other: Renderer): number { + return this.renderOrder - other.renderOrder; + } + + /** + * + * @param cam + */ + protected beginRender(cam: Camera) { + } + + /** + * + * @param renderable + * @param cam + */ + protected renderAfterStateCheck(renderable: IRenderable, cam: Camera) { + renderable.render(cam); + } } - - /** - * - * @param scene - */ - public abstract render(scene: Scene); - - public unload(){ } - - /** - * - * @param renderable - * @param cam - */ - protected renderAfterStateCheck(renderable: IRenderable, cam: Camera){ - renderable.render(cam); - } -} \ No newline at end of file +} diff --git a/source/src/Graphics/Renderers/ScreenSpaceRenderer.ts b/source/src/Graphics/Renderers/ScreenSpaceRenderer.ts index dbf7da35..0fbe20c0 100644 --- a/source/src/Graphics/Renderers/ScreenSpaceRenderer.ts +++ b/source/src/Graphics/Renderers/ScreenSpaceRenderer.ts @@ -1,7 +1,9 @@ -/** - * 渲染器使用自己的不移动的摄像机进行渲染。 - */ -class ScreenSpaceRenderer extends Renderer { - public render(scene: Scene) { +module es { + /** + * 渲染器使用自己的不移动的摄像机进行渲染。 + */ + export class ScreenSpaceRenderer extends Renderer { + public render(scene: Scene) { + } } -} \ No newline at end of file +} diff --git a/source/src/Graphics/Transitions/FadeTransition.ts b/source/src/Graphics/Transitions/FadeTransition.ts index 76d44cc5..d72b242f 100644 --- a/source/src/Graphics/Transitions/FadeTransition.ts +++ b/source/src/Graphics/Transitions/FadeTransition.ts @@ -1,38 +1,38 @@ /// -class FadeTransition extends SceneTransition { - public fadeToColor: number = 0x000000; - public fadeOutDuration = 0.4; - public fadeEaseType: Function = egret.Ease.quadInOut; - public delayBeforeFadeInDuration = 0.1; - private _mask: egret.Shape; - private _alpha: number = 0; +module es { + export class FadeTransition extends SceneTransition { + public fadeToColor: number = 0x000000; + public fadeOutDuration = 0.4; + public fadeEaseType: Function = egret.Ease.quadInOut; + public delayBeforeFadeInDuration = 0.1; + private _mask: egret.Shape; + private _alpha: number = 0; - constructor(sceneLoadAction: Function) { - super(sceneLoadAction); - this._mask = new egret.Shape(); - } + constructor(sceneLoadAction: Function) { + super(sceneLoadAction); + this._mask = new egret.Shape(); + } - public async onBeginTransition() { - this._mask.graphics.beginFill(this.fadeToColor, 1); - this._mask.graphics.drawRect(0, 0, SceneManager.stage.stageWidth, SceneManager.stage.stageHeight); - this._mask.graphics.endFill(); - SceneManager.stage.addChild(this._mask); + public async onBeginTransition() { + this._mask.graphics.beginFill(this.fadeToColor, 1); + this._mask.graphics.drawRect(0, 0, Core.graphicsDevice.viewport.width, Core.graphicsDevice.viewport.height); + this._mask.graphics.endFill(); - egret.Tween.get(this).to({ _alpha: 1}, this.fadeOutDuration * 1000, this.fadeEaseType) - .call(async () => { - await this.loadNextScene(); - }).wait(this.delayBeforeFadeInDuration).call(() => { - egret.Tween.get(this).to({ _alpha: 0 }, this.fadeOutDuration * 1000, this.fadeEaseType).call(() => { + egret.Tween.get(this).to({_alpha: 1}, this.fadeOutDuration * 1000, this.fadeEaseType) + .call(async () => { + await this.loadNextScene(); + }).wait(this.delayBeforeFadeInDuration).call(() => { + egret.Tween.get(this).to({_alpha: 0}, this.fadeOutDuration * 1000, this.fadeEaseType).call(() => { this.transitionComplete(); - SceneManager.stage.removeChild(this._mask); }); }); - } + } - public render(){ - this._mask.graphics.clear(); - this._mask.graphics.beginFill(this.fadeToColor, this._alpha); - this._mask.graphics.drawRect(0, 0, SceneManager.stage.stageWidth, SceneManager.stage.stageHeight); - this._mask.graphics.endFill(); + public render() { + this._mask.graphics.clear(); + this._mask.graphics.beginFill(this.fadeToColor, this._alpha); + this._mask.graphics.drawRect(0, 0, Core.graphicsDevice.viewport.width, Core.graphicsDevice.viewport.height); + this._mask.graphics.endFill(); + } } -} \ No newline at end of file +} diff --git a/source/src/Graphics/Transitions/SceneTransition.ts b/source/src/Graphics/Transitions/SceneTransition.ts index 5db16fa4..6a23c0a1 100644 --- a/source/src/Graphics/Transitions/SceneTransition.ts +++ b/source/src/Graphics/Transitions/SceneTransition.ts @@ -1,75 +1,79 @@ -/** - * SceneTransition用于从一个场景过渡到另一个场景或在一个有效果的场景中过渡 - */ -abstract class SceneTransition { - private _hasPreviousSceneRender: boolean; - /** 是否加载新场景的标志 */ - public loadsNewScene: boolean; - /** - * 将此用于两个部分的转换。例如,淡出会先淡出到黑色,然后当isNewSceneLoaded为true,它会淡出。 - * 对于场景过渡,isNewSceneLoaded应该在中点设置为true,这就标识一个新的场景被加载了。 +module es { + /** + * SceneTransition用于从一个场景过渡到另一个场景或在一个有效果的场景中过渡 */ - public isNewSceneLoaded: boolean; - /** 返回新加载场景的函数 */ - protected sceneLoadAction: Function; - /** 在loadNextScene执行时调用。这在进行场景间过渡时很有用,这样你就知道什么时候可以更多地使用相机或者重置任何实体 */ - public onScreenObscured: Function; - /** 当转换完成执行时调用,以便可以调用其他工作,比如启动另一个转换。 */ - public onTransitionCompleted: Function; + export abstract class SceneTransition { + /** 是否加载新场景的标志 */ + public loadsNewScene: boolean; + /** + * 将此用于两个部分的转换。例如,淡出会先淡出到黑色,然后当isNewSceneLoaded为true,它会淡出。 + * 对于场景过渡,isNewSceneLoaded应该在中点设置为true,这就标识一个新的场景被加载了。 + */ + public isNewSceneLoaded: boolean; + /** 在loadNextScene执行时调用。这在进行场景间过渡时很有用,这样你就知道什么时候可以更多地使用相机或者重置任何实体 */ + public onScreenObscured: Function; + /** 当转换完成执行时调用,以便可以调用其他工作,比如启动另一个转换。 */ + public onTransitionCompleted: Function; + /** 返回新加载场景的函数 */ + protected sceneLoadAction: Function; - public get hasPreviousSceneRender(){ - if (!this._hasPreviousSceneRender){ - this._hasPreviousSceneRender = true; - return false; + constructor(sceneLoadAction: Function) { + this.sceneLoadAction = sceneLoadAction; + this.loadsNewScene = sceneLoadAction != null; } - return true; - } + private _hasPreviousSceneRender: boolean; - constructor(sceneLoadAction: Function) { - this.sceneLoadAction = sceneLoadAction; - this.loadsNewScene = sceneLoadAction != null; - } + public get hasPreviousSceneRender() { + if (!this._hasPreviousSceneRender) { + this._hasPreviousSceneRender = true; + return false; + } - public preRender() { } - - public render() { - - } - - public async onBeginTransition() { - await this.loadNextScene(); - this.transitionComplete(); - } - - protected transitionComplete() { - SceneManager.sceneTransition = null; - - if (this.onTransitionCompleted) { - this.onTransitionCompleted(); + return true; } - } - protected async loadNextScene() { - if (this.onScreenObscured) - this.onScreenObscured(); + public preRender() { + } - if (!this.loadsNewScene) { + public render() { + + } + + public async onBeginTransition() { + await this.loadNextScene(); + this.transitionComplete(); + } + + public tickEffectProgressProperty(filter: egret.CustomFilter, duration: number, easeType: Function, reverseDirection = false): Promise { + return new Promise((resolve) => { + let start = reverseDirection ? 1 : 0; + let end = reverseDirection ? 0 : 1; + + egret.Tween.get(filter.uniforms).set({_progress: start}).to({_progress: end}, duration * 1000, easeType).call(() => { + resolve(); + }); + }); + } + + protected transitionComplete() { + Core._instance._sceneTransition = null; + + if (this.onTransitionCompleted) { + this.onTransitionCompleted(); + } + } + + protected async loadNextScene() { + if (this.onScreenObscured) + this.onScreenObscured(); + + if (!this.loadsNewScene) { + this.isNewSceneLoaded = true; + } + + Core.scene = await this.sceneLoadAction(); this.isNewSceneLoaded = true; } - - SceneManager.scene = await this.sceneLoadAction(); - this.isNewSceneLoaded = true; } - - public tickEffectProgressProperty(filter: egret.CustomFilter, duration: number, easeType: Function, reverseDirection = false){ - return new Promise((resolve)=>{ - let start = reverseDirection ? 1 : 0; - let end = reverseDirection ? 0 : 1; - - egret.Tween.get(filter.uniforms).set({_progress: start}).to({_progress: end}, duration * 1000, easeType).call(()=>{ - resolve(); - }); - }); - } -} \ No newline at end of file +} diff --git a/source/src/Graphics/Transitions/WindTransition.ts b/source/src/Graphics/Transitions/WindTransition.ts index 3bf540f4..8ce82c75 100644 --- a/source/src/Graphics/Transitions/WindTransition.ts +++ b/source/src/Graphics/Transitions/WindTransition.ts @@ -1,65 +1,67 @@ -class WindTransition extends SceneTransition { - private _mask: egret.Shape; - private _windEffect: egret.CustomFilter; +module es { + export class WindTransition extends SceneTransition { + public duration = 1; + public easeType = egret.Ease.quadOut; + private _mask: egret.Shape; + private _windEffect: egret.CustomFilter; - public duration = 1; - public set windSegments(value: number) { - this._windEffect.uniforms._windSegments = value; + constructor(sceneLoadAction: Function) { + super(sceneLoadAction); + + let vertexSrc = "attribute vec2 aVertexPosition;\n" + + "attribute vec2 aTextureCoord;\n" + + + "uniform vec2 projectionVector;\n" + + + "varying vec2 vTextureCoord;\n" + + + "const vec2 center = vec2(-1.0, 1.0);\n" + + + "void main(void) {\n" + + " gl_Position = vec4( (aVertexPosition / projectionVector) + center , 0.0, 1.0);\n" + + " vTextureCoord = aTextureCoord;\n" + + "}"; + let fragmentSrc = "precision lowp float;\n" + + "varying vec2 vTextureCoord;\n" + + "uniform sampler2D uSampler;\n" + + "uniform float _progress;\n" + + "uniform float _size;\n" + + "uniform float _windSegments;\n" + + + "void main(void) {\n" + + "vec2 co = floor(vec2(0.0, vTextureCoord.y * _windSegments));\n" + + "float x = sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453;\n" + + "float r = x - floor(x);\n" + + "float m = smoothstep(0.0, -_size, vTextureCoord.x * (1.0 - _size) + _size * r - (_progress * (1.0 + _size)));\n" + + "vec4 fg = texture2D(uSampler, vTextureCoord);\n" + + "gl_FragColor = mix(fg, vec4(0, 0, 0, 0), m);\n" + + "}"; + + this._windEffect = new egret.CustomFilter(vertexSrc, fragmentSrc, { + _progress: 0, + _size: 0.3, + _windSegments: 100 + }); + + this._mask = new egret.Shape(); + this._mask.graphics.beginFill(0xFFFFFF, 1); + this._mask.graphics.drawRect(0, 0, Core.graphicsDevice.viewport.width, Core.graphicsDevice.viewport.height); + this._mask.graphics.endFill(); + this._mask.filters = [this._windEffect]; + } + + public set windSegments(value: number) { + this._windEffect.uniforms._windSegments = value; + } + + public set size(value: number) { + this._windEffect.uniforms._size = value; + } + + public async onBeginTransition() { + this.loadNextScene(); + await this.tickEffectProgressProperty(this._windEffect, this.duration, this.easeType); + this.transitionComplete(); + } } - public set size(value: number) { - this._windEffect.uniforms._size = value; - } - public easeType = egret.Ease.quadOut; - constructor(sceneLoadAction: Function) { - super(sceneLoadAction); - - let vertexSrc = "attribute vec2 aVertexPosition;\n" + - "attribute vec2 aTextureCoord;\n" + - - "uniform vec2 projectionVector;\n" + - - "varying vec2 vTextureCoord;\n" + - - "const vec2 center = vec2(-1.0, 1.0);\n" + - - "void main(void) {\n" + - " gl_Position = vec4( (aVertexPosition / projectionVector) + center , 0.0, 1.0);\n" + - " vTextureCoord = aTextureCoord;\n" + - "}"; - let fragmentSrc = "precision lowp float;\n" + - "varying vec2 vTextureCoord;\n" + - "uniform sampler2D uSampler;\n" + - "uniform float _progress;\n" + - "uniform float _size;\n" + - "uniform float _windSegments;\n" + - - "void main(void) {\n" + - "vec2 co = floor(vec2(0.0, vTextureCoord.y * _windSegments));\n" + - "float x = sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453;\n" + - "float r = x - floor(x);\n" + - "float m = smoothstep(0.0, -_size, vTextureCoord.x * (1.0 - _size) + _size * r - (_progress * (1.0 + _size)));\n" + - "vec4 fg = texture2D(uSampler, vTextureCoord);\n" + - "gl_FragColor = mix(fg, vec4(0, 0, 0, 0), m);\n" + - "}"; - - this._windEffect = new egret.CustomFilter(vertexSrc, fragmentSrc, { - _progress: 0, - _size: 0.3, - _windSegments: 100 - }); - - this._mask = new egret.Shape(); - this._mask.graphics.beginFill(0xFFFFFF, 1); - this._mask.graphics.drawRect(0, 0, SceneManager.stage.stageWidth, SceneManager.stage.stageHeight); - this._mask.graphics.endFill(); - this._mask.filters = [this._windEffect]; - SceneManager.stage.addChild(this._mask); - } - - public async onBeginTransition() { - this.loadNextScene(); - await this.tickEffectProgressProperty(this._windEffect, this.duration, this.easeType); - this.transitionComplete(); - SceneManager.stage.removeChild(this._mask); - } -} \ No newline at end of file +} diff --git a/source/src/Graphics/Viewport.ts b/source/src/Graphics/Viewport.ts index 38ebef3f..412dda02 100644 --- a/source/src/Graphics/Viewport.ts +++ b/source/src/Graphics/Viewport.ts @@ -1,34 +1,55 @@ -class Viewport { - private _x: number; - private _y: number; - private _width: number; - private _height: number; - private _minDepth: number; - private _maxDepth: number; - - public get aspectRatio(){ - if ((this._height != 0) && (this._width != 0)) - return (this._width / this._height); - return 0; - } +module es { + export class Viewport { + private _x: number; + private _y: number; + private _minDepth: number; + private _maxDepth: number; - public get bounds(){ - return new Rectangle(this._x, this._y, this._width, this._height); - } - public set bounds(value: Rectangle){ - this._x = value.x; - this._y = value.y; - this._width = value.width; - this._height = value.height; - } + constructor(x: number, y: number, width: number, height: number) { + this._x = x; + this._y = y; + this._width = width; + this._height = height; + this._minDepth = 0; + this._maxDepth = 1; + } + + private _width: number; + + public get width() { + return this._width; + } + + public set width(value: number) { + this._width = value; + } + + private _height: number; + + public get height() { + return this._height; + } + + public set height(value: number) { + this._height = value; + } + + public get aspectRatio() { + if ((this._height != 0) && (this._width != 0)) + return (this._width / this._height); + return 0; + } + + public get bounds() { + return new Rectangle(this._x, this._y, this._width, this._height); + } + + public set bounds(value: Rectangle) { + this._x = value.x; + this._y = value.y; + this._width = value.width; + this._height = value.height; + } - constructor(x: number, y: number, width: number, height: number){ - this._x = x; - this._y = y; - this._width = width; - this._height = height; - this._minDepth = 0; - this._maxDepth = 1; } - -} \ No newline at end of file +} diff --git a/source/src/Math/Bezier.ts b/source/src/Math/Bezier.ts new file mode 100644 index 00000000..e6a4fbe1 --- /dev/null +++ b/source/src/Math/Bezier.ts @@ -0,0 +1,123 @@ +module es { + /** 贝塞尔帮助类 */ + export class Bezier { + /** + * 二次贝塞尔曲线 + * @param p0 + * @param p1 + * @param p2 + * @param t + */ + public static getPoint(p0: Vector2, p1: Vector2, p2: Vector2, t: number): Vector2 { + t = MathHelper.clamp01(t); + let oneMinusT = 1 - t; + return Vector2.add(Vector2.add(Vector2.multiply(new Vector2(oneMinusT * oneMinusT), p0), + Vector2.multiply(new Vector2(2 * oneMinusT * t), p1)), Vector2.multiply(new Vector2(t * t), p2)); + } + + /** + * 得到二次贝塞尔函数的一阶导数 + * @param p0 + * @param p1 + * @param p2 + * @param t + */ + public static getFirstDerivative(p0: Vector2, p1: Vector2, p2: Vector2, t: number) { + return Vector2.add(Vector2.multiply(new Vector2(2 * (1 - t)), Vector2.subtract(p1, p0)), + Vector2.multiply(new Vector2(2 * t), Vector2.subtract(p2, p1))); + } + + /** + * 得到一个三次贝塞尔函数的一阶导数 + * @param start + * @param firstControlPoint + * @param secondControlPoint + * @param end + * @param t + */ + public static getFirstDerivativeThree(start: Vector2, firstControlPoint: Vector2, secondControlPoint: Vector2, + end: Vector2, t: number) { + t = MathHelper.clamp01(t); + let oneMunusT = 1 - t; + return Vector2.add(Vector2.add(Vector2.multiply(new Vector2(3 * oneMunusT * oneMunusT), Vector2.subtract(firstControlPoint, start)), + Vector2.multiply(new Vector2(6 * oneMunusT * t), Vector2.subtract(secondControlPoint, firstControlPoint))), + Vector2.multiply(new Vector2(3 * t * t), Vector2.subtract(end, secondControlPoint))); + } + + /** + * 计算一个三次贝塞尔 + * @param start + * @param firstControlPoint + * @param secondControlPoint + * @param end + * @param t + */ + public static getPointThree(start: Vector2, firstControlPoint: Vector2, secondControlPoint: Vector2, + end: Vector2, t: number) { + t = MathHelper.clamp01(t); + let oneMunusT = 1 - t; + return Vector2.add(Vector2.add(Vector2.add(Vector2.multiply(new Vector2(oneMunusT * oneMunusT * oneMunusT), start), + Vector2.multiply(new Vector2(3 * oneMunusT * oneMunusT * t), firstControlPoint)), + Vector2.multiply(new Vector2(3 * oneMunusT * t * t), secondControlPoint)), + Vector2.multiply(new Vector2(t * t * t), end)); + } + + /** + * 递归地细分bezier曲线,直到满足距离校正 + * 在这种算法中,平面切片的点要比曲面切片少。返回完成后应返回到ListPool的合并列表。 + * @param start + * @param firstCtrlPoint + * @param secondCtrlPoint + * @param end + * @param distanceTolerance + */ + public static getOptimizedDrawingPoints(start: Vector2, firstCtrlPoint: Vector2, secondCtrlPoint: Vector2, + end: Vector2, distanceTolerance: number = 1) { + let points = ListPool.obtain(); + points.push(start); + this.recursiveGetOptimizedDrawingPoints(start, firstCtrlPoint, secondCtrlPoint, end, points, distanceTolerance); + points.push(end); + + return points; + } + + /** + * 递归地细分bezier曲线,直到满足距离校正。在这种算法中,平面切片的点要比曲面切片少。 + * @param start + * @param firstCtrlPoint + * @param secondCtrlPoint + * @param end + * @param points + * @param distanceTolerance + */ + private static recursiveGetOptimizedDrawingPoints(start: Vector2, firstCtrlPoint: Vector2, secondCtrlPoint: Vector2, + end: Vector2, points: Vector2[], distanceTolerance: number) { + // 计算线段的所有中点 + let pt12 = Vector2.divide(Vector2.add(start, firstCtrlPoint), new Vector2(2)); + let pt23 = Vector2.divide(Vector2.add(firstCtrlPoint, secondCtrlPoint), new Vector2(2)); + let pt34 = Vector2.divide(Vector2.add(secondCtrlPoint, end), new Vector2(2)); + + // 计算新半直线的中点 + let pt123 = Vector2.divide(Vector2.add(pt12, pt23), new Vector2(2)); + let pt234 = Vector2.divide(Vector2.add(pt23, pt34), new Vector2(2)); + + // 最后再细分最后两个中点。如果我们满足我们的距离公差,这将是我们使用的最后一点。 + let pt1234 = Vector2.divide(Vector2.add(pt123, pt234), new Vector2(2)); + + // 试着用一条直线来近似整个三次曲线 + let deltaLine = Vector2.subtract(end, start); + + let d2 = Math.abs(((firstCtrlPoint.x, end.x) * deltaLine.y - (firstCtrlPoint.y - end.y) * deltaLine.x)); + let d3 = Math.abs(((secondCtrlPoint.x - end.x) * deltaLine.y - (secondCtrlPoint.y - end.y) * deltaLine.x)); + + if ((d2 + d3) * (d2 + d3) < distanceTolerance * (deltaLine.x * deltaLine.x + deltaLine.y * deltaLine.y)) { + points.push(pt1234); + return; + } + + // 继续细分 + this.recursiveGetOptimizedDrawingPoints(start, pt12, pt123, pt1234, points, distanceTolerance); + this.recursiveGetOptimizedDrawingPoints(pt1234, pt234, pt34, end, points, distanceTolerance); + } + } +} diff --git a/source/src/Math/Flags.ts b/source/src/Math/Flags.ts index c9b00034..55e473af 100644 --- a/source/src/Math/Flags.ts +++ b/source/src/Math/Flags.ts @@ -1,62 +1,64 @@ -/** - * 帮助处理位掩码的实用程序类 - * 除了isFlagSet之外,所有方法都期望flag参数是一个非移位的标志 - * 允许您使用普通的(0、1、2、3等)来设置/取消您的标记 - */ -class Flags { +module es { /** - * 检查位标志是否已在数值中设置 - * 检查期望标志是否已经移位 - * @param self - * @param flag + * 帮助处理位掩码的实用程序类 + * 除了isFlagSet之外,所有方法都期望flag参数是一个非移位的标志 + * 允许您使用普通的(0、1、2、3等)来设置/取消您的标记 */ - public static isFlagSet(self: number, flag: number){ - return (self & flag) != 0; - } + export class Flags { + /** + * 检查位标志是否已在数值中设置 + * 检查期望标志是否已经移位 + * @param self + * @param flag + */ + public static isFlagSet(self: number, flag: number): boolean { + return (self & flag) != 0; + } - /** - * 检查位标志是否在数值中设置 - * @param self - * @param flag - */ - public static isUnshiftedFlagSet(self: number, flag: number){ - flag = 1 << flag; - return (self & flag) != 0; - } + /** + * 检查位标志是否在数值中设置 + * @param self + * @param flag + */ + public static isUnshiftedFlagSet(self: number, flag: number): boolean { + flag = 1 << flag; + return (self & flag) != 0; + } - /** - * 设置数值标志位,移除所有已经设置的标志 - * @param self - * @param flag - */ - public static setFlagExclusive(self: number, flag: number){ - return 1 << flag; - } + /** + * 设置数值标志位,移除所有已经设置的标志 + * @param self + * @param flag + */ + public static setFlagExclusive(self: number, flag: number) { + return 1 << flag; + } - /** - * 设置标志位 - * @param self - * @param flag - */ - public static setFlag(self: number, flag: number){ - return (self | 1 << flag); - } + /** + * 设置标志位 + * @param self + * @param flag + */ + public static setFlag(self: number, flag: number) { + return (self | 1 << flag); + } - /** - * 取消标志位 - * @param self - * @param flag - */ - public static unsetFlag(self: number, flag: number){ - flag = 1 << flag; - return (self & (~flag)); - } + /** + * 取消标志位 + * @param self + * @param flag + */ + public static unsetFlag(self: number, flag: number) { + flag = 1 << flag; + return (self & (~flag)); + } - /** - * 反转数值集合位 - * @param self - */ - public static invertFlags(self: number){ - return ~self; + /** + * 反转数值集合位 + * @param self + */ + public static invertFlags(self: number) { + return ~self; + } } -} \ No newline at end of file +} diff --git a/source/src/Math/MathHelper.ts b/source/src/Math/MathHelper.ts index 7f9eb678..79030310 100644 --- a/source/src/Math/MathHelper.ts +++ b/source/src/Math/MathHelper.ts @@ -1,56 +1,80 @@ -class MathHelper { - public static readonly Epsilon: number = 0.00001; - public static readonly Rad2Deg = 57.29578; - public static readonly Deg2Rad = 0.0174532924; +module es { + export class MathHelper { + public static readonly Epsilon: number = 0.00001; + public static readonly Rad2Deg = 57.29578; + public static readonly Deg2Rad = 0.0174532924; - /** - * 将弧度转换成角度。 - * @param radians 用弧度表示的角 - */ - public static toDegrees(radians: number){ - return radians * 57.295779513082320876798154814105; + /** + * 将弧度转换成角度。 + * @param radians 用弧度表示的角 + */ + public static toDegrees(radians: number) { + return radians * 57.295779513082320876798154814105; + } + + /** + * 将角度转换为弧度 + * @param degrees + */ + public static toRadians(degrees: number) { + return degrees * 0.017453292519943295769236907684886; + } + + /** + * mapps值(在leftMin - leftMax范围内)到rightMin - rightMax范围内的值 + * @param value + * @param leftMin + * @param leftMax + * @param rightMin + * @param rightMax + */ + public static map(value: number, leftMin: number, leftMax: number, rightMin: number, rightMax: number) { + return rightMin + (value - leftMin) * (rightMax - rightMin) / (leftMax - leftMin); + } + + public static lerp(value1: number, value2: number, amount: number) { + return value1 + (value2 - value1) * amount; + } + + public static clamp(value: number, min: number, max: number) { + if (value < min) + return min; + + if (value > max) + return max; + + return value; + } + + public static pointOnCirlce(circleCenter: Vector2, radius: number, angleInDegrees: number) { + let radians = MathHelper.toRadians(angleInDegrees); + return new Vector2(Math.cos(radians) * radians + circleCenter.x, Math.sin(radians) * radians + circleCenter.y); + } + + /** + * 如果值为偶数,返回true + * @param value + */ + public static isEven(value: number) { + return value % 2 == 0; + } + + /** + * 数值限定在0-1之间 + * @param value + */ + public static clamp01(value: number) { + if (value < 0) + return 0; + + if (value > 1) + return 1; + + return value; + } + + public static angleBetweenVectors(from: Vector2, to: Vector2) { + return Math.atan2(to.y - from.y, to.x - from.x); + } } - - /** - * 将角度转换为弧度 - * @param degrees - */ - public static toRadians(degrees: number){ - return degrees * 0.017453292519943295769236907684886; - } - - /** - * mapps值(在leftMin - leftMax范围内)到rightMin - rightMax范围内的值 - * @param value - * @param leftMin - * @param leftMax - * @param rightMin - * @param rightMax - */ - public static map(value: number, leftMin: number, leftMax: number, rightMin: number, rightMax: number){ - return rightMin + (value - leftMin) * (rightMax - rightMin) / (leftMax - leftMin); - } - - public static lerp(value1: number, value2: number, amount: number){ - return value1 + (value2 - value1) * amount; - } - - public static clamp(value: number, min: number, max: number){ - if (value < min) - return min; - - if (value > max) - return max; - - return value; - } - - public static pointOnCirlce(circleCenter: Vector2, radius: number, angleInDegrees: number){ - let radians = MathHelper.toRadians(angleInDegrees); - return new Vector2(Math.cos(radians) * radians + circleCenter.x, Math.sin(radians) * radians + circleCenter.y); - } - - public static isEven(value: number){ - return value % 2 == 0; - } -} \ No newline at end of file +} diff --git a/source/src/Math/Matrix2D.ts b/source/src/Math/Matrix2D.ts index 41794194..7a2b6d9d 100644 --- a/source/src/Math/Matrix2D.ts +++ b/source/src/Math/Matrix2D.ts @@ -1,217 +1,194 @@ -/** - * 表示右手3 * 3的浮点矩阵,可以存储平移、缩放和旋转信息。 - */ -class Matrix2D { - public m11: number = 0; - public m12: number = 0; - - public m21: number = 0; - public m22: number = 0; - - public m31: number = 0; - public m32: number = 0; - - private static _identity: Matrix2D = new Matrix2D(1, 0, 0, 1, 0, 0); +module es { + export var matrixPool = []; /** - * 单位矩阵 + * 表示右手3 * 3的浮点矩阵,可以存储平移、缩放和旋转信息。 */ - public static get identity(){ - return Matrix2D._identity; + export class Matrix2D extends egret.Matrix { + public get m11(): number { + return this.a; + } + + public set m11(value: number) { + this.a = value; + } + + public get m12(): number { + return this.b; + } + + public set m12(value: number) { + this.b = value; + } + + public get m21(): number { + return this.c; + } + + public set m21(value: number) { + this.c = value; + } + + public get m22(): number { + return this.d; + } + + public set m22(value: number) { + this.d = value; + } + + public get m31(): number { + return this.tx; + } + + public set m31(value: number) { + this.tx = value; + } + + public get m32(): number { + return this.ty; + } + + public set m32(value: number) { + this.ty = value; + } + + /** + * 从对象池中取出或创建一个新的Matrix对象。 + */ + public static create(): Matrix2D { + let matrix = matrixPool.pop(); + if (!matrix) + matrix = new Matrix2D(); + return matrix; + } + + public identity(): Matrix2D { + this.a = this.d = 1; + this.b = this.c = this.tx = this.ty = 0; + return this; + } + + public translate(dx: number, dy: number): Matrix2D { + this.tx += dx; + this.ty += dy; + return this; + } + + public scale(sx: number, sy: number): Matrix2D { + if (sx !== 1) { + this.a *= sx; + this.c *= sx; + this.tx *= sx; + } + if (sy !== 1) { + this.b *= sy; + this.d *= sy; + this.ty *= sy; + } + return this; + } + + public rotate(angle: number): Matrix2D { + angle = +angle; + if (angle !== 0) { + angle = angle / DEG_TO_RAD; + let u = Math.cos(angle); + let v = Math.sin(angle); + let ta = this.a; + let tb = this.b; + let tc = this.c; + let td = this.d; + let ttx = this.tx; + let tty = this.ty; + this.a = ta * u - tb * v; + this.b = ta * v + tb * u; + this.c = tc * u - td * v; + this.d = tc * v + td * u; + this.tx = ttx * u - tty * v; + this.ty = ttx * v + tty * u; + } + return this; + } + + public invert(): Matrix2D { + this.$invertInto(this); + return this; + } + + /** + * 创建一个新的matrix, 它包含两个矩阵的和。 + * @param matrix + */ + public add(matrix: Matrix2D): Matrix2D { + this.m11 += matrix.m11; + this.m12 += matrix.m12; + + this.m21 += matrix.m21; + this.m22 += matrix.m22; + + this.m31 += matrix.m31; + this.m32 += matrix.m32; + + return this; + } + + public substract(matrix: Matrix2D): Matrix2D { + this.m11 -= matrix.m11; + this.m12 -= matrix.m12; + + this.m21 -= matrix.m21; + this.m22 -= matrix.m22; + + this.m31 -= matrix.m31; + this.m32 -= matrix.m32; + + return this; + } + + public divide(matrix: Matrix2D): Matrix2D { + this.m11 /= matrix.m11; + this.m12 /= matrix.m12; + + this.m21 /= matrix.m21; + this.m22 /= matrix.m22; + + this.m31 /= matrix.m31; + this.m32 /= matrix.m32; + + return this; + } + + public multiply(matrix: Matrix2D): Matrix2D { + let m11 = (this.m11 * matrix.m11) + (this.m12 * matrix.m21); + let m12 = (this.m11 * matrix.m12) + (this.m12 * matrix.m22); + + let m21 = (this.m21 * matrix.m11) + (this.m22 * matrix.m21); + let m22 = (this.m21 * matrix.m12) + (this.m22 * matrix.m22); + + let m31 = (this.m31 * matrix.m11) + (this.m32 * matrix.m21) + matrix.m31; + let m32 = (this.m31 * matrix.m12) + (this.m32 * matrix.m22) + matrix.m32; + + this.m11 = m11; + this.m12 = m12; + + this.m21 = m21; + this.m22 = m22; + + this.m31 = m31; + this.m32 = m32; + + return this; + } + + public determinant() { + return this.m11 * this.m22 - this.m12 * this.m21; + } + + public release(matrix: Matrix2D) { + if (!matrix) + return; + matrixPool.push(matrix); + } } - - constructor(m11?: number, m12?: number, m21?: number, m22?: number, m31?: number, m32?: number){ - this.m11 = m11 ? m11 : 1; - this.m12 = m12 ? m12 : 0; - - this.m21 = m21 ? m21 : 0; - this.m22 = m22 ? m22 : 1; - - this.m31 = m31 ? m31 : 0; - this.m32 = m32 ? m32 : 0; - } - - /** 存储在这个矩阵中的位置 */ - public get translation(){ - return new Vector2(this.m31, this.m32); - } - - public set translation(value: Vector2){ - this.m31 = value.x; - this.m32 = value.y; - } - - /** 以弧度表示的旋转存储在这个矩阵中 */ - public get rotation(){ - return Math.atan2(this.m21, this.m11); - } - - public set rotation(value: number){ - let val1 = Math.cos(value); - let val2 = Math.sin(value); - - this.m11 = val1; - this.m12 = val2; - this.m21 = -val2; - this.m22 = val1; - } - - /** - * 以度为单位的旋转存储在这个矩阵中 - */ - public get rotationDegrees(){ - return MathHelper.toDegrees(this.rotation); - } - - public set rotationDegrees(value: number){ - this.rotation = MathHelper.toRadians(value); - } - - public get scale(){ - return new Vector2(this.m11, this.m22); - } - - public set scale(value: Vector2){ - this.m11 = value.x; - this.m12 = value.y; - } - - /** - * 创建一个新的matrix, 它包含两个矩阵的和。 - * @param matrix1 - * @param matrix2 - */ - public static add(matrix1: Matrix2D, matrix2: Matrix2D){ - matrix1.m11 += matrix2.m11; - matrix1.m12 += matrix2.m12; - - matrix1.m21 += matrix2.m21; - matrix1.m22 += matrix2.m22; - - matrix1.m31 += matrix2.m31; - matrix1.m32 += matrix2.m32; - - return matrix1; - } - - public static divide(matrix1: Matrix2D, matrix2: Matrix2D){ - matrix1.m11 /= matrix2.m11; - matrix1.m12 /= matrix2.m12; - - matrix1.m21 /= matrix2.m21; - matrix1.m22 /= matrix2.m22; - - matrix1.m31 /= matrix2.m31; - matrix1.m32 /= matrix2.m32; - - return matrix1; - } - - public static multiply(matrix1: Matrix2D, matrix2: Matrix2D){ - let result = new Matrix2D(); - - let m11 = ( matrix1.m11 * matrix2.m11 ) + ( matrix1.m12 * matrix2.m21 ); - let m12 = ( matrix1.m11 * matrix2.m12 ) + ( matrix1.m12 * matrix2.m22 ); - - let m21 = ( matrix1.m21 * matrix2.m11 ) + ( matrix1.m22 * matrix2.m21 ); - let m22 = ( matrix1.m21 * matrix2.m12 ) + ( matrix1.m22 * matrix2.m22 ); - - let m31 = ( matrix1.m31 * matrix2.m11 ) + ( matrix1.m32 * matrix2.m21 ) + matrix2.m31; - let m32 = ( matrix1.m31 * matrix2.m12 ) + ( matrix1.m32 * matrix2.m22 ) + matrix2.m32; - - result.m11 = m11; - result.m12 = m12; - - result.m21 = m21; - result.m22 = m22; - - result.m31 = m31; - result.m32 = m32; - - return result; - } - - public static multiplyTranslation(matrix: Matrix2D, x: number, y: number){ - let trans = Matrix2D.createTranslation(x, y); - return Matrix2D.multiply(matrix, trans); - } - - public determinant(){ - return this.m11 * this.m22 - this.m12 * this.m21; - } - - public static invert(matrix: Matrix2D, result: Matrix2D = new Matrix2D()){ - let det = 1 / matrix.determinant(); - - result.m11 = matrix.m22 * det; - result.m12 = -matrix.m12 * det; - - result.m21 = -matrix.m21 * det; - result.m22 = matrix.m11 * det; - - result.m31 = (matrix.m32 * matrix.m21 - matrix.m31 * matrix.m22) * det; - result.m32 = -(matrix.m32 * matrix.m11 - matrix.m31 * matrix.m12) * det; - - return result; - } - - /** - * 创建一个新的tranlation - * @param xPosition - * @param yPosition - */ - public static createTranslation(xPosition: number, yPosition: number){ - let result = new Matrix2D(); - - result.m11 = 1; - result.m12 = 0; - - result.m21 = 0; - result.m22 = 1; - - result.m31 = xPosition; - result.m32 = yPosition; - - return result; - } - - /** - * 根据position 创建一个translation - * @param position - */ - public static createTranslationVector(position: Vector2){ - return this.createTranslation(position.x, position.y); - } - - public static createRotation(radians: number, result?: Matrix2D){ - result = new Matrix2D(); - - let val1 = Math.cos(radians); - let val2 = Math.sin(radians); - - result.m11 = val1; - result.m12 = val2; - result.m21 = -val2; - result.m22 = val1; - - return result; - } - - public static createScale(xScale: number, yScale: number, result: Matrix2D = new Matrix2D()){ - result.m11 = xScale; - result.m12 = 0; - - result.m21 = 0; - result.m22 = yScale; - - result.m31 = 0; - result.m32 = 0; - - return result; - } - - public toEgretMatrix(): egret.Matrix{ - let matrix = new egret.Matrix(this.m11, this.m12, this.m21, this.m22, this.m31, this.m32); - return matrix; - } -} \ No newline at end of file +} diff --git a/source/src/Math/Rectangle.ts b/source/src/Math/Rectangle.ts index e83be97e..6cab79b3 100644 --- a/source/src/Math/Rectangle.ts +++ b/source/src/Math/Rectangle.ts @@ -1,174 +1,262 @@ -class Rectangle extends egret.Rectangle { - /** - * 获取矩形的最大点,即右下角 - */ - public get max() { - return new Vector2(this.right, this.bottom); - } +module es { + export class Rectangle extends egret.Rectangle { + public _tempMat: Matrix2D; + public _transformMat: Matrix2D; - /** 中心点坐标 */ - public get center() { - return new Vector2(this.x + (this.width / 2), this.y + (this.height / 2)); - } + /** + * 获取矩形的最大点,即右下角 + */ + public get max() { + return new Vector2(this.right, this.bottom); + } - /** 左上角的坐标 */ - public get location() { - return new Vector2(this.x, this.y); - } - /** 左上角的坐标 */ - public set location(value: Vector2) { - this.x = value.x; - this.y = value.y; - } + /** 中心点坐标 */ + public get center() { + return new Vector2(this.x + (this.width / 2), this.y + (this.height / 2)); + } - public get size() { - return new Vector2(this.width, this.height); - } + /** 左上角的坐标 */ + public get location() { + return new Vector2(this.x, this.y); + } - public set size(value: Vector2) { - this.width = value.x; - this.height = value.y; - } + /** 左上角的坐标 */ + public set location(value: Vector2) { + this.x = value.x; + this.y = value.y; + } - /** - * 是否与另一个矩形相交 - * @param value - */ - public intersects(value: egret.Rectangle) { - return value.left < this.right && - this.left < value.right && - value.top < this.bottom && - this.top < value.bottom; - } + public get size() { + return new Vector2(this.width, this.height); + } - /** - * 判断点是否在矩形内 - * @param value - */ - public containsInVec(value: Vector2) { - return ((((this.x <= value.x) && (value.x < (this.x + this.width))) && - (this.y <= value.y)) && - (value.y < (this.y + this.height))); - } + public set size(value: Vector2) { + this.width = value.x; + this.height = value.y; + } - /** - * 获取所提供的矩形是否在此矩形的边界内 - * @param value - */ - public containsRect(value: Rectangle) { - return ((((this.x <= value.x) && (value.x < (this.x + this.width))) && - (this.y <= value.y)) && - (value.y < (this.y + this.height))); - } + /** + * 创建一个矩形的最小/最大点(左上角,右下角的点) + * @param minX + * @param minY + * @param maxX + * @param maxY + */ + public static fromMinMax(minX: number, minY: number, maxX: number, maxY: number) { + return new Rectangle(minX, minY, maxX - minX, maxY - minY); + } - public getHalfSize() { - return new Vector2(this.width * 0.5, this.height * 0.5); - } + /** + * 给定多边形的点,计算边界 + * @param points + */ + public static rectEncompassingPoints(points: Vector2[]) { + // 我们需要求出x/y的最小值/最大值 + let minX = Number.POSITIVE_INFINITY; + let minY = Number.POSITIVE_INFINITY; + let maxX = Number.NEGATIVE_INFINITY; + let maxY = Number.NEGATIVE_INFINITY; - /** - * 创建一个矩形的最小/最大点(左上角,右下角的点) - * @param minX - * @param minY - * @param maxX - * @param maxY - */ - public static fromMinMax(minX: number, minY: number, maxX: number, maxY: number) { - return new Rectangle(minX, minY, maxX - minX, maxY - minY); - } + for (let i = 0; i < points.length; i++) { + let pt = points[i]; - /** - * 获取矩形边界上与给定点最近的点 - * @param point - */ - public getClosestPointOnRectangleBorderToPoint(point: Vector2): { res: Vector2, edgeNormal: Vector2 } { - let edgeNormal = Vector2.zero; + if (pt.x < minX) minX = pt.x; + if (pt.x > maxX) maxX = pt.x; - // 对于每个轴,如果点在盒子外面 - let res = new Vector2(); - res.x = MathHelper.clamp(point.x, this.left, this.right); - res.y = MathHelper.clamp(point.y, this.top, this.bottom); - - // 如果点在矩形内,我们需要推res到边界,因为它将在矩形内 - if (this.containsInVec(res)) { - let dl = res.x - this.left; - let dr = this.right - res.x; - let dt = res.y - this.top; - let db = this.bottom - res.y; - - let min = Math.min(dl, dr, dt, db); - if (min == dt) { - res.y = this.top; - edgeNormal.y = -1; - } else if (min == db) { - res.y = this.bottom; - edgeNormal.y = 1; - } else if (min == dl) { - res.x = this.left; - edgeNormal.x = -1; - } else { - res.x = this.right; - edgeNormal.x = 1; + if (pt.y < minY) minY = pt.y; + if (pt.y > maxY) maxY = pt.y; } - } else { - if (res.x == this.left) edgeNormal.x = -1; - if (res.x == this.right) edgeNormal.x = 1; - if (res.y == this.top) edgeNormal.y = -1; - if (res.y == this.bottom) edgeNormal.y = 1; + + return this.fromMinMax(minX, minY, maxX, maxY); } - return { res: res, edgeNormal: edgeNormal }; + /** + * 如果其他相交矩形返回true + * @param value + */ + public intersects(value: egret.Rectangle) { + return value.left < this.right && + this.left < value.right && + value.top < this.bottom && + this.top < value.bottom; + } + + public rayIntersects(ray: Ray2D): number{ + let distance = 0; + let maxValue = Number.MAX_VALUE; + + if (Math.abs(ray.direction.x) < 1E-06){ + if ((ray.start.x < this.x) || (ray.start.x > this.x + this.width)) + return distance; + }else{ + let num11 = 1 / ray.direction.x; + let num8 = (this.x - ray.start.x) * num11; + let num7 = (this.x + this.width - ray.start.x) * num11; + if (num8 > num7){ + let num14 = num8; + num8 = num7; + num7 = num14; + } + + distance = Math.max(num8, distance); + maxValue = Math.min(num7, maxValue); + if (distance > maxValue) + return distance; + } + + if (Math.abs(ray.direction.y) < 1E-06){ + if ((ray.start.y < this.y) || (ray.start.y > this.y + this.height)) + return distance; + }else{ + let num10 = 1 / ray.direction.y; + let num6 = (this.y - ray.start.y) * num10; + let num5 = (this.y + this.height - ray.start.y) * num10; + if (num6 > num5){ + let num13 = num6; + num6 = num5; + num5 = num13; + } + + distance = Math.max(num6, distance); + maxValue = Math.max(num5, maxValue); + if (distance > maxValue) + return distance; + } + + return distance; + } + + /** + * 获取所提供的矩形是否在此矩形的边界内 + * @param value + */ + public containsRect(value: Rectangle) { + return ((((this.x <= value.x) && (value.x < (this.x + this.width))) && + (this.y <= value.y)) && + (value.y < (this.y + this.height))); + } + + public contains(x: number, y: number): boolean{ + return ((((this.x <= x) && (x < (this.x + this.width))) && (this.y <= y)) && (y < (this.y + this.height))); + } + + public getHalfSize() { + return new Vector2(this.width * 0.5, this.height * 0.5); + } + + /** + * 获取矩形边界上与给定点最近的点 + * @param point + * @param edgeNormal + */ + public getClosestPointOnRectangleBorderToPoint(point: Vector2, edgeNormal: Vector2): Vector2 { + edgeNormal = Vector2.zero; + + // 对于每个轴,如果点在盒子外面 + let res = new Vector2(); + res.x = MathHelper.clamp(point.x, this.left, this.right); + res.y = MathHelper.clamp(point.y, this.top, this.bottom); + + // 如果点在矩形内,我们需要推res到边界,因为它将在矩形内 + if (this.contains(res.x, res.y)) { + let dl = res.x - this.left; + let dr = this.right - res.x; + let dt = res.y - this.top; + let db = this.bottom - res.y; + + let min = Math.min(dl, dr, dt, db); + if (min == dt) { + res.y = this.top; + edgeNormal.y = -1; + } else if (min == db) { + res.y = this.bottom; + edgeNormal.y = 1; + } else if (min == dl) { + res.x = this.left; + edgeNormal.x = -1; + } else { + res.x = this.right; + edgeNormal.x = 1; + } + } else { + if (res.x == this.left) edgeNormal.x = -1; + if (res.x == this.right) edgeNormal.x = 1; + if (res.y == this.top) edgeNormal.y = -1; + if (res.y == this.bottom) edgeNormal.y = 1; + } + + return res; + } + + /** + * + */ + public getClosestPointOnBoundsToOrigin() { + let max = this.max; + let minDist = Math.abs(this.location.x); + let boundsPoint = new Vector2(this.location.x, 0); + + if (Math.abs(max.x) < minDist) { + minDist = Math.abs(max.x); + boundsPoint.x = max.x; + boundsPoint.y = 0; + } + + if (Math.abs(max.y) < minDist) { + minDist = Math.abs(max.y); + boundsPoint.x = 0; + boundsPoint.y = max.y; + } + + if (Math.abs(this.location.y) < minDist) { + minDist = Math.abs(this.location.y); + boundsPoint.x = 0; + boundsPoint.y = this.location.y; + } + + return boundsPoint; + } + + public calculateBounds(parentPosition: Vector2, position: Vector2, origin: Vector2, scale: Vector2, rotation: number, width: number, height: number) { + if (rotation == 0) { + this.x = parentPosition.x + position.x - origin.x * scale.x; + this.y = parentPosition.y + position.y - origin.y * scale.y; + this.width = width * scale.x; + this.height = height * scale.y; + } else { + // 特别注意旋转的边界。我们需要找到绝对的最小/最大值并从中创建边界 + let worldPosX = parentPosition.x + position.x; + let worldPosY = parentPosition.y + position.y; + + // 将参考点设置为世界参考 + this._transformMat = Matrix2D.create().translate(-worldPosX - origin.x, -worldPosY - origin.y); + this._tempMat = Matrix2D.create().scale(scale.x, scale.y); + this._transformMat = this._transformMat.multiply(this._tempMat); + this._tempMat = Matrix2D.create().rotate(rotation); + this._transformMat = this._transformMat.multiply(this._tempMat); + this._tempMat = Matrix2D.create().translate(worldPosX, worldPosY); + this._transformMat = this._transformMat.multiply(this._tempMat); + + // TODO: 这有点傻。我们可以把世界变换留在矩阵中,避免在世界空间中得到所有的四个角 + let topLeft = new Vector2(worldPosX, worldPosY); + let topRight = new Vector2(worldPosX + width, worldPosY); + let bottomLeft = new Vector2(worldPosX, worldPosY + height); + let bottomRight = new Vector2(worldPosX + width, worldPosY + height); + + topLeft = Vector2Ext.transformR(topLeft, this._transformMat); + topRight = Vector2Ext.transformR(topRight, this._transformMat); + bottomLeft = Vector2Ext.transformR(bottomLeft, this._transformMat); + bottomRight = Vector2Ext.transformR(bottomRight, this._transformMat); + + let minX = Math.min(topLeft.x, bottomRight.x, topRight.x, bottomLeft.x); + let maxX = Math.max(topLeft.x, bottomRight.x, topRight.x, bottomLeft.x); + let minY = Math.min(topLeft.y, bottomRight.y, topRight.y, bottomLeft.y); + let maxY = Math.max(topLeft.y, bottomRight.y, topRight.y, bottomLeft.y); + + this.location = new Vector2(minX, minY); + this.width = maxX - minX; + this.height = maxY - minY; + } + } } - - /** - * - */ - public getClosestPointOnBoundsToOrigin() { - let max = this.max; - let minDist = Math.abs(this.location.x); - let boundsPoint = new Vector2(this.location.x, 0); - - if (Math.abs(max.x) < minDist) { - minDist = Math.abs(max.x); - boundsPoint.x = max.x; - boundsPoint.y = 0; - } - - if (Math.abs(max.y) < minDist) { - minDist = Math.abs(max.y); - boundsPoint.x = 0; - boundsPoint.y = max.y; - } - - if (Math.abs(this.location.y) < minDist) { - minDist = Math.abs(this.location.y); - boundsPoint.x = 0; - boundsPoint.y = this.location.y; - } - - return boundsPoint; - } - - /** - * 给定多边形的点,计算边界 - * @param points - */ - public static rectEncompassingPoints(points: Vector2[]) { - // 我们需要求出x/y的最小值/最大值 - let minX = Number.POSITIVE_INFINITY; - let minY = Number.POSITIVE_INFINITY; - let maxX = Number.NEGATIVE_INFINITY; - let maxY = Number.NEGATIVE_INFINITY; - - for (let i = 0; i < points.length; i++) { - let pt = points[i]; - - if (pt.x < minX) minX = pt.x; - if (pt.x > maxX) maxX = pt.x; - - if (pt.y < minY) minY = pt.y; - if (pt.y > maxY) maxY = pt.y; - } - - return this.fromMinMax(minX, minY, maxX, maxY); - } -} \ No newline at end of file +} diff --git a/source/src/Math/Vector2.ts b/source/src/Math/Vector2.ts index 9529ac41..777f359b 100644 --- a/source/src/Math/Vector2.ts +++ b/source/src/Math/Vector2.ts @@ -1,183 +1,238 @@ -/** 2d 向量 */ -class Vector2 { - public x: number = 0; - public y: number = 0; +module es { + /** 2d 向量 */ + export class Vector2 { + private static readonly unitYVector = new Vector2(0, 1); + private static readonly unitXVector = new Vector2(1, 0); + private static readonly unitVector2 = new Vector2(1, 1); + private static readonly zeroVector2 = new Vector2(0, 0); + public x: number = 0; + public y: number = 0; - private static readonly unitYVector = new Vector2(0, 1); - private static readonly unitXVector = new Vector2(1, 0); - private static readonly unitVector2 = new Vector2(1, 1); - private static readonly zeroVector2 = new Vector2(0, 0); - public static get zero(){ - return Vector2.zeroVector2; + /** + * 从两个值构造一个带有X和Y的二维向量。 + * @param x 二维空间中的x坐标 + * @param y 二维空间的y坐标 + */ + constructor(x?: number, y?: number) { + this.x = x ? x : 0; + this.y = y != undefined ? y : this.x; + } + + public static get zero() { + return Vector2.zeroVector2; + } + + public static get one() { + return Vector2.unitVector2; + } + + public static get unitX() { + return Vector2.unitXVector; + } + + public static get unitY() { + return Vector2.unitYVector; + } + + /** + * + * @param value1 + * @param value2 + */ + public static add(value1: Vector2, value2: Vector2) { + let result: Vector2 = new Vector2(0, 0); + result.x = value1.x + value2.x; + result.y = value1.y + value2.y; + return result; + } + + /** + * + * @param value1 + * @param value2 + */ + public static divide(value1: Vector2, value2: Vector2) { + let result: Vector2 = new Vector2(0, 0); + result.x = value1.x / value2.x; + result.y = value1.y / value2.y; + return result; + } + + /** + * + * @param value1 + * @param value2 + */ + public static multiply(value1: Vector2, value2: Vector2) { + let result: Vector2 = new Vector2(0, 0); + result.x = value1.x * value2.x; + result.y = value1.y * value2.y; + return result; + } + + /** + * + * @param value1 + * @param value2 + */ + public static subtract(value1: Vector2, value2: Vector2) { + let result: Vector2 = new Vector2(0, 0); + result.x = value1.x - value2.x; + result.y = value1.y - value2.y; + return result; + } + + /** + * 创建一个新的Vector2 + * 它包含来自另一个向量的标准化值。 + * @param value + */ + public static normalize(value: Vector2) { + let val = 1 / Math.sqrt((value.x * value.x) + (value.y * value.y)); + value.x *= val; + value.y *= val; + return value; + } + + /** + * 返回两个向量的点积 + * @param value1 + * @param value2 + */ + public static dot(value1: Vector2, value2: Vector2): number { + return (value1.x * value2.x) + (value1.y * value2.y); + } + + /** + * 返回两个向量之间距离的平方 + * @param value1 + * @param value2 + */ + public static distanceSquared(value1: Vector2, value2: Vector2) { + let v1 = value1.x - value2.x, v2 = value1.y - value2.y; + return (v1 * v1) + (v2 * v2); + } + + /** + * + * @param value1 + * @param min + * @param max + */ + public static clamp(value1: Vector2, min: Vector2, max: Vector2) { + return new Vector2(MathHelper.clamp(value1.x, min.x, max.x), + MathHelper.clamp(value1.y, min.y, max.y)); + } + + /** + * 包含指定向量的线性插值 + * @param value1 第一个向量 + * @param value2 第二个向量 + * @param amount 权重值(0.0到1.0之间) + */ + public static lerp(value1: Vector2, value2: Vector2, amount: number) { + return new Vector2(MathHelper.lerp(value1.x, value2.x, amount), MathHelper.lerp(value1.y, value2.y, amount)); + } + + /** + * + * @param position + * @param matrix + */ + public static transform(position: Vector2, matrix: Matrix2D) { + return new Vector2((position.x * matrix.m11) + (position.y * matrix.m21) + matrix.m31, + (position.x * matrix.m12) + (position.y * matrix.m22) + matrix.m32); + } + + /** + * 返回两个向量之间的距离 + * @param value1 + * @param value2 + */ + public static distance(value1: Vector2, value2: Vector2) { + let v1 = value1.x - value2.x, v2 = value1.y - value2.y; + return Math.sqrt((v1 * v1) + (v2 * v2)); + } + + /** + * 矢量反演的结果 + * @param value + */ + public static negate(value: Vector2) { + let result: Vector2 = new Vector2(); + result.x = -value.x; + result.y = -value.y; + + return result; + } + + /** + * + * @param value + */ + public add(value: Vector2): Vector2 { + this.x += value.x; + this.y += value.y; + return this; + } + + /** + * + * @param value + */ + public divide(value: Vector2): Vector2 { + this.x /= value.x; + this.y /= value.y; + return this; + } + + /** + * + * @param value + */ + public multiply(value: Vector2): Vector2 { + this.x *= value.x; + this.y *= value.y; + return this; + } + + /** + * + * @param value + */ + public subtract(value: Vector2) { + this.x -= value.x; + this.y -= value.y; + return this; + } + + /** 变成一个方向相同的单位向量 */ + public normalize() { + let val = 1 / Math.sqrt((this.x * this.x) + (this.y * this.y)); + this.x *= val; + this.y *= val; + return this; + } + + /** 返回它的长度 */ + public length() { + return Math.sqrt((this.x * this.x) + (this.y * this.y)); + } + + /** + * 返回其长度的平方 + */ + public lengthSquared(): number { + return (this.x * this.x) + (this.y * this.y); + } + + /** 对x和y值四舍五入 */ + public round(): Vector2 { + return new Vector2(Math.round(this.x), Math.round(this.y)); + } + + public equals(other: Vector2) { + return other.x == this.x && other.y == this.y; + } } - - public static get one(){ - return Vector2.unitVector2; - } - - public static get unitX(){ - return Vector2.unitXVector; - } - - public static get unitY(){ - return Vector2.unitYVector; - } - - /** - * 从两个值构造一个带有X和Y的二维向量。 - * @param x 二维空间中的x坐标 - * @param y 二维空间的y坐标 - */ - constructor(x? : number, y?: number){ - this.x = x ? x : 0; - this.y = y ? y : this.x; - } - - /** - * - * @param value1 - * @param value2 - */ - public static add(value1: Vector2, value2: Vector2){ - let result: Vector2 = new Vector2(0, 0); - result.x = value1.x + value2.x; - result.y = value1.y + value2.y; - return result; - } - - /** - * - * @param value1 - * @param value2 - */ - public static divide(value1: Vector2, value2: Vector2){ - let result: Vector2 = new Vector2(0, 0); - result.x = value1.x / value2.x; - result.y = value1.y / value2.y; - return result; - } - - /** - * - * @param value1 - * @param value2 - */ - public static multiply(value1: Vector2, value2: Vector2){ - let result: Vector2 = new Vector2(0, 0); - result.x = value1.x * value2.x; - result.y = value1.y * value2.y; - return result; - } - - /** - * - * @param value1 - * @param value2 - */ - public static subtract(value1: Vector2, value2: Vector2){ - let result: Vector2 = new Vector2(0, 0); - result.x = value1.x - value2.x; - result.y = value1.y - value2.y; - return result; - } - - /** 变成一个方向相同的单位向量 */ - public normalize(){ - let val = 1 / Math.sqrt((this.x * this.x) + (this.y * this.y)); - this.x *= val; - this.y *= val; - } - - /** 返回它的长度 */ - public length(){ - return Math.sqrt((this.x * this.x) + (this.y * this.y)); - } - - /** 对x和y值四舍五入 */ - public round(): Vector2{ - return new Vector2(Math.round(this.x), Math.round(this.y)); - } - - /** - * 创建一个新的Vector2 - * 它包含来自另一个向量的标准化值。 - * @param value - */ - public static normalize(value: Vector2){ - let val = 1 / Math.sqrt((value.x * value.x) + (value.y * value.y)); - value.x *= val; - value.y *= val; - return value; - } - - /** - * 返回两个向量的点积 - * @param value1 - * @param value2 - */ - public static dot(value1: Vector2, value2: Vector2): number{ - return (value1.x * value2.x) + (value1.y * value2.y); - } - - /** - * 返回两个向量之间距离的平方 - * @param value1 - * @param value2 - */ - public static distanceSquared(value1: Vector2, value2: Vector2){ - let v1 = value1.x - value2.x, v2 = value1.y - value2.y; - return (v1 * v1) + (v2 * v2); - } - - /** - * - * @param value1 - * @param min - * @param max - */ - public static clamp(value1: Vector2, min: Vector2, max: Vector2){ - return new Vector2(MathHelper.clamp(value1.x, min.x, max.x), - MathHelper.clamp(value1.y, min.y, max.y)); - } - - /** - * 包含指定向量的线性插值 - * @param value1 第一个向量 - * @param value2 第二个向量 - * @param amount 权重值(0.0到1.0之间) - */ - public static lerp(value1: Vector2, value2: Vector2, amount: number){ - return new Vector2(MathHelper.lerp(value1.x, value2.x, amount), MathHelper.lerp(value1.y, value2.y, amount)); - } - - /** - * - * @param position - * @param matrix - */ - public static transform(position: Vector2, matrix: Matrix2D){ - return new Vector2((position.x * matrix.m11) + (position.y * matrix.m21), (position.x * matrix.m12) + (position.y * matrix.m22)); - } - - /** - * 返回两个向量之间的距离 - * @param value1 - * @param value2 - */ - public static distance(value1: Vector2, value2: Vector2){ - let v1 = value1.x - value2.x, v2 = value1.y - value2.y; - return Math.sqrt((v1 * v1) + (v2 * v2)); - } - - /** - * 矢量反演的结果 - * @param value - */ - public static negate(value: Vector2){ - let result: Vector2 = new Vector2(); - result.x = -value.x; - result.y = -value.y; - - return result; - } -} \ No newline at end of file +} diff --git a/source/src/Math/Vector3.ts b/source/src/Math/Vector3.ts index 7ef18989..c22878d2 100644 --- a/source/src/Math/Vector3.ts +++ b/source/src/Math/Vector3.ts @@ -1,11 +1,13 @@ -class Vector3 { - public x: number; - public y: number; - public z: number; +module es { + export class Vector3 { + public x: number; + public y: number; + public z: number; - constructor(x: number, y: number, z: number){ - this.x = x; - this.y = y; - this.z = z; + constructor(x: number, y: number, z: number) { + this.x = x; + this.y = y; + this.z = z; + } } -} \ No newline at end of file +} diff --git a/source/src/Physics/ColliderTriggerHelper.ts b/source/src/Physics/ColliderTriggerHelper.ts index 303c678d..4dd0c985 100644 --- a/source/src/Physics/ColliderTriggerHelper.ts +++ b/source/src/Physics/ColliderTriggerHelper.ts @@ -1,101 +1,103 @@ -/** 移动器使用的帮助器类,用于管理触发器碰撞器交互并调用itriggerlistener。 */ -class ColliderTriggerHelper { - private _entity: Entity; - /** 存储当前帧中发生的所有活动交集对 */ - private _activeTriggerIntersections: Pair[] = []; - /** 存储前一帧的交叉对,以便我们可以在移动该帧后检测出口 */ - private _previousTriggerIntersections: Pair[] = []; - private _tempTriggerList: ITriggerListener[] = []; - - constructor(entity: Entity) { - this._entity = entity; - } - +module es { /** - * 实体被移动后,应该调用更新。它会处理碰撞器重叠的任何itriggerlistener。 + * 移动器使用的帮助器类,用于管理触发器碰撞器交互并调用itriggerlistener */ - public update() { - let colliders = this._entity.getComponents(Collider); - for (let i = 0; i < colliders.length; i++) { - let collider = colliders[i]; + export class ColliderTriggerHelper { + private _entity: Entity; + /** 存储当前帧中发生的所有活动交集对 */ + private _activeTriggerIntersections: Pair[] = []; + /** 存储前一帧的交叉对,以便我们可以在移动该帧后检测出口 */ + private _previousTriggerIntersections: Pair[] = []; + private _tempTriggerList: ITriggerListener[] = []; - let boxcastResult = Physics.boxcastBroadphase(collider.bounds, collider.collidesWithLayers); - collider.bounds = boxcastResult.rect; - let neighbors = boxcastResult.colliders; - for (let j = 0; j < neighbors.length; j++) { - let neighbor = neighbors[j]; - if (!collider.isTrigger && !neighbor.isTrigger) - continue; + constructor(entity: Entity) { + this._entity = entity; + } - if (collider.overlaps(neighbor)) { - let pair = new Pair(collider, neighbor); - let shouldReportTriggerEvent = this._activeTriggerIntersections.findIndex(value => { - return value.first == pair.first && value.second == pair.second; - }) == -1 && this._previousTriggerIntersections.findIndex(value => { - return value.first == pair.first && value.second == pair.second; - }) == -1; + /** + * 实体被移动后,应该调用更新。它会处理碰撞器重叠的任何itriggerlistener。 + */ + public update() { + let colliders = this._entity.getComponents(Collider); + for (let i = 0; i < colliders.length; i++) { + let collider = colliders[i]; - if (shouldReportTriggerEvent) - this.notifyTriggerListeners(pair, true); + let neighbors = Physics.boxcastBroadphase(collider.bounds, collider.collidesWithLayers); + for (let j = 0; j < neighbors.length; j++) { + let neighbor = neighbors[j]; + if (!collider.isTrigger && !neighbor.isTrigger) + continue; - if (!this._activeTriggerIntersections.contains(pair)) - this._activeTriggerIntersections.push(pair); + if (collider.overlaps(neighbor)) { + let pair = new Pair(collider, neighbor); + let shouldReportTriggerEvent = this._activeTriggerIntersections.findIndex(value => { + return value.first == pair.first && value.second == pair.second; + }) == -1 && this._previousTriggerIntersections.findIndex(value => { + return value.first == pair.first && value.second == pair.second; + }) == -1; + + if (shouldReportTriggerEvent) + this.notifyTriggerListeners(pair, true); + + if (!this._activeTriggerIntersections.contains(pair)) + this._activeTriggerIntersections.push(pair); + } } } + + ListPool.free(colliders); + + this.checkForExitedColliders(); } - ListPool.free(colliders); + private checkForExitedColliders() { + for (let i = 0; i < this._activeTriggerIntersections.length; i++) { + let index = this._previousTriggerIntersections.findIndex(value => { + if (value.first == this._activeTriggerIntersections[i].first && value.second == this._activeTriggerIntersections[i].second) + return true; - this.checkForExitedColliders(); - } - - private checkForExitedColliders(){ - for (let i = 0; i < this._activeTriggerIntersections.length; i ++){ - let index = this._previousTriggerIntersections.findIndex(value => { - if (value.first == this._activeTriggerIntersections[i].first && value.second == this._activeTriggerIntersections[i].second) - return true; - - return false; - }); - if (index != -1) - this._previousTriggerIntersections.removeAt(index); - } - - for (let i = 0; i < this._previousTriggerIntersections.length; i ++){ - this.notifyTriggerListeners(this._previousTriggerIntersections[i], false) - } - this._previousTriggerIntersections.length = 0; - for (let i = 0; i < this._activeTriggerIntersections.length; i ++){ - if (!this._previousTriggerIntersections.contains(this._activeTriggerIntersections[i])){ - this._previousTriggerIntersections.push(this._activeTriggerIntersections[i]); - } - } - this._activeTriggerIntersections.length = 0; - } - - private notifyTriggerListeners(collisionPair: Pair, isEntering: boolean) { - collisionPair.first.entity.getComponents("ITriggerListener", this._tempTriggerList); - for (let i = 0; i < this._tempTriggerList.length; i ++){ - if (isEntering){ - this._tempTriggerList[i].onTriggerEnter(collisionPair.second, collisionPair.first); - } else { - this._tempTriggerList[i].onTriggerExit(collisionPair.second, collisionPair.first); + return false; + }); + if (index != -1) + this._previousTriggerIntersections.removeAt(index); } - this._tempTriggerList.length = 0; + for (let i = 0; i < this._previousTriggerIntersections.length; i++) { + this.notifyTriggerListeners(this._previousTriggerIntersections[i], false) + } + this._previousTriggerIntersections.length = 0; + for (let i = 0; i < this._activeTriggerIntersections.length; i++) { + if (!this._previousTriggerIntersections.contains(this._activeTriggerIntersections[i])) { + this._previousTriggerIntersections.push(this._activeTriggerIntersections[i]); + } + } + this._activeTriggerIntersections.length = 0; + } - if (collisionPair.second.entity){ - collisionPair.second.entity.getComponents("ITriggerListener", this._tempTriggerList); - for (let i = 0; i < this._tempTriggerList.length; i ++){ - if (isEntering){ - this._tempTriggerList[i].onTriggerEnter(collisionPair.first, collisionPair.second); - } else { - this._tempTriggerList[i].onTriggerExit(collisionPair.first, collisionPair.second); - } + private notifyTriggerListeners(collisionPair: Pair, isEntering: boolean) { + collisionPair.first.entity.getComponents("ITriggerListener", this._tempTriggerList); + for (let i = 0; i < this._tempTriggerList.length; i++) { + if (isEntering) { + this._tempTriggerList[i].onTriggerEnter(collisionPair.second, collisionPair.first); + } else { + this._tempTriggerList[i].onTriggerExit(collisionPair.second, collisionPair.first); } this._tempTriggerList.length = 0; + + if (collisionPair.second.entity) { + collisionPair.second.entity.getComponents("ITriggerListener", this._tempTriggerList); + for (let i = 0; i < this._tempTriggerList.length; i++) { + if (isEntering) { + this._tempTriggerList[i].onTriggerEnter(collisionPair.first, collisionPair.second); + } else { + this._tempTriggerList[i].onTriggerExit(collisionPair.first, collisionPair.second); + } + } + + this._tempTriggerList.length = 0; + } } } } -} \ No newline at end of file +} diff --git a/source/src/Physics/Collision.ts b/source/src/Physics/Collision.ts index 4b153203..dc82e398 100644 --- a/source/src/Physics/Collision.ts +++ b/source/src/Physics/Collision.ts @@ -1,168 +1,170 @@ -enum PointSectors { - center = 0, - top = 1, - bottom = 2, - topLeft = 9, - topRight = 5, - left = 8, - right = 4, - bottomLeft = 10, - bottomRight = 6 -} - -class Collisions { - public static isLineToLine(a1: Vector2, a2: Vector2, b1: Vector2, b2: Vector2): boolean { - let b = Vector2.subtract(a2, a1); - let d = Vector2.subtract(b2, b1); - let bDotDPerp = b.x * d.y - b.y * d.x; - - // 如果b*d = 0,表示这两条直线平行,因此有无穷个交点 - if (bDotDPerp == 0) - return false; - - let c = Vector2.subtract(b1, a1); - let t = (c.x * d.y - c.y * d.x) / bDotDPerp; - if (t < 0 || t > 1) - return false; - - let u = (c.x * b.y - c.y * b.x) / bDotDPerp; - if (u < 0 || u > 1) - return false; - - return true; +module es { + export enum PointSectors { + center = 0, + top = 1, + bottom = 2, + topLeft = 9, + topRight = 5, + left = 8, + right = 4, + bottomLeft = 10, + bottomRight = 6 } - public static lineToLineIntersection(a1: Vector2, a2: Vector2, b1: Vector2, b2: Vector2): Vector2 { - let intersection = new Vector2(0, 0); + export class Collisions { + public static isLineToLine(a1: Vector2, a2: Vector2, b1: Vector2, b2: Vector2): boolean { + let b = Vector2.subtract(a2, a1); + let d = Vector2.subtract(b2, b1); + let bDotDPerp = b.x * d.y - b.y * d.x; - let b = Vector2.subtract(a2, a1); - let d = Vector2.subtract(b2, b1); - let bDotDPerp = b.x * d.y - b.y * d.x; + // 如果b*d = 0,表示这两条直线平行,因此有无穷个交点 + if (bDotDPerp == 0) + return false; - // 如果b*d = 0,表示这两条直线平行,因此有无穷个交点 - if (bDotDPerp == 0) - return intersection; + let c = Vector2.subtract(b1, a1); + let t = (c.x * d.y - c.y * d.x) / bDotDPerp; + if (t < 0 || t > 1) + return false; - let c = Vector2.subtract(b1, a1); - let t = (c.x * d.y - c.y * d.x) / bDotDPerp; - if (t < 0 || t > 1) - return intersection; + let u = (c.x * b.y - c.y * b.x) / bDotDPerp; + if (u < 0 || u > 1) + return false; - let u = (c.x * b.y - c.y * b.x) / bDotDPerp; - if (u < 0 || u > 1) - return intersection; - - intersection = Vector2.add(a1, new Vector2(t * b.x, t * b.y)); - - return intersection; - } - - public static closestPointOnLine(lineA: Vector2, lineB: Vector2, closestTo: Vector2) { - let v = Vector2.subtract(lineB, lineA); - let w = Vector2.subtract(closestTo, lineA); - let t = Vector2.dot(w, v) / Vector2.dot(v, v); - t = MathHelper.clamp(t, 0, 1); - - return Vector2.add(lineA, new Vector2(v.x * t, v.y * t)); - } - - public static isCircleToCircle(circleCenter1: Vector2, circleRadius1: number, circleCenter2: Vector2, circleRadius2: number): boolean { - return Vector2.distanceSquared(circleCenter1, circleCenter2) < (circleRadius1 + circleRadius2) * (circleRadius1 + circleRadius2); - } - - public static isCircleToLine(circleCenter: Vector2, radius: number, lineFrom: Vector2, lineTo: Vector2): boolean { - return Vector2.distanceSquared(circleCenter, this.closestPointOnLine(lineFrom, lineTo, circleCenter)) < radius * radius; - } - - public static isCircleToPoint(circleCenter: Vector2, radius: number, point: Vector2): boolean { - return Vector2.distanceSquared(circleCenter, point) < radius * radius; - } - - public static isRectToCircle(rect: Rectangle, cPosition: Vector2, cRadius: number): boolean { - let ew = rect.width * 0.5; - let eh = rect.height * 0.5; - let vx = Math.max(0, Math.max(cPosition.x - rect.x) - ew); - let vy = Math.max(0, Math.max(cPosition.y - rect.y) - eh); - - return vx * vx + vy * vy < cRadius * cRadius; - } - - public static isRectToLine(rect: Rectangle, lineFrom: Vector2, lineTo: Vector2){ - let fromSector = this.getSector(rect.x, rect.y, rect.width, rect.height, lineFrom); - let toSector = this.getSector(rect.x, rect.y, rect.width, rect.height, lineTo); - - if (fromSector == PointSectors.center || toSector == PointSectors.center){ return true; - } else if((fromSector & toSector) != 0){ - return false; - } else{ - let both = fromSector | toSector; - // 线对边进行检查 - let edgeFrom: Vector2; - let edgeTo: Vector2; - - if ((both & PointSectors.top) != 0){ - edgeFrom = new Vector2(rect.x, rect.y); - edgeTo = new Vector2(rect.x + rect.width, rect.y); - if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo)) - return true; - } - - if ((both & PointSectors.bottom) != 0){ - edgeFrom = new Vector2(rect.x, rect.y + rect.height); - edgeTo = new Vector2(rect.x + rect.width, rect.y + rect.height); - if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo)) - return true; - } - - if ((both & PointSectors.left) != 0){ - edgeFrom = new Vector2(rect.x, rect.y); - edgeTo = new Vector2(rect.x, rect.y + rect.height); - if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo)) - return true; - } - - if ((both & PointSectors.right) != 0){ - edgeFrom = new Vector2(rect.x + rect.width, rect.y); - edgeTo = new Vector2(rect.x + rect.width, rect.y + rect.height); - if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo)) - return true; - } } - return false; + public static lineToLineIntersection(a1: Vector2, a2: Vector2, b1: Vector2, b2: Vector2): Vector2 { + let intersection = new Vector2(0, 0); + + let b = Vector2.subtract(a2, a1); + let d = Vector2.subtract(b2, b1); + let bDotDPerp = b.x * d.y - b.y * d.x; + + // 如果b*d = 0,表示这两条直线平行,因此有无穷个交点 + if (bDotDPerp == 0) + return intersection; + + let c = Vector2.subtract(b1, a1); + let t = (c.x * d.y - c.y * d.x) / bDotDPerp; + if (t < 0 || t > 1) + return intersection; + + let u = (c.x * b.y - c.y * b.x) / bDotDPerp; + if (u < 0 || u > 1) + return intersection; + + intersection = Vector2.add(a1, new Vector2(t * b.x, t * b.y)); + + return intersection; + } + + public static closestPointOnLine(lineA: Vector2, lineB: Vector2, closestTo: Vector2) { + let v = Vector2.subtract(lineB, lineA); + let w = Vector2.subtract(closestTo, lineA); + let t = Vector2.dot(w, v) / Vector2.dot(v, v); + t = MathHelper.clamp(t, 0, 1); + + return Vector2.add(lineA, new Vector2(v.x * t, v.y * t)); + } + + public static isCircleToCircle(circleCenter1: Vector2, circleRadius1: number, circleCenter2: Vector2, circleRadius2: number): boolean { + return Vector2.distanceSquared(circleCenter1, circleCenter2) < (circleRadius1 + circleRadius2) * (circleRadius1 + circleRadius2); + } + + public static isCircleToLine(circleCenter: Vector2, radius: number, lineFrom: Vector2, lineTo: Vector2): boolean { + return Vector2.distanceSquared(circleCenter, this.closestPointOnLine(lineFrom, lineTo, circleCenter)) < radius * radius; + } + + public static isCircleToPoint(circleCenter: Vector2, radius: number, point: Vector2): boolean { + return Vector2.distanceSquared(circleCenter, point) < radius * radius; + } + + public static isRectToCircle(rect: egret.Rectangle, cPosition: Vector2, cRadius: number): boolean { + let ew = rect.width * 0.5; + let eh = rect.height * 0.5; + let vx = Math.max(0, Math.max(cPosition.x - rect.x) - ew); + let vy = Math.max(0, Math.max(cPosition.y - rect.y) - eh); + + return vx * vx + vy * vy < cRadius * cRadius; + } + + public static isRectToLine(rect: Rectangle, lineFrom: Vector2, lineTo: Vector2) { + let fromSector = this.getSector(rect.x, rect.y, rect.width, rect.height, lineFrom); + let toSector = this.getSector(rect.x, rect.y, rect.width, rect.height, lineTo); + + if (fromSector == PointSectors.center || toSector == PointSectors.center) { + return true; + } else if ((fromSector & toSector) != 0) { + return false; + } else { + let both = fromSector | toSector; + // 线对边进行检查 + let edgeFrom: Vector2; + let edgeTo: Vector2; + + if ((both & PointSectors.top) != 0) { + edgeFrom = new Vector2(rect.x, rect.y); + edgeTo = new Vector2(rect.x + rect.width, rect.y); + if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo)) + return true; + } + + if ((both & PointSectors.bottom) != 0) { + edgeFrom = new Vector2(rect.x, rect.y + rect.height); + edgeTo = new Vector2(rect.x + rect.width, rect.y + rect.height); + if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo)) + return true; + } + + if ((both & PointSectors.left) != 0) { + edgeFrom = new Vector2(rect.x, rect.y); + edgeTo = new Vector2(rect.x, rect.y + rect.height); + if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo)) + return true; + } + + if ((both & PointSectors.right) != 0) { + edgeFrom = new Vector2(rect.x + rect.width, rect.y); + edgeTo = new Vector2(rect.x + rect.width, rect.y + rect.height); + if (this.isLineToLine(edgeFrom, edgeTo, lineFrom, lineTo)) + return true; + } + } + + return false; + } + + public static isRectToPoint(rX: number, rY: number, rW: number, rH: number, point: Vector2) { + return point.x >= rX && point.y >= rY && point.x < rX + rW && point.y < rY + rH; + } + + /** + * 位标志和帮助使用Cohen–Sutherland算法 + * + * 位标志: + * 1001 1000 1010 + * 0001 0000 0010 + * 0101 0100 0110 + * @param rX + * @param rY + * @param rW + * @param rH + * @param point + */ + public static getSector(rX: number, rY: number, rW: number, rH: number, point: Vector2): PointSectors { + let sector = PointSectors.center; + + if (point.x < rX) + sector |= PointSectors.left; + else if (point.x >= rX + rW) + sector |= PointSectors.right; + + if (point.y < rY) + sector |= PointSectors.top; + else if (point.y >= rY + rH) + sector |= PointSectors.bottom; + + return sector; + } } - - public static isRectToPoint(rX: number, rY: number, rW: number, rH: number, point: Vector2) { - return point.x >= rX && point.y >= rY && point.x < rX + rW && point.y < rY + rH; - } - - /** - * 位标志和帮助使用Cohen–Sutherland算法 - * - * 位标志: - * 1001 1000 1010 - * 0001 0000 0010 - * 0101 0100 0110 - * @param rX - * @param rY - * @param rW - * @param rH - * @param point - */ - public static getSector(rX: number, rY: number, rW: number, rH: number, point: Vector2): PointSectors { - let sector = PointSectors.center; - - if (point.x < rX) - sector |= PointSectors.left; - else if (point.x >= rX + rW) - sector |= PointSectors.right; - - if (point.y < rY) - sector |= PointSectors.top; - else if (point.y >= rY + rH) - sector |= PointSectors.bottom; - - return sector; - } -} \ No newline at end of file +} diff --git a/source/src/Physics/Physics.ts b/source/src/Physics/Physics.ts index f27a7d58..fb62c479 100644 --- a/source/src/Physics/Physics.ts +++ b/source/src/Physics/Physics.ts @@ -1,56 +1,96 @@ -class Physics { - private static _spatialHash: SpatialHash; - /** 调用reset并创建一个新的SpatialHash时使用的单元格大小 */ - public static spatialHashCellSize = 100; - /** 接受layerMask的所有方法的默认值 */ - public static readonly allLayers: number = -1; +module es { + export class Physics { + /** 调用reset并创建一个新的SpatialHash时使用的单元格大小 */ + public static spatialHashCellSize = 100; + /** 接受layerMask的所有方法的默认值 */ + public static readonly allLayers: number = -1; + private static _spatialHash: SpatialHash; + /** + * raycast是否检测配置为触发器的碰撞器 + */ + public static raycastsHitTriggers: boolean = false; + /** + * 在碰撞器中开始的射线/直线是否强制转换检测到那些碰撞器 + */ + public static raycastsStartInColliders = false; - public static reset(){ - this._spatialHash = new SpatialHash(this.spatialHashCellSize); - } + public static reset() { + this._spatialHash = new SpatialHash(this.spatialHashCellSize); + } - /** - * 从SpatialHash中移除所有碰撞器 - */ - public static clear(){ - this._spatialHash.clear(); - } + /** + * 从SpatialHash中移除所有碰撞器 + */ + public static clear() { + this._spatialHash.clear(); + } - public static overlapCircleAll(center: Vector2, randius: number, results: any[], layerMask = -1){ - return this._spatialHash.overlapCircle(center, randius, results, layerMask); - } + /** + * 获取位于指定圆内的所有碰撞器 + * @param center + * @param randius + * @param results + * @param layerMask + */ + public static overlapCircleAll(center: Vector2, randius: number, results: any[], layerMask = -1) { + if (results.length == 0) { + console.error("An empty results array was passed in. No results will ever be returned."); + return; + } - public static boxcastBroadphase(rect: Rectangle, layerMask: number = this.allLayers){ - let boxcastResult = this._spatialHash.aabbBroadphase(rect, null, layerMask); - return {colliders: boxcastResult.tempHashSet, rect: boxcastResult.bounds}; - } + return this._spatialHash.overlapCircle(center, randius, results, layerMask); + } - public static boxcastBroadphaseExcludingSelf(collider: Collider, rect: Rectangle, layerMask = this.allLayers){ - return this._spatialHash.aabbBroadphase(rect, collider, layerMask); - } + /** + * 返回所有碰撞器与边界相交的碰撞器。bounds。请注意,这是一个broadphase检查,所以它只检查边界,不做单个碰撞到碰撞器的检查! + * @param rect + * @param layerMask + */ + public static boxcastBroadphase(rect: Rectangle, layerMask: number = this.allLayers) { + return this._spatialHash.aabbBroadphase(rect, null, layerMask); + } - /** - * 将对撞机添加到物理系统中 - * @param collider - */ - public static addCollider(collider: Collider){ - Physics._spatialHash.register(collider); - } + /** + * 返回所有与边界相交的碰撞器,不包括传入的碰撞器(self)。如果您希望为其他查询自行创建扫过的边界,则此方法非常有用 + * @param collider + * @param rect + * @param layerMask + */ + public static boxcastBroadphaseExcludingSelf(collider: Collider, rect: Rectangle, layerMask = this.allLayers) { + return this._spatialHash.aabbBroadphase(rect, collider, layerMask); + } - /** - * 从物理系统中移除对撞机 - * @param collider - */ - public static removeCollider(collider: Collider){ - Physics._spatialHash.remove(collider); - } + /** + * 将对撞机添加到物理系统中 + * @param collider + */ + public static addCollider(collider: Collider) { + Physics._spatialHash.register(collider); + } - /** - * 更新物理系统中对撞机的位置。这实际上只是移除然后重新添加带有新边界的碰撞器 - * @param collider - */ - public static updateCollider(collider: Collider){ - this._spatialHash.remove(collider); - this._spatialHash.register(collider); + /** + * 从物理系统中移除对撞机 + * @param collider + */ + public static removeCollider(collider: Collider) { + Physics._spatialHash.remove(collider); + } + + /** + * 更新物理系统中对撞机的位置。这实际上只是移除然后重新添加带有新边界的碰撞器 + * @param collider + */ + public static updateCollider(collider: Collider) { + this._spatialHash.remove(collider); + this._spatialHash.register(collider); + } + + /** + * debug绘制空间散列的内容 + * @param secondsToDisplay + */ + public static debugDraw(secondsToDisplay) { + this._spatialHash.debugDraw(secondsToDisplay, 2); + } } -} \ No newline at end of file +} diff --git a/source/src/Physics/Ray2D.ts b/source/src/Physics/Ray2D.ts new file mode 100644 index 00000000..9a2043ce --- /dev/null +++ b/source/src/Physics/Ray2D.ts @@ -0,0 +1,16 @@ +module es { + /** + * 不是真正的射线(射线只有开始和方向),作为一条线和射线。 + */ + export class Ray2D { + public start: Vector2; + public end: Vector2; + public direction: Vector2; + + constructor(position: Vector2, end: Vector2){ + this.start = position; + this.end = end; + this.direction = Vector2.subtract(this.end, this.start); + } + } +} \ No newline at end of file diff --git a/source/src/Physics/RaycastHit.ts b/source/src/Physics/RaycastHit.ts new file mode 100644 index 00000000..683802ba --- /dev/null +++ b/source/src/Physics/RaycastHit.ts @@ -0,0 +1,64 @@ +module es { + export class RaycastHit { + /** + * 对撞机被射线击中 + */ + public collider: Collider; + + /** + * 撞击发生时沿射线的距离。 + */ + public fraction: number = 0; + + /** + * 从射线原点到碰撞点的距离 + */ + public distance: number = 0; + + /** + * 世界空间中光线击中对撞机表面的点 + */ + public point: Vector2 = Vector2.zero; + + /** + * 被射线击中的表面的法向量 + */ + public normal: Vector2 = Vector2.zero; + + /** + * 用于执行转换的质心。使其接触的形状的位置。 + */ + public centroid: Vector2; + + constructor(collider: Collider, fraction: number, distance: number, point: Vector2, normal: Vector2){ + this.collider = collider; + this.fraction = fraction; + this.distance = distance; + this.point = point; + this.centroid = Vector2.zero; + } + + public setValues(collider: Collider, fraction: number, distance: number, point: Vector2){ + this.collider = collider; + this.fraction = fraction; + this.distance = distance; + this.point = point; + } + + public setValuesNonCollider(fraction: number, distance: number, point: Vector2, normal: Vector2){ + this.fraction = fraction; + this.distance = distance; + this.point = point; + this.normal = normal; + } + + public reset(){ + this.collider = null; + this.fraction = this.distance = 0; + } + + public toString(){ + return `[RaycastHit] fraction: ${this.fraction}, distance: ${this.distance}, normal: ${this.normal}, centroid: ${this.centroid}, point: ${this.point}`; + } + } +} \ No newline at end of file diff --git a/source/src/Physics/Shapes/Box.ts b/source/src/Physics/Shapes/Box.ts index a78a96bd..ea9ef7b2 100644 --- a/source/src/Physics/Shapes/Box.ts +++ b/source/src/Physics/Shapes/Box.ts @@ -1,85 +1,94 @@ /// -/** - * 多边形的特殊情况。在进行SAT碰撞检查时,我们只需要检查2个轴而不是8个轴 - */ -class Box extends Polygon { - public width: number; - public height: number; - - constructor(width: number, height: number){ - super(Box.buildBox(width, height), true); - this.width = width; - this.height = height; - } - +module es { /** - * 在一个盒子的形状中建立多边形需要的点的帮助方法 - * @param width - * @param height + * 多边形的特殊情况。在进行SAT碰撞检查时,我们只需要检查2个轴而不是8个轴 */ - private static buildBox(width: number, height: number): Vector2[]{ - // 我们在(0,0)的中心周围创建点 - let halfWidth = width / 2; - let halfHeight = height / 2; - let verts = new Array(4); - verts[0] = new Vector2(-halfWidth, -halfHeight); - verts[1] = new Vector2(halfWidth, -halfHeight); - verts[2] = new Vector2(halfWidth, halfHeight); - verts[3] = new Vector2(-halfWidth, halfHeight); + export class Box extends Polygon { + public width: number; + public height: number; - return verts; - } - - public overlaps(other: Shape){ - // 特殊情况,这一个高性能方式实现,其他情况则使用polygon方法检测 - if (this.isUnrotated){ - if (other instanceof Box && other.isUnrotated) - return this.bounds.intersects(other.bounds); - - if (other instanceof Circle) - return Collisions.isRectToCircle(this.bounds, other.position, other.radius); + constructor(width: number, height: number) { + super(Box.buildBox(width, height), true); + this.width = width; + this.height = height; } - return super.overlaps(other); - } + /** + * 在一个盒子的形状中建立多边形需要的点的帮助方法 + * @param width + * @param height + */ + private static buildBox(width: number, height: number): Vector2[] { + // 我们在(0,0)的中心周围创建点 + let halfWidth = width / 2; + let halfHeight = height / 2; + let verts = new Array(4); + verts[0] = new Vector2(-halfWidth, -halfHeight); + verts[1] = new Vector2(halfWidth, -halfHeight); + verts[2] = new Vector2(halfWidth, halfHeight); + verts[3] = new Vector2(-halfWidth, halfHeight); - public collidesWithShape(other: Shape){ - // 特殊情况,这一个高性能方式实现,其他情况则使用polygon方法检测 - if (this.isUnrotated && other instanceof Box && other.isUnrotated){ - return ShapeCollisions.boxToBox(this, other); + return verts; } - // TODO: 让 minkowski 运行于 cricleToBox + /** + * 更新框点,重新计算中心,设置宽度/高度 + * @param width + * @param height + */ + public updateBox(width: number, height: number) { + this.width = width; + this.height = height; - return super.collidesWithShape(other); - } + // 我们在(0,0)的中心周围创建点 + let halfWidth = width / 2; + let halfHeight = height / 2; - /** - * 更新框点,重新计算中心,设置宽度/高度 - * @param width - * @param height - */ - public updateBox(width: number, height: number){ - this.width = width; - this.height = height; + this.points[0] = new Vector2(-halfWidth, -halfHeight); + this.points[1] = new Vector2(halfWidth, -halfHeight); + this.points[2] = new Vector2(halfWidth, halfHeight); + this.points[3] = new Vector2(-halfWidth, halfHeight); - // 我们在(0,0)的中心周围创建点 - let halfWidth = width / 2; - let halfHeight = height / 2; + for (let i = 0; i < this.points.length; i++) + this._originalPoints[i] = this.points[i]; + } - this.points[0] = new Vector2(-halfWidth, -halfHeight); - this.points[1] = new Vector2(halfWidth, -halfHeight); - this.points[2] = new Vector2(halfWidth, halfHeight); - this.points[3] = new Vector2(-halfWidth, halfHeight); + public overlaps(other: Shape) { + // 特殊情况,这一个高性能方式实现,其他情况则使用polygon方法检测 + if (this.isUnrotated) { + if (other instanceof Box && other.isUnrotated) + return this.bounds.intersects(other.bounds); - for (let i = 0; i < this.points.length; i ++) - this._originalPoints[i] = this.points[i]; - } + if (other instanceof Circle) + return Collisions.isRectToCircle(this.bounds, other.position, other.radius); + } - public containsPoint(point: Vector2){ - if (this.isUnrotated) - return this.bounds.containsInVec(point); + return super.overlaps(other); + } - return super.containsPoint(point); + public collidesWithShape(other: Shape, result: CollisionResult): boolean { + // 特殊情况,这一个高性能方式实现,其他情况则使用polygon方法检测 + if (other instanceof Box && (other as Box).isUnrotated) { + return ShapeCollisions.boxToBox(this, other, result); + } + + // TODO: 让 minkowski 运行于 cricleToBox + + return super.collidesWithShape(other, result); + } + + public containsPoint(point: Vector2) { + if (this.isUnrotated) + return this.bounds.contains(point.x, point.y); + + return super.containsPoint(point); + } + + public pointCollidesWithShape(point: es.Vector2, result: es.CollisionResult): boolean { + if (this.isUnrotated) + return ShapeCollisions.pointToBox(point, this, result); + + return super.pointCollidesWithShape(point, result); + } } } \ No newline at end of file diff --git a/source/src/Physics/Shapes/Circle.ts b/source/src/Physics/Shapes/Circle.ts index b89ba6ff..e90182c3 100644 --- a/source/src/Physics/Shapes/Circle.ts +++ b/source/src/Physics/Shapes/Circle.ts @@ -1,64 +1,82 @@ /// -class Circle extends Shape { - public radius: number; - private _originalRadius: number; +module es { + export class Circle extends Shape { + public radius: number; + public _originalRadius: number; - constructor(radius: number) { - super(); - this.radius = radius; - this._originalRadius = radius; - } - - public pointCollidesWithShape(point: Vector2): CollisionResult { - return ShapeCollisions.pointToCircle(point, this); - } - - public collidesWithShape(other: Shape): CollisionResult { - if (other instanceof Box && (other as Box).isUnrotated) { - return ShapeCollisions.circleToBox(this, other); + constructor(radius: number) { + super(); + this.radius = radius; + this._originalRadius = radius; } - if (other instanceof Circle) { - return ShapeCollisions.circleToCircle(this, other); - } + public recalculateBounds(collider: es.Collider) { + // 如果我们没有旋转或不关心TRS我们使用localOffset作为中心 + this.center = collider.localOffset; - if (other instanceof Polygon) { - return ShapeCollisions.circleToPolygon(this, other); - } + if (collider.shouldColliderScaleAndRotateWithTransform) { + // 我们只将直线缩放为一个圆,所以我们将使用最大值 + let scale = collider.entity.transform.scale; + let hasUnitScale = scale.x == 1 && scale.y == 1; + let maxScale = Math.max(scale.x, scale.y); + this.radius = this._originalRadius * maxScale; - throw new Error(`Collisions of Circle to ${other} are not supported`); - } - - public recalculateBounds(collider: Collider) { - this.center = collider.localOffset; - - if (collider.shouldColliderScaleAndRotateWithTransform) { - let scale = collider.entity.scale; - let hasUnitScale = scale.x == 1 && scale.y == 1; - let maxScale = Math.max(scale.x, scale.y); - this.radius = this._originalRadius * maxScale; - - if (collider.entity.rotation != 0) { - let offsetAngle = Math.atan2(collider.localOffset.y, collider.localOffset.x) * MathHelper.Rad2Deg; - let offsetLength = hasUnitScale ? collider._localOffsetLength : (Vector2.multiply(collider.localOffset, collider.entity.scale)).length(); - this.center = MathHelper.pointOnCirlce(Vector2.zero, offsetLength, MathHelper.toDegrees(collider.entity.rotation) + offsetAngle); + if (collider.entity.transform.rotation != 0) { + // 为了处理偏移原点的旋转,我们只需要将圆心围绕(0,0)在一个圆上移动,我们的偏移量就是0角 + let offsetAngle = Math.atan2(collider.localOffset.y, collider.localOffset.x) * MathHelper.Rad2Deg; + let offsetLength = hasUnitScale ? collider._localOffsetLength : Vector2.multiply(collider.localOffset, collider.entity.transform.scale).length(); + this.center = MathHelper.pointOnCirlce(Vector2.zero, offsetLength, collider.entity.transform.rotation + offsetAngle); + } } + + this.position = Vector2.add(collider.transform.position, this.center); + this.bounds = new Rectangle(this.position.x - this.radius, this.position.y - this.radius, this.radius * 2, this.radius * 2); } - this.position = Vector2.add(collider.entity.position, this.center); - this.bounds = new Rectangle(this.position.x - this.radius, this.position.y - this.radius, this.radius * 2, this.radius * 2); + public overlaps(other: Shape) { + let result: CollisionResult = new CollisionResult(); + if (other instanceof Box && (other as Box).isUnrotated) + return Collisions.isRectToCircle(other.bounds, this.position, this.radius); + + if (other instanceof Circle) + return Collisions.isCircleToCircle(this.position, this.radius, other.position, (other as Circle).radius); + + if (other instanceof Polygon) + return ShapeCollisions.circleToPolygon(this, other, result); + + throw new Error(`overlaps of circle to ${other} are not supported`); + } + + public collidesWithShape(other: Shape, result: CollisionResult): boolean { + if (other instanceof Box && (other as Box).isUnrotated) { + return ShapeCollisions.circleToBox(this, other, result); + } + + if (other instanceof Circle) { + return ShapeCollisions.circleToCircle(this, other, result); + } + + if (other instanceof Polygon) { + return ShapeCollisions.circleToPolygon(this, other, result); + } + + throw new Error(`Collisions of Circle to ${other} are not supported`); + } + + public collidesWithLine(start: es.Vector2, end: es.Vector2, hit: es.RaycastHit): boolean { + return ShapeCollisions.lineToCircle(start, end, this, hit); + } + + /** + * 获取所提供的点是否在此范围内 + * @param point + */ + public containsPoint(point: es.Vector2) { + return (Vector2.subtract(point, this.position)).lengthSquared() <= this.radius * this.radius; + } + + public pointCollidesWithShape(point: Vector2, result: CollisionResult): boolean { + return ShapeCollisions.pointToCircle(point, this, result); + } } - - public overlaps(other: Shape){ - if (other instanceof Box && (other as Box).isUnrotated) - return Collisions.isRectToCircle(other.bounds, this.position, this.radius); - - if (other instanceof Circle) - return Collisions.isCircleToCircle(this.position, this.radius, other.position, (other as Circle).radius); - - if (other instanceof Polygon) - return ShapeCollisions.circleToPolygon(this, other); - - throw new Error(`overlaps of circle to ${other} are not supported`); - } -} \ No newline at end of file +} diff --git a/source/src/Physics/Shapes/CollisionResult.ts b/source/src/Physics/Shapes/CollisionResult.ts index 3593068c..d4eafa05 100644 --- a/source/src/Physics/Shapes/CollisionResult.ts +++ b/source/src/Physics/Shapes/CollisionResult.ts @@ -1,11 +1,47 @@ -class CollisionResult { - public collider: Collider; - public minimumTranslationVector: Vector2 = Vector2.zero; - public normal: Vector2 = Vector2.zero; - public point: Vector2 = Vector2.zero; +module es { + export class CollisionResult { + /** + * 与之相撞的对撞机 + */ + public collider: Collider; + /** + * 被形状击中的表面的法向量 + */ + public normal: Vector2 = Vector2.zero; + /** + * 应用于第一个形状以推入形状的转换 + */ + public minimumTranslationVector: Vector2 = Vector2.zero; + /** + * 不是所有冲突类型都使用!在依赖这个字段之前,请检查ShapeCollisions切割类! + */ + public point: Vector2 = Vector2.zero; - public invertResult(){ - this.minimumTranslationVector = Vector2.negate(this.minimumTranslationVector); - this.normal = Vector2.negate(this.normal); + /** + * 改变最小平移向量,如果没有相同方向上的运动,它将移除平移的x分量。 + * @param deltaMovement + */ + public removeHorizontal(deltaMovement: Vector2){ + // 检查是否需要横向移动,如果需要,移除并固定响应 + if (Math.sign(this.normal.x) != Math.sign(deltaMovement.x) || (deltaMovement.x == 0 && this.normal.x != 0)){ + let responseDistance = this.minimumTranslationVector.length(); + let fix = responseDistance / this.normal.y; + + // 检查一些边界情况。因为我们除以法线 使得x == 1和一个非常小的y这将导致一个巨大的固定值 + if (Math.abs(this.normal.x) != 1 && Math.abs(fix) < Math.abs(deltaMovement.y * 3)){ + this.minimumTranslationVector = new Vector2(0, -fix); + } + } + } + + public invertResult() { + this.minimumTranslationVector = Vector2.negate(this.minimumTranslationVector); + this.normal = Vector2.negate(this.normal); + return this; + } + + public toString(){ + return `[CollisionResult] normal: ${this.normal}, minimumTranslationVector: ${this.minimumTranslationVector}`; + } } -} \ No newline at end of file +} diff --git a/source/src/Physics/Shapes/Polygon.ts b/source/src/Physics/Shapes/Polygon.ts index 86342362..8d1de9fe 100644 --- a/source/src/Physics/Shapes/Polygon.ts +++ b/source/src/Physics/Shapes/Polygon.ts @@ -1,227 +1,323 @@ /// -class Polygon extends Shape { - public points: Vector2[]; - public isUnrotated: boolean = true; - private _polygonCenter: Vector2; - private _areEdgeNormalsDirty = true; - protected _originalPoints: Vector2[]; - - public _edgeNormals: Vector2[]; - public get edgeNormals(){ - if (this._areEdgeNormalsDirty) - this.buildEdgeNormals(); - return this._edgeNormals; - } - public isBox: boolean; - - constructor(points: Vector2[], isBox?: boolean){ - super(); - - this.setPoints(points); - this.isBox = isBox; - } - - private buildEdgeNormals(){ - let totalEdges = this.isBox ? 2 : this.points.length; - if (this._edgeNormals == null || this._edgeNormals.length != totalEdges) - this._edgeNormals = new Array(totalEdges); - - let p2: Vector2; - for (let i = 0; i < totalEdges; i ++){ - let p1 = this.points[i]; - if (i + 1 >= this.points.length) - p2 = this.points[0]; - else - p2 = this.points[i + 1]; - - let perp = Vector2Ext.perpendicular(p1, p2); - perp = Vector2.normalize(perp); - this._edgeNormals[i] = perp; - } - } - - public setPoints(points: Vector2[]) { - this.points = points; - this.recalculateCenterAndEdgeNormals(); - - this._originalPoints = []; - for (let i = 0; i < this.points.length; i ++){ - this._originalPoints.push(this.points[i]); - } - } - - public collidesWithShape(other: Shape){ - let result = new CollisionResult(); - if (other instanceof Polygon){ - return ShapeCollisions.polygonToPolygon(this, other); - } - - if (other instanceof Circle){ - result = ShapeCollisions.circleToPolygon(other, this); - if (result){ - result.invertResult(); - return result; - } - - return null; - } - - throw new Error(`overlaps of Polygon to ${other} are not supported`); - } - - public recalculateCenterAndEdgeNormals() { - this._polygonCenter = Polygon.findPolygonCenter(this.points); - this._areEdgeNormalsDirty = true; - } - - public overlaps(other: Shape){ - let result: CollisionResult; - if (other instanceof Polygon) - return ShapeCollisions.polygonToPolygon(this, other); - - if (other instanceof Circle){ - result = ShapeCollisions.circleToPolygon(other, this); - if (result){ - result.invertResult(); - return true; - } - - return false; - } - - throw new Error(`overlaps of Pologon to ${other} are not supported`); - } - - public static findPolygonCenter(points: Vector2[]) { - let x = 0, y = 0; - - for (let i = 0; i < points.length; i++) { - x += points[i].x; - y += points[i].y; - } - - return new Vector2(x / points.length, y / points.length); - } - +module es { /** - * 迭代多边形的所有边,并得到任意边上离点最近的点。 - * 通过最近点的平方距离和它所在的边的法线返回。 - * 点应该在多边形的空间中(点-多边形.位置) - * @param points - * @param point + * 多边形 */ - public static getClosestPointOnPolygonToPoint(points: Vector2[], point: Vector2): { closestPoint, distanceSquared, edgeNormal } { - let distanceSquared = Number.MAX_VALUE; - let edgeNormal = new Vector2(0, 0); - let closestPoint = new Vector2(0, 0); + export class Polygon extends Shape { + /** + * 组成多边形的点 + * 保持顺时针与凸边形 + */ + public points: Vector2[]; + public _areEdgeNormalsDirty = true; + /** + * 多边形的原始数据 + */ + public _originalPoints: Vector2[]; + public _polygonCenter: Vector2; + /** + * 用于优化未旋转box碰撞 + */ + public isBox: boolean; + public isUnrotated: boolean = true; - let tempDistanceSquared; - for (let i = 0; i < points.length; i++) { - let j = i + 1; - if (j == points.length) - j = 0; + /** + * 从点构造一个多边形 + * 多边形应该以顺时针方式指定 不能重复第一个/最后一个点,它们以0 0为中心 + * @param points + * @param isBox + */ + constructor(points: Vector2[], isBox?: boolean) { + super(); - let closest = ShapeCollisions.closestPointOnLine(points[i], points[j], point); - tempDistanceSquared = Vector2.distanceSquared(point, closest); + this.setPoints(points); + this.isBox = isBox; + } - if (tempDistanceSquared < distanceSquared) { - distanceSquared = tempDistanceSquared; - closestPoint = closest; + public _edgeNormals: Vector2[]; - // 求直线的法线 - let line = Vector2.subtract(points[j], points[i]); - edgeNormal.x = -line.y; - edgeNormal.y = line.x; + /** + * 边缘法线用于SAT碰撞检测。缓存它们用于避免squareRoots + * box只有两个边缘 因为其他两边是平行的 + */ + public get edgeNormals() { + if (this._areEdgeNormalsDirty) + this.buildEdgeNormals(); + return this._edgeNormals; + } + + /** + * 重置点并重新计算中心和边缘法线 + * @param points + */ + public setPoints(points: Vector2[]) { + this.points = points; + this.recalculateCenterAndEdgeNormals(); + + this._originalPoints = []; + for (let i = 0; i < this.points.length; i++) { + this._originalPoints.push(this.points[i]); } } - edgeNormal = Vector2.normalize(edgeNormal); + /** + * 重新计算多边形中心 + * 如果点数改变必须调用该方法 + */ + public recalculateCenterAndEdgeNormals() { + this._polygonCenter = Polygon.findPolygonCenter(this.points); + this._areEdgeNormalsDirty = true; + } - return { closestPoint: closestPoint, distanceSquared: distanceSquared, edgeNormal: edgeNormal }; - } + /** + * 建立多边形边缘法线 + * 它们仅由edgeNormals getter惰性创建和更新 + */ + public buildEdgeNormals() { + // 对于box 我们只需要两条边,因为另外两条边是平行的 + let totalEdges = this.isBox ? 2 : this.points.length; + if (this._edgeNormals == null || this._edgeNormals.length != totalEdges) + this._edgeNormals = new Array(totalEdges); - public pointCollidesWithShape(point: Vector2): CollisionResult { - return ShapeCollisions.pointToPoly(point, this); - } + let p2: Vector2; + for (let i = 0; i < totalEdges; i++) { + let p1 = this.points[i]; + if (i + 1 >= this.points.length) + p2 = this.points[0]; + else + p2 = this.points[i + 1]; - /** - * 本质上,这个算法所做的就是从一个点发射一条射线。 - * 如果它与奇数条多边形边相交,我们就知道它在多边形内部。 - * @param point - */ - public containsPoint(point: Vector2) { - // 将点归一化到多边形坐标空间中 - point = Vector2.subtract(point, this.position); - - let isInside = false; - for (let i = 0, j = this.points.length - 1; i < this.points.length; j = i++) { - if (((this.points[i].y > point.y) != (this.points[j].y > point.y)) && - (point.x < (this.points[j].x - this.points[i].x) * (point.y - this.points[i].y) / (this.points[j].y - this.points[i].y) + - this.points[i].x)) { - isInside = !isInside; + let perp = Vector2Ext.perpendicular(p1, p2); + perp = Vector2.normalize(perp); + this._edgeNormals[i] = perp; } } - return isInside; - } + /** + * 建立一个对称的多边形(六边形,八角形,n角形)并返回点 + * @param vertCount + * @param radius + */ + public static buildSymmetricalPolygon(vertCount: number, radius: number) { + let verts = new Array(vertCount); - /** - * 建立一个对称的多边形(六边形,八角形,n角形)并返回点 - * @param vertCount - * @param radius - */ - public static buildSymmertricalPolygon(vertCount: number, radius: number) { - let verts = new Array(vertCount); - - for (let i = 0; i < vertCount; i++) { - let a = 2 * Math.PI * (i / vertCount); - verts[i] = new Vector2(Math.cos(a), Math.sin(a) * radius); - } - - return verts; - } - - public recalculateBounds(collider: Collider) { - // 如果我们没有旋转或不关心TRS我们使用localOffset作为中心,我们会从那开始 - this.center = collider.localOffset; - - if (collider.shouldColliderScaleAndRotateWithTransform){ - let hasUnitScale = true; - let tempMat: Matrix2D; - let combinedMatrix = Matrix2D.createTranslation(-this._polygonCenter.x, -this._polygonCenter.y); - - if (collider.entity.scale != Vector2.one){ - tempMat = Matrix2D.createScale(collider.entity.scale.x, collider.entity.scale.y); - combinedMatrix = Matrix2D.multiply(combinedMatrix, tempMat); - - hasUnitScale = false; - - // 缩放偏移量并将其设置为中心。如果我们有旋转,它会在下面重置 - let scaledOffset = Vector2.multiply(collider.localOffset, collider.entity.scale); - this.center = scaledOffset; + for (let i = 0; i < vertCount; i++) { + let a = 2 * Math.PI * (i / vertCount); + verts[i] = Vector2.multiply(new Vector2(Math.cos(a), Math.sin(a)), new Vector2(radius)); } - if (collider.entity.rotation != 0){ - tempMat = Matrix2D.createRotation(collider.entity.rotation, tempMat); - combinedMatrix = Matrix2D.multiply(combinedMatrix, tempMat); - - // 为了处理偏移原点的旋转我们只需要将圆心在(0,0)附近移动我们的偏移使角度为0 - // 我们还需要处理这里的比例所以我们先对偏移进行缩放以得到合适的长度。 - let offsetAngle = Math.atan2(collider.localOffset.y, collider.localOffset.x) * MathHelper.Rad2Deg; - let offsetLength = hasUnitScale ? collider._localOffsetLength : (Vector2.multiply(collider.localOffset, collider.entity.scale)).length(); - this.center = MathHelper.pointOnCirlce(Vector2.zero, offsetLength, MathHelper.toDegrees(collider.entity.rotation) + offsetAngle); - } - - tempMat = Matrix2D.createTranslation(this._polygonCenter.x, this._polygonCenter.y); - combinedMatrix = Matrix2D.multiply(combinedMatrix, tempMat); - - // 最后变换原始点 - Vector2Ext.transform(this._originalPoints, combinedMatrix, this.points); - this.isUnrotated = collider.entity.rotation == 0; + return verts; } - this.position = Vector2.add(collider.entity.position, this.center); - this.bounds = Rectangle.rectEncompassingPoints(this.points); - this.bounds.location = Vector2.add(this.bounds.location, this.position); + /** + * 重定位多边形的点 + * @param points + */ + public static recenterPolygonVerts(points: Vector2[]) { + let center = this.findPolygonCenter(points); + for (let i = 0; i < points.length; i++) + points[i] = Vector2.subtract(points[i], center); + } + + /** + * 找到多边形的中心。注意,这对于正则多边形是准确的。不规则多边形没有中心。 + * @param points + */ + public static findPolygonCenter(points: Vector2[]) { + let x = 0, y = 0; + + for (let i = 0; i < points.length; i++) { + x += points[i].x; + y += points[i].y; + } + + return new Vector2(x / points.length, y / points.length); + } + + /** + * 不知道辅助顶点,所以取每个顶点,如果你知道辅助顶点,执行climbing算法 + * @param points + * @param direction + */ + public static getFarthestPointInDirection(points: Vector2[], direction: Vector2): Vector2{ + let index = 0; + let maxDot = Vector2.dot(points[index], direction); + + for (let i = 1; i < points.length; i ++){ + let dot = Vector2.dot(points[i], direction); + if (dot > maxDot){ + maxDot = dot; + index = i; + } + } + + return points[index]; + } + + /** + * 迭代多边形的所有边,并得到任意边上离点最近的点。 + * 通过最近点的平方距离和它所在的边的法线返回。 + * 点应该在多边形的空间中(点-多边形.位置) + * @param points + * @param point + * @param distanceSquared + * @param edgeNormal + */ + public static getClosestPointOnPolygonToPoint(points: Vector2[], point: Vector2, distanceSquared: number, edgeNormal: Vector2): Vector2 { + distanceSquared = Number.MAX_VALUE; + edgeNormal = new Vector2(0, 0); + let closestPoint = new Vector2(0, 0); + + let tempDistanceSquared; + for (let i = 0; i < points.length; i++) { + let j = i + 1; + if (j == points.length) + j = 0; + + let closest = ShapeCollisions.closestPointOnLine(points[i], points[j], point); + tempDistanceSquared = Vector2.distanceSquared(point, closest); + + if (tempDistanceSquared < distanceSquared) { + distanceSquared = tempDistanceSquared; + closestPoint = closest; + + // 求直线的法线 + let line = Vector2.subtract(points[j], points[i]); + edgeNormal = new Vector2(-line.y, line.x); + } + } + + Vector2Ext.normalize(edgeNormal); + + return closestPoint; + } + + /** + * 旋转原始点并复制旋转的值到旋转的点 + * @param radians + * @param originalPoints + * @param rotatedPoints + */ + public static rotatePolygonVerts(radians: number, originalPoints: Vector2[], rotatedPoints){ + let cos = Math.cos(radians); + let sin = Math.sign(radians); + + for (let i = 0; i < originalPoints.length; i ++){ + let position = originalPoints[i]; + rotatedPoints[i] = new Vector2(position.x * cos + position.y * -sin, position.x * sin + position.y * cos); + } + } + + public recalculateBounds(collider: Collider) { + // 如果我们没有旋转或不关心TRS我们使用localOffset作为中心,我们会从那开始 + this.center = collider.localOffset; + + if (collider.shouldColliderScaleAndRotateWithTransform) { + let hasUnitScale = true; + let tempMat: Matrix2D; + let combinedMatrix = Matrix2D.create().translate(-this._polygonCenter.x, -this._polygonCenter.y); + + if (collider.entity.transform.scale != Vector2.zero) { + tempMat = Matrix2D.create().scale(collider.entity.transform.scale.x, collider.entity.transform.scale.y); + combinedMatrix = combinedMatrix.multiply(tempMat); + hasUnitScale = false; + + // 缩放偏移量并将其设置为中心。如果我们有旋转,它会在下面重置 + this.center = Vector2.multiply(collider.localOffset, collider.entity.transform.scale); + } + + if (collider.entity.transform.rotation != 0) { + tempMat = Matrix2D.create().rotate(collider.entity.transform.rotation); + combinedMatrix = combinedMatrix.multiply(tempMat); + + // 为了处理偏移原点的旋转我们只需要将圆心在(0,0)附近移动 + // 我们的偏移使角度为0我们还需要处理这里的比例所以我们先对偏移进行缩放以得到合适的长度。 + let offsetAngle = Math.atan2(collider.localOffset.y, collider.localOffset.x) * MathHelper.Rad2Deg; + let offsetLength = hasUnitScale ? collider._localOffsetLength : + Vector2.multiply(collider.localOffset, collider.entity.transform.scale).length(); + this.center = MathHelper.pointOnCirlce(Vector2.zero, offsetLength, + collider.entity.transform.rotation + offsetAngle); + } + + tempMat = Matrix2D.create().translate(this._polygonCenter.x, this._polygonCenter.y); + combinedMatrix = combinedMatrix.multiply(tempMat); + + // 最后变换原始点 + Vector2Ext.transform(this._originalPoints, combinedMatrix, this.points); + + this.isUnrotated = collider.entity.transform.rotation == 0; + + // 如果旋转的话,我们只需要重建边的法线 + if (collider._isRotationDirty) + this._areEdgeNormalsDirty = true; + } + + this.position = Vector2.add(collider.entity.transform.position, this.center); + this.bounds = Rectangle.rectEncompassingPoints(this.points); + this.bounds.location = this.bounds.location.add(this.position); + } + + public overlaps(other: Shape) { + let result: CollisionResult = new CollisionResult(); + if (other instanceof Polygon) + return ShapeCollisions.polygonToPolygon(this, other, result); + + if (other instanceof Circle) { + if (ShapeCollisions.circleToPolygon(other, this, result)) { + result.invertResult(); + return true; + } + + return false; + } + + throw new Error(`overlaps of Pologon to ${other} are not supported`); + } + + public collidesWithShape(other: Shape, result: CollisionResult): boolean { + if (other instanceof Polygon) { + return ShapeCollisions.polygonToPolygon(this, other, result); + } + + if (other instanceof Circle) { + if (ShapeCollisions.circleToPolygon(other, this, result)) { + result.invertResult(); + return true; + } + + return false; + } + + throw new Error(`overlaps of Polygon to ${other} are not supported`); + } + + public collidesWithLine(start: es.Vector2, end: es.Vector2, hit: es.RaycastHit): boolean { + return ShapeCollisions.lineToPoly(start, end, this, hit); + } + + /** + * 本质上,这个算法所做的就是从一个点发射一条射线。 + * 如果它与奇数条多边形边相交,我们就知道它在多边形内部。 + * @param point + */ + public containsPoint(point: Vector2) { + // 将点归一化到多边形坐标空间中 + point = Vector2.subtract(point, this.position); + + let isInside = false; + for (let i = 0, j = this.points.length - 1; i < this.points.length; j = i++) { + if (((this.points[i].y > point.y) != (this.points[j].y > point.y)) && + (point.x < (this.points[j].x - this.points[i].x) * (point.y - this.points[i].y) / (this.points[j].y - this.points[i].y) + + this.points[i].x)) { + isInside = !isInside; + } + } + + return isInside; + } + + public pointCollidesWithShape(point: Vector2, result: CollisionResult): boolean { + return ShapeCollisions.pointToPoly(point, this, result); + } } } \ No newline at end of file diff --git a/source/src/Physics/Shapes/RealtimeCollisions.ts b/source/src/Physics/Shapes/RealtimeCollisions.ts new file mode 100644 index 00000000..47314dc5 --- /dev/null +++ b/source/src/Physics/Shapes/RealtimeCollisions.ts @@ -0,0 +1,48 @@ +module es { + export class RealtimeCollisions { + public static intersectMovingCircleToBox(s: Circle, b: Box, movement: Vector2): number { + // 计算用球面半径r inflate b得到的AABB + let e = b.bounds; + e.inflate(s.radius, s.radius); + + // 射线与展开矩形e相交。如果射线错过了e,则退出不相交,否则得到相交点p和时间t + let ray = new Ray2D(Vector2.subtract(s.position, movement), s.position); + let time = e.rayIntersects(ray); + if (time > 1) + return time; + + // 求交点 + let point = Vector2.add(ray.start, Vector2.add(ray.direction, new Vector2(time))); + + // 计算b的最小面和最大面p的交点在哪个面之外。注意,u和v不能有相同的位集,它们之间必须至少有一个位集。 + let u, v = 0; + if (point.x < b.bounds.left) + u |= 1; + if (point.x > b.bounds.right) + v |= 1; + if (point.y < b.bounds.top) + u |= 2; + if (point.y > b.bounds.bottom) + v |= 2; + + // 将所有位集合成位掩码(注意u + v == u | v) + let m = u + v; + + // 如果所有的3位都被设置,那么点在一个顶点区域 + if (m == 3){ + // 现在必须相交的部分,如果一个或多个击中对胶囊的两边会合在斜面和返回的最佳时间 + // TODO: 需要实现这个 + console.log(`m == 3. corner ${Time.frameCount}`); + } + + // 如果m中只设置了一个位,那么点在一个面区域 + if ((m & (m - 1)) == 0){ + // 什么也不做。从扩展矩形交集的时间是正确的时间 + return time; + } + + // 点在边缘区域上。与边缘相交。 + return time; + } + } +} \ No newline at end of file diff --git a/source/src/Physics/Shapes/Shape.ts b/source/src/Physics/Shapes/Shape.ts index ccc3a5a4..b095c1cb 100644 --- a/source/src/Physics/Shapes/Shape.ts +++ b/source/src/Physics/Shapes/Shape.ts @@ -1,10 +1,34 @@ -abstract class Shape { - public bounds: Rectangle; - public position: Vector2; - public center: Vector2; +module es { + export abstract class Shape { + /** + * 有一个单独的位置字段可以让我们改变形状的位置来进行碰撞检查,而不是改变entity.position。 + * 触发碰撞器/边界/散列更新的位置。 + * 内部字段 + */ + public position: Vector2; + /** + * 这不是中心。这个值不一定是物体的中心。对撞机更准确。 + * 应用任何转换旋转的localOffset + * 内部字段 + */ + public center: Vector2; + /** 缓存的形状边界 内部字段 */ + public bounds: Rectangle; - public abstract recalculateBounds(collider: Collider); - public abstract pointCollidesWithShape(point: Vector2): CollisionResult; - public abstract overlaps(other: Shape); - public abstract collidesWithShape(other: Shape): CollisionResult; -} \ No newline at end of file + public abstract recalculateBounds(collider: Collider); + + public abstract overlaps(other: Shape): boolean; + + public abstract collidesWithShape(other: Shape, collisionResult: CollisionResult): boolean; + + public abstract collidesWithLine(start: Vector2, end: Vector2, hit: RaycastHit): boolean; + + public abstract containsPoint(point: Vector2); + + public abstract pointCollidesWithShape(point: Vector2, result: CollisionResult): boolean; + + public clone(): Shape { + return ObjectUtils.clone(this); + } + } +} diff --git a/source/src/Physics/Shapes/ShapeCollisions/ShapeCollisions.ts b/source/src/Physics/Shapes/ShapeCollisions/ShapeCollisions.ts index a45c32e8..d8cdbd0e 100644 --- a/source/src/Physics/Shapes/ShapeCollisions/ShapeCollisions.ts +++ b/source/src/Physics/Shapes/ShapeCollisions/ShapeCollisions.ts @@ -1,302 +1,448 @@ -class ShapeCollisions { +module es { /** - * 检查两个多边形之间的碰撞 - * @param first - * @param second + * 各种形状的碰撞例程 + * 大多数人都希望第一个形状位于第二个形状的空间内(即shape1) + * pos应该设置为shape1。pos - shape2.pos)。 */ - public static polygonToPolygon(first: Polygon, second: Polygon) { - let result = new CollisionResult(); - let isIntersecting = true; + export class ShapeCollisions { + /** + * 检查两个多边形之间的碰撞 + * @param first + * @param second + * @param result + */ + public static polygonToPolygon(first: Polygon, second: Polygon, result: CollisionResult): boolean { + let isIntersecting = true; - let firstEdges = first.edgeNormals; - let secondEdges = second.edgeNormals; - let minIntervalDistance = Number.POSITIVE_INFINITY; - let translationAxis = new Vector2(); - let polygonOffset = Vector2.subtract(first.position, second.position); - let axis: Vector2; + let firstEdges = first.edgeNormals; + let secondEdges = second.edgeNormals; + let minIntervalDistance = Number.POSITIVE_INFINITY; + let translationAxis = new Vector2(); + let polygonOffset = Vector2.subtract(first.position, second.position); + let axis: Vector2; - // 循环穿过两个多边形的所有边 - for (let edgeIndex = 0; edgeIndex < firstEdges.length + secondEdges.length; edgeIndex++) { - // 1. 找出当前多边形是否相交 - // 多边形的归一化轴垂直于缓存给我们的当前边 - if (edgeIndex < firstEdges.length) { - axis = firstEdges[edgeIndex]; + // 循环穿过两个多边形的所有边 + for (let edgeIndex = 0; edgeIndex < firstEdges.length + secondEdges.length; edgeIndex++) { + // 1. 找出当前多边形是否相交 + // 多边形的归一化轴垂直于缓存给我们的当前边 + if (edgeIndex < firstEdges.length) { + axis = firstEdges[edgeIndex]; + } else { + axis = secondEdges[edgeIndex - firstEdges.length]; + } + + // 求多边形在当前轴上的投影 + let minA = 0; + let minB = 0; + let maxA = 0; + let maxB = 0; + let intervalDist = 0; + let ta = this.getInterval(axis, first, minA, maxA); + minA = ta.min; + minB = ta.max; + let tb = this.getInterval(axis, second, minB, maxB); + minB = tb.min; + maxB = tb.max; + + // 将区间设为第二个多边形的空间。由轴上投影的位置差偏移。 + let relativeIntervalOffset = Vector2.dot(polygonOffset, axis); + minA += relativeIntervalOffset; + maxA += relativeIntervalOffset; + + // 检查多边形投影是否正在相交 + intervalDist = this.intervalDistance(minA, maxA, minB, maxB); + if (intervalDist > 0) + isIntersecting = false; + + // 对于多对多数据类型转换,添加一个Vector2?参数称为deltaMovement。为了提高速度,我们这里不使用它 + // TODO: 现在找出多边形是否会相交。只要检查速度就行了 + + // 如果多边形不相交,也不会相交,退出循环 + if (!isIntersecting) + return false; + + // 检查当前间隔距离是否为最小值。如果是,则存储间隔距离和当前距离。这将用于计算最小平移向量 + intervalDist = Math.abs(intervalDist); + if (intervalDist < minIntervalDistance) { + minIntervalDistance = intervalDist; + translationAxis = axis; + + if (Vector2.dot(translationAxis, polygonOffset) < 0) + translationAxis = new Vector2(-translationAxis); + } + } + + // 利用最小平移向量对多边形进行推入。 + result.normal = translationAxis; + result.minimumTranslationVector = Vector2.multiply(new Vector2(-translationAxis.x, -translationAxis.y), new Vector2(minIntervalDistance)); + + return true; + } + + /** + * 计算[minA, maxA]和[minB, maxB]之间的距离。如果间隔重叠,距离是负的 + * @param minA + * @param maxA + * @param minB + * @param maxB + */ + public static intervalDistance(minA: number, maxA: number, minB: number, maxB) { + if (minA < minB) + return minB - maxA; + + return minA - minB; + } + + /** + * 计算一个多边形在一个轴上的投影,并返回一个[min,max]区间 + * @param axis + * @param polygon + * @param min + * @param max + */ + public static getInterval(axis: Vector2, polygon: Polygon, min: number, max: number) { + let dot = Vector2.dot(polygon.points[0], axis); + min = max = dot; + + for (let i = 1; i < polygon.points.length; i++) { + dot = Vector2.dot(polygon.points[i], axis); + if (dot < min) { + min = dot; + } else if (dot > max) { + max = dot; + } + } + + return {min: min, max: max}; + } + + /** + * + * @param circle + * @param polygon + * @param result + */ + public static circleToPolygon(circle: Circle, polygon: Polygon, result: CollisionResult): boolean { + let poly2Circle = Vector2.subtract(circle.position, polygon.position); + + let distanceSquared = 0; + let closestPoint = Polygon.getClosestPointOnPolygonToPoint(polygon.points, poly2Circle, distanceSquared, result.normal); + + let circleCenterInsidePoly = polygon.containsPoint(circle.position); + if (distanceSquared > circle.radius * circle.radius && !circleCenterInsidePoly) + return false; + + let mtv: Vector2; + if (circleCenterInsidePoly) { + mtv = Vector2.multiply(result.normal, new Vector2(Math.sqrt(distanceSquared) - circle.radius)); } else { - axis = secondEdges[edgeIndex - firstEdges.length]; + if (distanceSquared == 0) { + mtv = Vector2.multiply(result.normal, new Vector2(circle.radius)); + } else { + let distance = Math.sqrt(distanceSquared); + mtv = Vector2.multiply(new Vector2(-Vector2.subtract(poly2Circle, closestPoint)), new Vector2((circle.radius - distanceSquared) / distance)); + } } - // 求多边形在当前轴上的投影 - let minA = 0; - let minB = 0; - let maxA = 0; - let maxB = 0; - let intervalDist = 0; - let ta = this.getInterval(axis, first, minA, maxA); - minA = ta.min; - minB = ta.max; - let tb = this.getInterval(axis, second, minB, maxB); - minB = tb.min; - maxB = tb.max; + result.minimumTranslationVector = mtv; + result.point = Vector2.add(closestPoint, polygon.position); - // 将区间设为第二个多边形的空间。由轴上投影的位置差偏移。 - let relativeIntervalOffset = Vector2.dot(polygonOffset, axis); - minA += relativeIntervalOffset; - maxA += relativeIntervalOffset; + return true; + } - // 检查多边形投影是否正在相交 - intervalDist = this.intervalDistance(minA, maxA, minB, maxB); - if (intervalDist > 0) - isIntersecting = false; + /** + * 适用于圆心在方框内以及只与方框外圆心重叠的圆。 + * @param circle + * @param box + * @param result + */ + public static circleToBox(circle: Circle, box: Box, result: CollisionResult): boolean { + let closestPointOnBounds = box.bounds.getClosestPointOnRectangleBorderToPoint(circle.position, result.normal); - // 对于多对多数据类型转换,添加一个Vector2?参数称为deltaMovement。为了提高速度,我们这里不使用它 - // TODO: 现在找出多边形是否会相交。只要检查速度就行了 + // 处理那些中心在盒子里的圆,因为比较好操作, + if (box.containsPoint(circle.position)) { + result.point = closestPointOnBounds; - // 如果多边形不相交,也不会相交,退出循环 - if (!isIntersecting) - return null; + // 计算mtv。找到安全的,没有碰撞的位置,然后从那里得到mtv + let safePlace = Vector2.add(closestPointOnBounds, Vector2.multiply(result.normal, new Vector2(circle.radius))); + result.minimumTranslationVector = Vector2.subtract(circle.position, safePlace); - // 检查当前间隔距离是否为最小值。如果是,则存储间隔距离和当前距离。这将用于计算最小平移向量 - intervalDist = Math.abs(intervalDist); - if (intervalDist < minIntervalDistance) { - minIntervalDistance = intervalDist; - translationAxis = axis; - - if (Vector2.dot(translationAxis, polygonOffset) < 0) - translationAxis = new Vector2(-translationAxis); + return true; } - } - // 利用最小平移向量对多边形进行推入。 - result.normal = translationAxis; - result.minimumTranslationVector = Vector2.multiply(new Vector2(-translationAxis.x, -translationAxis.y), new Vector2(minIntervalDistance)); + let sqrDistance = Vector2.distanceSquared(closestPointOnBounds, circle.position); + // 看盒子上的点与圆的距离是否小于半径 + if (sqrDistance == 0) { + result.minimumTranslationVector = Vector2.multiply(result.normal, new Vector2(circle.radius)); + } else if (sqrDistance <= circle.radius * circle.radius) { + result.normal = Vector2.subtract(circle.position, closestPointOnBounds); + let depth = result.normal.length() - circle.radius; - return result; - } + result.point = closestPointOnBounds; + result.normal = Vector2Ext.normalize(result.normal); + result.minimumTranslationVector = Vector2.multiply(new Vector2(depth), result.normal); - /** - * 计算[minA, maxA]和[minB, maxB]之间的距离。如果间隔重叠,距离是负的 - * @param minA - * @param maxA - * @param minB - * @param maxB - */ - public static intervalDistance(minA: number, maxA: number, minB: number, maxB) { - if (minA < minB) - return minB - maxA; - - return minA - minB; - } - - /** - * 计算一个多边形在一个轴上的投影,并返回一个[min,max]区间 - * @param axis - * @param polygon - * @param min - * @param max - */ - public static getInterval(axis: Vector2, polygon: Polygon, min: number, max: number) { - let dot = Vector2.dot(polygon.points[0], axis); - min = max = dot; - - for (let i = 1; i < polygon.points.length; i++) { - dot = Vector2.dot(polygon.points[i], axis); - if (dot < min) { - min = dot; - } else if (dot > max) { - max = dot; + return true; } + + return false; } - return { min: min, max: max }; - } + /** + * + * @param point + * @param circle + * @param result + */ + public static pointToCircle(point: Vector2, circle: Circle, result: CollisionResult): boolean { + let distanceSquared = Vector2.distanceSquared(point, circle.position); + let sumOfRadii = 1 + circle.radius; + let collided = distanceSquared < sumOfRadii * sumOfRadii; + if (collided) { + result.normal = Vector2.normalize(Vector2.subtract(point, circle.position)); + let depth = sumOfRadii - Math.sqrt(distanceSquared); + result.minimumTranslationVector = Vector2.multiply(new Vector2(-depth, -depth), result.normal); + result.point = Vector2.add(circle.position, Vector2.multiply(result.normal, new Vector2(circle.radius, circle.radius))); - /** - * - * @param circle - * @param polygon - */ - public static circleToPolygon(circle: Circle, polygon: Polygon) { - let result = new CollisionResult(); - - let poly2Circle = Vector2.subtract(circle.position, polygon.position); - - let gpp = Polygon.getClosestPointOnPolygonToPoint(polygon.points, poly2Circle); - let closestPoint: Vector2 = gpp.closestPoint; - let distanceSquared: number = gpp.distanceSquared; - result.normal = gpp.edgeNormal; - - let circleCenterInsidePoly = polygon.containsPoint(circle.position); - if (distanceSquared > circle.radius * circle.radius && !circleCenterInsidePoly) - return null; - - let mtv: Vector2; - if (circleCenterInsidePoly) { - mtv = Vector2.multiply(result.normal, new Vector2(Math.sqrt(distanceSquared) - circle.radius)); - } else { - if (distanceSquared == 0) { - mtv = Vector2.multiply(result.normal, new Vector2(circle.radius)); - } else { - let distance = Math.sqrt(distanceSquared); - mtv = Vector2.multiply(new Vector2(-Vector2.subtract(poly2Circle, closestPoint)), new Vector2((circle.radius - distanceSquared) / distance)); + return true; } + + return false; } - result.minimumTranslationVector = mtv; - result.point = Vector2.add(closestPoint, polygon.position); + public static pointToBox(point: Vector2, box: Box, result: CollisionResult){ + if (box.containsPoint(point)){ + // 在方框的空间里找到点 + result.point = box.bounds.getClosestPointOnRectangleBorderToPoint(point, result.normal); + result.minimumTranslationVector = Vector2.subtract(point, result.point); - return result; - } + return true; + } - /** - * 适用于圆心在方框内以及只与方框外圆心重叠的圆。 - * @param circle - * @param box - */ - public static circleToBox(circle: Circle, box: Box): CollisionResult { - let result = new CollisionResult(); - let closestPointOnBounds = box.bounds.getClosestPointOnRectangleBorderToPoint(circle.position).res; - - if (box.containsPoint(circle.position)) { - result.point = closestPointOnBounds; - - let safePlace = Vector2.add(closestPointOnBounds, Vector2.subtract(result.normal, new Vector2(circle.radius))); - result.minimumTranslationVector = Vector2.subtract(circle.position, safePlace); - - return result; + return false; } - let sqrDistance = Vector2.distanceSquared(closestPointOnBounds, circle.position); - if (sqrDistance == 0) { - result.minimumTranslationVector = Vector2.multiply(result.normal, new Vector2(circle.radius)); - } else if (sqrDistance <= circle.radius * circle.radius) { - result.normal = Vector2.subtract(circle.position, closestPointOnBounds); - let depth = result.normal.length() - circle.radius; - result.normal = Vector2Ext.normalize(result.normal); - result.minimumTranslationVector = Vector2.multiply(new Vector2(depth), result.normal); + /** + * + * @param lineA + * @param lineB + * @param closestTo + */ + public static closestPointOnLine(lineA: Vector2, lineB: Vector2, closestTo: Vector2): Vector2 { + let v = Vector2.subtract(lineB, lineA); + let w = Vector2.subtract(closestTo, lineA); + let t = Vector2.dot(w, v) / Vector2.dot(v, v); + t = MathHelper.clamp(t, 0, 1); - return result; + return Vector2.add(lineA, Vector2.multiply(v, new Vector2(t, t))); } - return null; - } + /** + * + * @param point + * @param poly + * @param result + */ + public static pointToPoly(point: Vector2, poly: Polygon, result: CollisionResult): boolean { + if (poly.containsPoint(point)) { + let distanceSquared: number = 0; + let closestPoint = Polygon.getClosestPointOnPolygonToPoint(poly.points, Vector2.subtract(point, poly.position), distanceSquared, result.normal); - /** - * - * @param point - * @param circle - */ - public static pointToCircle(point: Vector2, circle: Circle) { - let result = new CollisionResult(); + result.minimumTranslationVector = Vector2.multiply(result.normal, new Vector2(Math.sqrt(distanceSquared), Math.sqrt(distanceSquared))); + result.point = Vector2.add(closestPoint, poly.position); - let distanceSquared = Vector2.distanceSquared(point, circle.position); - let sumOfRadii = 1 + circle.radius; - let collided = distanceSquared < sumOfRadii * sumOfRadii; - if (collided) { - result.normal = Vector2.normalize(Vector2.subtract(point, circle.position)); - let depth = sumOfRadii - Math.sqrt(distanceSquared); - result.minimumTranslationVector = Vector2.multiply(new Vector2(-depth, -depth), result.normal); - result.point = Vector2.add(circle.position, Vector2.multiply(result.normal, new Vector2(circle.radius, circle.radius))); + return true; + } - return result; + return false; } - return null; - } + /** + * + * @param first + * @param second + */ + public static circleToCircle(first: Circle, second: Circle, result: CollisionResult): boolean { + let distanceSquared = Vector2.distanceSquared(first.position, second.position); + let sumOfRadii = first.radius + second.radius; + let collided = distanceSquared < sumOfRadii * sumOfRadii; + if (collided) { + result.normal = Vector2.normalize(Vector2.subtract(first.position, second.position)); + let depth = sumOfRadii - Math.sqrt(distanceSquared); + result.minimumTranslationVector = Vector2.multiply(new Vector2(-depth), result.normal); + result.point = Vector2.add(second.position, Vector2.multiply(result.normal, new Vector2(second.radius))); - /** - * - * @param lineA - * @param lineB - * @param closestTo - */ - public static closestPointOnLine(lineA: Vector2, lineB: Vector2, closestTo: Vector2) { - let v = Vector2.subtract(lineB, lineA); - let w = Vector2.subtract(closestTo, lineA); - let t = Vector2.dot(w, v) / Vector2.dot(v, v); - t = MathHelper.clamp(t, 0, 1); + return true; + } - return Vector2.add(lineA, Vector2.multiply(v, new Vector2(t, t))); - } - - /** - * - * @param point - * @param poly - */ - public static pointToPoly(point: Vector2, poly: Polygon) { - let result = new CollisionResult(); - - if (poly.containsPoint(point)) { - let distanceSquared: number; - let gpp = Polygon.getClosestPointOnPolygonToPoint(poly.points, Vector2.subtract(point, poly.position)); - let closestPoint = gpp.closestPoint; - distanceSquared = gpp.distanceSquared; - result.normal = gpp.edgeNormal; - - result.minimumTranslationVector = Vector2.multiply(result.normal, new Vector2(Math.sqrt(distanceSquared), Math.sqrt(distanceSquared))); - result.point = Vector2.add(closestPoint, poly.position); - - return result; + return false; } - return null; - } + /** + * + * @param first + * @param second + * @param result + */ + public static boxToBox(first: Box, second: Box, result: CollisionResult): boolean { + let minkowskiDiff = this.minkowskiDifference(first, second); + if (minkowskiDiff.contains(0, 0)) { + // 计算MTV。如果它是零,我们就可以称它为非碰撞 + result.minimumTranslationVector = minkowskiDiff.getClosestPointOnBoundsToOrigin(); - /** - * - * @param first - * @param second - */ - public static circleToCircle(first: Circle, second: Circle){ - let result = new CollisionResult(); + if (result.minimumTranslationVector.equals(Vector2.zero)) + return false; - let distanceSquared = Vector2.distanceSquared(first.position, second.position); - let sumOfRadii = first.radius + second.radius; - let collided = distanceSquared < sumOfRadii * sumOfRadii; - if (collided){ - result.normal = Vector2.normalize(Vector2.subtract(first.position, second.position)); - let depth = sumOfRadii - Math.sqrt(distanceSquared); - result.minimumTranslationVector = Vector2.multiply(new Vector2(-depth), result.normal); - result.point = Vector2.add(second.position, Vector2.multiply(result.normal, new Vector2(second.radius))); + result.normal = new Vector2(-result.minimumTranslationVector.x, -result.minimumTranslationVector.y); + result.normal = result.normal.normalize(); - return result; + return true; + } + + return false; } - return null; - } + private static minkowskiDifference(first: Box, second: Box): Rectangle { + // 我们需要第一个框的左上角 + // 碰撞器只会修改运动的位置所以我们需要用位置来计算出运动是什么。 + let positionOffset = Vector2.subtract(first.position, Vector2.add(first.bounds.location, Vector2.divide(first.bounds.size, new Vector2(2)))); + let topLeft = Vector2.subtract(Vector2.add(first.bounds.location, positionOffset), second.bounds.max); + let fullSize = Vector2.add(first.bounds.size, second.bounds.size); - /** - * - * @param first - * @param second - */ - public static boxToBox(first: Box, second: Box){ - let result = new CollisionResult(); - - let minkowskiDiff = this.minkowskiDifference(first, second); - if (minkowskiDiff.containsInVec(new Vector2(0, 0))){ - // 计算MTV。如果它是零,我们就可以称它为非碰撞 - result.minimumTranslationVector = minkowskiDiff.getClosestPointOnBoundsToOrigin(); - - if (result.minimumTranslationVector.x == 0 && result.minimumTranslationVector.y == 0) - return null; - - result.normal = new Vector2(-result.minimumTranslationVector.x, -result.minimumTranslationVector.y); - result.normal.normalize(); - - return result; + return new Rectangle(topLeft.x, topLeft.y, fullSize.x, fullSize.y) } - return null; - } + public static lineToPoly(start: Vector2, end: Vector2, polygon: Polygon, hit: RaycastHit): boolean { + let normal = Vector2.zero; + let intersectionPoint = Vector2.zero; + let fraction = Number.MAX_VALUE; + let hasIntersection = false; - private static minkowskiDifference(first: Box, second: Box){ - // 我们需要第一个框的左上角 - // 碰撞器只会修改运动的位置所以我们需要用位置来计算出运动是什么。 - let positionOffset = Vector2.subtract(first.position, Vector2.add(first.bounds.location, Vector2.divide(first.bounds.size, new Vector2(2)))); - let topLeft = Vector2.subtract(Vector2.add(first.bounds.location, positionOffset), second.bounds.max); - let fullSize = Vector2.add(first.bounds.size, second.bounds.size); + for (let j = polygon.points.length - 1, i = 0; i < polygon.points.length; j = i, i ++){ + let edge1 = Vector2.add(polygon.position, polygon.points[j]); + let edge2 = Vector2.add(polygon.position, polygon.points[i]); + let intersection: Vector2 = Vector2.zero; + if (this.lineToLine(edge1, edge2, start, end, intersection)){ + hasIntersection = true; - return new Rectangle(topLeft.x, topLeft.y, fullSize.x, fullSize.y) + // TODO: 这是得到分数的正确和最有效的方法吗? + // 先检查x分数。如果是NaN,就用y代替 + let distanceFraction = (intersection.x - start.x) / (end.x - start.x); + if (Number.isNaN(distanceFraction) || Number.isFinite(distanceFraction)) + distanceFraction = (intersection.y - start.y) / (end.y - start.y); + + if (distanceFraction < fraction){ + let edge = Vector2.subtract(edge2, edge1); + normal = new Vector2(edge.y, -edge.x); + fraction = distanceFraction; + intersectionPoint = intersection; + } + } + } + + if (hasIntersection){ + normal = normal.normalize(); + let distance = Vector2.distance(start, intersectionPoint); + hit.setValuesNonCollider(fraction, distance, intersectionPoint, normal); + return true; + } + + return false; + } + + public static lineToLine(a1: Vector2, a2: Vector2, b1: Vector2, b2: Vector2, intersection: Vector2){ + let b = Vector2.subtract(a2, a1); + let d = Vector2.subtract(b2, b1); + let bDotDPerp = b.x * d.y - b.y * d.x; + + // 如果b*d = 0,表示这两条直线平行,因此有无穷个交点 + if (bDotDPerp == 0) + return false; + + let c = Vector2.subtract(b1, a1); + let t = (c.x * d.y - c.y * d.x) / bDotDPerp; + if (t < 0 || t > 1) + return false; + + let u = (c.x * b.y - c.y * b.x) / bDotDPerp; + if (u < 0 || u > 1) + return false; + + intersection = intersection.add(a1).add(Vector2.multiply(new Vector2(t), b)); + + return true; + } + + public static lineToCircle(start: Vector2, end: Vector2, s: Circle, hit: RaycastHit): boolean{ + // 计算这里的长度并分别对d进行标准化,因为如果我们命中了我们需要它来得到分数 + let lineLength = Vector2.distance(start, end); + let d = Vector2.divide(Vector2.subtract(end, start), new Vector2(lineLength)); + let m = Vector2.subtract(start, s.position); + let b = Vector2.dot(m, d); + let c = Vector2.dot(m, m) - s.radius * s.radius; + + // 如果r的原点在s之外,(c>0)和r指向s (b>0) 则返回 + if (c > 0 && b > 0) + return false; + + let discr = b * b - c; + // 线不在圆圈上 + if (discr < 0) + return false; + + // 射线相交圆 + hit.fraction = -b - Math.sqrt(discr); + + // 如果分数为负数,射线从圈内开始, + if (hit.fraction < 0) + hit.fraction = 0; + + hit.point = Vector2.add(start, Vector2.multiply(new Vector2(hit.fraction), d)); + hit.distance = Vector2.distance(start, hit.point); + hit.normal = Vector2.normalize(Vector2.subtract(hit.point, s.position)); + hit.fraction = hit.distance / lineLength; + + return true; + } + + /** + * 用second检查被deltaMovement移动的框的结果 + * @param first + * @param second + * @param movement + * @param hit + */ + public static boxToBoxCast(first: Box, second: Box, movement: Vector2, hit: RaycastHit): boolean{ + // 首先,我们检查是否有重叠。如果有重叠,我们就不做扫描测试 + let minkowskiDiff = this.minkowskiDifference(first, second); + if (minkowskiDiff.contains(0, 0)){ + // 计算MTV。如果它是零,我们就可以称它为非碰撞 + let mtv = minkowskiDiff.getClosestPointOnBoundsToOrigin(); + if (mtv.equals(Vector2.zero)) + return false; + + hit.normal = new Vector2(-mtv.x); + hit.normal = hit.normal.normalize(); + hit.distance = 0; + hit.fraction = 0; + + return true; + }else{ + // 射线投射移动矢量 + let ray = new Ray2D(Vector2.zero, new Vector2(-movement.x)); + let fraction: number = minkowskiDiff.rayIntersects(ray); + if (fraction <= 1){ + hit.fraction = fraction; + hit.distance = movement.length() * fraction; + hit.normal = new Vector2(-movement.x); + hit.normal = hit.normal.normalize(); + hit.centroid = Vector2.add(first.bounds.center, Vector2.multiply(movement, new Vector2(fraction))); + + return true; + } + } + + return false; + } } -} \ No newline at end of file +} diff --git a/source/src/Physics/Verlet/SpatialHash.ts b/source/src/Physics/Verlet/SpatialHash.ts index 205da0ed..44213b67 100644 --- a/source/src/Physics/Verlet/SpatialHash.ts +++ b/source/src/Physics/Verlet/SpatialHash.ts @@ -1,225 +1,350 @@ -class SpatialHash { - public gridBounds: Rectangle = new Rectangle(); +module es { + export class SpatialHash { + public gridBounds: Rectangle = new Rectangle(); - private _raycastParser: RaycastResultParser; - /** 散列中每个单元格的大小 */ - private _cellSize: number; - /** 1除以单元格大小。缓存结果,因为它被大量使用。 */ - private _inverseCellSize: number; - /** 缓存的循环用于重叠检查 */ - private _overlapTestCircle: Circle = new Circle(0); - /** 用于返回冲突信息的共享HashSet */ - private _tempHashSet: Collider[] = []; - /** 保存所有数据的字典 */ - private _cellDict: NumberDictionary = new NumberDictionary(); + public _raycastParser: RaycastResultParser; + /** + * 散列中每个单元格的大小 + */ + public _cellSize: number; + /** + * 1除以单元格大小。缓存结果,因为它被大量使用。 + */ + public _inverseCellSize: number; + /** + * 缓存的循环用于重叠检查 + */ + public _overlapTestCircle: Circle = new Circle(0); + /** + * 保存所有数据的字典 + */ + public _cellDict: NumberDictionary = new NumberDictionary(); + /** + * 用于返回冲突信息的共享HashSet + */ + public _tempHashSet: Collider[] = []; - constructor(cellSize: number = 100) { - this._cellSize = cellSize; - this._inverseCellSize = 1 / this._cellSize; - this._raycastParser = new RaycastResultParser(); - } - - /** - * 从SpatialHash中删除对象 - * @param collider - */ - public remove(collider: Collider) { - let bounds = collider.registeredPhysicsBounds; - let p1 = this.cellCoords(bounds.x, bounds.y); - let p2 = this.cellCoords(bounds.right, bounds.bottom); - - for (let x = p1.x; x <= p2.x; x++) { - for (let y = p1.y; y <= p2.y; y++) { - // 单元格应该始终存在,因为这个碰撞器应该在所有查询的单元格中 - let cell = this.cellAtPosition(x, y); - if (!cell) - console.error(`removing Collider [${collider}] from a cell that it is not present in`); - else - cell.remove(collider); - } - } - } - - /** - * 将对象添加到SpatialHash - * @param collider - */ - public register(collider: Collider) { - let bounds = collider.bounds; - collider.registeredPhysicsBounds = bounds; - let p1 = this.cellCoords(bounds.x, bounds.y); - let p2 = this.cellCoords(bounds.right, bounds.bottom); - - // 更新边界以跟踪网格大小 - if (!this.gridBounds.containsInVec(new Vector2(p1.x, p1.y))) { - this.gridBounds = RectangleExt.union(this.gridBounds, p1); + constructor(cellSize: number = 100) { + this._cellSize = cellSize; + this._inverseCellSize = 1 / this._cellSize; + this._raycastParser = new RaycastResultParser(); } - if (!this.gridBounds.containsInVec(new Vector2(p2.x, p2.y))) { - this.gridBounds = RectangleExt.union(this.gridBounds, p2); - } + /** + * 将对象添加到SpatialHash + * @param collider + */ + public register(collider: Collider) { + let bounds = collider.bounds; + collider.registeredPhysicsBounds = bounds; + let p1 = this.cellCoords(bounds.x, bounds.y); + let p2 = this.cellCoords(bounds.right, bounds.bottom); - for (let x = p1.x; x <= p2.x; x++) { - for (let y = p1.y; y <= p2.y; y++) { - // 如果没有单元格,我们需要创建它 - let c = this.cellAtPosition(x, y, true); - c.push(collider); - } - } - } - - public clear(){ - this._cellDict.clear(); - } - - /** - * 获取位于指定圆内的所有碰撞器 - * @param circleCenter - * @param radius - * @param results - * @param layerMask - */ - public overlapCircle(circleCenter: Vector2, radius: number, results: Collider[], layerMask) { - let bounds = new Rectangle(circleCenter.x - radius, circleCenter.y - radius, radius * 2, radius * 2); - - this._overlapTestCircle.radius = radius; - this._overlapTestCircle.position = circleCenter; - - let resultCounter = 0; - let aabbBroadphaseResult = this.aabbBroadphase(bounds, null, layerMask); - bounds = aabbBroadphaseResult.bounds; - let potentials = aabbBroadphaseResult.tempHashSet; - for (let i = 0; i < potentials.length; i++) { - let collider = potentials[i]; - if (collider instanceof BoxCollider) { - results[resultCounter] = collider; - resultCounter++; - } else { - throw new Error("overlapCircle against this collider type is not implemented!"); + // 更新边界以跟踪网格大小 + if (!this.gridBounds.contains(p1.x, p1.y)) { + this.gridBounds = RectangleExt.union(this.gridBounds, p1); } - if (resultCounter == results.length) - return resultCounter; - } + if (!this.gridBounds.contains(p2.x, p2.y)) { + this.gridBounds = RectangleExt.union(this.gridBounds, p2); + } - return resultCounter; - } - - /** - * 返回边框与单元格相交的所有对象 - * @param bounds - * @param excludeCollider - * @param layerMask - */ - public aabbBroadphase(bounds: Rectangle, excludeCollider: Collider, layerMask: number) { - this._tempHashSet.length = 0; - - let p1 = this.cellCoords(bounds.x, bounds.y); - let p2 = this.cellCoords(bounds.right, bounds.bottom); - - for (let x = p1.x; x <= p2.x; x++) { - for (let y = p1.y; y <= p2.y; y++) { - let cell = this.cellAtPosition(x, y); - if (!cell) - continue; - - // 当cell不为空。循环并取回所有碰撞器 - for (let i = 0; i < cell.length; i++) { - let collider = cell[i]; - - // 如果它是自身或者如果它不匹配我们的层掩码 跳过这个碰撞器 - if (collider == excludeCollider || !Flags.isFlagSet(layerMask, collider.physicsLayer)) - continue; - - if (bounds.intersects(collider.bounds)){ - if (this._tempHashSet.indexOf(collider) == -1) - this._tempHashSet.push(collider); - } + for (let x = p1.x; x <= p2.x; x++) { + for (let y = p1.y; y <= p2.y; y++) { + // 如果没有单元格,我们需要创建它 + let c: Collider[] = this.cellAtPosition(x, y, true); + if (!c.firstOrDefault(c => c.hashCode == collider.hashCode)) + c.push(collider); } } } - return {tempHashSet: this._tempHashSet, bounds: bounds}; - } + /** + * 从SpatialHash中删除对象 + * @param collider + */ + public remove(collider: Collider) { + let bounds = collider.registeredPhysicsBounds; + let p1 = this.cellCoords(bounds.x, bounds.y); + let p2 = this.cellCoords(bounds.right, bounds.bottom); - /** - * 获取世界空间x,y值的单元格。 - * 如果单元格为空且createCellIfEmpty为true,则会创建一个新的单元格 - * @param x - * @param y - * @param createCellIfEmpty - */ - private cellAtPosition(x: number, y: number, createCellIfEmpty: boolean = false) { - let cell: Collider[] = this._cellDict.tryGetValue(x, y); - if (!cell) { - if (createCellIfEmpty) { - cell = []; - this._cellDict.add(x, y, cell); + for (let x = p1.x; x <= p2.x; x++) { + for (let y = p1.y; y <= p2.y; y++) { + // 单元格应该始终存在,因为这个碰撞器应该在所有查询的单元格中 + let cell = this.cellAtPosition(x, y); + if (!cell) + console.error(`removing Collider [${collider}] from a cell that it is not present in`); + else + cell.remove(collider); + } } } - return cell; + + /** + * 使用蛮力方法从SpatialHash中删除对象 + * @param obj + */ + public removeWithBruteForce(obj: Collider) { + this._cellDict.remove(obj); + } + + public clear() { + this._cellDict.clear(); + } + + /** + * debug绘制空间散列的内容 + * @param secondsToDisplay + * @param textScale + */ + public debugDraw(secondsToDisplay: number, textScale: number = 1) { + for (let x = this.gridBounds.x; x <= this.gridBounds.right; x++) { + for (let y = this.gridBounds.y; y <= this.gridBounds.bottom; y++) { + let cell = this.cellAtPosition(x, y); + if (cell && cell.length > 0) + this.debugDrawCellDetails(x, y, cell.length, secondsToDisplay, textScale); + } + } + } + + /** + * 返回边框与单元格相交的所有对象 + * @param bounds + * @param excludeCollider + * @param layerMask + */ + public aabbBroadphase(bounds: Rectangle, excludeCollider: Collider, layerMask: number): Collider[] { + this._tempHashSet.length = 0; + + let p1 = this.cellCoords(bounds.x, bounds.y); + let p2 = this.cellCoords(bounds.right, bounds.bottom); + + for (let x = p1.x; x <= p2.x; x++) { + for (let y = p1.y; y <= p2.y; y++) { + let cell = this.cellAtPosition(x, y); + if (!cell) + continue; + + // 当cell不为空。循环并取回所有碰撞器 + for (let i = 0; i < cell.length; i++) { + let collider = cell[i]; + + // 如果它是自身或者如果它不匹配我们的层掩码 跳过这个碰撞器 + if (collider == excludeCollider || !Flags.isFlagSet(layerMask, collider.physicsLayer)) + continue; + + if (bounds.intersects(collider.bounds)) { + if (!this._tempHashSet.firstOrDefault(c => c.hashCode == collider.hashCode)) + this._tempHashSet.push(collider); + } + } + } + } + + return this._tempHashSet; + } + + /** + * 获取位于指定圆内的所有碰撞器 + * @param circleCenter + * @param radius + * @param results + * @param layerMask + */ + public overlapCircle(circleCenter: Vector2, radius: number, results: Collider[], layerMask): number { + let bounds = new Rectangle(circleCenter.x - radius, circleCenter.y - radius, radius * 2, radius * 2); + + this._overlapTestCircle.radius = radius; + this._overlapTestCircle.position = circleCenter; + + let resultCounter = 0; + let potentials = this.aabbBroadphase(bounds, null, layerMask); + for (let i = 0; i < potentials.length; i++) { + let collider = potentials[i]; + if (collider instanceof BoxCollider) { + results[resultCounter] = collider; + resultCounter++; + } else if (collider instanceof CircleCollider) { + if (collider.shape.overlaps(this._overlapTestCircle)) { + results[resultCounter] = collider; + resultCounter++; + } + } else if (collider instanceof PolygonCollider) { + if (collider.shape.overlaps(this._overlapTestCircle)) { + results[resultCounter] = collider; + resultCounter++; + } + } else { + throw new Error("overlapCircle against this collider type is not implemented!"); + } + + // 如果我们所有的结果数据有了则返回 + if (resultCounter == results.length) + return resultCounter; + } + + return resultCounter; + } + + /** + * 获取单元格的x,y值作为世界空间的x,y值 + * @param x + * @param y + */ + private cellCoords(x: number, y: number): Vector2 { + return new Vector2(Math.floor(x * this._inverseCellSize), Math.floor(y * this._inverseCellSize)); + } + + /** + * 获取世界空间x,y值的单元格。 + * 如果单元格为空且createCellIfEmpty为true,则会创建一个新的单元格 + * @param x + * @param y + * @param createCellIfEmpty + */ + private cellAtPosition(x: number, y: number, createCellIfEmpty: boolean = false): Collider[] { + let cell: Collider[] = this._cellDict.tryGetValue(x, y); + if (!cell) { + if (createCellIfEmpty) { + cell = []; + this._cellDict.add(x, y, cell); + } + } + return cell; + } + + private debugDrawCellDetails(x: number, y: number, cellCount: number, secondsToDisplay = 0.5, textScale = 1) { + + } } /** - * 获取单元格的x,y值作为世界空间的x,y值 - * @param x - * @param y + * 包装一个Unit32,列表碰撞器字典 + * 它的主要目的是将int、int x、y坐标散列到单个Uint32键中,使用O(1)查找。 */ - private cellCoords(x: number, y: number): Vector2 { - return new Vector2(Math.floor(x * this._inverseCellSize), Math.floor(y * this._inverseCellSize)); + export class NumberDictionary { + public _store: Map = new Map(); + + public add(x: number, y: number, list: Collider[]) { + this._store.set(this.getKey(x, y), list); + } + + /** + * 使用蛮力方法从字典存储列表中移除碰撞器 + * @param obj + */ + public remove(obj: Collider) { + this._store.forEach(list => { + if (list.contains(obj)) + list.remove(obj); + }) + } + + public tryGetValue(x: number, y: number): Collider[] { + return this._store.get(this.getKey(x, y)); + } + + /** + * 清除字典数据 + */ + public clear() { + this._store.clear(); + } + + /** + * 根据x和y值计算并返回散列键 + * @param x + * @param y + */ + private getKey(x: number, y: number): string { + return Long.fromNumber(x).shiftLeft(32).or(Long.fromNumber(y, true)).toString(); + } + } + + export class RaycastResultParser { + public hitCounter: number; + public static compareRaycastHits = (a: RaycastHit, b: RaycastHit) => { + return a.distance - b.distance; + }; + + public _hits: RaycastHit[]; + public _tempHit: RaycastHit; + public _checkedColliders: Collider[] = []; + public _cellHits: RaycastHit[] = []; + public _ray: Ray2D; + public _layerMask: number; + + public start(ray: Ray2D, hits: RaycastHit[], layerMask: number) { + this._ray = ray; + this._hits = hits; + this._layerMask = layerMask; + this.hitCounter = 0; + } + + /** + * 如果hits数组被填充,返回true。单元格不能为空! + * @param cellX + * @param cellY + * @param cell + */ + public checkRayIntersection(cellX: number, cellY: number, cell: Collider[]): boolean { + let fraction: number = 0; + for (let i = 0; i < cell.length; i++) { + let potential = cell[i]; + + // 管理我们已经处理过的碰撞器 + if (this._checkedColliders.contains(potential)) + continue; + + this._checkedColliders.push(potential); + // 只有当我们被设置为这样做时才会点击触发器 + if (potential.isTrigger && !Physics.raycastsHitTriggers) + continue; + + // 确保碰撞器在图层蒙版上 + if (!Flags.isFlagSet(this._layerMask, potential.physicsLayer)) + continue; + + // TODO: rayIntersects的性能够吗?需要测试它。Collisions.rectToLine可能更快 + // TODO: 如果边界检查返回更多数据,我们就不需要为BoxCollider检查做任何事情 + // 在做形状测试之前先做一个边界检查 + let colliderBounds = potential.bounds; + let fraction = colliderBounds.rayIntersects(this._ray); + if (fraction <= 1) { + if (potential.shape.collidesWithLine(this._ray.start, this._ray.end, this._tempHit)) { + // 检查一下,我们应该排除这些射线,射线cast是否在碰撞器中开始 + if (!Physics.raycastsStartInColliders && potential.shape.containsPoint(this._ray.start)) + continue; + + // TODO: 确保碰撞点在当前单元格中,如果它没有保存它以供以后计算 + + this._tempHit.collider = potential; + this._cellHits.push(this._tempHit); + } + } + } + + if (this._cellHits.length == 0) + return false; + + // 所有处理单元完成。对结果进行排序并将命中结果打包到结果数组中 + this._cellHits.sort(RaycastResultParser.compareRaycastHits); + for (let i = 0; i < this._cellHits.length; i ++){ + this._hits[this.hitCounter] = this._cellHits[i]; + + // 增加命中计数器,如果它已经达到数组大小的限制,我们就完成了 + this.hitCounter ++; + if (this.hitCounter == this._hits.length) + return true; + } + + return false; + } + + public reset(){ + this._hits = null; + this._checkedColliders.length = 0; + this._cellHits.length = 0; + } } } - -class RaycastResultParser { - -} - -/** - * 包装一个Unit32,列表碰撞器字典 - * 它的主要目的是将int、int x、y坐标散列到单个Uint32键中,使用O(1)查找。 - */ -class NumberDictionary { - private _store: Map = new Map(); - - /** - * 根据x和y值计算并返回散列键 - * @param x - * @param y - */ - private getKey(x: number, y: number): number { - return Long.fromNumber(x).shiftLeft(32).or(this.intToUint(y)).toString(); - } - - private intToUint(i) { - if (i >= 0) - return i; - else - return 4294967296 + i; - } - - public add(x: number, y: number, list: Collider[]) { - this._store.set(this.getKey(x, y), list); - } - - /** - * 使用蛮力方法从字典存储列表中移除碰撞器 - * @param obj - */ - public remove(obj: Collider) { - this._store.forEach(list => { - if (list.contains(obj)) - list.remove(obj); - }) - } - - public tryGetValue(x: number, y: number): Collider[] { - return this._store.get(this.getKey(x, y)); - } - - /** - * 清除字典数据 - */ - public clear() { - this._store.clear(); - } -} \ No newline at end of file diff --git a/source/src/Utils/Analysis/Layout.ts b/source/src/Utils/Analysis/Layout.ts new file mode 100644 index 00000000..dc9468c9 --- /dev/null +++ b/source/src/Utils/Analysis/Layout.ts @@ -0,0 +1,71 @@ +module es { + /** + * 支持标题安全区的布局类。 + */ + export class Layout { + public clientArea: Rectangle; + public safeArea: Rectangle; + + constructor() { + this.clientArea = new Rectangle(0, 0, Core.graphicsDevice.viewport.width, Core.graphicsDevice.viewport.height); + this.safeArea = this.clientArea; + } + + public place(size: Vector2, horizontalMargin: number, verticalMargine: number, alignment: Alignment) { + let rc = new Rectangle(0, 0, size.x, size.y); + if ((alignment & Alignment.left) != 0) { + rc.x = this.clientArea.x + (this.clientArea.width * horizontalMargin); + } else if ((alignment & Alignment.right) != 0) { + rc.x = this.clientArea.x + (this.clientArea.width * (1 - horizontalMargin)) - rc.width; + } else if ((alignment & Alignment.horizontalCenter) != 0) { + rc.x = this.clientArea.x + (this.clientArea.width - rc.width) / 2 + (horizontalMargin * this.clientArea.width); + } else { + + } + + if ((alignment & Alignment.top) != 0) { + rc.y = this.clientArea.y + (this.clientArea.height * verticalMargine); + } else if ((alignment & Alignment.bottom) != 0) { + rc.y = this.clientArea.y + (this.clientArea.height * (1 - verticalMargine)) - rc.height; + } else if ((alignment & Alignment.verticalCenter) != 0) { + rc.y = this.clientArea.y + (this.clientArea.height - rc.height) / 2 + (verticalMargine * this.clientArea.height); + } else { + + } + + // 确保布局区域在安全区域内。 + if (rc.left < this.safeArea.left) + rc.x = this.safeArea.left; + + if (rc.right > this.safeArea.right) + rc.x = this.safeArea.right - rc.width; + + if (rc.top < this.safeArea.top) + rc.y = this.safeArea.top; + + if (rc.bottom > this.safeArea.bottom) + rc.y = this.safeArea.bottom - rc.height; + + return rc; + } + } + + export enum Alignment { + none = 0, + left = 1, + right = 2, + horizontalCenter = 4, + top = 8, + bottom = 16, + verticalCenter = 32, + topLeft = top | left, + topRight = top | right, + topCenter = top | horizontalCenter, + bottomLeft = bottom | left, + bottomRight = bottom | right, + bottomCenter = bottom | horizontalCenter, + centerLeft = verticalCenter | left, + centerRight = verticalCenter | right, + center = verticalCenter | horizontalCenter + } +} diff --git a/source/src/Utils/Analysis/Stopwatch.ts b/source/src/Utils/Analysis/Stopwatch.ts new file mode 100644 index 00000000..2b630d29 --- /dev/null +++ b/source/src/Utils/Analysis/Stopwatch.ts @@ -0,0 +1,234 @@ +namespace stopwatch { + /** + * 记录时间的持续时间,一些设计灵感来自物理秒表。 + */ + export class Stopwatch { + /** + * 秒表启动的系统时间。 + * undefined,如果秒表尚未启动,或已复位。 + */ + private _startSystemTime: number | undefined; + /** + * 秒表停止的系统时间。 + * undefined,如果秒表目前没有停止,尚未开始,或已复位。 + */ + private _stopSystemTime: number | undefined; + /** 自上次复位以来,秒表已停止的系统时间总数。 */ + private _stopDuration: number = 0; + /** + * 用秒表计时,当前等待的切片开始的时间。 + * undefined,如果秒表尚未启动,或已复位。 + */ + private _pendingSliceStartStopwatchTime: number | undefined; + /** + * 记录自上次复位以来所有已完成切片的结果。 + */ + private _completeSlices: Slice[] = []; + + constructor(private readonly getSystemTime = _defaultSystemTimeGetter) { + } + + public getState() { + if (this._startSystemTime === undefined) { + return State.IDLE; + } else if (this._stopSystemTime === undefined) { + return State.RUNNING; + } else { + return State.STOPPED; + } + } + + public isIdle() { + return this.getState() === State.IDLE; + } + + public isRunning() { + return this.getState() === State.RUNNING; + } + + public isStopped() { + return this.getState() === State.STOPPED; + } + + /** + * + */ + public slice() { + return this.recordPendingSlice(); + } + + /** + * 获取自上次复位以来该秒表已完成/记录的所有片的列表。 + */ + public getCompletedSlices(): Slice[] { + return Array.from(this._completeSlices); + } + + /** + * 获取自上次重置以来该秒表已完成/记录的所有片的列表,以及当前挂起的片。 + */ + public getCompletedAndPendingSlices(): Slice[] { + return [...this._completeSlices, this.getPendingSlice()]; + } + + /** + * 获取关于这个秒表当前挂起的切片的详细信息。 + */ + public getPendingSlice(): Slice { + return this.calculatePendingSlice(); + } + + /** + * 获取当前秒表时间。这是这个秒表自上次复位以来运行的系统时间总数。 + */ + public getTime() { + return this.caculateStopwatchTime(); + } + + /** + * 完全重置这个秒表到它的初始状态。清除所有记录的运行持续时间、切片等。 + */ + public reset() { + this._startSystemTime = this._pendingSliceStartStopwatchTime = this._stopSystemTime = undefined; + this._stopDuration = 0; + this._completeSlices = []; + } + + /** + * 开始(或继续)运行秒表。 + * @param forceReset + */ + public start(forceReset: boolean = false) { + if (forceReset) { + this.reset(); + } + + if (this._stopSystemTime !== undefined) { + const systemNow = this.getSystemTime(); + const stopDuration = systemNow - this._stopSystemTime; + + this._stopDuration += stopDuration; + this._stopSystemTime = undefined; + } else if (this._startSystemTime === undefined) { + const systemNow = this.getSystemTime(); + this._startSystemTime = systemNow; + this._pendingSliceStartStopwatchTime = 0; + } + } + + /** + * + * @param recordPendingSlice + */ + public stop(recordPendingSlice: boolean = false) { + if (this._startSystemTime === undefined) { + return 0; + } + + const systemTimeOfStopwatchTime = this.getSystemTimeOfCurrentStopwatchTime(); + + if (recordPendingSlice) { + this.recordPendingSlice(this.caculateStopwatchTime(systemTimeOfStopwatchTime)); + } + + this._stopSystemTime = systemTimeOfStopwatchTime; + return this.getTime(); + } + + /** + * 计算指定秒表时间的当前挂起片。 + * @param endStopwatchTime + */ + private calculatePendingSlice(endStopwatchTime?: number): Slice { + if (this._pendingSliceStartStopwatchTime === undefined) { + return Object.freeze({startTime: 0, endTime: 0, duration: 0}); + } + + if (endStopwatchTime === undefined) { + endStopwatchTime = this.getTime(); + } + + return Object.freeze({ + startTime: this._pendingSliceStartStopwatchTime, + endTime: endStopwatchTime, + duration: endStopwatchTime - this._pendingSliceStartStopwatchTime + }); + } + + /** + * 计算指定系统时间的当前秒表时间。 + * @param endSystemTime + */ + private caculateStopwatchTime(endSystemTime?: number) { + if (this._startSystemTime === undefined) + return 0; + + if (endSystemTime === undefined) + endSystemTime = this.getSystemTimeOfCurrentStopwatchTime(); + + return endSystemTime - this._startSystemTime - this._stopDuration; + } + + /** + * 获取与当前秒表时间等效的系统时间。 + * 如果该秒表当前停止,则返回该秒表停止时的系统时间。 + */ + private getSystemTimeOfCurrentStopwatchTime() { + return this._stopSystemTime === undefined ? this.getSystemTime() : this._stopSystemTime; + } + + /** + * 结束/记录当前挂起的片的私有实现。 + * @param endStopwatchTime + */ + private recordPendingSlice(endStopwatchTime?: number) { + if (this._pendingSliceStartStopwatchTime !== undefined) { + if (endStopwatchTime === undefined) { + endStopwatchTime = this.getTime(); + } + + const slice = this.calculatePendingSlice(endStopwatchTime); + + this._pendingSliceStartStopwatchTime = slice.endTime; + this._completeSlices.push(slice); + return slice; + } else { + return this.calculatePendingSlice(); + } + } + } + + /** + * 返回某个系统的“当前时间”的函数。 + * 惟一的要求是,对该函数的每次调用都必须返回一个大于或等于前一次对该函数的调用的数字。 + */ + export type GetTimeFunc = () => number; + + enum State { + /** 秒表尚未启动,或已复位。 */ + IDLE = "IDLE", + /** 秒表正在运行。 */ + RUNNING = "RUNNING", + /** 秒表以前还在跑,但现在已经停了。 */ + STOPPED = "STOPPED" + } + + export function setDefaultSystemTimeGetter(systemTimeGetter: GetTimeFunc = Date.now) { + _defaultSystemTimeGetter = systemTimeGetter; + } + + /** + * 由秒表记录的单个“薄片”的测量值 + */ + interface Slice { + /** 秒表显示的时间在这一片开始的时候。 */ + readonly startTime: number; + /** 秒表在这片片尾的时间。 */ + readonly endTime: number; + /** 该切片的运行时间 */ + readonly duration: number; + } + + /** 所有新实例的默认“getSystemTime”实现 */ + let _defaultSystemTimeGetter: GetTimeFunc = Date.now; +} diff --git a/source/src/Utils/Analysis/TimeRuler.ts b/source/src/Utils/Analysis/TimeRuler.ts new file mode 100644 index 00000000..696b1971 --- /dev/null +++ b/source/src/Utils/Analysis/TimeRuler.ts @@ -0,0 +1,357 @@ +module es { + /** + * 通过使用这个类,您可以直观地找到瓶颈和基本的CPU使用情况。 + */ + export class TimeRuler { + /** 最大条数 8 */ + public static readonly maxBars = 8; + /** */ + public static readonly maxSamples = 256; + /** 每条的最大嵌套调用 */ + public static readonly maxNestCall = 32; + /** 条的高度(以像素为单位) */ + public static readonly barHeight = 8; + /** 最大显示帧 */ + public static readonly maxSampleFrames = 4; + /** 持续时间(帧数)为采取抓拍日志。 */ + public static readonly logSnapDuration = 120; + public static readonly barPadding = 2; + public static readonly autoAdjustDelay = 30; + private static _instance; + /** 获取/设置目标样本帧。 */ + public targetSampleFrames: number; + /** 获取/设置计时器标尺宽度。 */ + public width: number; + public enabled: true; + /** */ + public showLog = false; + private _frameKey = 'frame'; + private _logKey = 'log'; + /** 每帧的日志 */ + private _logs: FrameLog[]; + /** 当前显示帧计数 */ + private sampleFrames: number; + /** TimerRuler画的位置。 */ + private _position: Vector2; + /** 上一帧日志 */ + private _prevLog: FrameLog; + /** 当前帧日志 */ + private _curLog: FrameLog; + /** 当前帧数量 */ + private frameCount: number; + /** */ + private markers: MarkerInfo[] = []; + /** 秒表用来测量时间。 */ + private stopwacth: stopwatch.Stopwatch = new stopwatch.Stopwatch(); + /** 从标记名映射到标记id的字典。 */ + private _markerNameToIdMap: Map = new Map(); + /** + * 你想在游戏开始时调用StartFrame更新方法。 + * 当游戏在固定时间步进模式下运行缓慢时,更新会多次调用。 + * 在这种情况下,我们应该忽略StartFrame调用。 + * 为此,我们只需一直跟踪StartFrame调用的次数,直到Draw被调用。 + */ + private _updateCount: number; + private _frameAdjust: number; + + constructor() { + this._logs = new Array(2); + for (let i = 0; i < this._logs.length; ++i) + this._logs[i] = new FrameLog(); + + this.sampleFrames = this.targetSampleFrames = 1; + this.width = Core.graphicsDevice.viewport.width * 0.8; + + es.Core.emitter.addObserver(CoreEvents.GraphicsDeviceReset, this.onGraphicsDeviceReset, this); + this.onGraphicsDeviceReset(); + } + + public static get Instance(): TimeRuler { + if (!this._instance) + this._instance = new TimeRuler(); + return this._instance; + } + + /** + * + */ + public startFrame() { + // 当这个方法被多次调用时,我们跳过重置帧。 + let lock = new LockUtils(this._frameKey); + lock.lock().then(() => { + this._updateCount = parseInt(egret.localStorage.getItem(this._frameKey), 10); + if (isNaN(this._updateCount)) + this._updateCount = 0; + let count = this._updateCount; + count += 1; + egret.localStorage.setItem(this._frameKey, count.toString()); + if (this.enabled && (1 < count && count < TimeRuler.maxSampleFrames)) + return; + + // 更新当前帧日志。 + this._prevLog = this._logs[this.frameCount++ & 0x1]; + this._curLog = this._logs[this.frameCount & 0x1]; + + let endFrameTime = this.stopwacth.getTime(); + // 更新标记并创建日志。 + for (let barIndex = 0; barIndex < this._prevLog.bars.length; ++barIndex) { + let prevBar = this._prevLog.bars[barIndex]; + let nextBar = this._curLog.bars[barIndex]; + + // 重新打开在前一帧中没有调用结束标记的标记。 + for (let nest = 0; nest < prevBar.nestCount; ++nest) { + let markerIdx = prevBar.markerNests[nest]; + prevBar.markers[markerIdx].endTime = endFrameTime; + nextBar.markerNests[nest] = nest; + nextBar.markers[nest].markerId = prevBar.markers[markerIdx].markerId; + nextBar.markers[nest].beginTime = 0; + nextBar.markers[nest].endTime = -1; + nextBar.markers[nest].color = prevBar.markers[markerIdx].color; + } + + // 更新日志标记 + for (let markerIdx = 0; markerIdx < prevBar.markCount; ++markerIdx) { + let duration = prevBar.markers[markerIdx].endTime - prevBar.markers[markerIdx].beginTime; + let markerId = prevBar.markers[markerIdx].markerId; + let m = this.markers[markerId]; + + m.logs[barIndex].color = prevBar.markers[markerIdx].color; + if (!m.logs[barIndex].initialized) { + m.logs[barIndex].min = duration; + m.logs[barIndex].max = duration; + m.logs[barIndex].avg = duration; + m.logs[barIndex].initialized = true; + } else { + m.logs[barIndex].min = Math.min(m.logs[barIndex].min, duration); + m.logs[barIndex].max = Math.min(m.logs[barIndex].max, duration); + m.logs[barIndex].avg += duration; + m.logs[barIndex].avg *= 0.5; + + if (m.logs[barIndex].samples++ >= TimeRuler.logSnapDuration) { + m.logs[barIndex].snapMin = m.logs[barIndex].min; + m.logs[barIndex].snapMax = m.logs[barIndex].max; + m.logs[barIndex].snapAvg = m.logs[barIndex].avg; + m.logs[barIndex].samples = 0; + } + } + } + + nextBar.markCount = prevBar.nestCount; + nextBar.nestCount = prevBar.nestCount; + } + + this.stopwacth.reset(); + this.stopwacth.start(); + }); + } + + /** + * 开始测量时间。 + * @param markerName + * @param color + */ + public beginMark(markerName: string, color: number, barIndex: number = 0) { + let lock = new LockUtils(this._frameKey); + lock.lock().then(() => { + if (barIndex < 0 || barIndex >= TimeRuler.maxBars) + throw new Error("barIndex argument out of range"); + + let bar = this._curLog.bars[barIndex]; + if (bar.markCount >= TimeRuler.maxSamples) { + throw new Error("exceeded sample count. either set larger number to timeruler.maxsaple or lower sample count"); + } + + if (bar.nestCount >= TimeRuler.maxNestCall) { + throw new Error("exceeded nest count. either set larger number to timeruler.maxnestcall or lower nest calls"); + } + + // 获取注册的标记 + let markerId = this._markerNameToIdMap.get(markerName); + if (isNaN(markerId)) { + // 如果此标记未注册,则注册此标记。 + markerId = this.markers.length; + this._markerNameToIdMap.set(markerName, markerId); + } + + bar.markerNests[bar.nestCount++] = bar.markCount; + bar.markers[bar.markCount].markerId = markerId; + bar.markers[bar.markCount].color = color; + bar.markers[bar.markCount].beginTime = this.stopwacth.getTime(); + bar.markers[bar.markCount].endTime = -1; + }); + } + + /** + * + * @param markerName + * @param barIndex + */ + public endMark(markerName: string, barIndex: number = 0) { + let lock = new LockUtils(this._frameKey); + lock.lock().then(() => { + if (barIndex < 0 || barIndex >= TimeRuler.maxBars) + throw new Error("barIndex argument out of range"); + + let bar = this._curLog.bars[barIndex]; + if (bar.nestCount <= 0) { + throw new Error("call beginMark method before calling endMark method"); + } + + let markerId = this._markerNameToIdMap.get(markerName); + if (isNaN(markerId)) { + throw new Error(`Marker ${markerName} is not registered. Make sure you specifed same name as you used for beginMark method`); + } + + let markerIdx = bar.markerNests[--bar.nestCount]; + if (bar.markers[markerIdx].markerId != markerId) { + throw new Error("Incorrect call order of beginMark/endMark method. beginMark(A), beginMark(B), endMark(B), endMark(A) But you can't called it like beginMark(A), beginMark(B), endMark(A), endMark(B)."); + } + + bar.markers[markerIdx].endTime = this.stopwacth.getTime(); + }); + } + + /** + * 获取给定bar索引和标记名称的平均时间。 + * @param barIndex + * @param markerName + */ + public getAverageTime(barIndex: number, markerName: string) { + if (barIndex < 0 || barIndex >= TimeRuler.maxBars) { + throw new Error("barIndex argument out of range"); + } + let result = 0; + let markerId = this._markerNameToIdMap.get(markerName); + if (markerId) { + result = this.markers[markerId].logs[barIndex].avg; + } + + return result; + } + + /** + * + */ + public resetLog() { + let lock = new LockUtils(this._logKey); + lock.lock().then(() => { + let count = parseInt(egret.localStorage.getItem(this._logKey), 10); + count += 1; + egret.localStorage.setItem(this._logKey, count.toString()); + this.markers.forEach(markerInfo => { + for (let i = 0; i < markerInfo.logs.length; ++i) { + markerInfo.logs[i].initialized = false; + markerInfo.logs[i].snapMin = 0; + markerInfo.logs[i].snapMax = 0; + markerInfo.logs[i].snapAvg = 0; + + markerInfo.logs[i].min = 0; + markerInfo.logs[i].max = 0; + markerInfo.logs[i].avg = 0; + + markerInfo.logs[i].samples = 0; + } + }); + }); + } + + public render(position: Vector2 = this._position, width: number = this.width) { + egret.localStorage.setItem(this._frameKey, "0"); + + if (!this.showLog) + return; + + let height = 0; + let maxTime = 0; + this._prevLog.bars.forEach(bar => { + if (bar.markCount > 0) { + height += TimeRuler.barHeight + TimeRuler.barPadding * 2; + maxTime = Math.max(maxTime, bar.markers[bar.markCount - 1].endTime); + } + }); + + const frameSpan = 1 / 60 * 1000; + let sampleSpan = this.sampleFrames * frameSpan; + + if (maxTime > sampleSpan) { + this._frameAdjust = Math.max(0, this._frameAdjust) + 1; + } else { + this._frameAdjust = Math.min(0, this._frameAdjust) - 1; + } + + if (Math.max(this._frameAdjust) > TimeRuler.autoAdjustDelay) { + this.sampleFrames = Math.min(TimeRuler.maxSampleFrames, this.sampleFrames); + this.sampleFrames = Math.max(this.targetSampleFrames, (maxTime / frameSpan) + 1); + + this._frameAdjust = 0; + } + + let msToPs = width / sampleSpan; + let startY = position.y - (height - TimeRuler.barHeight); + let y = startY; + + // TODO: draw + } + + private onGraphicsDeviceReset() { + let layout = new Layout(); + this._position = layout.place(new Vector2(this.width, TimeRuler.barHeight), 0, 0.01, Alignment.bottomCenter).location; + } + } + + /** + * 日志信息 + */ + export class FrameLog { + public bars: MarkerCollection[]; + + constructor() { + this.bars = new Array(TimeRuler.maxBars); + this.bars.fill(new MarkerCollection(), 0, TimeRuler.maxBars); + } + } + + /** + * 标记的集合 + */ + export class MarkerCollection { + public markers: Marker[] = new Array(TimeRuler.maxSamples); + public markCount: number = 0; + public markerNests: number[] = new Array(TimeRuler.maxNestCall); + public nestCount: number = 0; + + constructor() { + this.markers.fill(new Marker(), 0, TimeRuler.maxSamples); + this.markerNests.fill(0, 0, TimeRuler.maxNestCall); + } + } + + export class Marker { + public markerId: number = 0; + public beginTime: number = 0; + public endTime: number = 0; + public color: number = 0x000000; + } + + export class MarkerInfo { + public name: string; + public logs: MarkerLog[] = new Array(TimeRuler.maxBars); + + constructor(name) { + this.name = name; + this.logs.fill(new MarkerLog(), 0, TimeRuler.maxBars); + } + } + + export class MarkerLog { + public snapMin: number = 0; + public snapMax: number = 0; + public snapAvg: number = 0; + public min: number = 0; + public max: number = 0; + public avg: number = 0; + public samples: number = 0; + public color: number = 0x000000; + public initialized: boolean = false; + } +} diff --git a/source/src/Utils/ArrayUtils.ts b/source/src/Utils/ArrayUtils.ts new file mode 100644 index 00000000..be6ecd6b --- /dev/null +++ b/source/src/Utils/ArrayUtils.ts @@ -0,0 +1,240 @@ +class ArrayUtils { + /** + * 执行冒泡排序 + * @param ary + * 算法参考 -- http://www.hiahia.org/datastructure/paixu/paixu8.3.1.1-1.htm + */ + public static bubbleSort(ary: number[]): void { + let isExchange: Boolean = false; + for (let i: number = 0; i < ary.length; i++) { + isExchange = false; + for (let j: number = ary.length - 1; j > i; j--) { + if (ary[j] < ary[j - 1]) { + let temp: number = ary[j]; + ary[j] = ary[j - 1]; + ary[j - 1] = temp; + isExchange = true; + } + } + if (!isExchange) + break; + } + } + + + /** + * 执行插入排序 + * @param ary + */ + public static insertionSort(ary: number[]): void { + let len: number = ary.length; + for (let i: number = 1; i < len; i++) { + let val: number = ary[i]; + for (var j: number = i; j > 0 && ary[j - 1] > val; j--) { + ary[j] = ary[j - 1]; + } + ary[j] = val; + } + } + + /** + * 执行二分搜索 + * @param ary 搜索的数组(必须排序过) + * @param value 需要搜索的值 + * @return 返回匹配结果的数组索引 + */ + public static binarySearch(ary: number[], value: number): number { + let startIndex: number = 0; + let endIndex: number = ary.length; + let sub: number = (startIndex + endIndex) >> 1; + while (startIndex < endIndex) { + if (value <= ary[sub]) endIndex = sub; + else if (value >= ary[sub]) startIndex = sub + 1; + sub = (startIndex + endIndex) >> 1; + } + if (ary[startIndex] == value) return startIndex; + return -1; + } + + + /** + * 返回匹配项的索引 + * @param ary + * @param num + * @return 返回匹配项的索引 + */ + public static findElementIndex(ary: any[], num: any): any { + let len: number = ary.length; + for (let i: number = 0; i < len; ++i) { + if (ary[i] == num) + return i; + } + return null; + } + + /** + * 返回数组中最大值的索引 + * @param ary + * @return 返回数组中最大值的索引 + */ + public static getMaxElementIndex(ary: number[]): number { + let matchIndex: number = 0; + let len: number = ary.length; + for (let j: number = 1; j < len; j++) { + if (ary[j] > ary[matchIndex]) + matchIndex = j; + } + return matchIndex; + } + + /** + * 返回数组中最小值的索引 + * @param ary + * @return 返回数组中最小值的索引 + */ + public static getMinElementIndex(ary: number[]): number { + let matchIndex: number = 0; + let len: number = ary.length; + for (let j: number = 1; j < len; j++) { + if (ary[j] < ary[matchIndex]) + matchIndex = j; + } + return matchIndex; + } + + /** + * 返回一个"唯一性"数组 + * @param ary 需要唯一性的数组 + * @return 唯一性的数组 + * 比如: [1, 2, 2, 3, 4] + * 返回: [1, 2, 3, 4] + */ + public static getUniqueAry(ary: number[]): number[] { + let uAry: number[] = []; + let newAry: number[] = []; + let count = ary.length; + for (let i: number = 0; i < count; ++i) { + let value: number = ary[i]; + if (uAry.indexOf(value) == -1) uAry.push(value); + } + + count = uAry.length; + for (let i: number = count - 1; i >= 0; --i) { + newAry.unshift(uAry[i]); + } + return newAry; + } + + + /** + * 返回2个数组中不同的部分 + * 比如数组A = [1, 2, 3, 4, 6] + * 数组B = [0, 2, 1, 3, 4] + * 返回[6, 0] + * @param aryA + * @param aryB + * @return + */ + public static getDifferAry(aryA: number[], aryB: number[]): number[] { + aryA = this.getUniqueAry(aryA); + aryB = this.getUniqueAry(aryB); + let ary: number[] = aryA.concat(aryB); + let uObj: Object = {}; + let newAry: number[] = []; + let count: number = ary.length; + for (let j: number = 0; j < count; ++j) { + if (!uObj[ary[j]]) { + uObj[ary[j]] = {}; + uObj[ary[j]].count = 0; + uObj[ary[j]].key = ary[j]; + uObj[ary[j]].count++; + } else { + if (uObj[ary[j]] instanceof Object) { + uObj[ary[j]].count++; + } + } + } + for (let i in uObj) { + if (uObj[i].count != 2) { + newAry.unshift(uObj[i].key); + } + } + return newAry; + } + + /** + * 交换数组元素 + * @param array 目标数组 + * @param index1 交换后的索引 + * @param index2 交换前的索引 + */ + public static swap(array: any[], index1: number, index2: number): void { + let temp: any = array[index1]; + array[index1] = array[index2]; + array[index2] = temp; + } + + + /** + * 清除列表 + * @param ary 列表 + */ + public static clearList(ary: any[]): void { + if (!ary) return; + let length: number = ary.length; + for (let i: number = length - 1; i >= 0; i -= 1) { + ary.splice(i, 1); + } + } + + /** + * 克隆一个数组 + * @param ary 需要克隆的数组 + * @return 克隆的数组 + */ + public static cloneList(ary: any[]): any[] { + if (!ary) return null; + return ary.slice(0, ary.length); + } + + + /** + * 判断2个数组是否相同 + * @param ary1 数组1 + * @param ary2 数组2 + * @return 是否相同 + */ + public static equals(ary1: number[], ary2: number[]): Boolean { + if (ary1 == ary2) return true; + let length: number = ary1.length; + if (length != ary2.length) return false; + while (length--) { + if (ary1[length] != ary2[length]) + return false; + } + return true; + } + + + /** + * 根据索引插入元素,索引和索引后的元素都向后移动一位 + * @param index 插入索引 + * @param value 插入的元素 + * @return 插入的元素 未插入则返回空 + */ + public static insert(ary: any[], index: number, value: any): any { + if (!ary) return null; + let length: number = ary.length; + if (index > length) index = length; + if (index < 0) index = 0; + if (index == length) ary.push(value); //插入最后 + else if (index == 0) ary.unshift(value); //插入头 + else { + for (let i: number = length - 1; i >= index; i -= 1) { + ary[i + 1] = ary[i]; + } + ary[index] = value; + } + return value; + } +} \ No newline at end of file diff --git a/source/src/Utils/Base64Utils.ts b/source/src/Utils/Base64Utils.ts new file mode 100644 index 00000000..5586731d --- /dev/null +++ b/source/src/Utils/Base64Utils.ts @@ -0,0 +1,124 @@ +class Base64Utils { + private static _keyNum = "0123456789+/"; + private static _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + private static _keyAll = Base64Utils._keyNum + Base64Utils._keyStr; + /** + * 加密 + * @param input + */ + public static encode = function (input) { + let output = ""; + let chr1, chr2, chr3, enc1, enc2, enc3, enc4; + let i = 0; + input = this._utf8_encode(input); + while (i < input.length) { + chr1 = input.charCodeAt(i++); + chr2 = input.charCodeAt(i++); + chr3 = input.charCodeAt(i++); + enc1 = chr1 >> 2; + enc2 = ((chr1 & 3) << 4) | (chr2 >> 4); + enc3 = ((chr2 & 15) << 2) | (chr3 >> 6); + enc4 = chr3 & 63; + if (isNaN(chr2)) { + enc3 = enc4 = 64; + } else if (isNaN(chr3)) { + enc4 = 64; + } + output = output + + this._keyAll.charAt(enc1) + this._keyAll.charAt(enc2) + + this._keyAll.charAt(enc3) + this._keyAll.charAt(enc4); + } + return this._keyStr.charAt(Math.floor((Math.random() * this._keyStr.length))) + output; + }; + + /** + * 解码 + * @param input + * @param isNotStr + */ + public static decode(input, isNotStr: boolean = true) { + let output = ""; + let chr1, chr2, chr3; + let enc1, enc2, enc3, enc4; + let i = 0; + input = this.getConfKey(input); + input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); + while (i < input.length) { + enc1 = this._keyAll.indexOf(input.charAt(i++)); + enc2 = this._keyAll.indexOf(input.charAt(i++)); + enc3 = this._keyAll.indexOf(input.charAt(i++)); + enc4 = this._keyAll.indexOf(input.charAt(i++)); + chr1 = (enc1 << 2) | (enc2 >> 4); + chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); + chr3 = ((enc3 & 3) << 6) | enc4; + output = output + String.fromCharCode(chr1); + if (enc3 != 64) { + if (chr2 == 0) { + if (isNotStr) output = output + String.fromCharCode(chr2); + } else { + output = output + String.fromCharCode(chr2); + } + } + + if (enc4 != 64) { + if (chr3 == 0) { + if (isNotStr) output = output + String.fromCharCode(chr3); + } else { + output = output + String.fromCharCode(chr3); + } + } + } + output = this._utf8_decode(output); + return output; + } + + private static _utf8_encode(string) { + string = string.replace(/\r\n/g, "\n"); + let utftext = ""; + for (let n = 0; n < string.length; n++) { + let c = string.charCodeAt(n); + if (c < 128) { + utftext += String.fromCharCode(c); + } else if ((c > 127) && (c < 2048)) { + utftext += String.fromCharCode((c >> 6) | 192); + utftext += String.fromCharCode((c & 63) | 128); + } else { + utftext += String.fromCharCode((c >> 12) | 224); + utftext += String.fromCharCode(((c >> 6) & 63) | 128); + utftext += String.fromCharCode((c & 63) | 128); + } + + } + return utftext; + } + + private static _utf8_decode(utftext) { + let string = ""; + let i = 0; + let c = 0; + let c1 = 0; + let c2 = 0; + let c3 = 0; + while (i < utftext.length) { + c = utftext.charCodeAt(i); + if (c < 128) { + string += String.fromCharCode(c); + i++; + } else if ((c > 191) && (c < 224)) { + c2 = utftext.charCodeAt(i + 1); + string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); + i += 2; + } else { + c2 = utftext.charCodeAt(i + 1); + c3 = utftext.charCodeAt(i + 2); + string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); + i += 3; + } + } + return string; + } + + private static getConfKey(key): string { + return key.slice(1, key.length); + } +} \ No newline at end of file diff --git a/source/src/Utils/ContentManager.ts b/source/src/Utils/ContentManager.ts index 5b4ca44e..4d80348e 100644 --- a/source/src/Utils/ContentManager.ts +++ b/source/src/Utils/ContentManager.ts @@ -1,43 +1,43 @@ -declare class fui {} +module es { + export class ContentManager { + protected loadedAssets: Map = new Map(); -class ContentManager { - protected loadedAssets: Map = new Map(); + /** 异步加载资源 */ + public loadRes(name: string, local: boolean = true): Promise { + return new Promise((resolve, reject) => { + let res = this.loadedAssets.get(name); + if (res) { + resolve(res); + return; + } - /** 异步加载资源 */ - public loadRes(name: string, local: boolean = true): Promise { - return new Promise((resolve, reject) => { - let res = this.loadedAssets.get(name); - if (res) { - resolve(res); - return; - } + if (local) { + RES.getResAsync(name).then((data) => { + this.loadedAssets.set(name, data); + resolve(data); + }).catch((err) => { + console.error("资源加载错误:", name, err); + reject(err); + }); + } else { + RES.getResByUrl(name).then((data) => { + this.loadedAssets.set(name, data); + resolve(data); + }).catch((err) => { + console.error("资源加载错误:", name, err); + reject(err); + }); + } + }); + } - if (local) { - RES.getResAsync(name).then((data) => { - this.loadedAssets.set(name, data); - resolve(data); - }).catch((err) => { - console.error("资源加载错误:", name, err); - reject(err); - }); - } else { - RES.getResByUrl(name).then((data) => { - this.loadedAssets.set(name, data); - resolve(data); - }).catch((err) => { - console.error("资源加载错误:", name, err); - reject(err); - }); - } - }) + public dispose() { + this.loadedAssets.forEach(value => { + let assetsToRemove = value; + assetsToRemove.dispose(); + }); + + this.loadedAssets.clear(); + } } - - public dispose() { - this.loadedAssets.forEach(value => { - let assetsToRemove = value; - assetsToRemove.dispose(); - }); - - this.loadedAssets.clear(); - } -} \ No newline at end of file +} diff --git a/source/src/Utils/DrawUtils.ts b/source/src/Utils/DrawUtils.ts new file mode 100644 index 00000000..14332ad5 --- /dev/null +++ b/source/src/Utils/DrawUtils.ts @@ -0,0 +1,61 @@ +module es { + /** 各种辅助方法来辅助绘图 */ + export class DrawUtils { + public static drawLine(shape: egret.Shape, start: Vector2, end: Vector2, color: number, thickness: number = 1) { + this.drawLineAngle(shape, start, MathHelper.angleBetweenVectors(start, end), Vector2.distance(start, end), color, thickness); + } + + public static drawLineAngle(shape: egret.Shape, start: Vector2, radians: number, length: number, color: number, thickness = 1) { + shape.graphics.beginFill(color); + shape.graphics.drawRect(start.x, start.y, 1, 1); + shape.graphics.endFill(); + + shape.scaleX = length; + shape.scaleY = thickness; + shape.$anchorOffsetX = 0; + shape.$anchorOffsetY = 0; + shape.rotation = radians; + } + + public static drawHollowRect(shape: egret.Shape, rect: Rectangle, color: number, thickness = 1) { + this.drawHollowRectR(shape, rect.x, rect.y, rect.width, rect.height, color, thickness); + } + + public static drawHollowRectR(shape: egret.Shape, x: number, y: number, width: number, height: number, color: number, thickness = 1) { + let tl = new Vector2(x, y).round(); + let tr = new Vector2(x + width, y).round(); + let br = new Vector2(x + width, y + height).round(); + let bl = new Vector2(x, y + height).round(); + + this.drawLine(shape, tl, tr, color, thickness); + this.drawLine(shape, tr, br, color, thickness); + this.drawLine(shape, br, bl, color, thickness); + this.drawLine(shape, bl, tl, color, thickness); + } + + public static drawPixel(shape: egret.Shape, position: Vector2, color: number, size: number = 1) { + let destRect = new Rectangle(position.x, position.y, size, size); + if (size != 1) { + destRect.x -= size * 0.5; + destRect.y -= size * 0.5; + } + + shape.graphics.beginFill(color); + shape.graphics.drawRect(destRect.x, destRect.y, destRect.width, destRect.height); + shape.graphics.endFill(); + } + + public static getColorMatrix(color: number): egret.ColorMatrixFilter { + let colorMatrix = [ + 1, 0, 0, 0, 0, + 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0, + 0, 0, 0, 1, 0 + ]; + colorMatrix[0] = Math.floor(color / 256 / 256) / 255; + colorMatrix[6] = Math.floor(color / 256 % 256) / 255; + colorMatrix[12] = color % 256 / 255; + return new egret.ColorMatrixFilter(colorMatrix); + } + } +} diff --git a/source/src/Utils/Emitter.ts b/source/src/Utils/Emitter.ts index cd5175cc..2d469a9a 100644 --- a/source/src/Utils/Emitter.ts +++ b/source/src/Utils/Emitter.ts @@ -1,31 +1,70 @@ -class Emitter { - private _messageTable: Map; +module es { + /** + * 用于包装事件的一个小类 + */ + export class FuncPack { + /** 函数 */ + public func: Function; + /** 上下文 */ + public context: any; - constructor(){ - this._messageTable = new Map(); - } - - public addObserver(eventType: T, handler: Function){ - let list: Function[] = this._messageTable.get(eventType); - if (!list){ - list = []; - this._messageTable.set(eventType, list); - } - - if (list.contains(handler)) - console.warn("您试图添加相同的观察者两次"); - list.push(handler); - } - - public removeObserver(eventType: T, handler: Function){ - this._messageTable.get(eventType).remove(handler); - } - - public emit(eventType: T, data: any){ - let list: Function[] = this._messageTable.get(eventType); - if (list){ - for (let i = list.length - 1; i >= 0; i --) - list[i](data); + constructor(func: Function, context: any) { + this.func = func; + this.context = context; } } -} \ No newline at end of file + + /** + * 用于事件管理 + */ + export class Emitter { + private _messageTable: Map; + + constructor() { + this._messageTable = new Map(); + } + + /** + * 开始监听项 + * @param eventType 监听类型 + * @param handler 监听函数 + * @param context 监听上下文 + */ + public addObserver(eventType: T, handler: Function, context: any) { + let list: FuncPack[] = this._messageTable.get(eventType); + if (!list) { + list = []; + this._messageTable.set(eventType, list); + } + + if (list.findIndex(funcPack => funcPack.func == handler) != -1) + console.warn("您试图添加相同的观察者两次"); + list.push(new FuncPack(handler, context)); + } + + /** + * 移除监听项 + * @param eventType 事件类型 + * @param handler 事件函数 + */ + public removeObserver(eventType: T, handler: Function) { + let messageData = this._messageTable.get(eventType); + let index = messageData.findIndex(data => data.func == handler); + if (index != -1) + messageData.removeAt(index); + } + + /** + * 触发该事件 + * @param eventType 事件类型 + * @param data 事件数据 + */ + public emit(eventType: T, data?: any) { + let list: FuncPack[] = this._messageTable.get(eventType); + if (list) { + for (let i = list.length - 1; i >= 0; i--) + list[i].func.call(list[i].context, data); + } + } + } +} diff --git a/source/src/Utils/GlobalManager.ts b/source/src/Utils/GlobalManager.ts index 1e48ee99..f4799309 100644 --- a/source/src/Utils/GlobalManager.ts +++ b/source/src/Utils/GlobalManager.ts @@ -1,46 +1,55 @@ -class GlobalManager { - public static globalManagers: GlobalManager[] = []; - private _enabled: boolean; +module es { + export class GlobalManager { + public _enabled: boolean; - public get enabled(){ - return this._enabled; - } - public set enabled(value: boolean){ - this.setEnabled(value); - } - public setEnabled(isEnabled: boolean){ - if (this._enabled != isEnabled){ - this._enabled = isEnabled; - if (this._enabled){ - this.onEnabled(); - } else { - this.onDisabled(); + /** + * 如果true则启用了GlobalManager。 + * 状态的改变会导致调用OnEnabled/OnDisable + */ + public get enabled() { + return this._enabled; + } + + /** + * 如果true则启用了GlobalManager。 + * 状态的改变会导致调用OnEnabled/OnDisable + * @param value + */ + public set enabled(value: boolean) { + this.setEnabled(value); + } + + /** + * 启用/禁用这个GlobalManager + * @param isEnabled + */ + public setEnabled(isEnabled: boolean) { + if (this._enabled != isEnabled) { + this._enabled = isEnabled; + if (this._enabled) { + this.onEnabled(); + } else { + this.onDisabled(); + } } } - } - public onEnabled(){} - - public onDisabled(){} - - public update(){} - - public static registerGlobalManager(manager: GlobalManager){ - this.globalManagers.push(manager); - manager.enabled = true; - } - - public static unregisterGlobalManager(manager: GlobalManager){ - this.globalManagers.remove(manager); - manager.enabled = false; - } - - public static getGlobalManager(type){ - for (let i = 0; i < this.globalManagers.length; i ++){ - if (this.globalManagers[i] instanceof type) - return this.globalManagers[i] as T; + /** + * 此GlobalManager启用时调用 + */ + public onEnabled() { } - return null; + /** + * 此GlobalManager禁用时调用 + */ + public onDisabled() { + } + + /** + * 在frame .update之前调用每一帧 + */ + public update() { + } } -} \ No newline at end of file +} diff --git a/source/src/Utils/Input.ts b/source/src/Utils/Input.ts index 09d961f9..7dc5e8ee 100644 --- a/source/src/Utils/Input.ts +++ b/source/src/Utils/Input.ts @@ -1,147 +1,157 @@ -class TouchState { - public x = 0; - public y = 0; - public touchPoint: number = -1; - public touchDown: boolean = false; - public get position(){ - return new Vector2(this.x, this.y); - } +module es { + export class TouchState { + public x = 0; + public y = 0; + public touchPoint: number = -1; + public touchDown: boolean = false; - public reset(){ - this.x = 0; - this.y = 0; - this.touchDown = false; - this.touchPoint = -1; - } -} - -class Input { - private static _init: boolean = false; - private static _stage: egret.Stage; - private static _previousTouchState: TouchState = new TouchState(); - private static _gameTouchs: TouchState[] = []; - private static _resolutionOffset: Vector2 = new Vector2(); - private static _resolutionScale: Vector2 = Vector2.one; - private static _touchIndex: number = 0; - private static _totalTouchCount: number = 0; - /** 返回第一个触摸点的坐标 */ - public static get touchPosition(){ - if (!this._gameTouchs[0]) - return Vector2.zero; - return this._gameTouchs[0].position; - } - /** 获取最大触摸数 */ - public static get maxSupportedTouch(){ - return this._stage.maxTouches; - } - /** - * 设置最大触摸数 - */ - public static set maxSupportedTouch(value: number){ - this._stage.maxTouches = value; - this.initTouchCache(); - } - /** 获取缩放值 默认为1 */ - public static get resolutionScale(){ - return this._resolutionScale; - } - /** 当前触摸点数量 */ - public static get totalTouchCount(){ - return this._totalTouchCount; - } - /** - * 触摸列表 存放最大个数量触摸点信息 - * 可通过判断touchPoint是否为-1 来确定是否为有触摸 - * 通过判断touchDown 判断触摸点是否有按下 - */ - public static get gameTouchs(){ - return this._gameTouchs; - } - - /** 获取第一个触摸点距离上次距离的增量 */ - public static get touchPositionDelta(){ - let delta = Vector2.subtract(this.touchPosition, this._previousTouchState.position); - if (delta.length() > 0){ - this.setpreviousTouchState(this._gameTouchs[0]); + public get position() { + return new Vector2(this.x, this.y); } - return delta; - } - public static initialize(stage: egret.Stage){ - if (this._init) - return; - - this._init = true; - this._stage = stage; - this._stage.addEventListener(egret.TouchEvent.TOUCH_BEGIN, this.touchBegin, this); - this._stage.addEventListener(egret.TouchEvent.TOUCH_MOVE, this.touchMove, this); - this._stage.addEventListener(egret.TouchEvent.TOUCH_END, this.touchEnd, this); - this._stage.addEventListener(egret.TouchEvent.TOUCH_CANCEL, this.touchEnd, this); - this._stage.addEventListener(egret.TouchEvent.TOUCH_RELEASE_OUTSIDE, this.touchEnd, this); - - this.initTouchCache(); - } - - private static initTouchCache(){ - this._totalTouchCount = 0; - this._touchIndex = 0; - this._gameTouchs.length = 0; - for (let i = 0; i < this.maxSupportedTouch; i ++){ - this._gameTouchs.push(new TouchState()); + public reset() { + this.x = 0; + this.y = 0; + this.touchDown = false; + this.touchPoint = -1; } } - private static touchBegin(evt: egret.TouchEvent){ - if (this._touchIndex < this.maxSupportedTouch){ - this._gameTouchs[this._touchIndex].touchPoint = evt.touchPointID; - this._gameTouchs[this._touchIndex].touchDown = evt.touchDown; - this._gameTouchs[this._touchIndex].x = evt.stageX; - this._gameTouchs[this._touchIndex].y = evt.stageY; - if (this._touchIndex == 0){ + export class Input { + private static _init: boolean = false; + private static _previousTouchState: TouchState = new TouchState(); + private static _resolutionOffset: Vector2 = new Vector2(); + private static _touchIndex: number = 0; + + private static _gameTouchs: TouchState[] = []; + + /** + * 触摸列表 存放最大个数量触摸点信息 + * 可通过判断touchPoint是否为-1 来确定是否为有触摸 + * 通过判断touchDown 判断触摸点是否有按下 + */ + public static get gameTouchs() { + return this._gameTouchs; + } + + private static _resolutionScale: Vector2 = Vector2.one; + + /** 获取缩放值 默认为1 */ + public static get resolutionScale() { + return this._resolutionScale; + } + + private static _totalTouchCount: number = 0; + + /** 当前触摸点数量 */ + public static get totalTouchCount() { + return this._totalTouchCount; + } + + /** 返回第一个触摸点的坐标 */ + public static get touchPosition() { + if (!this._gameTouchs[0]) + return Vector2.zero; + return this._gameTouchs[0].position; + } + + /** 获取最大触摸数 */ + public static get maxSupportedTouch() { + return Core._instance.stage.maxTouches; + } + + /** + * 设置最大触摸数 + */ + public static set maxSupportedTouch(value: number) { + Core._instance.stage.maxTouches = value; + this.initTouchCache(); + } + + /** 获取第一个触摸点距离上次距离的增量 */ + public static get touchPositionDelta() { + let delta = Vector2.subtract(this.touchPosition, this._previousTouchState.position); + if (delta.length() > 0) { this.setpreviousTouchState(this._gameTouchs[0]); } - this._touchIndex ++; - this._totalTouchCount ++; - } - } - - private static touchMove(evt: egret.TouchEvent){ - if (evt.touchPointID == this._gameTouchs[0].touchPoint){ - this.setpreviousTouchState(this._gameTouchs[0]); + return delta; } - let touchIndex = this._gameTouchs.findIndex(touch => touch.touchPoint == evt.touchPointID); - if (touchIndex != -1){ - let touchData = this._gameTouchs[touchIndex]; - touchData.x = evt.stageX; - touchData.y = evt.stageY; - } - } + public static initialize() { + if (this._init) + return; - private static touchEnd(evt: egret.TouchEvent){ - let touchIndex = this._gameTouchs.findIndex(touch => touch.touchPoint == evt.touchPointID); - if (touchIndex != -1){ - let touchData = this._gameTouchs[touchIndex]; - touchData.reset(); - if (touchIndex == 0) - this._previousTouchState.reset(); - this._totalTouchCount --; - if (this.totalTouchCount == 0){ - this._touchIndex = 0; + this._init = true; + Core._instance.stage.addEventListener(egret.TouchEvent.TOUCH_BEGIN, this.touchBegin, this); + Core._instance.stage.addEventListener(egret.TouchEvent.TOUCH_MOVE, this.touchMove, this); + Core._instance.stage.addEventListener(egret.TouchEvent.TOUCH_END, this.touchEnd, this); + Core._instance.stage.addEventListener(egret.TouchEvent.TOUCH_CANCEL, this.touchEnd, this); + Core._instance.stage.addEventListener(egret.TouchEvent.TOUCH_RELEASE_OUTSIDE, this.touchEnd, this); + + this.initTouchCache(); + } + + public static scaledPosition(position: Vector2) { + let scaledPos = new Vector2(position.x - this._resolutionOffset.x, position.y - this._resolutionOffset.y); + return Vector2.multiply(scaledPos, this.resolutionScale); + } + + private static initTouchCache() { + this._totalTouchCount = 0; + this._touchIndex = 0; + this._gameTouchs.length = 0; + for (let i = 0; i < this.maxSupportedTouch; i++) { + this._gameTouchs.push(new TouchState()); } } - } - private static setpreviousTouchState(touchState: TouchState){ - this._previousTouchState = new TouchState(); - this._previousTouchState.x = touchState.position.x; - this._previousTouchState.y = touchState.position.y; - this._previousTouchState.touchPoint = touchState.touchPoint; - this._previousTouchState.touchDown = touchState.touchDown; - } + private static touchBegin(evt: egret.TouchEvent) { + if (this._touchIndex < this.maxSupportedTouch) { + this._gameTouchs[this._touchIndex].touchPoint = evt.touchPointID; + this._gameTouchs[this._touchIndex].touchDown = evt.touchDown; + this._gameTouchs[this._touchIndex].x = evt.stageX; + this._gameTouchs[this._touchIndex].y = evt.stageY; + if (this._touchIndex == 0) { + this.setpreviousTouchState(this._gameTouchs[0]); + } + this._touchIndex++; + this._totalTouchCount++; + } + } - public static scaledPosition(position: Vector2){ - let scaledPos = new Vector2(position.x - this._resolutionOffset.x, position.y - this._resolutionOffset.y); - return Vector2.multiply(scaledPos, this.resolutionScale); + private static touchMove(evt: egret.TouchEvent) { + if (evt.touchPointID == this._gameTouchs[0].touchPoint) { + this.setpreviousTouchState(this._gameTouchs[0]); + } + + let touchIndex = this._gameTouchs.findIndex(touch => touch.touchPoint == evt.touchPointID); + if (touchIndex != -1) { + let touchData = this._gameTouchs[touchIndex]; + touchData.x = evt.stageX; + touchData.y = evt.stageY; + } + } + + private static touchEnd(evt: egret.TouchEvent) { + let touchIndex = this._gameTouchs.findIndex(touch => touch.touchPoint == evt.touchPointID); + if (touchIndex != -1) { + let touchData = this._gameTouchs[touchIndex]; + touchData.reset(); + if (touchIndex == 0) + this._previousTouchState.reset(); + this._totalTouchCount--; + if (this.totalTouchCount == 0) { + this._touchIndex = 0; + } + } + } + + private static setpreviousTouchState(touchState: TouchState) { + this._previousTouchState = new TouchState(); + this._previousTouchState.x = touchState.position.x; + this._previousTouchState.y = touchState.position.y; + this._previousTouchState.touchPoint = touchState.touchPoint; + this._previousTouchState.touchDown = touchState.touchDown; + } } -} \ No newline at end of file +} diff --git a/source/src/Utils/KeyboardUtils.ts b/source/src/Utils/KeyboardUtils.ts new file mode 100644 index 00000000..3083301e --- /dev/null +++ b/source/src/Utils/KeyboardUtils.ts @@ -0,0 +1,225 @@ +class KeyboardUtils { + /** + * 键盘事件类型 + */ + public static TYPE_KEY_DOWN: number = 0; + public static TYPE_KEY_UP: number = 1; + /** + * 键值字符串枚举 + */ + public static A: string = "A"; + public static B: string = "B"; + public static C: string = "C"; + public static D: string = "D"; + public static E: string = "E"; + public static F: string = "F"; + public static G: string = "G"; + public static H: string = "H"; + public static I: string = "I"; + public static J: string = "J"; + public static K: string = "K"; + public static L: string = "L"; + public static M: string = "M"; + public static N: string = "N"; + public static O: string = "O"; + public static P: string = "P"; + public static Q: string = "Q"; + public static R: string = "R"; + public static S: string = "S"; + public static T: string = "T"; + public static U: string = "U"; + public static V: string = "V"; + public static W: string = "W"; + public static X: string = "X"; + public static Y: string = "Y"; + public static Z: string = "Z"; + public static ESC: string = "Esc"; + public static F1: string = "F1"; + public static F2: string = "F2"; + public static F3: string = "F3"; + public static F4: string = "F4"; + public static F5: string = "F5"; + public static F6: string = "F6"; + public static F7: string = "F7"; + public static F8: string = "F8"; + public static F9: string = "F9"; + public static F10: string = "F10"; + public static F11: string = "F11"; + public static F12: string = "F12"; + public static NUM_1: string = "1"; + public static NUM_2: string = "2"; + public static NUM_3: string = "3"; + public static NUM_4: string = "4"; + public static NUM_5: string = "5"; + public static NUM_6: string = "6"; + public static NUM_7: string = "7"; + public static NUM_8: string = "8"; + public static NUM_9: string = "9"; + public static NUM_0: string = "0"; + public static TAB: string = "Tab"; + public static CTRL: string = "Ctrl"; + public static ALT: string = "Alt"; + public static SHIFT: string = "Shift"; + public static CAPS_LOCK: string = "Caps Lock"; + public static ENTER: string = "Enter"; + public static SPACE: string = "Space"; + public static BACK_SPACE: string = "Back Space"; + public static INSERT: string = "Insert"; + public static DELETE: string = "Page Down"; + public static HOME: string = "Home"; + public static END: string = "Page Down"; + public static PAGE_UP: string = "Page Up"; + public static PAGE_DOWN: string = "Page Down"; + public static LEFT: string = "Left"; + public static RIGHT: string = "Right"; + public static UP: string = "Up"; + public static DOWN: string = "Down"; + public static PAUSE_BREAK: string = "Pause Break"; + public static NUM_LOCK: string = "Num Lock"; + public static SCROLL_LOCK: string = "Scroll Lock"; + public static WINDOWS: string = "Windows"; + //存放按下注册数据的字典 + private static keyDownDict: Object; + //存放按起注册数据的字典 + private static keyUpDict: Object; + + public static init(): void { + this.keyDownDict = {}; + this.keyUpDict = {}; + document.addEventListener("keydown", this.onKeyDonwHander); + document.addEventListener("keyup", this.onKeyUpHander); + } + + /** + * 注册按键 + * @param key 键值 + * @param fun 回调方法 + * @param type 按键类型 TYPE_KEY_DOWN、TYPE_KEY_UP + */ + public static registerKey(key: string, fun: Function, thisObj: any, type: number = 0, ...args): void { + var keyDict: Object = type ? this.keyUpDict : this.keyDownDict; + keyDict[key] = {"fun": fun, args: args, "thisObj": thisObj}; + } + + /** + * 注销按键 + * @param key 键值 + * @param type 注销的类型 + */ + public static unregisterKey(key: string, type: number = 0): void { + var keyDict: Object = type ? this.keyUpDict : this.keyDownDict; + delete keyDict[key]; + } + + /** + * 销毁方法 + */ + public static destroy(): void { + this.keyDownDict = null; + this.keyUpDict = null; + document.removeEventListener("keydown", this.onKeyDonwHander); + document.removeEventListener("keyup", this.onKeyUpHander); + } + + private static onKeyDonwHander(event: KeyboardEvent): void { + if (!this.keyDownDict) return; + var key: string = this.keyCodeToString(event.keyCode); + var o: Object = this.keyDownDict[key]; + if (o) { + var fun: Function = o["fun"]; + var thisObj: any = o["thisObj"]; + var args: any = o["args"]; + fun.apply(thisObj, args); + } + } + + private static onKeyUpHander(event: KeyboardEvent): void { + if (!this.keyUpDict) return; + var key: string = this.keyCodeToString(event.keyCode); + var o: Object = this.keyUpDict[key]; + if (o) { + var fun: Function = o["fun"]; + var thisObj: any = o["thisObj"]; + var args: any = o["args"]; + fun.apply(thisObj, args); + } + } + + /** + * 根据keyCode或charCode获取相应的字符串代号 + * @param keyCode + * @return 键盘所指字符串代号 + */ + private static keyCodeToString(keyCode: number): string { + switch (keyCode) { + case 8: + return this.BACK_SPACE; + case 9: + return this.TAB; + case 13: + return this.ENTER; + case 16: + return this.SHIFT; + case 17: + return this.CTRL; + case 19: + return this.PAUSE_BREAK; + case 20: + return this.CAPS_LOCK; + case 27: + return this.ESC; + case 32: + return this.SPACE; + case 33: + return this.PAGE_UP; + case 34: + return this.PAGE_DOWN; + case 35: + return this.END; + case 36: + return this.HOME; + case 37: + return this.LEFT; + case 38: + return this.UP; + case 39: + return this.RIGHT; + case 40: + return this.DOWN; + case 45: + return this.INSERT; + case 46: + return this.DELETE; + case 91: + return this.WINDOWS; + case 112: + return this.F1; + case 113: + return this.F2; + case 114: + return this.F3; + case 115: + return this.F4; + case 116: + return this.F5; + case 117: + return this.F6; + case 118: + return this.F7; + case 119: + return this.F8; + case 120: + return this.F9; + case 122: + return this.F11; + case 123: + return this.F12; + case 144: + return this.NUM_LOCK; + case 145: + return this.SCROLL_LOCK; + default: + return String.fromCharCode(keyCode); + } + } +} \ No newline at end of file diff --git a/source/src/Utils/ListPool.ts b/source/src/Utils/ListPool.ts index 1a871f11..acf5ea85 100644 --- a/source/src/Utils/ListPool.ts +++ b/source/src/Utils/ListPool.ts @@ -1,54 +1,56 @@ -/** - * 可以用于列表池的简单类 - */ -class ListPool { - private static readonly _objectQueue = []; - +module es { /** - * 预热缓存,使用最大的cacheCount对象填充缓存 - * @param cacheCount + * 可以用于列表池的简单类 */ - public static warmCache(cacheCount: number){ - cacheCount -= this._objectQueue.length; - if (cacheCount > 0){ - for (let i = 0; i < cacheCount; i ++){ - this._objectQueue.unshift([]); + export class ListPool { + private static readonly _objectQueue = []; + + /** + * 预热缓存,使用最大的cacheCount对象填充缓存 + * @param cacheCount + */ + public static warmCache(cacheCount: number) { + cacheCount -= this._objectQueue.length; + if (cacheCount > 0) { + for (let i = 0; i < cacheCount; i++) { + this._objectQueue.unshift([]); + } } } - } - /** - * 将缓存修剪为cacheCount项目 - * @param cacheCount - */ - public static trimCache(cacheCount){ - while (cacheCount > this._objectQueue.length) - this._objectQueue.shift(); - } + /** + * 将缓存修剪为cacheCount项目 + * @param cacheCount + */ + public static trimCache(cacheCount) { + while (cacheCount > this._objectQueue.length) + this._objectQueue.shift(); + } - /** - * 清除缓存 - */ - public static clearCache(){ - this._objectQueue.length = 0; - } + /** + * 清除缓存 + */ + public static clearCache() { + this._objectQueue.length = 0; + } - /** - * 如果可以的话,从堆栈中弹出一个项 - */ - public static obtain(): Array{ - if (this._objectQueue.length > 0) - return this._objectQueue.shift(); + /** + * 如果可以的话,从堆栈中弹出一个项 + */ + public static obtain(): T[] { + if (this._objectQueue.length > 0) + return this._objectQueue.shift(); - return []; - } + return []; + } - /** - * 将项推回堆栈 - * @param obj - */ - public static free(obj: Array){ - this._objectQueue.unshift(obj); - obj.length = 0; + /** + * 将项推回堆栈 + * @param obj + */ + public static free(obj: Array) { + this._objectQueue.unshift(obj); + obj.length = 0; + } } -} \ No newline at end of file +} diff --git a/source/src/Utils/LockUtils.ts b/source/src/Utils/LockUtils.ts new file mode 100644 index 00000000..e6df9456 --- /dev/null +++ b/source/src/Utils/LockUtils.ts @@ -0,0 +1,55 @@ +const THREAD_ID = `${Math.floor(Math.random() * 1000)}-${Date.now()}`; + +const nextTick = fn => { + setTimeout(fn, 0); +}; + +/** + * 利用共享区域实现快速锁 + */ +class LockUtils { + private _keyX: string; + private _keyY: string; + private setItem; + private getItem; + private removeItem; + + constructor(key) { + this._keyX = `mutex_key_${key}_X`; + this._keyY = `mutex_key_${key}_Y`; + this.setItem = egret.localStorage.setItem.bind(localStorage); + this.getItem = egret.localStorage.getItem.bind(localStorage); + this.removeItem = egret.localStorage.removeItem.bind(localStorage); + } + + public lock() { + return new Promise((resolve, reject) => { + const fn = () => { + this.setItem(this._keyX, THREAD_ID); + if (!this.getItem(this._keyY) === null) { + // restart + nextTick(fn); + } + this.setItem(this._keyY, THREAD_ID); + if (this.getItem(this._keyX) !== THREAD_ID) { + // delay + setTimeout(() => { + if (this.getItem(this._keyY) !== THREAD_ID) { + // restart + nextTick(fn); + return; + } + // critical section + resolve(); + this.removeItem(this._keyY); + }, 10); + } else { + resolve(); + this.removeItem(this._keyY); + } + }; + + fn(); + }); + } +} \ No newline at end of file diff --git a/source/src/Utils/Pair.ts b/source/src/Utils/Pair.ts index cc3cf6f2..69fb5a89 100644 --- a/source/src/Utils/Pair.ts +++ b/source/src/Utils/Pair.ts @@ -1,20 +1,22 @@ -/** - * 用于管理一对对象的简单DTO - */ -class Pair { - public first: T; - public second: T; +module es { + /** + * 用于管理一对对象的简单DTO + */ + export class Pair { + public first: T; + public second: T; - constructor(first: T, second: T){ - this.first = first; - this.second = second; - } + constructor(first: T, second: T) { + this.first = first; + this.second = second; + } - public clear(){ - this.first = this.second = null; - } + public clear() { + this.first = this.second = null; + } - public equals(other: Pair){ - return this.first == other.first && this.second == other.second; + public equals(other: Pair) { + return this.first == other.first && this.second == other.second; + } } -} \ No newline at end of file +} diff --git a/source/src/Utils/RandomUtils.ts b/source/src/Utils/RandomUtils.ts new file mode 100644 index 00000000..6aca63de --- /dev/null +++ b/source/src/Utils/RandomUtils.ts @@ -0,0 +1,133 @@ +class RandomUtils { + /** + * 在 start 与 stop之间取一个随机整数,可以用step指定间隔, 但不包括较大的端点(start与stop较大的一个) + * 如 + * this.randrange(1, 10, 3) + * 则返回的可能是 1 或 4 或 7 , 注意 这里面不会返回10,因为是10是大端点 + * + * @param start + * @param stop + * @param step + * @return 假设 start < stop, [start, stop) 区间内的随机整数 + * + */ + public static randrange(start: number, stop: number, step: number = 1): number { + if (step == 0) + throw new Error('step 不能为 0'); + + let width: number = stop - start; + if (width == 0) + throw new Error('没有可用的范围(' + start + ',' + stop + ')'); + if (width < 0) + width = start - stop; + + let n: number = Math.floor((width + step - 1) / step); + return Math.floor(this.random() * n) * step + Math.min(start, stop); + } + + /** + * 返回a 到 b直间的随机整数,包括 a 和 b + * @param a + * @param b + * @return [a, b] 直接的随机整数 + * + */ + public static randint(a: number, b: number): number { + a = Math.floor(a); + b = Math.floor(b); + if (a > b) + a++; + else + b++; + return this.randrange(a, b); + } + + /** + * 返回 a - b之间的随机数,不包括 Math.max(a, b) + * @param a + * @param b + * @return 假设 a < b, [a, b) + */ + public static randnum(a: number, b: number): number { + return this.random() * (b - a) + a; + } + + /** + * 打乱数组 + * @param array + * @return + */ + public static shuffle(array: any[]): any[] { + array.sort(this._randomCompare); + return array; + } + + /** + * 从序列中随机取一个元素 + * @param sequence 可以是 数组、 vector,等只要是有length属性,并且可以用数字索引获取元素的对象, + * 另外,字符串也是允许的。 + * @return 序列中的某一个元素 + * + */ + public static choice(sequence: any): any { + if (!sequence.hasOwnProperty("length")) + throw new Error('无法对此对象执行此操作'); + let index: number = Math.floor(this.random() * sequence.length); + if (sequence instanceof String) + return String(sequence).charAt(index); + else + return sequence[index]; + } + + /** + * 对列表中的元素进行随机采æ ? + *
+     * this.sample([1, 2, 3, 4, 5],  3)  // Choose 3 elements
+     * [4, 1, 5]
+     * 
+ * @param sequence + * @param num + * @return + * + */ + public static sample(sequence: any[], num: number): any[] { + let len: number = sequence.length; + if (num <= 0 || len < num) + throw new Error("采样数量不够"); + + let selected: any[] = []; + let indices: any[] = []; + for (let i: number = 0; i < num; i++) { + let index: number = Math.floor(this.random() * len); + while (indices.indexOf(index) >= 0) + index = Math.floor(this.random() * len); + + selected.push(sequence[index]); + indices.push(index); + } + + return selected; + } + + /** + * 返回 0.0 - 1.0 之间的随机数,等同于 Math.random() + * @return Math.random() + * + */ + public static random(): number { + return Math.random(); + } + + /** + * 计算概率 + * @param chance 概率 + * @return + */ + public static boolean(chance: number = .5): boolean { + return (this.random() < chance) ? true : false; + } + + private static _randomCompare(a: Object, b: Object): number { + return (this.random() > .5) ? 1 : -1; + } +} \ No newline at end of file diff --git a/source/src/Utils/RectangleExt.ts b/source/src/Utils/RectangleExt.ts index 9f681679..76b59fe8 100644 --- a/source/src/Utils/RectangleExt.ts +++ b/source/src/Utils/RectangleExt.ts @@ -1,16 +1,19 @@ -class RectangleExt { - public static union(first: Rectangle, point: Vector2){ - let rect = new Rectangle(point.x, point.y, 0, 0); - return this.unionR(first, rect); +module es { + export class RectangleExt { + /** + * 计算两个矩形的并集。结果将是一个包含其他两个的矩形。 + * @param first + * @param point + */ + public static union(first: Rectangle, point: Vector2) { + let rect = new Rectangle(point.x, point.y, 0, 0); + // let rectResult = first.union(rect); + let result = new Rectangle(); + result.x = Math.min(first.x, rect.x); + result.y = Math.min(first.y, rect.y); + result.width = Math.max(first.right, rect.right) - result.x; + result.height = Math.max(first.bottom, result.bottom) - result.y; + return result; + } } - - public static unionR(value1: Rectangle, value2: Rectangle){ - let result = new Rectangle(); - result.x = Math.min(value1.x, value2.x); - result.y = Math.min(value1.y, value2.y); - result.width = Math.max(value1.right, value2.right) - result.x; - result.height = Math.max(value1.bottom, value2.bottom) - result.y; - - return result; - } -} \ No newline at end of file +} diff --git a/source/src/Utils/Triangulator.ts b/source/src/Utils/Triangulator.ts index e283e4ce..5ef8b370 100644 --- a/source/src/Utils/Triangulator.ts +++ b/source/src/Utils/Triangulator.ts @@ -1,111 +1,113 @@ -/** - * 三角剖分 - */ -class Triangulator { - /** - * 最后一次三角调用中使用的点列表的三角形列表项的索引 - */ - public triangleIndices: number[] = []; - - private _triPrev: number[] = new Array(12); - private _triNext: number[] = new Array(12); - +module es { /** - * 计算一个三角形列表,该列表完全覆盖给定点集所包含的区域。如果点不是CCW,则将arePointsCCW参数传递为false - * @param points 定义封闭路径的点列表 - * @param arePointsCCW + * 三角剖分 */ - public triangulate(points: Vector2[], arePointsCCW: boolean = true){ - let count = points.length; + export class Triangulator { + /** + * 最后一次三角调用中使用的点列表的三角形列表项的索引 + */ + public triangleIndices: number[] = []; - // 设置前一个链接和下一个链接 - this.initialize(count); + private _triPrev: number[] = new Array(12); + private _triNext: number[] = new Array(12); - // 非三角的多边形断路器 - let iterations = 0; + public static testPointTriangle(point: Vector2, a: Vector2, b: Vector2, c: Vector2): boolean { + if (Vector2Ext.cross(Vector2.subtract(point, a), Vector2.subtract(b, a)) < 0) + return false; - // 从0开始 - let index = 0; + if (Vector2Ext.cross(Vector2.subtract(point, b), Vector2.subtract(c, b)) < 0) + return false; - // 继续移除所有的三角形,直到只剩下一个三角形 - while (count > 3 && iterations < 500){ - iterations ++; + if (Vector2Ext.cross(Vector2.subtract(point, c), Vector2.subtract(a, c)) < 0) + return false; - let isEar = true; - let a = points[this._triPrev[index]]; - let b = points[index]; - let c = points[this._triNext[index]]; + return true; + } - if (Vector2Ext.isTriangleCCW(a, b, c)){ - let k = this._triNext[this._triNext[index]]; - do { - if (Triangulator.testPointTriangle(points[k], a, b, c)){ - isEar = false; - break; - } + /** + * 计算一个三角形列表,该列表完全覆盖给定点集所包含的区域。如果点不是CCW,则将arePointsCCW参数传递为false + * @param points 定义封闭路径的点列表 + * @param arePointsCCW + */ + public triangulate(points: Vector2[], arePointsCCW: boolean = true) { + let count = points.length; - k = this._triNext[k]; - } while (k != this._triPrev[index]); - }else{ - isEar = false; + // 设置前一个链接和下一个链接 + this.initialize(count); + + // 非三角的多边形断路器 + let iterations = 0; + + // 从0开始 + let index = 0; + + // 继续移除所有的三角形,直到只剩下一个三角形 + while (count > 3 && iterations < 500) { + iterations++; + + let isEar = true; + let a = points[this._triPrev[index]]; + let b = points[index]; + let c = points[this._triNext[index]]; + + if (Vector2Ext.isTriangleCCW(a, b, c)) { + let k = this._triNext[this._triNext[index]]; + do { + if (Triangulator.testPointTriangle(points[k], a, b, c)) { + isEar = false; + break; + } + + k = this._triNext[k]; + } while (k != this._triPrev[index]); + } else { + isEar = false; + } + + if (isEar) { + this.triangleIndices.push(this._triPrev[index]); + this.triangleIndices.push(index); + this.triangleIndices.push(this._triNext[index]); + + // 删除vert通过重定向相邻vert的上一个和下一个链接,从而减少vertext计数 + this._triNext[this._triPrev[index]] = this._triNext[index]; + this._triPrev[this._triNext[index]] = this._triPrev[index]; + count--; + + // 接下来访问前一个vert + index = this._triPrev[index]; + } else { + index = this._triNext[index]; + } } - if (isEar){ - this.triangleIndices.push(this._triPrev[index]); - this.triangleIndices.push(index); - this.triangleIndices.push(this._triNext[index]); + this.triangleIndices.push(this._triPrev[index]); + this.triangleIndices.push(index); + this.triangleIndices.push(this._triNext[index]); - // 删除vert通过重定向相邻vert的上一个和下一个链接,从而减少vertext计数 - this._triNext[this._triPrev[index]] = this._triNext[index]; - this._triPrev[this._triNext[index]] = this._triPrev[index]; - count --; + if (!arePointsCCW) + this.triangleIndices.reverse(); + } - // 接下来访问前一个vert - index = this._triPrev[index]; - }else{ - index = this._triNext[index]; + private initialize(count: number) { + this.triangleIndices.length = 0; + + if (this._triNext.length < count) { + this._triNext.reverse(); + this._triNext = new Array(Math.max(this._triNext.length * 2, count)); } + if (this._triPrev.length < count) { + this._triPrev.reverse(); + this._triPrev = new Array(Math.max(this._triPrev.length * 2, count)); + } + + for (let i = 0; i < count; i++) { + this._triPrev[i] = i - 1; + this._triNext[i] = i + 1; + } + + this._triPrev[0] = count - 1; + this._triNext[count - 1] = 0; } - - this.triangleIndices.push(this._triPrev[index]); - this.triangleIndices.push(index); - this.triangleIndices.push(this._triNext[index]); - - if (!arePointsCCW) - this.triangleIndices.reverse(); } - - private initialize(count: number){ - this.triangleIndices.length = 0; - - if (this._triNext.length < count){ - this._triNext.reverse(); - this._triNext = new Array(Math.max(this._triNext.length * 2, count)); - } - if (this._triPrev.length < count){ - this._triPrev.reverse(); - this._triPrev = new Array(Math.max(this._triPrev.length * 2, count)); - } - - for (let i = 0; i < count;i ++){ - this._triPrev[i] = i - 1; - this._triNext[i] = i + 1; - } - - this._triPrev[0] = count - 1; - this._triNext[count - 1] = 0; - } - - public static testPointTriangle(point: Vector2, a: Vector2, b: Vector2, c: Vector2): boolean{ - if (Vector2Ext.cross(Vector2.subtract(point, a), Vector2.subtract(b, a)) < 0) - return false; - - if (Vector2Ext.cross(Vector2.subtract(point, b), Vector2.subtract(c, b)) < 0) - return false; - - if (Vector2Ext.cross(Vector2.subtract(point, c), Vector2.subtract(a, c)) < 0) - return false; - - return true; - } -} \ No newline at end of file +} diff --git a/source/src/Utils/Vector2Ext.ts b/source/src/Utils/Vector2Ext.ts index 17789716..2819d3fb 100644 --- a/source/src/Utils/Vector2Ext.ts +++ b/source/src/Utils/Vector2Ext.ts @@ -1,85 +1,87 @@ -class Vector2Ext { - /** - * 检查三角形是CCW还是CW - * @param a - * @param center - * @param c - */ - public static isTriangleCCW(a: Vector2, center: Vector2, c: Vector2) { - return this.cross(Vector2.subtract(center, a), Vector2.subtract(c, center)) < 0; - } - - /** - * 计算二维伪叉乘点(Perp(u), v) - * @param u - * @param v - */ - public static cross(u: Vector2, v: Vector2) { - return u.y * v.x - u.x * v.y; - } - - /** - * 返回与传入向量垂直的向量 - * @param first - * @param second - */ - public static perpendicular(first: Vector2, second: Vector2) { - return new Vector2(-1 * (second.y - first.y), second.x - first.x); - } - - /** - * Vector2的临时解决方案 - * 标准化把向量弄乱了 - * @param vec - */ - public static normalize(vec: Vector2) { - let magnitude = Math.sqrt((vec.x * vec.x) + (vec.y * vec.y)); - if (magnitude > MathHelper.Epsilon) { - vec = Vector2.divide(vec, new Vector2(magnitude)); - } else { - vec.x = vec.y = 0; +module es { + export class Vector2Ext { + /** + * 检查三角形是CCW还是CW + * @param a + * @param center + * @param c + */ + public static isTriangleCCW(a: Vector2, center: Vector2, c: Vector2) { + return this.cross(Vector2.subtract(center, a), Vector2.subtract(c, center)) < 0; } - return vec; - } + /** + * 计算二维伪叉乘点(Perp(u), v) + * @param u + * @param v + */ + public static cross(u: Vector2, v: Vector2) { + return u.y * v.x - u.x * v.y; + } - /** - * 通过指定的矩阵对Vector2的数组中的向量应用变换,并将结果放置在另一个数组中。 - * @param sourceArray - * @param sourceIndex - * @param matrix - * @param destinationArray - * @param destinationIndex - * @param length - */ - public static transformA(sourceArray: Vector2[], sourceIndex: number, matrix: Matrix2D, - destinationArray: Vector2[], destinationIndex: number, length: number) { - for (let i = 0; i < length; i ++){ + /** + * 返回与传入向量垂直的向量 + * @param first + * @param second + */ + public static perpendicular(first: Vector2, second: Vector2) { + return new Vector2(-1 * (second.y - first.y), second.x - first.x); + } + + /** + * Vector2的临时解决方案 + * 标准化把向量弄乱了 + * @param vec + */ + public static normalize(vec: Vector2) { + let magnitude = Math.sqrt((vec.x * vec.x) + (vec.y * vec.y)); + if (magnitude > MathHelper.Epsilon) { + vec = Vector2.divide(vec, new Vector2(magnitude)); + } else { + vec.x = vec.y = 0; + } + + return vec; + } + + /** + * 通过指定的矩阵对Vector2的数组中的向量应用变换,并将结果放置在另一个数组中。 + * @param sourceArray + * @param sourceIndex + * @param matrix + * @param destinationArray + * @param destinationIndex + * @param length + */ + public static transformA(sourceArray: Vector2[], sourceIndex: number, matrix: Matrix2D, + destinationArray: Vector2[], destinationIndex: number, length: number) { + for (let i = 0; i < length; i++) { let position = sourceArray[sourceIndex + i]; let destination = destinationArray[destinationIndex + i]; destination.x = (position.x * matrix.m11) + (position.y * matrix.m21) + matrix.m31; destination.y = (position.x * matrix.m12) + (position.y * matrix.m22) + matrix.m32; destinationArray[destinationIndex + i] = destination; } - } + } - public static transformR(position: Vector2, matrix: Matrix2D){ - let x = (position.x * matrix.m11) + (position.y * matrix.m21) + matrix.m31; - let y = (position.x * matrix.m12) + (position.y * matrix.m22) + matrix.m32; - return new Vector2(x, y); - } + public static transformR(position: Vector2, matrix: Matrix2D) { + let x = (position.x * matrix.m11) + (position.y * matrix.m21) + matrix.m31; + let y = (position.x * matrix.m12) + (position.y * matrix.m22) + matrix.m32; + return new Vector2(x, y); + } - /** - * 通过指定的矩阵对Vector2的数组中的所有向量应用变换,并将结果放到另一个数组中。 - * @param sourceArray - * @param matrix - * @param destinationArray - */ - public static transform(sourceArray: Vector2[], matrix: Matrix2D, destinationArray: Vector2[]) { - this.transformA(sourceArray, 0, matrix, destinationArray, 0, sourceArray.length); - } + /** + * 通过指定的矩阵对Vector2的数组中的所有向量应用变换,并将结果放到另一个数组中。 + * @param sourceArray + * @param matrix + * @param destinationArray + */ + public static transform(sourceArray: Vector2[], matrix: Matrix2D, destinationArray: Vector2[]) { + this.transformA(sourceArray, 0, matrix, destinationArray, 0, sourceArray.length); + } - public static round(vec: Vector2){ - return new Vector2(Math.round(vec.x), Math.round(vec.y)); + public static round(vec: Vector2) { + return new Vector2(Math.round(vec.x), Math.round(vec.y)); + } } -} \ No newline at end of file +} diff --git a/source/src/Utils/WebGLUtils.ts b/source/src/Utils/WebGLUtils.ts new file mode 100644 index 00000000..be82c9a5 --- /dev/null +++ b/source/src/Utils/WebGLUtils.ts @@ -0,0 +1,9 @@ +class WebGLUtils { + /** + * 获取webgl context + */ + public static getContext() { + const canvas = document.getElementsByTagName('canvas')[0]; + return canvas.getContext('2d'); + } +} \ No newline at end of file diff --git a/source/tsconfig.json b/source/tsconfig.json index ef11be0d..90444d67 100644 --- a/source/tsconfig.json +++ b/source/tsconfig.json @@ -12,7 +12,7 @@ "dom", "es2015.promise", "es6" - ] , + ] }, "include": [ "src",