From dba43b9773fb64ba310a942ddf07513b0a44e360 Mon Sep 17 00:00:00 2001 From: YHH <359807859@qq.com> Date: Tue, 16 Jun 2020 00:04:28 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84shapeCollision=20=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=A4=9A=E8=BE=B9=E5=BD=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 +- demo/libs/framework/framework.d.ts | 53 +++- demo/libs/framework/framework.js | 247 +++++++++++++++++- demo/libs/framework/framework.min.js | 2 +- demo/src/Main.ts | 3 + source/bin/framework.d.ts | 53 +++- source/bin/framework.js | 247 +++++++++++++++++- source/bin/framework.min.js | 2 +- source/src/ECS/Component.ts | 4 +- .../Components/Physics/Colliders/Collider.ts | 33 ++- .../Components/Physics/ITriggerListener.ts | 4 + source/src/ECS/Entity.ts | 4 + source/src/ECS/Utils/ComponentList.ts | 17 ++ source/src/Math/MathHelper.ts | 9 + source/src/Math/Vector2.ts | 28 ++ source/src/Physics/ColliderTriggerHelper.ts | 21 ++ source/src/Physics/Shapes/Circle.ts | 45 +++- source/src/Physics/Shapes/CollisionResult.ts | 5 + source/src/Physics/Shapes/Polygon.ts | 18 ++ source/src/Physics/Shapes/Shape.ts | 1 + .../Shapes/ShapeCollisions/ShapeCollisions.ts | 150 ++++++++--- source/src/Utils/Vector2Ext.ts | 16 ++ 22 files changed, 872 insertions(+), 94 deletions(-) create mode 100644 source/src/ECS/Components/Physics/ITriggerListener.ts create mode 100644 source/src/Physics/ColliderTriggerHelper.ts diff --git a/README.md b/README.md index 5dc1d41e..61d4bada 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ - [x] 掩码实用类 - [x] BreadthFirst 寻路算法 - [x] Dijkstra 寻路算法 +- [x] 事件处理器 ## 计划列表 @@ -33,14 +34,11 @@ - [ ] 系统列表 - [ ] 被动系统 - [ ] 协调系统 -- [ ] 高性能物理引擎 -- [ ] FSM 简易状态机 - [ ] 数学库 - [ ] 贝塞尔曲线 - [ ] 快速随机数类 - [ ] 浮点助手类 - [ ] 高性能数组 -- [ ] 事件处理器 ## 相关库 diff --git a/demo/libs/framework/framework.d.ts b/demo/libs/framework/framework.d.ts index a2f9bd99..404774b5 100644 --- a/demo/libs/framework/framework.d.ts +++ b/demo/libs/framework/framework.d.ts @@ -146,7 +146,7 @@ declare abstract class Component { readonly transform: Transform; enabled: boolean; setEnabled(isEnabled: boolean): this; - abstract initialize(): any; + initialize(): void; onAddedToEntity(): void; onRemovedFromEntity(): void; onEnabled(): void; @@ -194,6 +194,7 @@ declare class Entity { hasComponent(type: any): boolean; getOrCreateComponent(type: T): T; getComponent(type: any): T; + getComponents(type: any): T[]; removeComponentForType(type: any): boolean; removeComponent(component: Component): void; removeAllComponents(): void; @@ -376,11 +377,18 @@ declare class SpriteRenderer extends RenderableComponent { setSprite(sprite: egret.DisplayObject): SpriteRenderer; initialize(): void; } +interface ITriggerListener { + onTriggerEnter(other: Collider, local: Collider): any; + onTriggerExit(other: Collider, local: Collider): any; +} declare abstract class Collider extends Component { shape: Shape; physicsLayer: number; isTrigger: boolean; registeredPhysicsBounds: Rectangle; + shouldColliderScaleAndRotationWithTransform: boolean; + collidesWithLayers: number; + _localOffsetLength: number; protected _isParentEntityAddedToScene: any; protected _isPositionDirty: boolean; protected _isRotationDirty: boolean; @@ -392,7 +400,10 @@ declare abstract class Collider extends Component { setLocalOffset(offset: Vector2): void; registerColliderWithPhysicsSystem(): void; unregisterColliderWithPhysicsSystem(): void; - initialize(): void; + overlaps(other: Collider): any; + onEntityTransformChanged(comp: ComponentTransform): void; + onEnabled(): void; + onDisabled(): void; } declare class BoxCollider extends Collider { width: number; @@ -460,6 +471,7 @@ declare class ComponentList { updateLists(): void; private handleRemove; getComponent(type: any, onlyReturnInitializedComponents: boolean): T; + getComponents(type: any): T[]; update(): void; onEntityTransformChanged(comp: any): void; } @@ -529,6 +541,9 @@ declare class Flags { 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; @@ -536,6 +551,7 @@ declare class MathHelper { static clamp(value: number, min: number, max: number): number; static minOf(a: number, b: number, c: number, d: number): number; static maxOf(a: number, b: number, c: number, d: number): number; + static pointOnCirlce(circleCenter: Vector2, radius: number, angleInDegrees: number): Vector2; } declare class Matrix2D { m11: number; @@ -586,6 +602,14 @@ declare class Rectangle { 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; @@ -599,6 +623,11 @@ declare class 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 ColliderTriggerHelper { + private _entity; + update(): void; } declare enum PointSectors { center = 0, @@ -638,6 +667,7 @@ declare abstract class Shape { center: Vector2; abstract recalculateBounds(collider: Collider): any; abstract pointCollidesWithShape(point: Vector2): CollisionResult; + abstract overlaps(other: Shape): any; } declare class Polygon extends Shape { points: Vector2[]; @@ -651,8 +681,9 @@ declare class Polygon extends Shape { constructor(vertCount: number, radius: number); private buildEdgeNormals; setPoints(points: Vector2[]): void; - collidesWithShape(other: Shape): void; + collidesWithShape(other: Shape): CollisionResult; recalculateCenterAndEdgeNormals(): void; + overlaps(other: Shape): any; static findPolygonCenter(points: Vector2[]): Vector2; static getClosestPointOnPolygonToPoint(points: Vector2[], point: Vector2): { closestPoint: any; @@ -677,20 +708,27 @@ declare class Circle extends Shape { pointCollidesWithShape(point: Vector2): CollisionResult; collidesWithShape(other: Shape): CollisionResult; recalculateBounds(collider: Collider): void; + overlaps(other: Shape): any; } declare class CollisionResult { minimumTranslationVector: Vector2; normal: Vector2; point: Vector2; + invertResult(): void; } declare class ShapeCollisions { - static polygonToPolygon(first: Polygon, second: Polygon): void; - static getInterval(axis: Vector2, polygon: Polygon, min: number, max: number): void; + 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): { + min: number; + max: number; + }; static circleToPolygon(circle: Circle, polygon: Polygon): CollisionResult; - static circleToRect(circle: Circle, box: Box): CollisionResult; - static pointToCicle(point: Vector2, circle: Circle): 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; } declare class SpatialHash { gridBounds: Rectangle; @@ -738,6 +776,7 @@ 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; } declare class WebGLUtils { static getWebGL(): WebGLRenderingContext; diff --git a/demo/libs/framework/framework.js b/demo/libs/framework/framework.js index 2c8721f7..e2dbabc1 100644 --- a/demo/libs/framework/framework.js +++ b/demo/libs/framework/framework.js @@ -771,6 +771,8 @@ var Component = (function () { } return this; }; + Component.prototype.initialize = function () { + }; Component.prototype.onAddedToEntity = function () { }; Component.prototype.onRemovedFromEntity = function () { @@ -1011,6 +1013,9 @@ var Entity = (function () { Entity.prototype.getComponent = function (type) { return this.components.getComponent(type, false); }; + Entity.prototype.getComponents = function (type) { + return this.components.getComponents(type); + }; Entity.prototype.removeComponentForType = function (type) { var comp = this.getComponent(type); if (comp) { @@ -1786,6 +1791,8 @@ var Collider = (function (_super) { function Collider() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.physicsLayer = 1 << 0; + _this.shouldColliderScaleAndRotationWithTransform = true; + _this.collidesWithLayers = Physics.allLayers; _this._isPositionDirty = true; _this._isRotationDirty = true; return _this; @@ -1815,6 +1822,7 @@ var Collider = (function (_super) { if (this._localOffset != offset) { this.unregisterColliderWithPhysicsSystem(); this._localOffset = offset; + this._localOffsetLength = this._localOffset.length(); this._isPositionDirty = true; this.registerColliderWithPhysicsSystem(); } @@ -1831,7 +1839,30 @@ var Collider = (function (_super) { } this._isColliderRegisterd = false; }; - Collider.prototype.initialize = function () { + Collider.prototype.overlaps = function (other) { + return this.shape.overlaps(other.shape); + }; + Collider.prototype.onEntityTransformChanged = function (comp) { + switch (comp) { + case ComponentTransform.position: + this._isPositionDirty = true; + break; + case ComponentTransform.scale: + this._isPositionDirty = true; + break; + case ComponentTransform.rotation: + this._isRotationDirty = true; + break; + } + if (this._isColliderRegisterd) + Physics.updateCollider(this); + }; + Collider.prototype.onEnabled = function () { + this.registerColliderWithPhysicsSystem(); + this._isPositionDirty = this._isRotationDirty = true; + }; + Collider.prototype.onDisabled = function () { + this.unregisterColliderWithPhysicsSystem(); }; return Collider; }(Component)); @@ -2177,6 +2208,20 @@ var ComponentList = (function () { } return null; }; + ComponentList.prototype.getComponents = function (type) { + var components = []; + for (var i = 0; i < this._components.length; i++) { + var component = this._components[i]; + if (component instanceof type) + components.push(components); + } + for (var i = 0; i < this._componentsToAdd.length; i++) { + var component = this._componentsToAdd[i]; + if (component instanceof type) + components.push(components); + } + return components; + }; ComponentList.prototype.update = function () { this.updateLists(); for (var i = 0; i < this._components.length; i++) { @@ -2478,6 +2523,13 @@ var MathHelper = (function () { MathHelper.maxOf = function (a, b, c, d) { return Math.max(a, Math.max(b, Math.max(c, d))); }; + 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.Epsilon = 0.00001; + MathHelper.Rad2Deg = 57.29578; + MathHelper.Deg2Rad = 0.0174532924; return MathHelper; }()); var Matrix2D = (function () { @@ -2780,6 +2832,34 @@ var Vector2 = (function () { 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; @@ -2835,8 +2915,37 @@ var Vector2 = (function () { 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 ColliderTriggerHelper = (function () { + function ColliderTriggerHelper() { + } + ColliderTriggerHelper.prototype.update = function () { + var colliders = this._entity.getComponents(Collider); + for (var i = 0; i < colliders.length; i++) { + var collider = colliders[i]; + var neighbors = Physics.boxcastBroadphase(collider.bounds, collider.collidesWithLayers); + for (var i_2 = 0; i_2 < neighbors.length; i_2++) { + var neighbor = neighbors[i_2]; + if (!collider.isTrigger && !neighbor.isTrigger) + continue; + if (collider.overlaps(neighbor)) { + } + } + } + }; + return ColliderTriggerHelper; +}()); var PointSectors; (function (PointSectors) { PointSectors[PointSectors["center"] = 0] = "center"; @@ -3041,6 +3150,20 @@ var Polygon = (function (_super) { 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(); + 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++) { @@ -3132,13 +3255,14 @@ var Circle = (function (_super) { return _this; } Circle.prototype.pointCollidesWithShape = function (point) { - return ShapeCollisions.pointToCicle(point, this); + return ShapeCollisions.pointToCircle(point, this); }; Circle.prototype.collidesWithShape = function (other) { if (other instanceof Box && other.isUnrotated) { - return ShapeCollisions.circleToRect(this, other); + return ShapeCollisions.circleToBox(this, other); } if (other instanceof Circle) { + return ShapeCollisions.circleToCircle(this, other); } if (other instanceof Polygon) { return ShapeCollisions.circleToPolygon(this, other); @@ -3147,12 +3271,38 @@ var Circle = (function (_super) { }; Circle.prototype.recalculateBounds = function (collider) { this.center = collider.localOffset; + if (collider.shouldColliderScaleAndRotationWithTransform) { + 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) * MathHelper.Rad2Deg; + var offsetLength = hasUnitScale ? collider._localOffsetLength : (Vector2.multiply(collider.localOffset, collider.entity.transform.scale)).length(); + this.center = MathHelper.pointOnCirlce(Vector2.zero, offsetLength, collider.entity.transform.rotationDegrees + offsetAngle); + } + } + this.position = Vector2.add(collider.entity.transform.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() { } + CollisionResult.prototype.invertResult = function () { + this.minimumTranslationVector = Vector2.negate(this.minimumTranslationVector); + this.normal = Vector2.negate(this.normal); + }; return CollisionResult; }()); var ShapeCollisions = (function () { @@ -3179,9 +3329,36 @@ var ShapeCollisions = (function () { var maxA = 0; var maxB = 0; var intervalDist = 0; - this.getInterval(axis, first, minA, maxA); - this.getInterval(axis, second, minB, maxB); + 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), 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); @@ -3195,6 +3372,7 @@ var ShapeCollisions = (function () { max = dot; } } + return { min: min, max: max }; }; ShapeCollisions.circleToPolygon = function (circle, polygon) { var result = new CollisionResult(); @@ -3205,30 +3383,47 @@ var ShapeCollisions = (function () { result.normal = gpp.edgeNormal; var circleCenterInsidePoly = polygon.containsPoint(circle.position); if (distanceSquared > circle.radius * circle.radius && !circleCenterInsidePoly) - return result; + return null; var mtv; if (circleCenterInsidePoly) { - mtv = Vector2.multiply(result.normal, new Vector2(Math.sqrt(distanceSquared) - circle.radius, Math.sqrt(distanceSquared) - circle.radius)); + 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, circle.radius)); + 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.circleToRect = function (circle, box) { + 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, circle.radius))); + var safePlace = Vector2.add(closestPointOnBounds, Vector2.subtract(result.normal, new Vector2(circle.radius))); + result.minimumTranslationVector = Vector2.subtract(circle.position, safePlace); + return result; } - 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.pointToCicle = function (point, circle) { + ShapeCollisions.pointToCircle = function (point, circle) { var result = new CollisionResult(); var distanceSquared = Vector2.distanceSquared(point, circle.position); var sumOfRadii = 1 + circle.radius; @@ -3240,7 +3435,7 @@ var ShapeCollisions = (function () { result.point = Vector2.add(circle.position, Vector2.multiply(result.normal, new Vector2(circle.radius, circle.radius))); return result; } - return result; + return null; }; ShapeCollisions.closestPointOnLine = function (lineA, lineB, closestTo) { var v = Vector2.subtract(lineB, lineA); @@ -3261,7 +3456,21 @@ var ShapeCollisions = (function () { result.point = Vector2.add(closestPoint, poly.position); return result; } - 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; }; return ShapeCollisions; }()); @@ -3493,6 +3702,16 @@ var Vector2Ext = (function () { 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)); + } + else { + vec.x = vec.y = 0; + } + return vec; + }; return Vector2Ext; }()); var WebGLUtils = (function () { diff --git a/demo/libs/framework/framework.min.js b/demo/libs/framework/framework.min.js index 2982d5a0..6d30bd08 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 i in e)e.hasOwnProperty(i)&&(t[i]=e[i])};return function(e,i){function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Array.prototype.findIndex=function(t){return function(t,e){for(var i=0,n=t.length;i-1}(this,t)},Array.prototype.firstOrDefault=function(t){return function(t,e){var i=t.findIndex(e);return-1==i?null:t[i]}(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(i,n,o){return e.call(arguments[2],n,o,t)&&i.push(n),i},[]);for(var i=[],n=0,o=t.length;n=0&&t.splice(i,1)}while(i>=0)}(this,t)},Array.prototype.remove=function(t){return function(t,e){var i=t.findIndex(function(t){return t===e});return i>=0&&(t.splice(i,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,i){t.splice(e,i)}(this,t,e)},Array.prototype.select=function(t){return function(t,e){if("function"==typeof t.reduce)return t.reduce(function(i,n,o){return i.push(e.call(arguments[2],n,o,t)),i},[]);for(var i=[],n=0,o=t.length;nr?1:-1}),t}(this,t,e)},Array.prototype.orderByDescending=function(t,e){return function(t,e,i){return t.sort(function(t,n){var o=e(t),r=e(n);return i?-i(o,r):o0;){if("break"===h())break}return o?this.recontructPath(r,e,i):null},t.hasKey=function(t,e){for(var i,n=t.keys();!(i=n.next()).done;)if(JSON.stringify(i.value)==JSON.stringify(e))return!0;return!1},t.getKey=function(t,e){for(var i,n,o=t.keys(),r=t.values();i=o.next(),n=r.next(),!i.done;)if(JSON.stringify(i.value)==JSON.stringify(e))return n.value;return null},t.recontructPath=function(t,e,i){var n=[],o=i;for(n.push(i);o!=e;)o=this.getKey(t,o),n.push(o);return n.reverse(),n},t}(),AStarNode=function(t){function e(e){var i=t.call(this)||this;return i.data=e,i}return __extends(e,t),e}(PriorityQueueNode),AstarGridGraph=function(){function t(t,e){this.dirs=[new Point(1,0),new Point(0,-1),new Point(-1,0),new Point(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,i)?this.cascadeUp(t):this.cascadeDown(t)},t.prototype.cascadeDown=function(t){for(var e,i=t.queueIndex;;){e=t;var n=2*i;if(n>this._numNodes){t.queueIndex=i,this._nodes[i]=t;break}var o=this._nodes[n];this.hasHigherPriority(o,e)&&(e=o);var r=n+1;if(r<=this._numNodes){var s=this._nodes[r];this.hasHigherPriority(s,e)&&(e=s)}if(e==t){t.queueIndex=i,this._nodes[i]=t;break}this._nodes[i]=e;var a=e.queueIndex;e.queueIndex=i,i=a}},t.prototype.cascadeUp=function(t){for(var e=Math.floor(t.queueIndex/2);e>=1;){var i=this._nodes[e];if(this.hasHigherPriority(i,t))break;this.swap(t,i),e=Math.floor(t.queueIndex/2)}},t.prototype.swap=function(t,e){this._nodes[t.queueIndex]=e,this._nodes[e.queueIndex]=t;var i=t.queueIndex;t.queueIndex=e.queueIndex,e.queueIndex=i},t.prototype.hasHigherPriority=function(t,e){return t.priority0;){if("break"===a())break}return o?AStarPathfinder.recontructPath(s,e,i):null},t.hasKey=function(t,e){for(var i,n=t.keys();!(i=n.next()).done;)if(JSON.stringify(i.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}(),Point=function(){return function(t,e){this.x=t,this.y=e}}(),UnweightedGridGraph=function(){function t(e,i,n){void 0===n&&(n=!1),this.walls=[],this._neighbors=new Array(4),this._width=e,this._hegiht=i,this._dirs=n?t.COMPASS_DIRS:t.CARDINAL_DIRS}return t.prototype.isNodeInBounds=function(t){return 0<=t.x&&t.x0;){if("break"===h())break}return o?this.recontructPath(r,e,i):null},t.hasKey=function(t,e){for(var i,n=t.keys();!(i=n.next()).done;)if(JSON.stringify(i.value)==JSON.stringify(e))return!0;return!1},t.getKey=function(t,e){for(var i,n,o=t.keys(),r=t.values();i=o.next(),n=r.next(),!i.done;)if(JSON.stringify(i.value)==JSON.stringify(e))return n.value;return null},t.recontructPath=function(t,e,i){var n=[],o=i;for(n.push(i);o!=e;)o=this.getKey(t,o),n.push(o);return n.reverse(),n},t}(),DebugDefaults=function(){function t(){}return t.verletParticle=14431326,t.verletConstraintEdge=4406838,t}(),Component=function(){function t(){this._enabled=!0,this.updateInterval=1}return Object.defineProperty(t.prototype,"transform",{get:function(){return this.entity.transform},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"enabled",{get:function(){return this.entity?this.entity.enabled&&this._enabled:this._enabled},set:function(t){this.setEnabled(t)},enumerable:!0,configurable:!0}),t.prototype.setEnabled=function(t){return this._enabled!=t&&(this._enabled=t,this._enabled?this.onEnabled():this.onDisabled()),this},t.prototype.onAddedToEntity=function(){},t.prototype.onRemovedFromEntity=function(){},t.prototype.onEnabled=function(){},t.prototype.onDisabled=function(){},t.prototype.onEntityTransformChanged=function(t){},t.prototype.update=function(){},t.prototype.registerComponent=function(){this.entity.componentBits.set(ComponentTypeManager.getIndexFor(this),!1),this.entity.scene.entityProcessors.onComponentAdded(this.entity)},t.prototype.deregisterComponent=function(){this.entity.componentBits.set(ComponentTypeManager.getIndexFor(this)),this.entity.scene.entityProcessors.onComponentRemoved(this.entity)},t}(),Entity=function(){function t(e){this._updateOrder=0,this._enabled=!0,this._tag=0,this.name=e,this.transform=new Transform(this),this.components=new ComponentList(this),this.id=t._idGenerator++,this.componentBits=new BitSet}return Object.defineProperty(t.prototype,"parent",{get:function(){return this.transform.parent},set:function(t){this.transform.setParent(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"position",{get:function(){return this.transform.position},set:function(t){this.transform.setPosition(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"localPosition",{get:function(){return this.transform.localPosition},set:function(t){this.transform.setLocalPosition(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"rotation",{get:function(){return this.transform.rotation},set:function(t){this.transform.setRotation(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"rotationDegrees",{get:function(){return this.transform.rotationDegrees},set:function(t){this.transform.setRotationDegrees(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"localRotation",{get:function(){return this.transform.localRotation},set:function(t){this.transform.setLocalRotation(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"localRotationDegrees",{get:function(){return this.transform.localRotationDegrees},set:function(t){this.transform.setLocalRotationDegrees(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"scale",{get:function(){return this.transform.scale},set:function(t){this.transform.setScale(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"localScale",{get:function(){return this.transform.scale},set:function(t){this.transform.setScale(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"worldInverseTransform",{get:function(){return this.transform.worldInverseTransform},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"localToWorldTransform",{get:function(){return this.transform.localToWorldTransform},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"worldToLocalTransform",{get:function(){return this.transform.worldToLocalTransform},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"isDestoryed",{get:function(){return this._isDestoryed},enumerable:!0,configurable:!0}),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){return this._enabled!=t&&(this._enabled=t),this},Object.defineProperty(t.prototype,"tag",{get:function(){return this._tag},set:function(t){this.setTag(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"updateOrder",{get:function(){return this._updateOrder},set:function(t){this.setUpdateOrder(t)},enumerable:!0,configurable:!0}),t.prototype.setUpdateOrder=function(t){if(this._updateOrder!=t)return this._updateOrder=t,this.scene,this},t.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},t.prototype.attachToScene=function(t){this.scene=t,t.entities.add(this),this.components.registerAllComponents();for(var e=0;e=0;t--){this.transform.getChild(t).entity.destory()}},t}(),Scene=function(t){function e(e){var i=t.call(this)||this;return e.stage.addChild(i),i._projectionMatrix=new Matrix2D(0,0,0,0,0,0),i.entityProcessors=new EntityProcessorList,i.entities=new EntityList(i),i.addEventListener(egret.Event.ACTIVATE,i.onActive,i),i.addEventListener(egret.Event.DEACTIVATE,i.onDeactive,i),i.addEventListener(egret.Event.ENTER_FRAME,i.update,i),i}return __extends(e,t),e.prototype.createEntity=function(t){var e=new Entity(t);return e.transform.position=new Vector2(0,0),this.addEntity(e)},e.prototype.addEntity=function(t){this.entities.add(t),t.scene=this;for(var 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),this._areMatrixesDirty=!0,this},e.prototype.initialize=function(){},e.prototype.update=function(){},e.prototype.setPosition=function(t){return this.entity.transform.setPosition(t),this},e.prototype.updateMatrixes=function(){var t;this._areMatrixesDirty&&(this._transformMatrix=Matrix2D.createTranslation(-this.entity.transform.position.x,-this.entity.transform.position.y),1!=this._zoom&&(t=Matrix2D.createScale(this._zoom,this._zoom),this._transformMatrix=Matrix2D.multiply(this._transformMatrix,t)),t=Matrix2D.createTranslation(this._origin.x,this._origin.y,t),this._transformMatrix=Matrix2D.multiply(this._transformMatrix,t),this._inverseTransformMatrix=Matrix2D.invert(this._transformMatrix),this._areBoundsDirty=!0,this._areMatrixesDirty=!1)},e.prototype.screenToWorldPoint=function(t){return this.updateMatrixes(),Vector2.transform(t,this._inverseTransformMatrix)},e.prototype.worldToScreenPoint=function(t){return this.updateMatrixes(),Vector2.transform(t,this._transformMatrix)},e.prototype.destory=function(){},e}(Component),CameraInset=function(){return function(){}}(),Mesh=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return __extends(e,t),e.prototype.initialize=function(){},e.prototype.setVertPosition=function(t){(!this._verts||this._verts.length!=t.length)&&(this._verts=new Array(t.length));for(var e=0;e>6;0!=(e&t.LONG_MASK)&&i++,this._bits=new Array(i)}return t.prototype.and=function(t){for(var e,i=Math.min(this._bits.length,t._bits.length),n=0;n=0;)this._bits[e]&=~t._bits[e]},t.prototype.cardinality=function(){for(var t=0,e=this._bits.length-1;e>=0;e--){var i=this._bits[e];if(0!=i)if(-1!=i){var n=((i=((i=(i>>1&0x5555555555555400)+(0x5555555555555400&i))>>2&0x3333333333333400)+(0x3333333333333400&i))>>32)+i;t+=((n=((n=(n>>4&252645135)+(252645135&n))>>8&16711935)+(16711935&n))>>16&65535)+(65535&n)}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,i=1<>6;this.ensure(i),this._bits[i]|=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.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}(),Time=function(){function t(){}return t.update=function(t){var e=(t-this._lastTime)/1e3;this.deltaTime=e*this.timeScale,this.unscaledDeltaTime=e,this.frameCount++,this._lastTime=t},t.deltaTime=0,t.timeScale=1,t.frameCount=0,t._lastTime=0,t}(),Flags=function(){function t(){}return t.isFlagSet=function(t,e){return 0!=(t&e)},t.isUnshiftedFlagSet=function(t,e){return 0!=(t&(e=1<i?i:t},t.minOf=function(t,e,i,n){return Math.min(t,Math.min(e,Math.min(i,n)))},t.maxOf=function(t,e,i,n){return Math.max(t,Math.max(e,Math.max(i,n)))},t}(),Matrix2D=function(){function t(t,e,i,n,o,r){this.m11=0,this.m12=0,this.m21=0,this.m22=0,this.m31=0,this.m32=0,this.m11=t,this.m12=e,this.m21=i,this.m22=n,this.m31=o,this.m32=r}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),i=Math.sin(t);this.m11=e,this.m12=i,this.m21=-i,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(t,e){var i=t.m11*e.m11+t.m12*e.m21,n=t.m11*e.m12+t.m12*e.m22,o=t.m21*e.m11+t.m22*e.m21,r=t.m21*e.m12+t.m22*e.m22,s=t.m31*e.m11+t.m32*e.m21+e.m31,a=t.m31*e.m12+t.m32*e.m22+e.m32;return t.m11=i,t.m12=n,t.m21=o,t.m22=r,t.m31=s,t.m32=a,t},t.multiplyTranslation=function(e,i,n){var o=t.createTranslation(i,n);return t.multiply(e,o)},t.prototype.determinant=function(){return this.m11*this.m22-this.m12*this.m21},t.invert=function(e,i){void 0===i&&(i=t.identity);var n=1/e.determinant();return i.m11=e.m22*n,i.m12=-e.m12*n,i.m21=-e.m21*n,i.m22=e.m11*n,i.m31=(e.m32*e.m21-e.m31*e.m22)*n,i.m32=-(e.m32*e.m11-e.m31*e.m12)*n,i},t.createTranslation=function(e,i,n){return void 0===n&&(n=t.identity),n.m11=1,n.m12=0,n.m21=0,n.m22=1,n.m31=e,n.m32=i,n},t.createRotation=function(e,i){i=t.identity;var n=Math.cos(e),o=Math.sin(e);return i.m11=n,i.m12=o,i.m21=-o,i.m22=n,i},t.createScale=function(e,i,n){return void 0===n&&(n=t.identity),n.m11=e,n.m12=0,n.m21=0,n.m22=i,n.m31=0,n.m32=0,n},t._identity=new t(1,0,0,1,0,0),t}(),Rectangle=function(){function t(t,e,i,n){this.x=t||0,this.y=e||0,this.width=i||0,this.height=n||0}return Object.defineProperty(t.prototype,"left",{get:function(){return this.x},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"right",{get:function(){return this.x+this.width},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"top",{get:function(){return this.y},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"bottom",{get:function(){return this.y+this.height},enumerable:!0,configurable:!0}),Object.defineProperty(t.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}),t.prototype.intersects=function(t){return t.left1)return!1;var c=(a.x*o.y-a.y*o.x)/s;return!(c<0||c>1)},t.lineToLineIntersection=function(t,e,i,n){var o=new Vector2(0,0),r=Vector2.subtract(e,t),s=Vector2.subtract(n,i),a=r.x*s.y-r.y*s.x;if(0==a)return o;var h=Vector2.subtract(i,t),c=(h.x*s.y-h.y*s.x)/a;if(c<0||c>1)return o;var u=(h.x*r.y-h.y*r.x)/a;return u<0||u>1?o:o=Vector2.add(t,new Vector2(c*r.x,c*r.y))},t.closestPointOnLine=function(t,e,i){var n=Vector2.subtract(e,t),o=Vector2.subtract(i,t),r=Vector2.dot(o,n)/Vector2.dot(n,n);return r=MathHelper.clamp(r,0,1),Vector2.add(t,new Vector2(n.x*r,n.y*r))},t.isCircleToCircle=function(t,e,i,n){return Vector2.distanceSquared(t,i)<(e+n)*(e+n)},t.isCircleToLine=function(t,e,i,n){return Vector2.distanceSquared(t,this.closestPointOnLine(i,n,t))=t&&o.y>=e&&o.x=t+i&&(r|=PointSectors.right),o.y=e+n&&(r|=PointSectors.bottom),r},t}(),Physics=function(){function t(){}return t.overlapCircleAll=function(t,e,i,n){return void 0===n&&(n=-1),this._spatialHash.overlapCircle(t,e,i,n)},t.boxcastBroadphase=function(t,e){return void 0===e&&(e=this.allLayers),this._spatialHash.aabbBroadphase(t,null,e)},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.allLayers=-1,t}(),Shape=function(){return function(){}}(),Polygon=function(t){function e(i,n){var o=t.call(this)||this;return o.isUnrotated=!0,o._areEdgeNormalsDirty=!0,o.setPoints(e.buildSymmertricalPolygon(i,n)),o}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 i=0;i=this.points.length?this.points[0]:this.points[i+1];var o=Vector2Ext.perpendicular(n,t);o=Vector2.normalize(o),this._edgeNormals[i]=o}},e.prototype.setPoints=function(t){this.points=t,this.recalculateCenterAndEdgeNormals(),this._originalPoints=new Array(t.length),this._originalPoints=t},e.prototype.collidesWithShape=function(t){if(t instanceof e)return ShapeCollisions.polygonToPolygon(this,t)},e.prototype.recalculateCenterAndEdgeNormals=function(){this._polygonCenter=e.findPolygonCenter(this.points),this._areEdgeNormalsDirty=!0},e.findPolygonCenter=function(t){for(var e=0,i=0,n=0;nt.y!=this.points[n].y>t.y&&t.x<(this.points[n].x-this.points[i].x)*(t.y-this.points[i].y)/(this.points[n].y-this.points[i].y)+this.points[i].x&&(e=!e);return e},e.buildSymmertricalPolygon=function(t,e){for(var i=new Array(t),n=0;nn&&(n=o)},t.circleToPolygon=function(t,e){var i=new CollisionResult,n=Vector2.subtract(t.position,e.position),o=Polygon.getClosestPointOnPolygonToPoint(e.points,n),r=(o.closestPoint,o.distanceSquared);i.normal=o.edgeNormal;var s=e.containsPoint(t.position);if(r>t.radius*t.radius&&!s)return i;if(s)Vector2.multiply(i.normal,new Vector2(Math.sqrt(r)-t.radius,Math.sqrt(r)-t.radius));else if(0==r)Vector2.multiply(i.normal,new Vector2(t.radius,t.radius));else Math.sqrt(r)},t.circleToRect=function(t,e){var i=new CollisionResult,n=e.bounds.getClosestPointOnRectangleBorderToPoint(t.position).res;if(e.containsPoint(t.position)){i.point=n;Vector2.add(n,Vector2.subtract(i.normal,new Vector2(t.radius,t.radius)))}return i},t.pointToCicle=function(t,e){var i=new CollisionResult,n=Vector2.distanceSquared(t,e.position),o=1+e.radius;if(n=0;n--)i[n](e)},t}(),Triangulator=function(){function t(){this.triangleIndices=[],this._triPrev=new Array(12),this._triNext=new Array(12)}return t.prototype.triangulate=function(e,i){void 0===i&&(i=!0);var n=e.length;this.initialize(n);for(var o=0,r=0;n>3&&o<500;){o++;var s=!0,a=e[this._triPrev[r]],h=e[r],c=e[this._triNext[r]];if(Vector2Ext.isTriangleCCW(a,h,c)){var u=this._triNext[this._triNext[r]];do{if(t.testPointTriangle(e[u],a,h,c)){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],n--,r=this._triPrev[r]):r=this._triNext[r]}this.triangleIndices.push(this._triPrev[r]),this.triangleIndices.push(r),this.triangleIndices.push(this._triNext[r]),i||this.triangleIndices.reverse()},t.prototype.initialize=function(t){this.triangleIndices.length=0,this._triNext.length-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"===h())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 Point(1,0),new Point(0,-1),new Point(-1,0),new Point(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}(),Point=function(){return function(t,e){this.x=t,this.y=e}}(),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"===h())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(){function t(){this._enabled=!0,this.updateInterval=1}return Object.defineProperty(t.prototype,"transform",{get:function(){return this.entity.transform},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"enabled",{get:function(){return this.entity?this.entity.enabled&&this._enabled:this._enabled},set:function(t){this.setEnabled(t)},enumerable:!0,configurable:!0}),t.prototype.setEnabled=function(t){return this._enabled!=t&&(this._enabled=t,this._enabled?this.onEnabled():this.onDisabled()),this},t.prototype.initialize=function(){},t.prototype.onAddedToEntity=function(){},t.prototype.onRemovedFromEntity=function(){},t.prototype.onEnabled=function(){},t.prototype.onDisabled=function(){},t.prototype.onEntityTransformChanged=function(t){},t.prototype.update=function(){},t.prototype.registerComponent=function(){this.entity.componentBits.set(ComponentTypeManager.getIndexFor(this),!1),this.entity.scene.entityProcessors.onComponentAdded(this.entity)},t.prototype.deregisterComponent=function(){this.entity.componentBits.set(ComponentTypeManager.getIndexFor(this)),this.entity.scene.entityProcessors.onComponentRemoved(this.entity)},t}(),Entity=function(){function t(e){this._updateOrder=0,this._enabled=!0,this._tag=0,this.name=e,this.transform=new Transform(this),this.components=new ComponentList(this),this.id=t._idGenerator++,this.componentBits=new BitSet}return Object.defineProperty(t.prototype,"parent",{get:function(){return this.transform.parent},set:function(t){this.transform.setParent(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"position",{get:function(){return this.transform.position},set:function(t){this.transform.setPosition(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"localPosition",{get:function(){return this.transform.localPosition},set:function(t){this.transform.setLocalPosition(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"rotation",{get:function(){return this.transform.rotation},set:function(t){this.transform.setRotation(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"rotationDegrees",{get:function(){return this.transform.rotationDegrees},set:function(t){this.transform.setRotationDegrees(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"localRotation",{get:function(){return this.transform.localRotation},set:function(t){this.transform.setLocalRotation(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"localRotationDegrees",{get:function(){return this.transform.localRotationDegrees},set:function(t){this.transform.setLocalRotationDegrees(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"scale",{get:function(){return this.transform.scale},set:function(t){this.transform.setScale(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"localScale",{get:function(){return this.transform.scale},set:function(t){this.transform.setScale(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"worldInverseTransform",{get:function(){return this.transform.worldInverseTransform},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"localToWorldTransform",{get:function(){return this.transform.localToWorldTransform},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"worldToLocalTransform",{get:function(){return this.transform.worldToLocalTransform},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"isDestoryed",{get:function(){return this._isDestoryed},enumerable:!0,configurable:!0}),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){return this._enabled!=t&&(this._enabled=t),this},Object.defineProperty(t.prototype,"tag",{get:function(){return this._tag},set:function(t){this.setTag(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"updateOrder",{get:function(){return this._updateOrder},set:function(t){this.setUpdateOrder(t)},enumerable:!0,configurable:!0}),t.prototype.setUpdateOrder=function(t){if(this._updateOrder!=t)return this._updateOrder=t,this.scene,this},t.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},t.prototype.attachToScene=function(t){this.scene=t,t.entities.add(this),this.components.registerAllComponents();for(var e=0;e=0;t--){this.transform.getChild(t).entity.destory()}},t}(),Scene=function(t){function e(e){var n=t.call(this)||this;return e.stage.addChild(n),n._projectionMatrix=new Matrix2D(0,0,0,0,0,0),n.entityProcessors=new EntityProcessorList,n.entities=new EntityList(n),n.addEventListener(egret.Event.ACTIVATE,n.onActive,n),n.addEventListener(egret.Event.DEACTIVATE,n.onDeactive,n),n.addEventListener(egret.Event.ENTER_FRAME,n.update,n),n}return __extends(e,t),e.prototype.createEntity=function(t){var e=new Entity(t);return e.transform.position=new Vector2(0,0),this.addEntity(e)},e.prototype.addEntity=function(t){this.entities.add(t),t.scene=this;for(var 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),this._areMatrixesDirty=!0,this},e.prototype.initialize=function(){},e.prototype.update=function(){},e.prototype.setPosition=function(t){return this.entity.transform.setPosition(t),this},e.prototype.updateMatrixes=function(){var t;this._areMatrixesDirty&&(this._transformMatrix=Matrix2D.createTranslation(-this.entity.transform.position.x,-this.entity.transform.position.y),1!=this._zoom&&(t=Matrix2D.createScale(this._zoom,this._zoom),this._transformMatrix=Matrix2D.multiply(this._transformMatrix,t)),t=Matrix2D.createTranslation(this._origin.x,this._origin.y,t),this._transformMatrix=Matrix2D.multiply(this._transformMatrix,t),this._inverseTransformMatrix=Matrix2D.invert(this._transformMatrix),this._areBoundsDirty=!0,this._areMatrixesDirty=!1)},e.prototype.screenToWorldPoint=function(t){return this.updateMatrixes(),Vector2.transform(t,this._inverseTransformMatrix)},e.prototype.worldToScreenPoint=function(t){return this.updateMatrixes(),Vector2.transform(t,this._transformMatrix)},e.prototype.destory=function(){},e}(Component),CameraInset=function(){return function(){}}(),Mesh=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return __extends(e,t),e.prototype.initialize=function(){},e.prototype.setVertPosition=function(t){(!this._verts||this._verts.length!=t.length)&&(this._verts=new Array(t.length));for(var e=0;e>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.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}(),Time=function(){function t(){}return t.update=function(t){var e=(t-this._lastTime)/1e3;this.deltaTime=e*this.timeScale,this.unscaledDeltaTime=e,this.frameCount++,this._lastTime=t},t.deltaTime=0,t.timeScale=1,t.frameCount=0,t._lastTime=0,t}(),Flags=function(){function t(){}return t.isFlagSet=function(t,e){return 0!=(t&e)},t.isUnshiftedFlagSet=function(t,e){return 0!=(t&(e=1<n?n:t},t.minOf=function(t,e,n,i){return Math.min(t,Math.min(e,Math.min(n,i)))},t.maxOf=function(t,e,n,i){return Math.max(t,Math.max(e,Math.max(n,i)))},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.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,this.m12=e,this.m21=n,this.m22=i,this.m31=o,this.m32=r}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(t,e){var n=t.m11*e.m11+t.m12*e.m21,i=t.m11*e.m12+t.m12*e.m22,o=t.m21*e.m11+t.m22*e.m21,r=t.m21*e.m12+t.m22*e.m22,s=t.m31*e.m11+t.m32*e.m21+e.m31,a=t.m31*e.m12+t.m32*e.m22+e.m32;return t.m11=n,t.m12=i,t.m21=o,t.m22=r,t.m31=s,t.m32=a,t},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=t.identity);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,i){return void 0===i&&(i=t.identity),i.m11=1,i.m12=0,i.m21=0,i.m22=1,i.m31=e,i.m32=n,i},t.createRotation=function(e,n){n=t.identity;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=t.identity),i.m11=e,i.m12=0,i.m21=0,i.m22=n,i.m31=0,i.m32=0,i},t._identity=new t(1,0,0,1,0,0),t}(),Rectangle=function(){function t(t,e,n,i){this.x=t||0,this.y=e||0,this.width=n||0,this.height=i||0}return Object.defineProperty(t.prototype,"left",{get:function(){return this.x},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"right",{get:function(){return this.x+this.width},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"top",{get:function(){return this.y},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"bottom",{get:function(){return this.y+this.height},enumerable:!0,configurable:!0}),Object.defineProperty(t.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}),t.prototype.intersects=function(t){return t.left1)return!1;var c=(a.x*o.y-a.y*o.x)/s;return!(c<0||c>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 h=Vector2.subtract(n,t),c=(h.x*s.y-h.y*s.x)/a;if(c<0||c>1)return o;var u=(h.x*r.y-h.y*r.x)/a;return u<0||u>1?o:o=Vector2.add(t,new Vector2(c*r.x,c*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.overlapCircleAll=function(t,e,n,i){return void 0===i&&(i=-1),this._spatialHash.overlapCircle(t,e,n,i)},t.boxcastBroadphase=function(t,e){return void 0===e&&(e=this.allLayers),this._spatialHash.aabbBroadphase(t,null,e)},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.allLayers=-1,t}(),Shape=function(){return function(){}}(),Polygon=function(t){function e(n,i){var o=t.call(this)||this;return o.isUnrotated=!0,o._areEdgeNormalsDirty=!0,o.setPoints(e.buildSymmertricalPolygon(n,i)),o}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=new Array(t.length),this._originalPoints=t},e.prototype.collidesWithShape=function(t){if(t instanceof e)return ShapeCollisions.polygonToPolygon(this,t)},e.prototype.recalculateCenterAndEdgeNormals=function(){this._polygonCenter=e.findPolygonCenter(this.points),this._areEdgeNormalsDirty=!0},e.prototype.overlaps=function(t){var n;if(t instanceof e)return ShapeCollisions.polygonToPolygon(this,t);if(t instanceof Circle)return!!(n=ShapeCollisions.circleToPolygon(t,this))&&(n.invertResult(),!0);throw new Error("overlaps of Pologon to "+t+" are not supported")},e.findPolygonCenter=function(t){for(var e=0,n=0,i=0;it.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;(d=Math.abs(d))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,h=e.containsPoint(t.position);if(s>t.radius*t.radius&&!h)return null;if(h)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 c=Math.sqrt(s);a=Vector2.multiply(new Vector2(-Vector2.subtract(i,r)),new Vector2((t.radius-s)/c))}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;i--)n[i](e)},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]],h=e[r],c=e[this._triNext[r]];if(Vector2Ext.isTriangleCCW(a,h,c)){var u=this._triNext[this._triNext[r]];do{if(t.testPointTriangle(e[u],a,h,c)){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}(),WebGLUtils=function(){function t(){}return t.getWebGL=function(){if(egret.WebGLUtils.checkCanUseWebGL())return document.querySelector("canvas").getContext("webgl");throw new Error("cannot get webgl")},t.drawUserIndexPrimitives=function(t,e,n,i,o,r,s){var a=this.getWebGL();a.bindBuffer(a.ARRAY_BUFFER,0),this.checkGLError(),a.bindBuffer(a.ELEMENT_ARRAY_BUFFER,0),this.checkGLError(),a.drawElements(t,this.getElementCountArray(t,s),a.UNSIGNED_SHORT,2*r),this.checkGLError()},t.getElementCountArray=function(t,e){var n=this.getWebGL();switch(t){case n.LINES:return 2*e;case n.LINE_STRIP:return e+1;case n.TRIANGLES:return 3*e;case n.TRIANGLE_STRIP:return e+2}throw new Error("not support")},t.checkGLError=function(){var t=this.getWebGL(),e=t.getError();if(e!=t.NO_ERROR)throw new Error("GL.GetError() returned"+e)},t}(); \ No newline at end of file diff --git a/demo/src/Main.ts b/demo/src/Main.ts index 940bcdd6..bfb2e122 100644 --- a/demo/src/Main.ts +++ b/demo/src/Main.ts @@ -107,6 +107,9 @@ class Main extends eui.UILayer { player.addComponent(new SpawnComponent(EnemyType.worm)); player.addComponent(new BoxCollider()); + let player2 = scene.createEntity("player2"); + player2.addComponent(new BoxCollider()); + Main.emitter.addObserver(CoreEmitterType.Update, ()=>{ console.log("update emitter"); }); diff --git a/source/bin/framework.d.ts b/source/bin/framework.d.ts index a2f9bd99..404774b5 100644 --- a/source/bin/framework.d.ts +++ b/source/bin/framework.d.ts @@ -146,7 +146,7 @@ declare abstract class Component { readonly transform: Transform; enabled: boolean; setEnabled(isEnabled: boolean): this; - abstract initialize(): any; + initialize(): void; onAddedToEntity(): void; onRemovedFromEntity(): void; onEnabled(): void; @@ -194,6 +194,7 @@ declare class Entity { hasComponent(type: any): boolean; getOrCreateComponent(type: T): T; getComponent(type: any): T; + getComponents(type: any): T[]; removeComponentForType(type: any): boolean; removeComponent(component: Component): void; removeAllComponents(): void; @@ -376,11 +377,18 @@ declare class SpriteRenderer extends RenderableComponent { setSprite(sprite: egret.DisplayObject): SpriteRenderer; initialize(): void; } +interface ITriggerListener { + onTriggerEnter(other: Collider, local: Collider): any; + onTriggerExit(other: Collider, local: Collider): any; +} declare abstract class Collider extends Component { shape: Shape; physicsLayer: number; isTrigger: boolean; registeredPhysicsBounds: Rectangle; + shouldColliderScaleAndRotationWithTransform: boolean; + collidesWithLayers: number; + _localOffsetLength: number; protected _isParentEntityAddedToScene: any; protected _isPositionDirty: boolean; protected _isRotationDirty: boolean; @@ -392,7 +400,10 @@ declare abstract class Collider extends Component { setLocalOffset(offset: Vector2): void; registerColliderWithPhysicsSystem(): void; unregisterColliderWithPhysicsSystem(): void; - initialize(): void; + overlaps(other: Collider): any; + onEntityTransformChanged(comp: ComponentTransform): void; + onEnabled(): void; + onDisabled(): void; } declare class BoxCollider extends Collider { width: number; @@ -460,6 +471,7 @@ declare class ComponentList { updateLists(): void; private handleRemove; getComponent(type: any, onlyReturnInitializedComponents: boolean): T; + getComponents(type: any): T[]; update(): void; onEntityTransformChanged(comp: any): void; } @@ -529,6 +541,9 @@ declare class Flags { 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; @@ -536,6 +551,7 @@ declare class MathHelper { static clamp(value: number, min: number, max: number): number; static minOf(a: number, b: number, c: number, d: number): number; static maxOf(a: number, b: number, c: number, d: number): number; + static pointOnCirlce(circleCenter: Vector2, radius: number, angleInDegrees: number): Vector2; } declare class Matrix2D { m11: number; @@ -586,6 +602,14 @@ declare class Rectangle { 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; @@ -599,6 +623,11 @@ declare class 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 ColliderTriggerHelper { + private _entity; + update(): void; } declare enum PointSectors { center = 0, @@ -638,6 +667,7 @@ declare abstract class Shape { center: Vector2; abstract recalculateBounds(collider: Collider): any; abstract pointCollidesWithShape(point: Vector2): CollisionResult; + abstract overlaps(other: Shape): any; } declare class Polygon extends Shape { points: Vector2[]; @@ -651,8 +681,9 @@ declare class Polygon extends Shape { constructor(vertCount: number, radius: number); private buildEdgeNormals; setPoints(points: Vector2[]): void; - collidesWithShape(other: Shape): void; + collidesWithShape(other: Shape): CollisionResult; recalculateCenterAndEdgeNormals(): void; + overlaps(other: Shape): any; static findPolygonCenter(points: Vector2[]): Vector2; static getClosestPointOnPolygonToPoint(points: Vector2[], point: Vector2): { closestPoint: any; @@ -677,20 +708,27 @@ declare class Circle extends Shape { pointCollidesWithShape(point: Vector2): CollisionResult; collidesWithShape(other: Shape): CollisionResult; recalculateBounds(collider: Collider): void; + overlaps(other: Shape): any; } declare class CollisionResult { minimumTranslationVector: Vector2; normal: Vector2; point: Vector2; + invertResult(): void; } declare class ShapeCollisions { - static polygonToPolygon(first: Polygon, second: Polygon): void; - static getInterval(axis: Vector2, polygon: Polygon, min: number, max: number): void; + 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): { + min: number; + max: number; + }; static circleToPolygon(circle: Circle, polygon: Polygon): CollisionResult; - static circleToRect(circle: Circle, box: Box): CollisionResult; - static pointToCicle(point: Vector2, circle: Circle): 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; } declare class SpatialHash { gridBounds: Rectangle; @@ -738,6 +776,7 @@ 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; } declare class WebGLUtils { static getWebGL(): WebGLRenderingContext; diff --git a/source/bin/framework.js b/source/bin/framework.js index 2c8721f7..e2dbabc1 100644 --- a/source/bin/framework.js +++ b/source/bin/framework.js @@ -771,6 +771,8 @@ var Component = (function () { } return this; }; + Component.prototype.initialize = function () { + }; Component.prototype.onAddedToEntity = function () { }; Component.prototype.onRemovedFromEntity = function () { @@ -1011,6 +1013,9 @@ var Entity = (function () { Entity.prototype.getComponent = function (type) { return this.components.getComponent(type, false); }; + Entity.prototype.getComponents = function (type) { + return this.components.getComponents(type); + }; Entity.prototype.removeComponentForType = function (type) { var comp = this.getComponent(type); if (comp) { @@ -1786,6 +1791,8 @@ var Collider = (function (_super) { function Collider() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.physicsLayer = 1 << 0; + _this.shouldColliderScaleAndRotationWithTransform = true; + _this.collidesWithLayers = Physics.allLayers; _this._isPositionDirty = true; _this._isRotationDirty = true; return _this; @@ -1815,6 +1822,7 @@ var Collider = (function (_super) { if (this._localOffset != offset) { this.unregisterColliderWithPhysicsSystem(); this._localOffset = offset; + this._localOffsetLength = this._localOffset.length(); this._isPositionDirty = true; this.registerColliderWithPhysicsSystem(); } @@ -1831,7 +1839,30 @@ var Collider = (function (_super) { } this._isColliderRegisterd = false; }; - Collider.prototype.initialize = function () { + Collider.prototype.overlaps = function (other) { + return this.shape.overlaps(other.shape); + }; + Collider.prototype.onEntityTransformChanged = function (comp) { + switch (comp) { + case ComponentTransform.position: + this._isPositionDirty = true; + break; + case ComponentTransform.scale: + this._isPositionDirty = true; + break; + case ComponentTransform.rotation: + this._isRotationDirty = true; + break; + } + if (this._isColliderRegisterd) + Physics.updateCollider(this); + }; + Collider.prototype.onEnabled = function () { + this.registerColliderWithPhysicsSystem(); + this._isPositionDirty = this._isRotationDirty = true; + }; + Collider.prototype.onDisabled = function () { + this.unregisterColliderWithPhysicsSystem(); }; return Collider; }(Component)); @@ -2177,6 +2208,20 @@ var ComponentList = (function () { } return null; }; + ComponentList.prototype.getComponents = function (type) { + var components = []; + for (var i = 0; i < this._components.length; i++) { + var component = this._components[i]; + if (component instanceof type) + components.push(components); + } + for (var i = 0; i < this._componentsToAdd.length; i++) { + var component = this._componentsToAdd[i]; + if (component instanceof type) + components.push(components); + } + return components; + }; ComponentList.prototype.update = function () { this.updateLists(); for (var i = 0; i < this._components.length; i++) { @@ -2478,6 +2523,13 @@ var MathHelper = (function () { MathHelper.maxOf = function (a, b, c, d) { return Math.max(a, Math.max(b, Math.max(c, d))); }; + 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.Epsilon = 0.00001; + MathHelper.Rad2Deg = 57.29578; + MathHelper.Deg2Rad = 0.0174532924; return MathHelper; }()); var Matrix2D = (function () { @@ -2780,6 +2832,34 @@ var Vector2 = (function () { 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; @@ -2835,8 +2915,37 @@ var Vector2 = (function () { 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 ColliderTriggerHelper = (function () { + function ColliderTriggerHelper() { + } + ColliderTriggerHelper.prototype.update = function () { + var colliders = this._entity.getComponents(Collider); + for (var i = 0; i < colliders.length; i++) { + var collider = colliders[i]; + var neighbors = Physics.boxcastBroadphase(collider.bounds, collider.collidesWithLayers); + for (var i_2 = 0; i_2 < neighbors.length; i_2++) { + var neighbor = neighbors[i_2]; + if (!collider.isTrigger && !neighbor.isTrigger) + continue; + if (collider.overlaps(neighbor)) { + } + } + } + }; + return ColliderTriggerHelper; +}()); var PointSectors; (function (PointSectors) { PointSectors[PointSectors["center"] = 0] = "center"; @@ -3041,6 +3150,20 @@ var Polygon = (function (_super) { 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(); + 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++) { @@ -3132,13 +3255,14 @@ var Circle = (function (_super) { return _this; } Circle.prototype.pointCollidesWithShape = function (point) { - return ShapeCollisions.pointToCicle(point, this); + return ShapeCollisions.pointToCircle(point, this); }; Circle.prototype.collidesWithShape = function (other) { if (other instanceof Box && other.isUnrotated) { - return ShapeCollisions.circleToRect(this, other); + return ShapeCollisions.circleToBox(this, other); } if (other instanceof Circle) { + return ShapeCollisions.circleToCircle(this, other); } if (other instanceof Polygon) { return ShapeCollisions.circleToPolygon(this, other); @@ -3147,12 +3271,38 @@ var Circle = (function (_super) { }; Circle.prototype.recalculateBounds = function (collider) { this.center = collider.localOffset; + if (collider.shouldColliderScaleAndRotationWithTransform) { + 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) * MathHelper.Rad2Deg; + var offsetLength = hasUnitScale ? collider._localOffsetLength : (Vector2.multiply(collider.localOffset, collider.entity.transform.scale)).length(); + this.center = MathHelper.pointOnCirlce(Vector2.zero, offsetLength, collider.entity.transform.rotationDegrees + offsetAngle); + } + } + this.position = Vector2.add(collider.entity.transform.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() { } + CollisionResult.prototype.invertResult = function () { + this.minimumTranslationVector = Vector2.negate(this.minimumTranslationVector); + this.normal = Vector2.negate(this.normal); + }; return CollisionResult; }()); var ShapeCollisions = (function () { @@ -3179,9 +3329,36 @@ var ShapeCollisions = (function () { var maxA = 0; var maxB = 0; var intervalDist = 0; - this.getInterval(axis, first, minA, maxA); - this.getInterval(axis, second, minB, maxB); + 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), 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); @@ -3195,6 +3372,7 @@ var ShapeCollisions = (function () { max = dot; } } + return { min: min, max: max }; }; ShapeCollisions.circleToPolygon = function (circle, polygon) { var result = new CollisionResult(); @@ -3205,30 +3383,47 @@ var ShapeCollisions = (function () { result.normal = gpp.edgeNormal; var circleCenterInsidePoly = polygon.containsPoint(circle.position); if (distanceSquared > circle.radius * circle.radius && !circleCenterInsidePoly) - return result; + return null; var mtv; if (circleCenterInsidePoly) { - mtv = Vector2.multiply(result.normal, new Vector2(Math.sqrt(distanceSquared) - circle.radius, Math.sqrt(distanceSquared) - circle.radius)); + 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, circle.radius)); + 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.circleToRect = function (circle, box) { + 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, circle.radius))); + var safePlace = Vector2.add(closestPointOnBounds, Vector2.subtract(result.normal, new Vector2(circle.radius))); + result.minimumTranslationVector = Vector2.subtract(circle.position, safePlace); + return result; } - 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.pointToCicle = function (point, circle) { + ShapeCollisions.pointToCircle = function (point, circle) { var result = new CollisionResult(); var distanceSquared = Vector2.distanceSquared(point, circle.position); var sumOfRadii = 1 + circle.radius; @@ -3240,7 +3435,7 @@ var ShapeCollisions = (function () { result.point = Vector2.add(circle.position, Vector2.multiply(result.normal, new Vector2(circle.radius, circle.radius))); return result; } - return result; + return null; }; ShapeCollisions.closestPointOnLine = function (lineA, lineB, closestTo) { var v = Vector2.subtract(lineB, lineA); @@ -3261,7 +3456,21 @@ var ShapeCollisions = (function () { result.point = Vector2.add(closestPoint, poly.position); return result; } - 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; }; return ShapeCollisions; }()); @@ -3493,6 +3702,16 @@ var Vector2Ext = (function () { 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)); + } + else { + vec.x = vec.y = 0; + } + return vec; + }; return Vector2Ext; }()); var WebGLUtils = (function () { diff --git a/source/bin/framework.min.js b/source/bin/framework.min.js index 2982d5a0..6d30bd08 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 i in e)e.hasOwnProperty(i)&&(t[i]=e[i])};return function(e,i){function n(){this.constructor=e}t(e,i),e.prototype=null===i?Object.create(i):(n.prototype=i.prototype,new n)}}(),Array.prototype.findIndex=function(t){return function(t,e){for(var i=0,n=t.length;i-1}(this,t)},Array.prototype.firstOrDefault=function(t){return function(t,e){var i=t.findIndex(e);return-1==i?null:t[i]}(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(i,n,o){return e.call(arguments[2],n,o,t)&&i.push(n),i},[]);for(var i=[],n=0,o=t.length;n=0&&t.splice(i,1)}while(i>=0)}(this,t)},Array.prototype.remove=function(t){return function(t,e){var i=t.findIndex(function(t){return t===e});return i>=0&&(t.splice(i,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,i){t.splice(e,i)}(this,t,e)},Array.prototype.select=function(t){return function(t,e){if("function"==typeof t.reduce)return t.reduce(function(i,n,o){return i.push(e.call(arguments[2],n,o,t)),i},[]);for(var i=[],n=0,o=t.length;nr?1:-1}),t}(this,t,e)},Array.prototype.orderByDescending=function(t,e){return function(t,e,i){return t.sort(function(t,n){var o=e(t),r=e(n);return i?-i(o,r):o0;){if("break"===h())break}return o?this.recontructPath(r,e,i):null},t.hasKey=function(t,e){for(var i,n=t.keys();!(i=n.next()).done;)if(JSON.stringify(i.value)==JSON.stringify(e))return!0;return!1},t.getKey=function(t,e){for(var i,n,o=t.keys(),r=t.values();i=o.next(),n=r.next(),!i.done;)if(JSON.stringify(i.value)==JSON.stringify(e))return n.value;return null},t.recontructPath=function(t,e,i){var n=[],o=i;for(n.push(i);o!=e;)o=this.getKey(t,o),n.push(o);return n.reverse(),n},t}(),AStarNode=function(t){function e(e){var i=t.call(this)||this;return i.data=e,i}return __extends(e,t),e}(PriorityQueueNode),AstarGridGraph=function(){function t(t,e){this.dirs=[new Point(1,0),new Point(0,-1),new Point(-1,0),new Point(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,i)?this.cascadeUp(t):this.cascadeDown(t)},t.prototype.cascadeDown=function(t){for(var e,i=t.queueIndex;;){e=t;var n=2*i;if(n>this._numNodes){t.queueIndex=i,this._nodes[i]=t;break}var o=this._nodes[n];this.hasHigherPriority(o,e)&&(e=o);var r=n+1;if(r<=this._numNodes){var s=this._nodes[r];this.hasHigherPriority(s,e)&&(e=s)}if(e==t){t.queueIndex=i,this._nodes[i]=t;break}this._nodes[i]=e;var a=e.queueIndex;e.queueIndex=i,i=a}},t.prototype.cascadeUp=function(t){for(var e=Math.floor(t.queueIndex/2);e>=1;){var i=this._nodes[e];if(this.hasHigherPriority(i,t))break;this.swap(t,i),e=Math.floor(t.queueIndex/2)}},t.prototype.swap=function(t,e){this._nodes[t.queueIndex]=e,this._nodes[e.queueIndex]=t;var i=t.queueIndex;t.queueIndex=e.queueIndex,e.queueIndex=i},t.prototype.hasHigherPriority=function(t,e){return t.priority0;){if("break"===a())break}return o?AStarPathfinder.recontructPath(s,e,i):null},t.hasKey=function(t,e){for(var i,n=t.keys();!(i=n.next()).done;)if(JSON.stringify(i.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}(),Point=function(){return function(t,e){this.x=t,this.y=e}}(),UnweightedGridGraph=function(){function t(e,i,n){void 0===n&&(n=!1),this.walls=[],this._neighbors=new Array(4),this._width=e,this._hegiht=i,this._dirs=n?t.COMPASS_DIRS:t.CARDINAL_DIRS}return t.prototype.isNodeInBounds=function(t){return 0<=t.x&&t.x0;){if("break"===h())break}return o?this.recontructPath(r,e,i):null},t.hasKey=function(t,e){for(var i,n=t.keys();!(i=n.next()).done;)if(JSON.stringify(i.value)==JSON.stringify(e))return!0;return!1},t.getKey=function(t,e){for(var i,n,o=t.keys(),r=t.values();i=o.next(),n=r.next(),!i.done;)if(JSON.stringify(i.value)==JSON.stringify(e))return n.value;return null},t.recontructPath=function(t,e,i){var n=[],o=i;for(n.push(i);o!=e;)o=this.getKey(t,o),n.push(o);return n.reverse(),n},t}(),DebugDefaults=function(){function t(){}return t.verletParticle=14431326,t.verletConstraintEdge=4406838,t}(),Component=function(){function t(){this._enabled=!0,this.updateInterval=1}return Object.defineProperty(t.prototype,"transform",{get:function(){return this.entity.transform},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"enabled",{get:function(){return this.entity?this.entity.enabled&&this._enabled:this._enabled},set:function(t){this.setEnabled(t)},enumerable:!0,configurable:!0}),t.prototype.setEnabled=function(t){return this._enabled!=t&&(this._enabled=t,this._enabled?this.onEnabled():this.onDisabled()),this},t.prototype.onAddedToEntity=function(){},t.prototype.onRemovedFromEntity=function(){},t.prototype.onEnabled=function(){},t.prototype.onDisabled=function(){},t.prototype.onEntityTransformChanged=function(t){},t.prototype.update=function(){},t.prototype.registerComponent=function(){this.entity.componentBits.set(ComponentTypeManager.getIndexFor(this),!1),this.entity.scene.entityProcessors.onComponentAdded(this.entity)},t.prototype.deregisterComponent=function(){this.entity.componentBits.set(ComponentTypeManager.getIndexFor(this)),this.entity.scene.entityProcessors.onComponentRemoved(this.entity)},t}(),Entity=function(){function t(e){this._updateOrder=0,this._enabled=!0,this._tag=0,this.name=e,this.transform=new Transform(this),this.components=new ComponentList(this),this.id=t._idGenerator++,this.componentBits=new BitSet}return Object.defineProperty(t.prototype,"parent",{get:function(){return this.transform.parent},set:function(t){this.transform.setParent(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"position",{get:function(){return this.transform.position},set:function(t){this.transform.setPosition(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"localPosition",{get:function(){return this.transform.localPosition},set:function(t){this.transform.setLocalPosition(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"rotation",{get:function(){return this.transform.rotation},set:function(t){this.transform.setRotation(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"rotationDegrees",{get:function(){return this.transform.rotationDegrees},set:function(t){this.transform.setRotationDegrees(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"localRotation",{get:function(){return this.transform.localRotation},set:function(t){this.transform.setLocalRotation(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"localRotationDegrees",{get:function(){return this.transform.localRotationDegrees},set:function(t){this.transform.setLocalRotationDegrees(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"scale",{get:function(){return this.transform.scale},set:function(t){this.transform.setScale(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"localScale",{get:function(){return this.transform.scale},set:function(t){this.transform.setScale(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"worldInverseTransform",{get:function(){return this.transform.worldInverseTransform},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"localToWorldTransform",{get:function(){return this.transform.localToWorldTransform},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"worldToLocalTransform",{get:function(){return this.transform.worldToLocalTransform},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"isDestoryed",{get:function(){return this._isDestoryed},enumerable:!0,configurable:!0}),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){return this._enabled!=t&&(this._enabled=t),this},Object.defineProperty(t.prototype,"tag",{get:function(){return this._tag},set:function(t){this.setTag(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"updateOrder",{get:function(){return this._updateOrder},set:function(t){this.setUpdateOrder(t)},enumerable:!0,configurable:!0}),t.prototype.setUpdateOrder=function(t){if(this._updateOrder!=t)return this._updateOrder=t,this.scene,this},t.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},t.prototype.attachToScene=function(t){this.scene=t,t.entities.add(this),this.components.registerAllComponents();for(var e=0;e=0;t--){this.transform.getChild(t).entity.destory()}},t}(),Scene=function(t){function e(e){var i=t.call(this)||this;return e.stage.addChild(i),i._projectionMatrix=new Matrix2D(0,0,0,0,0,0),i.entityProcessors=new EntityProcessorList,i.entities=new EntityList(i),i.addEventListener(egret.Event.ACTIVATE,i.onActive,i),i.addEventListener(egret.Event.DEACTIVATE,i.onDeactive,i),i.addEventListener(egret.Event.ENTER_FRAME,i.update,i),i}return __extends(e,t),e.prototype.createEntity=function(t){var e=new Entity(t);return e.transform.position=new Vector2(0,0),this.addEntity(e)},e.prototype.addEntity=function(t){this.entities.add(t),t.scene=this;for(var 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),this._areMatrixesDirty=!0,this},e.prototype.initialize=function(){},e.prototype.update=function(){},e.prototype.setPosition=function(t){return this.entity.transform.setPosition(t),this},e.prototype.updateMatrixes=function(){var t;this._areMatrixesDirty&&(this._transformMatrix=Matrix2D.createTranslation(-this.entity.transform.position.x,-this.entity.transform.position.y),1!=this._zoom&&(t=Matrix2D.createScale(this._zoom,this._zoom),this._transformMatrix=Matrix2D.multiply(this._transformMatrix,t)),t=Matrix2D.createTranslation(this._origin.x,this._origin.y,t),this._transformMatrix=Matrix2D.multiply(this._transformMatrix,t),this._inverseTransformMatrix=Matrix2D.invert(this._transformMatrix),this._areBoundsDirty=!0,this._areMatrixesDirty=!1)},e.prototype.screenToWorldPoint=function(t){return this.updateMatrixes(),Vector2.transform(t,this._inverseTransformMatrix)},e.prototype.worldToScreenPoint=function(t){return this.updateMatrixes(),Vector2.transform(t,this._transformMatrix)},e.prototype.destory=function(){},e}(Component),CameraInset=function(){return function(){}}(),Mesh=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return __extends(e,t),e.prototype.initialize=function(){},e.prototype.setVertPosition=function(t){(!this._verts||this._verts.length!=t.length)&&(this._verts=new Array(t.length));for(var e=0;e>6;0!=(e&t.LONG_MASK)&&i++,this._bits=new Array(i)}return t.prototype.and=function(t){for(var e,i=Math.min(this._bits.length,t._bits.length),n=0;n=0;)this._bits[e]&=~t._bits[e]},t.prototype.cardinality=function(){for(var t=0,e=this._bits.length-1;e>=0;e--){var i=this._bits[e];if(0!=i)if(-1!=i){var n=((i=((i=(i>>1&0x5555555555555400)+(0x5555555555555400&i))>>2&0x3333333333333400)+(0x3333333333333400&i))>>32)+i;t+=((n=((n=(n>>4&252645135)+(252645135&n))>>8&16711935)+(16711935&n))>>16&65535)+(65535&n)}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,i=1<>6;this.ensure(i),this._bits[i]|=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.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}(),Time=function(){function t(){}return t.update=function(t){var e=(t-this._lastTime)/1e3;this.deltaTime=e*this.timeScale,this.unscaledDeltaTime=e,this.frameCount++,this._lastTime=t},t.deltaTime=0,t.timeScale=1,t.frameCount=0,t._lastTime=0,t}(),Flags=function(){function t(){}return t.isFlagSet=function(t,e){return 0!=(t&e)},t.isUnshiftedFlagSet=function(t,e){return 0!=(t&(e=1<i?i:t},t.minOf=function(t,e,i,n){return Math.min(t,Math.min(e,Math.min(i,n)))},t.maxOf=function(t,e,i,n){return Math.max(t,Math.max(e,Math.max(i,n)))},t}(),Matrix2D=function(){function t(t,e,i,n,o,r){this.m11=0,this.m12=0,this.m21=0,this.m22=0,this.m31=0,this.m32=0,this.m11=t,this.m12=e,this.m21=i,this.m22=n,this.m31=o,this.m32=r}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),i=Math.sin(t);this.m11=e,this.m12=i,this.m21=-i,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(t,e){var i=t.m11*e.m11+t.m12*e.m21,n=t.m11*e.m12+t.m12*e.m22,o=t.m21*e.m11+t.m22*e.m21,r=t.m21*e.m12+t.m22*e.m22,s=t.m31*e.m11+t.m32*e.m21+e.m31,a=t.m31*e.m12+t.m32*e.m22+e.m32;return t.m11=i,t.m12=n,t.m21=o,t.m22=r,t.m31=s,t.m32=a,t},t.multiplyTranslation=function(e,i,n){var o=t.createTranslation(i,n);return t.multiply(e,o)},t.prototype.determinant=function(){return this.m11*this.m22-this.m12*this.m21},t.invert=function(e,i){void 0===i&&(i=t.identity);var n=1/e.determinant();return i.m11=e.m22*n,i.m12=-e.m12*n,i.m21=-e.m21*n,i.m22=e.m11*n,i.m31=(e.m32*e.m21-e.m31*e.m22)*n,i.m32=-(e.m32*e.m11-e.m31*e.m12)*n,i},t.createTranslation=function(e,i,n){return void 0===n&&(n=t.identity),n.m11=1,n.m12=0,n.m21=0,n.m22=1,n.m31=e,n.m32=i,n},t.createRotation=function(e,i){i=t.identity;var n=Math.cos(e),o=Math.sin(e);return i.m11=n,i.m12=o,i.m21=-o,i.m22=n,i},t.createScale=function(e,i,n){return void 0===n&&(n=t.identity),n.m11=e,n.m12=0,n.m21=0,n.m22=i,n.m31=0,n.m32=0,n},t._identity=new t(1,0,0,1,0,0),t}(),Rectangle=function(){function t(t,e,i,n){this.x=t||0,this.y=e||0,this.width=i||0,this.height=n||0}return Object.defineProperty(t.prototype,"left",{get:function(){return this.x},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"right",{get:function(){return this.x+this.width},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"top",{get:function(){return this.y},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"bottom",{get:function(){return this.y+this.height},enumerable:!0,configurable:!0}),Object.defineProperty(t.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}),t.prototype.intersects=function(t){return t.left1)return!1;var c=(a.x*o.y-a.y*o.x)/s;return!(c<0||c>1)},t.lineToLineIntersection=function(t,e,i,n){var o=new Vector2(0,0),r=Vector2.subtract(e,t),s=Vector2.subtract(n,i),a=r.x*s.y-r.y*s.x;if(0==a)return o;var h=Vector2.subtract(i,t),c=(h.x*s.y-h.y*s.x)/a;if(c<0||c>1)return o;var u=(h.x*r.y-h.y*r.x)/a;return u<0||u>1?o:o=Vector2.add(t,new Vector2(c*r.x,c*r.y))},t.closestPointOnLine=function(t,e,i){var n=Vector2.subtract(e,t),o=Vector2.subtract(i,t),r=Vector2.dot(o,n)/Vector2.dot(n,n);return r=MathHelper.clamp(r,0,1),Vector2.add(t,new Vector2(n.x*r,n.y*r))},t.isCircleToCircle=function(t,e,i,n){return Vector2.distanceSquared(t,i)<(e+n)*(e+n)},t.isCircleToLine=function(t,e,i,n){return Vector2.distanceSquared(t,this.closestPointOnLine(i,n,t))=t&&o.y>=e&&o.x=t+i&&(r|=PointSectors.right),o.y=e+n&&(r|=PointSectors.bottom),r},t}(),Physics=function(){function t(){}return t.overlapCircleAll=function(t,e,i,n){return void 0===n&&(n=-1),this._spatialHash.overlapCircle(t,e,i,n)},t.boxcastBroadphase=function(t,e){return void 0===e&&(e=this.allLayers),this._spatialHash.aabbBroadphase(t,null,e)},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.allLayers=-1,t}(),Shape=function(){return function(){}}(),Polygon=function(t){function e(i,n){var o=t.call(this)||this;return o.isUnrotated=!0,o._areEdgeNormalsDirty=!0,o.setPoints(e.buildSymmertricalPolygon(i,n)),o}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 i=0;i=this.points.length?this.points[0]:this.points[i+1];var o=Vector2Ext.perpendicular(n,t);o=Vector2.normalize(o),this._edgeNormals[i]=o}},e.prototype.setPoints=function(t){this.points=t,this.recalculateCenterAndEdgeNormals(),this._originalPoints=new Array(t.length),this._originalPoints=t},e.prototype.collidesWithShape=function(t){if(t instanceof e)return ShapeCollisions.polygonToPolygon(this,t)},e.prototype.recalculateCenterAndEdgeNormals=function(){this._polygonCenter=e.findPolygonCenter(this.points),this._areEdgeNormalsDirty=!0},e.findPolygonCenter=function(t){for(var e=0,i=0,n=0;nt.y!=this.points[n].y>t.y&&t.x<(this.points[n].x-this.points[i].x)*(t.y-this.points[i].y)/(this.points[n].y-this.points[i].y)+this.points[i].x&&(e=!e);return e},e.buildSymmertricalPolygon=function(t,e){for(var i=new Array(t),n=0;nn&&(n=o)},t.circleToPolygon=function(t,e){var i=new CollisionResult,n=Vector2.subtract(t.position,e.position),o=Polygon.getClosestPointOnPolygonToPoint(e.points,n),r=(o.closestPoint,o.distanceSquared);i.normal=o.edgeNormal;var s=e.containsPoint(t.position);if(r>t.radius*t.radius&&!s)return i;if(s)Vector2.multiply(i.normal,new Vector2(Math.sqrt(r)-t.radius,Math.sqrt(r)-t.radius));else if(0==r)Vector2.multiply(i.normal,new Vector2(t.radius,t.radius));else Math.sqrt(r)},t.circleToRect=function(t,e){var i=new CollisionResult,n=e.bounds.getClosestPointOnRectangleBorderToPoint(t.position).res;if(e.containsPoint(t.position)){i.point=n;Vector2.add(n,Vector2.subtract(i.normal,new Vector2(t.radius,t.radius)))}return i},t.pointToCicle=function(t,e){var i=new CollisionResult,n=Vector2.distanceSquared(t,e.position),o=1+e.radius;if(n=0;n--)i[n](e)},t}(),Triangulator=function(){function t(){this.triangleIndices=[],this._triPrev=new Array(12),this._triNext=new Array(12)}return t.prototype.triangulate=function(e,i){void 0===i&&(i=!0);var n=e.length;this.initialize(n);for(var o=0,r=0;n>3&&o<500;){o++;var s=!0,a=e[this._triPrev[r]],h=e[r],c=e[this._triNext[r]];if(Vector2Ext.isTriangleCCW(a,h,c)){var u=this._triNext[this._triNext[r]];do{if(t.testPointTriangle(e[u],a,h,c)){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],n--,r=this._triPrev[r]):r=this._triNext[r]}this.triangleIndices.push(this._triPrev[r]),this.triangleIndices.push(r),this.triangleIndices.push(this._triNext[r]),i||this.triangleIndices.reverse()},t.prototype.initialize=function(t){this.triangleIndices.length=0,this._triNext.length-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"===h())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 Point(1,0),new Point(0,-1),new Point(-1,0),new Point(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}(),Point=function(){return function(t,e){this.x=t,this.y=e}}(),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"===h())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(){function t(){this._enabled=!0,this.updateInterval=1}return Object.defineProperty(t.prototype,"transform",{get:function(){return this.entity.transform},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"enabled",{get:function(){return this.entity?this.entity.enabled&&this._enabled:this._enabled},set:function(t){this.setEnabled(t)},enumerable:!0,configurable:!0}),t.prototype.setEnabled=function(t){return this._enabled!=t&&(this._enabled=t,this._enabled?this.onEnabled():this.onDisabled()),this},t.prototype.initialize=function(){},t.prototype.onAddedToEntity=function(){},t.prototype.onRemovedFromEntity=function(){},t.prototype.onEnabled=function(){},t.prototype.onDisabled=function(){},t.prototype.onEntityTransformChanged=function(t){},t.prototype.update=function(){},t.prototype.registerComponent=function(){this.entity.componentBits.set(ComponentTypeManager.getIndexFor(this),!1),this.entity.scene.entityProcessors.onComponentAdded(this.entity)},t.prototype.deregisterComponent=function(){this.entity.componentBits.set(ComponentTypeManager.getIndexFor(this)),this.entity.scene.entityProcessors.onComponentRemoved(this.entity)},t}(),Entity=function(){function t(e){this._updateOrder=0,this._enabled=!0,this._tag=0,this.name=e,this.transform=new Transform(this),this.components=new ComponentList(this),this.id=t._idGenerator++,this.componentBits=new BitSet}return Object.defineProperty(t.prototype,"parent",{get:function(){return this.transform.parent},set:function(t){this.transform.setParent(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"position",{get:function(){return this.transform.position},set:function(t){this.transform.setPosition(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"localPosition",{get:function(){return this.transform.localPosition},set:function(t){this.transform.setLocalPosition(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"rotation",{get:function(){return this.transform.rotation},set:function(t){this.transform.setRotation(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"rotationDegrees",{get:function(){return this.transform.rotationDegrees},set:function(t){this.transform.setRotationDegrees(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"localRotation",{get:function(){return this.transform.localRotation},set:function(t){this.transform.setLocalRotation(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"localRotationDegrees",{get:function(){return this.transform.localRotationDegrees},set:function(t){this.transform.setLocalRotationDegrees(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"scale",{get:function(){return this.transform.scale},set:function(t){this.transform.setScale(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"localScale",{get:function(){return this.transform.scale},set:function(t){this.transform.setScale(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"worldInverseTransform",{get:function(){return this.transform.worldInverseTransform},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"localToWorldTransform",{get:function(){return this.transform.localToWorldTransform},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"worldToLocalTransform",{get:function(){return this.transform.worldToLocalTransform},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"isDestoryed",{get:function(){return this._isDestoryed},enumerable:!0,configurable:!0}),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){return this._enabled!=t&&(this._enabled=t),this},Object.defineProperty(t.prototype,"tag",{get:function(){return this._tag},set:function(t){this.setTag(t)},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"updateOrder",{get:function(){return this._updateOrder},set:function(t){this.setUpdateOrder(t)},enumerable:!0,configurable:!0}),t.prototype.setUpdateOrder=function(t){if(this._updateOrder!=t)return this._updateOrder=t,this.scene,this},t.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},t.prototype.attachToScene=function(t){this.scene=t,t.entities.add(this),this.components.registerAllComponents();for(var e=0;e=0;t--){this.transform.getChild(t).entity.destory()}},t}(),Scene=function(t){function e(e){var n=t.call(this)||this;return e.stage.addChild(n),n._projectionMatrix=new Matrix2D(0,0,0,0,0,0),n.entityProcessors=new EntityProcessorList,n.entities=new EntityList(n),n.addEventListener(egret.Event.ACTIVATE,n.onActive,n),n.addEventListener(egret.Event.DEACTIVATE,n.onDeactive,n),n.addEventListener(egret.Event.ENTER_FRAME,n.update,n),n}return __extends(e,t),e.prototype.createEntity=function(t){var e=new Entity(t);return e.transform.position=new Vector2(0,0),this.addEntity(e)},e.prototype.addEntity=function(t){this.entities.add(t),t.scene=this;for(var 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),this._areMatrixesDirty=!0,this},e.prototype.initialize=function(){},e.prototype.update=function(){},e.prototype.setPosition=function(t){return this.entity.transform.setPosition(t),this},e.prototype.updateMatrixes=function(){var t;this._areMatrixesDirty&&(this._transformMatrix=Matrix2D.createTranslation(-this.entity.transform.position.x,-this.entity.transform.position.y),1!=this._zoom&&(t=Matrix2D.createScale(this._zoom,this._zoom),this._transformMatrix=Matrix2D.multiply(this._transformMatrix,t)),t=Matrix2D.createTranslation(this._origin.x,this._origin.y,t),this._transformMatrix=Matrix2D.multiply(this._transformMatrix,t),this._inverseTransformMatrix=Matrix2D.invert(this._transformMatrix),this._areBoundsDirty=!0,this._areMatrixesDirty=!1)},e.prototype.screenToWorldPoint=function(t){return this.updateMatrixes(),Vector2.transform(t,this._inverseTransformMatrix)},e.prototype.worldToScreenPoint=function(t){return this.updateMatrixes(),Vector2.transform(t,this._transformMatrix)},e.prototype.destory=function(){},e}(Component),CameraInset=function(){return function(){}}(),Mesh=function(t){function e(){return null!==t&&t.apply(this,arguments)||this}return __extends(e,t),e.prototype.initialize=function(){},e.prototype.setVertPosition=function(t){(!this._verts||this._verts.length!=t.length)&&(this._verts=new Array(t.length));for(var e=0;e>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.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}(),Time=function(){function t(){}return t.update=function(t){var e=(t-this._lastTime)/1e3;this.deltaTime=e*this.timeScale,this.unscaledDeltaTime=e,this.frameCount++,this._lastTime=t},t.deltaTime=0,t.timeScale=1,t.frameCount=0,t._lastTime=0,t}(),Flags=function(){function t(){}return t.isFlagSet=function(t,e){return 0!=(t&e)},t.isUnshiftedFlagSet=function(t,e){return 0!=(t&(e=1<n?n:t},t.minOf=function(t,e,n,i){return Math.min(t,Math.min(e,Math.min(n,i)))},t.maxOf=function(t,e,n,i){return Math.max(t,Math.max(e,Math.max(n,i)))},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.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,this.m12=e,this.m21=n,this.m22=i,this.m31=o,this.m32=r}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(t,e){var n=t.m11*e.m11+t.m12*e.m21,i=t.m11*e.m12+t.m12*e.m22,o=t.m21*e.m11+t.m22*e.m21,r=t.m21*e.m12+t.m22*e.m22,s=t.m31*e.m11+t.m32*e.m21+e.m31,a=t.m31*e.m12+t.m32*e.m22+e.m32;return t.m11=n,t.m12=i,t.m21=o,t.m22=r,t.m31=s,t.m32=a,t},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=t.identity);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,i){return void 0===i&&(i=t.identity),i.m11=1,i.m12=0,i.m21=0,i.m22=1,i.m31=e,i.m32=n,i},t.createRotation=function(e,n){n=t.identity;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=t.identity),i.m11=e,i.m12=0,i.m21=0,i.m22=n,i.m31=0,i.m32=0,i},t._identity=new t(1,0,0,1,0,0),t}(),Rectangle=function(){function t(t,e,n,i){this.x=t||0,this.y=e||0,this.width=n||0,this.height=i||0}return Object.defineProperty(t.prototype,"left",{get:function(){return this.x},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"right",{get:function(){return this.x+this.width},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"top",{get:function(){return this.y},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"bottom",{get:function(){return this.y+this.height},enumerable:!0,configurable:!0}),Object.defineProperty(t.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}),t.prototype.intersects=function(t){return t.left1)return!1;var c=(a.x*o.y-a.y*o.x)/s;return!(c<0||c>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 h=Vector2.subtract(n,t),c=(h.x*s.y-h.y*s.x)/a;if(c<0||c>1)return o;var u=(h.x*r.y-h.y*r.x)/a;return u<0||u>1?o:o=Vector2.add(t,new Vector2(c*r.x,c*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.overlapCircleAll=function(t,e,n,i){return void 0===i&&(i=-1),this._spatialHash.overlapCircle(t,e,n,i)},t.boxcastBroadphase=function(t,e){return void 0===e&&(e=this.allLayers),this._spatialHash.aabbBroadphase(t,null,e)},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.allLayers=-1,t}(),Shape=function(){return function(){}}(),Polygon=function(t){function e(n,i){var o=t.call(this)||this;return o.isUnrotated=!0,o._areEdgeNormalsDirty=!0,o.setPoints(e.buildSymmertricalPolygon(n,i)),o}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=new Array(t.length),this._originalPoints=t},e.prototype.collidesWithShape=function(t){if(t instanceof e)return ShapeCollisions.polygonToPolygon(this,t)},e.prototype.recalculateCenterAndEdgeNormals=function(){this._polygonCenter=e.findPolygonCenter(this.points),this._areEdgeNormalsDirty=!0},e.prototype.overlaps=function(t){var n;if(t instanceof e)return ShapeCollisions.polygonToPolygon(this,t);if(t instanceof Circle)return!!(n=ShapeCollisions.circleToPolygon(t,this))&&(n.invertResult(),!0);throw new Error("overlaps of Pologon to "+t+" are not supported")},e.findPolygonCenter=function(t){for(var e=0,n=0,i=0;it.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;(d=Math.abs(d))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,h=e.containsPoint(t.position);if(s>t.radius*t.radius&&!h)return null;if(h)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 c=Math.sqrt(s);a=Vector2.multiply(new Vector2(-Vector2.subtract(i,r)),new Vector2((t.radius-s)/c))}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;i--)n[i](e)},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]],h=e[r],c=e[this._triNext[r]];if(Vector2Ext.isTriangleCCW(a,h,c)){var u=this._triNext[this._triNext[r]];do{if(t.testPointTriangle(e[u],a,h,c)){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}(),WebGLUtils=function(){function t(){}return t.getWebGL=function(){if(egret.WebGLUtils.checkCanUseWebGL())return document.querySelector("canvas").getContext("webgl");throw new Error("cannot get webgl")},t.drawUserIndexPrimitives=function(t,e,n,i,o,r,s){var a=this.getWebGL();a.bindBuffer(a.ARRAY_BUFFER,0),this.checkGLError(),a.bindBuffer(a.ELEMENT_ARRAY_BUFFER,0),this.checkGLError(),a.drawElements(t,this.getElementCountArray(t,s),a.UNSIGNED_SHORT,2*r),this.checkGLError()},t.getElementCountArray=function(t,e){var n=this.getWebGL();switch(t){case n.LINES:return 2*e;case n.LINE_STRIP:return e+1;case n.TRIANGLES:return 3*e;case n.TRIANGLE_STRIP:return e+2}throw new Error("not support")},t.checkGLError=function(){var t=this.getWebGL(),e=t.getError();if(e!=t.NO_ERROR)throw new Error("GL.GetError() returned"+e)},t}(); \ No newline at end of file diff --git a/source/src/ECS/Component.ts b/source/src/ECS/Component.ts index 81e10727..86355e6a 100644 --- a/source/src/ECS/Component.ts +++ b/source/src/ECS/Component.ts @@ -29,7 +29,9 @@ abstract class Component { return this; } - public abstract initialize(); + public initialize(){ + + } public onAddedToEntity(){ diff --git a/source/src/ECS/Components/Physics/Colliders/Collider.ts b/source/src/ECS/Components/Physics/Colliders/Collider.ts index fcf84315..8fb48072 100644 --- a/source/src/ECS/Components/Physics/Colliders/Collider.ts +++ b/source/src/ECS/Components/Physics/Colliders/Collider.ts @@ -3,7 +3,10 @@ abstract class Collider extends Component{ public physicsLayer = 1 << 0; public isTrigger: boolean; public registeredPhysicsBounds: Rectangle; + public shouldColliderScaleAndRotationWithTransform = true; + public collidesWithLayers = Physics.allLayers; + public _localOffsetLength: number; protected _isParentEntityAddedToScene; protected _isPositionDirty = true; protected _isRotationDirty = true; @@ -32,6 +35,7 @@ abstract class Collider extends Component{ if (this._localOffset != offset){ this.unregisterColliderWithPhysicsSystem(); this._localOffset = offset; + this._localOffsetLength = this._localOffset.length(); this._isPositionDirty = true; this.registerColliderWithPhysicsSystem(); } @@ -51,6 +55,33 @@ abstract class Collider extends Component{ this._isColliderRegisterd = false; } - public initialize() { + public overlaps(other: Collider){ + return this.shape.overlaps(other.shape); + } + + public onEntityTransformChanged(comp: ComponentTransform){ + switch (comp){ + case ComponentTransform.position: + this._isPositionDirty = true; + break; + case ComponentTransform.scale: + this._isPositionDirty = true; + break; + case ComponentTransform.rotation: + this._isRotationDirty = true; + break; + } + + if (this._isColliderRegisterd) + Physics.updateCollider(this); + } + + public onEnabled(){ + this.registerColliderWithPhysicsSystem(); + this._isPositionDirty = this._isRotationDirty = true; + } + + public onDisabled(){ + this.unregisterColliderWithPhysicsSystem(); } } \ No newline at end of file diff --git a/source/src/ECS/Components/Physics/ITriggerListener.ts b/source/src/ECS/Components/Physics/ITriggerListener.ts new file mode 100644 index 00000000..a04f150c --- /dev/null +++ b/source/src/ECS/Components/Physics/ITriggerListener.ts @@ -0,0 +1,4 @@ +interface ITriggerListener { + onTriggerEnter(other: Collider, local: Collider); + onTriggerExit(other: Collider, local: Collider); +} \ No newline at end of file diff --git a/source/src/ECS/Entity.ts b/source/src/ECS/Entity.ts index 03e2911b..977f6718 100644 --- a/source/src/ECS/Entity.ts +++ b/source/src/ECS/Entity.ts @@ -212,6 +212,10 @@ class Entity { return this.components.getComponent(type, false) as T; } + public getComponents(type): T[]{ + return this.components.getComponents(type); + } + public removeComponentForType(type){ let comp = this.getComponent(type); if (comp){ diff --git a/source/src/ECS/Utils/ComponentList.ts b/source/src/ECS/Utils/ComponentList.ts index 938e7a81..e07942b2 100644 --- a/source/src/ECS/Utils/ComponentList.ts +++ b/source/src/ECS/Utils/ComponentList.ts @@ -120,6 +120,23 @@ class ComponentList { return null; } + public getComponents(type): T[]{ + let components = []; + for (let i = 0; i < this._components.length; i ++){ + let component = this._components[i]; + if (component instanceof type) + components.push(components); + } + + for (let i = 0; i < this._componentsToAdd.length; i ++){ + let component = this._componentsToAdd[i]; + if (component instanceof type) + components.push(components); + } + + return components; + } + public update(){ this.updateLists(); for (let i = 0; i < this._components.length; i ++){ diff --git a/source/src/Math/MathHelper.ts b/source/src/Math/MathHelper.ts index 0b774ef4..253a1877 100644 --- a/source/src/Math/MathHelper.ts +++ b/source/src/Math/MathHelper.ts @@ -1,4 +1,8 @@ class MathHelper { + public static readonly Epsilon: number = 0.00001; + public static readonly Rad2Deg = 57.29578; + public static readonly Deg2Rad = 0.0174532924; + /** * 将弧度转换成角度。 * @param radians 用弧度表示的角 @@ -48,4 +52,9 @@ class MathHelper { public static maxOf(a: number, b: number, c: number, d: number){ return Math.max(a, Math.max(b, Math.max(c, d))); } + + 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); + } } \ No newline at end of file diff --git a/source/src/Math/Vector2.ts b/source/src/Math/Vector2.ts index 1250dde8..bdf3bf5a 100644 --- a/source/src/Math/Vector2.ts +++ b/source/src/Math/Vector2.ts @@ -3,6 +3,26 @@ class Vector2 { 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; + } + + 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坐标 @@ -90,4 +110,12 @@ class Vector2 { let v1 = value1.x - value2.x, v2 = value1.y - value2.y; return Math.sqrt((v1 * v1) + (v2 * v2)); } + + 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/Physics/ColliderTriggerHelper.ts b/source/src/Physics/ColliderTriggerHelper.ts new file mode 100644 index 00000000..65270a56 --- /dev/null +++ b/source/src/Physics/ColliderTriggerHelper.ts @@ -0,0 +1,21 @@ +class ColliderTriggerHelper { + private _entity: Entity; + + public update(){ + let colliders = this._entity.getComponents(Collider); + for (let i = 0; i < colliders.length; i ++){ + let collider = colliders[i]; + + let neighbors = Physics.boxcastBroadphase(collider.bounds, collider.collidesWithLayers); + for (let i = 0; i < neighbors.length; i ++){ + let neighbor = neighbors[i]; + if (!collider.isTrigger && !neighbor.isTrigger) + continue; + + if (collider.overlaps(neighbor)){ + + } + } + } + } +} \ No newline at end of file diff --git a/source/src/Physics/Shapes/Circle.ts b/source/src/Physics/Shapes/Circle.ts index a21bcabc..13d31c90 100644 --- a/source/src/Physics/Shapes/Circle.ts +++ b/source/src/Physics/Shapes/Circle.ts @@ -3,26 +3,26 @@ class Circle extends Shape { public radius: number; private _originalRadius: number; - constructor(radius: number){ + constructor(radius: number) { super(); this.radius = radius; this._originalRadius = radius; } public pointCollidesWithShape(point: Vector2): CollisionResult { - return ShapeCollisions.pointToCicle(point, this); + return ShapeCollisions.pointToCircle(point, this); } - public collidesWithShape(other: Shape): CollisionResult{ - if (other instanceof Box && (other as Box).isUnrotated){ - return ShapeCollisions.circleToRect(this, other as Box); + public collidesWithShape(other: Shape): CollisionResult { + if (other instanceof Box && (other as Box).isUnrotated) { + return ShapeCollisions.circleToBox(this, other); } - if (other instanceof Circle){ - // TODO CIRCLETOCIRCLE + if (other instanceof Circle) { + return ShapeCollisions.circleToCircle(this, other); } - if (other instanceof Polygon){ + if (other instanceof Polygon) { return ShapeCollisions.circleToPolygon(this, other); } @@ -31,5 +31,34 @@ class Circle extends Shape { public recalculateBounds(collider: Collider) { this.center = collider.localOffset; + + if (collider.shouldColliderScaleAndRotationWithTransform) { + 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; + + if (collider.entity.transform.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.transform.scale)).length(); + this.center = MathHelper.pointOnCirlce(Vector2.zero, offsetLength, collider.entity.transform.rotationDegrees + offsetAngle); + } + } + + this.position = Vector2.add(collider.entity.transform.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){ + 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 7a6944c8..0b1218c9 100644 --- a/source/src/Physics/Shapes/CollisionResult.ts +++ b/source/src/Physics/Shapes/CollisionResult.ts @@ -2,4 +2,9 @@ class CollisionResult { public minimumTranslationVector: Vector2; public normal: Vector2; public point: Vector2; + + public invertResult(){ + this.minimumTranslationVector = Vector2.negate(this.minimumTranslationVector); + this.normal = Vector2.negate(this.normal); + } } \ No newline at end of file diff --git a/source/src/Physics/Shapes/Polygon.ts b/source/src/Physics/Shapes/Polygon.ts index 3e8b8494..57e5dfa2 100644 --- a/source/src/Physics/Shapes/Polygon.ts +++ b/source/src/Physics/Shapes/Polygon.ts @@ -56,6 +56,24 @@ class Polygon extends Shape { 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; diff --git a/source/src/Physics/Shapes/Shape.ts b/source/src/Physics/Shapes/Shape.ts index 7f20e0f4..ed6b7f94 100644 --- a/source/src/Physics/Shapes/Shape.ts +++ b/source/src/Physics/Shapes/Shape.ts @@ -5,4 +5,5 @@ abstract class Shape { public abstract recalculateBounds(collider: Collider); public abstract pointCollidesWithShape(point: Vector2): CollisionResult; + public abstract overlaps(other: Shape); } \ No newline at end of file diff --git a/source/src/Physics/Shapes/ShapeCollisions/ShapeCollisions.ts b/source/src/Physics/Shapes/ShapeCollisions/ShapeCollisions.ts index b62541c8..c29ac643 100644 --- a/source/src/Physics/Shapes/ShapeCollisions/ShapeCollisions.ts +++ b/source/src/Physics/Shapes/ShapeCollisions/ShapeCollisions.ts @@ -1,5 +1,5 @@ class ShapeCollisions { - public static polygonToPolygon(first: Polygon, second: Polygon){ + public static polygonToPolygon(first: Polygon, second: Polygon) { let result = new CollisionResult(); let isIntersecting = true; @@ -9,9 +9,9 @@ class ShapeCollisions { 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 ++){ - if (edgeIndex < firstEdges.length){ + + for (let edgeIndex = 0; edgeIndex < firstEdges.length + secondEdges.length; edgeIndex++) { + if (edgeIndex < firstEdges.length) { axis = firstEdges[edgeIndex]; } else { axis = secondEdges[edgeIndex - firstEdges.length]; @@ -22,72 +22,130 @@ class ShapeCollisions { let maxA = 0; let maxB = 0; let intervalDist = 0; - this.getInterval(axis, first, minA, maxA); - this.getInterval(axis, second, minB, maxB); + 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; + + 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), new Vector2(minIntervalDistance)); + + return result; } - public static getInterval(axis: Vector2, polygon: Polygon, min: number, max: number){ + public static intervalDistance(minA: number, maxA: number, minB: number, maxB) { + if (minA < minB) + return minB - maxA; + + return minA - minB; + } + + 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++){ + for (let i = 1; i < polygon.points.length; i++) { dot = Vector2.dot(polygon.points[i], axis); - if (dot < min){ + if (dot < min) { min = dot; - }else if(dot > max){ + } else if (dot > max) { max = dot; } } + + return { min: min, max: max }; } - public static circleToPolygon(circle: Circle, polygon: 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 = gpp.closestPoint; + 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 result; + return null; let mtv: Vector2; - if (circleCenterInsidePoly){ - mtv = Vector2.multiply(result.normal, new Vector2(Math.sqrt(distanceSquared) - circle.radius, Math.sqrt(distanceSquared) - circle.radius)); - }else{ - if (distanceSquared == 0){ - mtv = Vector2.multiply(result.normal, new Vector2(circle.radius, circle.radius)); - }else{ + 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( -Vector2.subtract(poly2Circle, closestPoint), new Vector2((circle.radius - distanceSquared) / distance)) + mtv = Vector2.multiply(new Vector2(-Vector2.subtract(poly2Circle, closestPoint)), new Vector2((circle.radius - distanceSquared) / distance)); } } - } - public static circleToRect(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, circle.radius))); - } + result.minimumTranslationVector = mtv; + result.point = Vector2.add(closestPoint, polygon.position); return result; } - public static pointToCicle(point: Vector2, circle: Circle){ + 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; + } + + 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); + + return result; + } + + return null; + } + + public static pointToCircle(point: Vector2, circle: Circle) { let result = new CollisionResult(); let distanceSquared = Vector2.distanceSquared(point, circle.position); let sumOfRadii = 1 + circle.radius; let collided = distanceSquared < sumOfRadii * sumOfRadii; - if (collided){ + 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); @@ -96,10 +154,10 @@ class ShapeCollisions { return result; } - return result; + return null; } - public static closestPointOnLine(lineA: Vector2, lineB: Vector2, closestTo: Vector2){ + 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); @@ -108,10 +166,10 @@ class ShapeCollisions { return Vector2.add(lineA, Vector2.multiply(v, new Vector2(t, t))); } - public static pointToPoly(point: Vector2, poly: Polygon){ + public static pointToPoly(point: Vector2, poly: Polygon) { let result = new CollisionResult(); - if (poly.containsPoint(point)){ + if (poly.containsPoint(point)) { let distanceSquared: number; let gpp = Polygon.getClosestPointOnPolygonToPoint(poly.points, Vector2.subtract(point, poly.position)); let closestPoint = gpp.closestPoint; @@ -124,6 +182,24 @@ class ShapeCollisions { return result; } - return result; + return null; + } + + public static circleToCircle(first: Circle, second: Circle){ + let result = new CollisionResult(); + + 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))); + + return result; + } + + return null; } } \ No newline at end of file diff --git a/source/src/Utils/Vector2Ext.ts b/source/src/Utils/Vector2Ext.ts index 6c07e431..e7045c8b 100644 --- a/source/src/Utils/Vector2Ext.ts +++ b/source/src/Utils/Vector2Ext.ts @@ -26,4 +26,20 @@ class Vector2Ext { 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; + } } \ No newline at end of file