diff --git a/demo/libs/framework/framework.d.ts b/demo/libs/framework/framework.d.ts index 5027afdb..c20ebc01 100644 --- a/demo/libs/framework/framework.d.ts +++ b/demo/libs/framework/framework.d.ts @@ -17,6 +17,61 @@ declare interface Array { groupBy(keySelector: Function): Array; sum(selector: any): any; } +declare class PriorityQueueNode { + priority: number; + insertionIndex: number; + queueIndex: number; +} +declare class AStarPathfinder { + static search(graph: IAstarGraph, start: T, goal: T): T[]; + private static hasKey; + private static getKey; + static recontructPath(cameFrom: Map, start: T, goal: T): T[]; +} +declare class AStarNode extends PriorityQueueNode { + data: T; + constructor(data: T); +} +declare class AstarGridGraph implements IAstarGraph { + dirs: Point[]; + walls: Point[]; + weightedNodes: Point[]; + defaultWeight: number; + weightedNodeWeight: number; + private _width; + private _height; + private _neighbors; + constructor(width: number, height: number); + isNodeInBounds(node: Point): boolean; + isNodePassable(node: Point): boolean; + search(start: Point, goal: Point): Point[]; + getNeighbors(node: Point): Point[]; + cost(from: Point, to: Point): number; + heuristic(node: Point, goal: Point): number; +} +interface IAstarGraph { + getNeighbors(node: T): Array; + cost(from: T, to: T): number; + heuristic(node: T, goal: T): any; +} +declare class PriorityQueue { + private _numNodes; + private _nodes; + private _numNodesEverEnqueued; + constructor(maxNodes: number); + clear(): void; + readonly count: number; + contains(node: T): boolean; + enqueue(node: T, priority: number): void; + dequeue(): T; + remove(node: T): void; + isValidQueue(): boolean; + private onNodeUpdated; + private cascadeDown; + private cascadeUp; + private swap; + private hasHigherPriority; +} declare abstract class Component { entity: Entity; displayRender: egret.DisplayObject; @@ -338,6 +393,11 @@ declare class Matrix2D { static createRotation(radians: number, result?: Matrix2D): Matrix2D; static createScale(xScale: number, yScale: number, result?: Matrix2D): Matrix2D; } +declare class Point { + x: number; + y: number; + constructor(x: number, y: number); +} declare class Vector2 { x: number; y: number; diff --git a/demo/libs/framework/framework.js b/demo/libs/framework/framework.js index 7164625a..d4a31b55 100644 --- a/demo/libs/framework/framework.js +++ b/demo/libs/framework/framework.js @@ -238,6 +238,262 @@ Array.prototype.sum = function (selector) { } return sum(this, selector); }; +var PriorityQueueNode = (function () { + function PriorityQueueNode() { + this.priority = 0; + this.insertionIndex = 0; + this.queueIndex = 0; + } + return PriorityQueueNode; +}()); +var AStarPathfinder = (function () { + function AStarPathfinder() { + } + AStarPathfinder.search = function (graph, start, goal) { + var _this = this; + var foundPath = false; + var cameFrom = new Map(); + cameFrom.set(start, start); + var costSoFar = new Map(); + var frontier = new PriorityQueue(1000); + frontier.enqueue(new AStarNode(start), 0); + costSoFar.set(start, 0); + var _loop_2 = function () { + var current = frontier.dequeue(); + if (JSON.stringify(current.data) == JSON.stringify(goal)) { + foundPath = true; + return "break"; + } + graph.getNeighbors(current.data).forEach(function (next) { + var newCost = costSoFar.get(current.data) + graph.cost(current.data, next); + if (!_this.hasKey(costSoFar, next) || newCost < costSoFar.get(next)) { + costSoFar.set(next, newCost); + var priority = newCost + graph.heuristic(next, goal); + frontier.enqueue(new AStarNode(next), priority); + cameFrom.set(next, current.data); + } + }); + }; + while (frontier.count > 0) { + var state_1 = _loop_2(); + if (state_1 === "break") + break; + } + return foundPath ? this.recontructPath(cameFrom, start, goal) : null; + }; + AStarPathfinder.hasKey = function (map, compareKey) { + var iterator = map.keys(); + var r; + while (r = iterator.next(), !r.done) { + if (JSON.stringify(r.value) == JSON.stringify(compareKey)) + return true; + } + return false; + }; + AStarPathfinder.getKey = function (map, compareKey) { + var iterator = map.keys(); + var valueIterator = map.values(); + var r; + var v; + while (r = iterator.next(), v = valueIterator.next(), !r.done) { + if (JSON.stringify(r.value) == JSON.stringify(compareKey)) + return v.value; + } + return null; + }; + AStarPathfinder.recontructPath = function (cameFrom, start, goal) { + var path = []; + var current = goal; + path.push(goal); + while (current != start) { + current = this.getKey(cameFrom, current); + path.push(current); + } + path.reverse(); + return path; + }; + return AStarPathfinder; +}()); +var AStarNode = (function (_super) { + __extends(AStarNode, _super); + function AStarNode(data) { + var _this = _super.call(this) || this; + _this.data = data; + return _this; + } + return AStarNode; +}(PriorityQueueNode)); +var AstarGridGraph = (function () { + function AstarGridGraph(width, height) { + this.dirs = [ + new 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 = width; + this._height = height; + } + AstarGridGraph.prototype.isNodeInBounds = function (node) { + return 0 <= node.x && node.x < this._width && 0 <= node.y && node.y < this._height; + }; + AstarGridGraph.prototype.isNodePassable = function (node) { + return !this.walls.contains(node); + }; + AstarGridGraph.prototype.search = function (start, goal) { + return AStarPathfinder.search(this, start, goal); + }; + AstarGridGraph.prototype.getNeighbors = function (node) { + var _this = this; + this._neighbors.length = 0; + this.dirs.forEach(function (dir) { + var next = new Point(node.x + dir.x, node.y + dir.y); + if (_this.isNodeInBounds(next) && _this.isNodePassable(next)) + _this._neighbors.push(next); + }); + return this._neighbors; + }; + AstarGridGraph.prototype.cost = function (from, to) { + return this.weightedNodes.find(function (p) { return JSON.stringify(p) == JSON.stringify(to); }) ? this.weightedNodeWeight : this.defaultWeight; + }; + AstarGridGraph.prototype.heuristic = function (node, goal) { + return Math.abs(node.x - goal.x) + Math.abs(node.y - goal.y); + }; + return AstarGridGraph; +}()); +var PriorityQueue = (function () { + function PriorityQueue(maxNodes) { + this._numNodes = 0; + this._nodes = new Array(maxNodes + 1); + this._numNodesEverEnqueued = 0; + } + PriorityQueue.prototype.clear = function () { + this._nodes.splice(1, this._numNodes); + this._numNodes = 0; + }; + Object.defineProperty(PriorityQueue.prototype, "count", { + get: function () { + return this._numNodes; + }, + enumerable: true, + configurable: true + }); + PriorityQueue.prototype.contains = function (node) { + return (this._nodes[node.queueIndex] == node); + }; + PriorityQueue.prototype.enqueue = function (node, priority) { + node.priority = priority; + this._numNodes++; + this._nodes[this._numNodes] = node; + node.queueIndex = this._numNodes; + node.insertionIndex = this._numNodesEverEnqueued++; + this.cascadeUp(this._nodes[this._numNodes]); + }; + PriorityQueue.prototype.dequeue = function () { + var returnMe = this._nodes[1]; + this.remove(returnMe); + return returnMe; + }; + PriorityQueue.prototype.remove = function (node) { + if (node.queueIndex == this._numNodes) { + this._nodes[this._numNodes] = null; + this._numNodes--; + return; + } + var formerLastNode = this._nodes[this._numNodes]; + this.swap(node, formerLastNode); + delete this._nodes[this._numNodes]; + this._numNodes--; + this.onNodeUpdated(formerLastNode); + }; + PriorityQueue.prototype.isValidQueue = function () { + for (var i = 1; i < this._nodes.length; i++) { + if (this._nodes[i]) { + var childLeftIndex = 2 * i; + if (childLeftIndex < this._nodes.length && this._nodes[childLeftIndex] && + this.hasHigherPriority(this._nodes[childLeftIndex], this._nodes[i])) + return false; + var childRightIndex = childLeftIndex + 1; + if (childRightIndex < this._nodes.length && this._nodes[childRightIndex] && + this.hasHigherPriority(this._nodes[childRightIndex], this._nodes[i])) + return false; + } + } + return true; + }; + PriorityQueue.prototype.onNodeUpdated = function (node) { + var parentIndex = Math.floor(node.queueIndex / 2); + var parentNode = this._nodes[parentIndex]; + if (parentIndex > 0 && this.hasHigherPriority(node, parentNode)) { + this.cascadeUp(node); + } + else { + this.cascadeDown(node); + } + }; + PriorityQueue.prototype.cascadeDown = function (node) { + var newParent; + var finalQueueIndex = node.queueIndex; + while (true) { + newParent = node; + var childLeftIndex = 2 * finalQueueIndex; + if (childLeftIndex > this._numNodes) { + node.queueIndex = finalQueueIndex; + this._nodes[finalQueueIndex] = node; + break; + } + var childLeft = this._nodes[childLeftIndex]; + if (this.hasHigherPriority(childLeft, newParent)) { + newParent = childLeft; + } + var childRightIndex = childLeftIndex + 1; + if (childRightIndex <= this._numNodes) { + var childRight = this._nodes[childRightIndex]; + if (this.hasHigherPriority(childRight, newParent)) { + newParent = childRight; + } + } + if (newParent != node) { + this._nodes[finalQueueIndex] = newParent; + var temp = newParent.queueIndex; + newParent.queueIndex = finalQueueIndex; + finalQueueIndex = temp; + } + else { + node.queueIndex = finalQueueIndex; + this._nodes[finalQueueIndex] = node; + break; + } + } + }; + PriorityQueue.prototype.cascadeUp = function (node) { + var parent = Math.floor(node.queueIndex / 2); + while (parent >= 1) { + var parentNode = this._nodes[parent]; + if (this.hasHigherPriority(parentNode, node)) + break; + this.swap(node, parentNode); + parent = Math.floor(node.queueIndex / 2); + } + }; + PriorityQueue.prototype.swap = function (node1, node2) { + this._nodes[node1.queueIndex] = node2; + this._nodes[node2.queueIndex] = node1; + var temp = node1.queueIndex; + node1.queueIndex = node2.queueIndex; + node2.queueIndex = temp; + }; + PriorityQueue.prototype.hasHigherPriority = function (higher, lower) { + return (higher.priority < lower.priority || + (higher.priority == lower.priority && higher.insertionIndex < lower.insertionIndex)); + }; + return PriorityQueue; +}()); var Component = (function () { function Component() { this._enabled = true; @@ -1763,6 +2019,13 @@ var Matrix2D = (function () { Matrix2D._identity = new Matrix2D(1, 0, 0, 1, 0, 0); return Matrix2D; }()); +var Point = (function () { + function Point(x, y) { + this.x = x; + this.y = y; + } + return Point; +}()); var Vector2 = (function () { function Vector2(x, y) { this.x = 0; diff --git a/demo/libs/framework/framework.min.js b/demo/libs/framework/framework.min.js index 8f9e6e47..f83322e0 100644 --- a/demo/libs/framework/framework.min.js +++ b/demo/libs/framework/framework.min.js @@ -1 +1 @@ -window.framework={},window.__extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])};return function(e,n){function o(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(o.prototype=n.prototype,new o)}}(),Array.prototype.findIndex=function(t){return function(t,e){for(var n=0,o=t.length;n-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,o,i){return e.call(arguments[2],o,i,t)&&n.push(o),n},[]);for(var n=[],o=0,i=t.length;o=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,o,i){return n.push(e.call(arguments[2],o,i,t)),n},[]);for(var n=[],o=0,i=t.length;or?1:-1}),t}(this,t,e)},Array.prototype.orderByDescending=function(t,e){return function(t,e,n){return t.sort(function(t,o){var i=e(t),r=e(o);return n?-n(i,r):i=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(){var t=this;SceneManager.getActiveScene().entities.buffer.forEach(function(e){return e.components.buffer.forEach(function(e){e.displayRender&&(-1==t.entity.scene.$children.indexOf(e.displayRender)&&t.entity.scene.stage.addChild(e.displayRender))})})},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._areMatrixesDirty=!1)},e.prototype.destory=function(){},e}(Component),EntitySystem=function(){function t(t){this._entities=[],this._matcher=t||Matcher.empty()}return Object.defineProperty(t.prototype,"matcher",{get:function(){return this._matcher},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"scene",{get:function(){return this._scene},set:function(t){this._scene=t,this._entities=[]},enumerable:!0,configurable:!0}),t.prototype.initialize=function(){},t.prototype.onChanged=function(t){var e=this._entities.contains(t),n=this._matcher.IsIntersted(t);n&&!e?this.add(t):!n&&e&&this.remove(t)},t.prototype.add=function(t){this._entities.push(t),this.onAdded(t)},t.prototype.onAdded=function(t){},t.prototype.remove=function(t){this._entities.remove(t),this.onRemoved(t)},t.prototype.onRemoved=function(t){},t.prototype.update=function(){this.begin(),this.process(this._entities)},t.prototype.lateUpdate=function(){this.lateProcess(this._entities),this.end()},t.prototype.begin=function(){},t.prototype.process=function(t){},t.prototype.lateProcess=function(t){},t.prototype.end=function(){},t}(),EntityProcessingSystem=function(t){function e(e){return t.call(this,e)||this}return __extends(e,t),e.prototype.lateProcessEntity=function(t){},e.prototype.process=function(t){var e=this;t.forEach(function(t){return e.processEntity(t)})},e.prototype.lateProcess=function(t){var e=this;t.forEach(function(t){return e.lateProcessEntity(t)})},e}(EntitySystem),BitSet=function(){function t(e){void 0===e&&(e=64);var n=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),o=0;o=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 o=((n=((n=(n>>1&0x5555555555555400)+(0x5555555555555400&n))>>2&0x3333333333333400)+(0x3333333333333400&n))>>32)+n;t+=((o=((o=(o>>4&252645135)+(252645135&o))>>8&16711935)+(16711935&o))>>16&65535)+(65535&o)}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}},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._lastTime=t},t.timeScale=1,t._lastTime=0,t}(),MathHelper=function(){function t(){}return t.toDegrees=function(t){return 57.29577951308232*t},t.toRadians=function(t){return.017453292519943295*t},t.map=function(t,e,n,o,i){return o+(t-e)*(i-o)/(n-e)},t.clamp=function(t,e,n){return tn?n:t},t}(),Matrix2D=function(){function t(t,e,n,o,i,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=o,this.m31=i,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,o=t.m11*e.m12+t.m12*e.m22,i=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=o,t.m21=i,t.m22=r,t.m31=s,t.m32=a,t},t.multiplyTranslation=function(e,n,o){var i=t.createTranslation(n,o);return t.multiply(e,i)},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 o=1/e.determinant();return n.m11=e.m22*o,n.m12=-e.m12*o,n.m21=-e.m21*o,n.m22=e.m11*o,n.m31=(e.m32*e.m21-e.m31*e.m22)*o,n.m32=-(e.m32*e.m11-e.m31*e.m12)*o,n},t.createTranslation=function(e,n,o){return void 0===o&&(o=t.identity),o.m11=1,o.m12=0,o.m21=0,o.m22=1,o.m31=e,o.m32=n,o},t.createRotation=function(e,n){n=t.identity;var o=Math.cos(e),i=Math.sin(e);return n.m11=o,n.m12=i,n.m21=-i,n.m22=o,n},t.createScale=function(e,n,o){return void 0===o&&(o=t.identity),o.m11=e,o.m12=0,o.m21=0,o.m22=n,o.m31=0,o.m32=0,o},t._identity=new t(1,0,0,1,0,0),t}(),Vector2=function(){function t(t,e){this.x=0,this.y=0,this.x=t,this.y=e}return Object.defineProperty(t,"One",{get:function(){return this.unitVector2},enumerable:!0,configurable:!0}),t.add=function(t,e){return t.x+=e.x,t.y+=e.y,t},t.divide=function(t,e){return t.x/=e.x,t.y/=e.y,t},t.multiply=function(t,e){return t.x*=e.x,t.y*=e.y,t},t.subtract=function(t,e){return t.x-=e.x,t.y-=e.y,t},t.prototype.normalize=function(){var t=1/Math.sqrt(this.x*this.x+this.y*this.y);this.x*=t,this.y*=t},t.transform=function(e,n){return new t(e.x*n.m11+e.y*n.m21,e.x*n.m12+e.y*n.m22)},t.unitVector2=new t(1,1),t}(); \ No newline at end of file +window.framework={},window.__extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])};return function(e,n){function o(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(o.prototype=n.prototype,new o)}}(),Array.prototype.findIndex=function(t){return function(t,e){for(var n=0,o=t.length;n-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,o,i){return e.call(arguments[2],o,i,t)&&n.push(o),n},[]);for(var n=[],o=0,i=t.length;o=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,o,i){return n.push(e.call(arguments[2],o,i,t)),n},[]);for(var n=[],o=0,i=t.length;or?1:-1}),t}(this,t,e)},Array.prototype.orderByDescending=function(t,e){return function(t,e,n){return t.sort(function(t,o){var i=e(t),r=e(o);return n?-n(i,r):i0;){if("break"===h())break}return i?this.recontructPath(r,e,n):null},t.hasKey=function(t,e){for(var n,o=t.keys();!(n=o.next()).done;)if(JSON.stringify(n.value)==JSON.stringify(e))return!0;return!1},t.getKey=function(t,e){for(var n,o,i=t.keys(),r=t.values();n=i.next(),o=r.next(),!n.done;)if(JSON.stringify(n.value)==JSON.stringify(e))return o.value;return null},t.recontructPath=function(t,e,n){var o=[],i=n;for(o.push(n);i!=e;)i=this.getKey(t,i),o.push(i);return o.reverse(),o},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 o=2*n;if(o>this._numNodes){t.queueIndex=n,this._nodes[n]=t;break}var i=this._nodes[o];this.hasHigherPriority(i,e)&&(e=i);var r=o+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.priority=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(){var t=this;SceneManager.getActiveScene().entities.buffer.forEach(function(e){return e.components.buffer.forEach(function(e){e.displayRender&&(-1==t.entity.scene.$children.indexOf(e.displayRender)&&t.entity.scene.stage.addChild(e.displayRender))})})},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._areMatrixesDirty=!1)},e.prototype.destory=function(){},e}(Component),EntitySystem=function(){function t(t){this._entities=[],this._matcher=t||Matcher.empty()}return Object.defineProperty(t.prototype,"matcher",{get:function(){return this._matcher},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"scene",{get:function(){return this._scene},set:function(t){this._scene=t,this._entities=[]},enumerable:!0,configurable:!0}),t.prototype.initialize=function(){},t.prototype.onChanged=function(t){var e=this._entities.contains(t),n=this._matcher.IsIntersted(t);n&&!e?this.add(t):!n&&e&&this.remove(t)},t.prototype.add=function(t){this._entities.push(t),this.onAdded(t)},t.prototype.onAdded=function(t){},t.prototype.remove=function(t){this._entities.remove(t),this.onRemoved(t)},t.prototype.onRemoved=function(t){},t.prototype.update=function(){this.begin(),this.process(this._entities)},t.prototype.lateUpdate=function(){this.lateProcess(this._entities),this.end()},t.prototype.begin=function(){},t.prototype.process=function(t){},t.prototype.lateProcess=function(t){},t.prototype.end=function(){},t}(),EntityProcessingSystem=function(t){function e(e){return t.call(this,e)||this}return __extends(e,t),e.prototype.lateProcessEntity=function(t){},e.prototype.process=function(t){var e=this;t.forEach(function(t){return e.processEntity(t)})},e.prototype.lateProcess=function(t){var e=this;t.forEach(function(t){return e.lateProcessEntity(t)})},e}(EntitySystem),BitSet=function(){function t(e){void 0===e&&(e=64);var n=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),o=0;o=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 o=((n=((n=(n>>1&0x5555555555555400)+(0x5555555555555400&n))>>2&0x3333333333333400)+(0x3333333333333400&n))>>32)+n;t+=((o=((o=(o>>4&252645135)+(252645135&o))>>8&16711935)+(16711935&o))>>16&65535)+(65535&o)}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}},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._lastTime=t},t.timeScale=1,t._lastTime=0,t}(),MathHelper=function(){function t(){}return t.toDegrees=function(t){return 57.29577951308232*t},t.toRadians=function(t){return.017453292519943295*t},t.map=function(t,e,n,o,i){return o+(t-e)*(i-o)/(n-e)},t.clamp=function(t,e,n){return tn?n:t},t}(),Matrix2D=function(){function t(t,e,n,o,i,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=o,this.m31=i,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,o=t.m11*e.m12+t.m12*e.m22,i=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=o,t.m21=i,t.m22=r,t.m31=s,t.m32=a,t},t.multiplyTranslation=function(e,n,o){var i=t.createTranslation(n,o);return t.multiply(e,i)},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 o=1/e.determinant();return n.m11=e.m22*o,n.m12=-e.m12*o,n.m21=-e.m21*o,n.m22=e.m11*o,n.m31=(e.m32*e.m21-e.m31*e.m22)*o,n.m32=-(e.m32*e.m11-e.m31*e.m12)*o,n},t.createTranslation=function(e,n,o){return void 0===o&&(o=t.identity),o.m11=1,o.m12=0,o.m21=0,o.m22=1,o.m31=e,o.m32=n,o},t.createRotation=function(e,n){n=t.identity;var o=Math.cos(e),i=Math.sin(e);return n.m11=o,n.m12=i,n.m21=-i,n.m22=o,n},t.createScale=function(e,n,o){return void 0===o&&(o=t.identity),o.m11=e,o.m12=0,o.m21=0,o.m22=n,o.m31=0,o.m32=0,o},t._identity=new t(1,0,0,1,0,0),t}(),Point=function(){return function(t,e){this.x=t,this.y=e}}(),Vector2=function(){function t(t,e){this.x=0,this.y=0,this.x=t,this.y=e}return Object.defineProperty(t,"One",{get:function(){return this.unitVector2},enumerable:!0,configurable:!0}),t.add=function(t,e){return t.x+=e.x,t.y+=e.y,t},t.divide=function(t,e){return t.x/=e.x,t.y/=e.y,t},t.multiply=function(t,e){return t.x*=e.x,t.y*=e.y,t},t.subtract=function(t,e){return t.x-=e.x,t.y-=e.y,t},t.prototype.normalize=function(){var t=1/Math.sqrt(this.x*this.x+this.y*this.y);this.x*=t,this.y*=t},t.transform=function(e,n){return new t(e.x*n.m11+e.y*n.m21,e.x*n.m12+e.y*n.m22)},t.unitVector2=new t(1,1),t}(); \ No newline at end of file diff --git a/demo/src/game/MainScene.ts b/demo/src/game/MainScene.ts index 89214259..6c49b2e4 100644 --- a/demo/src/game/MainScene.ts +++ b/demo/src/game/MainScene.ts @@ -3,5 +3,18 @@ class MainScene extends Scene { super(displayContent); this.addEntityProcessor(new SpawnerSystem(new Matcher())); + this.astarTest(); + } + + public astarTest(){ + let graph = new AstarGridGraph(20, 20); + + graph.weightedNodes.push(new Point(3, 3)); + graph.weightedNodes.push(new Point(3, 4)); + graph.weightedNodes.push(new Point(4, 3)); + graph.weightedNodes.push(new Point(4, 4)); + + let path = graph.search(new Point(3, 4), new Point(15, 17)); + console.log(path); } } \ No newline at end of file diff --git a/demo/tsconfig.json b/demo/tsconfig.json index 905433a2..5737e5ba 100644 --- a/demo/tsconfig.json +++ b/demo/tsconfig.json @@ -3,10 +3,12 @@ "target": "es5", "outDir": "bin-debug", "experimentalDecorators": true, + "emitDecoratorMetadata": true, "lib": [ "es5", "dom", - "es2015.promise" + "es2015.promise", + "es6" ], "types": [] }, diff --git a/source/bin/framework.d.ts b/source/bin/framework.d.ts index 5027afdb..c20ebc01 100644 --- a/source/bin/framework.d.ts +++ b/source/bin/framework.d.ts @@ -17,6 +17,61 @@ declare interface Array { groupBy(keySelector: Function): Array; sum(selector: any): any; } +declare class PriorityQueueNode { + priority: number; + insertionIndex: number; + queueIndex: number; +} +declare class AStarPathfinder { + static search(graph: IAstarGraph, start: T, goal: T): T[]; + private static hasKey; + private static getKey; + static recontructPath(cameFrom: Map, start: T, goal: T): T[]; +} +declare class AStarNode extends PriorityQueueNode { + data: T; + constructor(data: T); +} +declare class AstarGridGraph implements IAstarGraph { + dirs: Point[]; + walls: Point[]; + weightedNodes: Point[]; + defaultWeight: number; + weightedNodeWeight: number; + private _width; + private _height; + private _neighbors; + constructor(width: number, height: number); + isNodeInBounds(node: Point): boolean; + isNodePassable(node: Point): boolean; + search(start: Point, goal: Point): Point[]; + getNeighbors(node: Point): Point[]; + cost(from: Point, to: Point): number; + heuristic(node: Point, goal: Point): number; +} +interface IAstarGraph { + getNeighbors(node: T): Array; + cost(from: T, to: T): number; + heuristic(node: T, goal: T): any; +} +declare class PriorityQueue { + private _numNodes; + private _nodes; + private _numNodesEverEnqueued; + constructor(maxNodes: number); + clear(): void; + readonly count: number; + contains(node: T): boolean; + enqueue(node: T, priority: number): void; + dequeue(): T; + remove(node: T): void; + isValidQueue(): boolean; + private onNodeUpdated; + private cascadeDown; + private cascadeUp; + private swap; + private hasHigherPriority; +} declare abstract class Component { entity: Entity; displayRender: egret.DisplayObject; @@ -338,6 +393,11 @@ declare class Matrix2D { static createRotation(radians: number, result?: Matrix2D): Matrix2D; static createScale(xScale: number, yScale: number, result?: Matrix2D): Matrix2D; } +declare class Point { + x: number; + y: number; + constructor(x: number, y: number); +} declare class Vector2 { x: number; y: number; diff --git a/source/bin/framework.js b/source/bin/framework.js index 7164625a..d4a31b55 100644 --- a/source/bin/framework.js +++ b/source/bin/framework.js @@ -238,6 +238,262 @@ Array.prototype.sum = function (selector) { } return sum(this, selector); }; +var PriorityQueueNode = (function () { + function PriorityQueueNode() { + this.priority = 0; + this.insertionIndex = 0; + this.queueIndex = 0; + } + return PriorityQueueNode; +}()); +var AStarPathfinder = (function () { + function AStarPathfinder() { + } + AStarPathfinder.search = function (graph, start, goal) { + var _this = this; + var foundPath = false; + var cameFrom = new Map(); + cameFrom.set(start, start); + var costSoFar = new Map(); + var frontier = new PriorityQueue(1000); + frontier.enqueue(new AStarNode(start), 0); + costSoFar.set(start, 0); + var _loop_2 = function () { + var current = frontier.dequeue(); + if (JSON.stringify(current.data) == JSON.stringify(goal)) { + foundPath = true; + return "break"; + } + graph.getNeighbors(current.data).forEach(function (next) { + var newCost = costSoFar.get(current.data) + graph.cost(current.data, next); + if (!_this.hasKey(costSoFar, next) || newCost < costSoFar.get(next)) { + costSoFar.set(next, newCost); + var priority = newCost + graph.heuristic(next, goal); + frontier.enqueue(new AStarNode(next), priority); + cameFrom.set(next, current.data); + } + }); + }; + while (frontier.count > 0) { + var state_1 = _loop_2(); + if (state_1 === "break") + break; + } + return foundPath ? this.recontructPath(cameFrom, start, goal) : null; + }; + AStarPathfinder.hasKey = function (map, compareKey) { + var iterator = map.keys(); + var r; + while (r = iterator.next(), !r.done) { + if (JSON.stringify(r.value) == JSON.stringify(compareKey)) + return true; + } + return false; + }; + AStarPathfinder.getKey = function (map, compareKey) { + var iterator = map.keys(); + var valueIterator = map.values(); + var r; + var v; + while (r = iterator.next(), v = valueIterator.next(), !r.done) { + if (JSON.stringify(r.value) == JSON.stringify(compareKey)) + return v.value; + } + return null; + }; + AStarPathfinder.recontructPath = function (cameFrom, start, goal) { + var path = []; + var current = goal; + path.push(goal); + while (current != start) { + current = this.getKey(cameFrom, current); + path.push(current); + } + path.reverse(); + return path; + }; + return AStarPathfinder; +}()); +var AStarNode = (function (_super) { + __extends(AStarNode, _super); + function AStarNode(data) { + var _this = _super.call(this) || this; + _this.data = data; + return _this; + } + return AStarNode; +}(PriorityQueueNode)); +var AstarGridGraph = (function () { + function AstarGridGraph(width, height) { + this.dirs = [ + new 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 = width; + this._height = height; + } + AstarGridGraph.prototype.isNodeInBounds = function (node) { + return 0 <= node.x && node.x < this._width && 0 <= node.y && node.y < this._height; + }; + AstarGridGraph.prototype.isNodePassable = function (node) { + return !this.walls.contains(node); + }; + AstarGridGraph.prototype.search = function (start, goal) { + return AStarPathfinder.search(this, start, goal); + }; + AstarGridGraph.prototype.getNeighbors = function (node) { + var _this = this; + this._neighbors.length = 0; + this.dirs.forEach(function (dir) { + var next = new Point(node.x + dir.x, node.y + dir.y); + if (_this.isNodeInBounds(next) && _this.isNodePassable(next)) + _this._neighbors.push(next); + }); + return this._neighbors; + }; + AstarGridGraph.prototype.cost = function (from, to) { + return this.weightedNodes.find(function (p) { return JSON.stringify(p) == JSON.stringify(to); }) ? this.weightedNodeWeight : this.defaultWeight; + }; + AstarGridGraph.prototype.heuristic = function (node, goal) { + return Math.abs(node.x - goal.x) + Math.abs(node.y - goal.y); + }; + return AstarGridGraph; +}()); +var PriorityQueue = (function () { + function PriorityQueue(maxNodes) { + this._numNodes = 0; + this._nodes = new Array(maxNodes + 1); + this._numNodesEverEnqueued = 0; + } + PriorityQueue.prototype.clear = function () { + this._nodes.splice(1, this._numNodes); + this._numNodes = 0; + }; + Object.defineProperty(PriorityQueue.prototype, "count", { + get: function () { + return this._numNodes; + }, + enumerable: true, + configurable: true + }); + PriorityQueue.prototype.contains = function (node) { + return (this._nodes[node.queueIndex] == node); + }; + PriorityQueue.prototype.enqueue = function (node, priority) { + node.priority = priority; + this._numNodes++; + this._nodes[this._numNodes] = node; + node.queueIndex = this._numNodes; + node.insertionIndex = this._numNodesEverEnqueued++; + this.cascadeUp(this._nodes[this._numNodes]); + }; + PriorityQueue.prototype.dequeue = function () { + var returnMe = this._nodes[1]; + this.remove(returnMe); + return returnMe; + }; + PriorityQueue.prototype.remove = function (node) { + if (node.queueIndex == this._numNodes) { + this._nodes[this._numNodes] = null; + this._numNodes--; + return; + } + var formerLastNode = this._nodes[this._numNodes]; + this.swap(node, formerLastNode); + delete this._nodes[this._numNodes]; + this._numNodes--; + this.onNodeUpdated(formerLastNode); + }; + PriorityQueue.prototype.isValidQueue = function () { + for (var i = 1; i < this._nodes.length; i++) { + if (this._nodes[i]) { + var childLeftIndex = 2 * i; + if (childLeftIndex < this._nodes.length && this._nodes[childLeftIndex] && + this.hasHigherPriority(this._nodes[childLeftIndex], this._nodes[i])) + return false; + var childRightIndex = childLeftIndex + 1; + if (childRightIndex < this._nodes.length && this._nodes[childRightIndex] && + this.hasHigherPriority(this._nodes[childRightIndex], this._nodes[i])) + return false; + } + } + return true; + }; + PriorityQueue.prototype.onNodeUpdated = function (node) { + var parentIndex = Math.floor(node.queueIndex / 2); + var parentNode = this._nodes[parentIndex]; + if (parentIndex > 0 && this.hasHigherPriority(node, parentNode)) { + this.cascadeUp(node); + } + else { + this.cascadeDown(node); + } + }; + PriorityQueue.prototype.cascadeDown = function (node) { + var newParent; + var finalQueueIndex = node.queueIndex; + while (true) { + newParent = node; + var childLeftIndex = 2 * finalQueueIndex; + if (childLeftIndex > this._numNodes) { + node.queueIndex = finalQueueIndex; + this._nodes[finalQueueIndex] = node; + break; + } + var childLeft = this._nodes[childLeftIndex]; + if (this.hasHigherPriority(childLeft, newParent)) { + newParent = childLeft; + } + var childRightIndex = childLeftIndex + 1; + if (childRightIndex <= this._numNodes) { + var childRight = this._nodes[childRightIndex]; + if (this.hasHigherPriority(childRight, newParent)) { + newParent = childRight; + } + } + if (newParent != node) { + this._nodes[finalQueueIndex] = newParent; + var temp = newParent.queueIndex; + newParent.queueIndex = finalQueueIndex; + finalQueueIndex = temp; + } + else { + node.queueIndex = finalQueueIndex; + this._nodes[finalQueueIndex] = node; + break; + } + } + }; + PriorityQueue.prototype.cascadeUp = function (node) { + var parent = Math.floor(node.queueIndex / 2); + while (parent >= 1) { + var parentNode = this._nodes[parent]; + if (this.hasHigherPriority(parentNode, node)) + break; + this.swap(node, parentNode); + parent = Math.floor(node.queueIndex / 2); + } + }; + PriorityQueue.prototype.swap = function (node1, node2) { + this._nodes[node1.queueIndex] = node2; + this._nodes[node2.queueIndex] = node1; + var temp = node1.queueIndex; + node1.queueIndex = node2.queueIndex; + node2.queueIndex = temp; + }; + PriorityQueue.prototype.hasHigherPriority = function (higher, lower) { + return (higher.priority < lower.priority || + (higher.priority == lower.priority && higher.insertionIndex < lower.insertionIndex)); + }; + return PriorityQueue; +}()); var Component = (function () { function Component() { this._enabled = true; @@ -1763,6 +2019,13 @@ var Matrix2D = (function () { Matrix2D._identity = new Matrix2D(1, 0, 0, 1, 0, 0); return Matrix2D; }()); +var Point = (function () { + function Point(x, y) { + this.x = x; + this.y = y; + } + return Point; +}()); var Vector2 = (function () { function Vector2(x, y) { this.x = 0; diff --git a/source/bin/framework.min.js b/source/bin/framework.min.js index 8f9e6e47..f83322e0 100644 --- a/source/bin/framework.min.js +++ b/source/bin/framework.min.js @@ -1 +1 @@ -window.framework={},window.__extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])};return function(e,n){function o(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(o.prototype=n.prototype,new o)}}(),Array.prototype.findIndex=function(t){return function(t,e){for(var n=0,o=t.length;n-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,o,i){return e.call(arguments[2],o,i,t)&&n.push(o),n},[]);for(var n=[],o=0,i=t.length;o=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,o,i){return n.push(e.call(arguments[2],o,i,t)),n},[]);for(var n=[],o=0,i=t.length;or?1:-1}),t}(this,t,e)},Array.prototype.orderByDescending=function(t,e){return function(t,e,n){return t.sort(function(t,o){var i=e(t),r=e(o);return n?-n(i,r):i=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(){var t=this;SceneManager.getActiveScene().entities.buffer.forEach(function(e){return e.components.buffer.forEach(function(e){e.displayRender&&(-1==t.entity.scene.$children.indexOf(e.displayRender)&&t.entity.scene.stage.addChild(e.displayRender))})})},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._areMatrixesDirty=!1)},e.prototype.destory=function(){},e}(Component),EntitySystem=function(){function t(t){this._entities=[],this._matcher=t||Matcher.empty()}return Object.defineProperty(t.prototype,"matcher",{get:function(){return this._matcher},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"scene",{get:function(){return this._scene},set:function(t){this._scene=t,this._entities=[]},enumerable:!0,configurable:!0}),t.prototype.initialize=function(){},t.prototype.onChanged=function(t){var e=this._entities.contains(t),n=this._matcher.IsIntersted(t);n&&!e?this.add(t):!n&&e&&this.remove(t)},t.prototype.add=function(t){this._entities.push(t),this.onAdded(t)},t.prototype.onAdded=function(t){},t.prototype.remove=function(t){this._entities.remove(t),this.onRemoved(t)},t.prototype.onRemoved=function(t){},t.prototype.update=function(){this.begin(),this.process(this._entities)},t.prototype.lateUpdate=function(){this.lateProcess(this._entities),this.end()},t.prototype.begin=function(){},t.prototype.process=function(t){},t.prototype.lateProcess=function(t){},t.prototype.end=function(){},t}(),EntityProcessingSystem=function(t){function e(e){return t.call(this,e)||this}return __extends(e,t),e.prototype.lateProcessEntity=function(t){},e.prototype.process=function(t){var e=this;t.forEach(function(t){return e.processEntity(t)})},e.prototype.lateProcess=function(t){var e=this;t.forEach(function(t){return e.lateProcessEntity(t)})},e}(EntitySystem),BitSet=function(){function t(e){void 0===e&&(e=64);var n=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),o=0;o=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 o=((n=((n=(n>>1&0x5555555555555400)+(0x5555555555555400&n))>>2&0x3333333333333400)+(0x3333333333333400&n))>>32)+n;t+=((o=((o=(o>>4&252645135)+(252645135&o))>>8&16711935)+(16711935&o))>>16&65535)+(65535&o)}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}},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._lastTime=t},t.timeScale=1,t._lastTime=0,t}(),MathHelper=function(){function t(){}return t.toDegrees=function(t){return 57.29577951308232*t},t.toRadians=function(t){return.017453292519943295*t},t.map=function(t,e,n,o,i){return o+(t-e)*(i-o)/(n-e)},t.clamp=function(t,e,n){return tn?n:t},t}(),Matrix2D=function(){function t(t,e,n,o,i,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=o,this.m31=i,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,o=t.m11*e.m12+t.m12*e.m22,i=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=o,t.m21=i,t.m22=r,t.m31=s,t.m32=a,t},t.multiplyTranslation=function(e,n,o){var i=t.createTranslation(n,o);return t.multiply(e,i)},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 o=1/e.determinant();return n.m11=e.m22*o,n.m12=-e.m12*o,n.m21=-e.m21*o,n.m22=e.m11*o,n.m31=(e.m32*e.m21-e.m31*e.m22)*o,n.m32=-(e.m32*e.m11-e.m31*e.m12)*o,n},t.createTranslation=function(e,n,o){return void 0===o&&(o=t.identity),o.m11=1,o.m12=0,o.m21=0,o.m22=1,o.m31=e,o.m32=n,o},t.createRotation=function(e,n){n=t.identity;var o=Math.cos(e),i=Math.sin(e);return n.m11=o,n.m12=i,n.m21=-i,n.m22=o,n},t.createScale=function(e,n,o){return void 0===o&&(o=t.identity),o.m11=e,o.m12=0,o.m21=0,o.m22=n,o.m31=0,o.m32=0,o},t._identity=new t(1,0,0,1,0,0),t}(),Vector2=function(){function t(t,e){this.x=0,this.y=0,this.x=t,this.y=e}return Object.defineProperty(t,"One",{get:function(){return this.unitVector2},enumerable:!0,configurable:!0}),t.add=function(t,e){return t.x+=e.x,t.y+=e.y,t},t.divide=function(t,e){return t.x/=e.x,t.y/=e.y,t},t.multiply=function(t,e){return t.x*=e.x,t.y*=e.y,t},t.subtract=function(t,e){return t.x-=e.x,t.y-=e.y,t},t.prototype.normalize=function(){var t=1/Math.sqrt(this.x*this.x+this.y*this.y);this.x*=t,this.y*=t},t.transform=function(e,n){return new t(e.x*n.m11+e.y*n.m21,e.x*n.m12+e.y*n.m22)},t.unitVector2=new t(1,1),t}(); \ No newline at end of file +window.framework={},window.__extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])};return function(e,n){function o(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(o.prototype=n.prototype,new o)}}(),Array.prototype.findIndex=function(t){return function(t,e){for(var n=0,o=t.length;n-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,o,i){return e.call(arguments[2],o,i,t)&&n.push(o),n},[]);for(var n=[],o=0,i=t.length;o=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,o,i){return n.push(e.call(arguments[2],o,i,t)),n},[]);for(var n=[],o=0,i=t.length;or?1:-1}),t}(this,t,e)},Array.prototype.orderByDescending=function(t,e){return function(t,e,n){return t.sort(function(t,o){var i=e(t),r=e(o);return n?-n(i,r):i0;){if("break"===h())break}return i?this.recontructPath(r,e,n):null},t.hasKey=function(t,e){for(var n,o=t.keys();!(n=o.next()).done;)if(JSON.stringify(n.value)==JSON.stringify(e))return!0;return!1},t.getKey=function(t,e){for(var n,o,i=t.keys(),r=t.values();n=i.next(),o=r.next(),!n.done;)if(JSON.stringify(n.value)==JSON.stringify(e))return o.value;return null},t.recontructPath=function(t,e,n){var o=[],i=n;for(o.push(n);i!=e;)i=this.getKey(t,i),o.push(i);return o.reverse(),o},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 o=2*n;if(o>this._numNodes){t.queueIndex=n,this._nodes[n]=t;break}var i=this._nodes[o];this.hasHigherPriority(i,e)&&(e=i);var r=o+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.priority=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(){var t=this;SceneManager.getActiveScene().entities.buffer.forEach(function(e){return e.components.buffer.forEach(function(e){e.displayRender&&(-1==t.entity.scene.$children.indexOf(e.displayRender)&&t.entity.scene.stage.addChild(e.displayRender))})})},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._areMatrixesDirty=!1)},e.prototype.destory=function(){},e}(Component),EntitySystem=function(){function t(t){this._entities=[],this._matcher=t||Matcher.empty()}return Object.defineProperty(t.prototype,"matcher",{get:function(){return this._matcher},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"scene",{get:function(){return this._scene},set:function(t){this._scene=t,this._entities=[]},enumerable:!0,configurable:!0}),t.prototype.initialize=function(){},t.prototype.onChanged=function(t){var e=this._entities.contains(t),n=this._matcher.IsIntersted(t);n&&!e?this.add(t):!n&&e&&this.remove(t)},t.prototype.add=function(t){this._entities.push(t),this.onAdded(t)},t.prototype.onAdded=function(t){},t.prototype.remove=function(t){this._entities.remove(t),this.onRemoved(t)},t.prototype.onRemoved=function(t){},t.prototype.update=function(){this.begin(),this.process(this._entities)},t.prototype.lateUpdate=function(){this.lateProcess(this._entities),this.end()},t.prototype.begin=function(){},t.prototype.process=function(t){},t.prototype.lateProcess=function(t){},t.prototype.end=function(){},t}(),EntityProcessingSystem=function(t){function e(e){return t.call(this,e)||this}return __extends(e,t),e.prototype.lateProcessEntity=function(t){},e.prototype.process=function(t){var e=this;t.forEach(function(t){return e.processEntity(t)})},e.prototype.lateProcess=function(t){var e=this;t.forEach(function(t){return e.lateProcessEntity(t)})},e}(EntitySystem),BitSet=function(){function t(e){void 0===e&&(e=64);var n=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),o=0;o=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 o=((n=((n=(n>>1&0x5555555555555400)+(0x5555555555555400&n))>>2&0x3333333333333400)+(0x3333333333333400&n))>>32)+n;t+=((o=((o=(o>>4&252645135)+(252645135&o))>>8&16711935)+(16711935&o))>>16&65535)+(65535&o)}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}},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._lastTime=t},t.timeScale=1,t._lastTime=0,t}(),MathHelper=function(){function t(){}return t.toDegrees=function(t){return 57.29577951308232*t},t.toRadians=function(t){return.017453292519943295*t},t.map=function(t,e,n,o,i){return o+(t-e)*(i-o)/(n-e)},t.clamp=function(t,e,n){return tn?n:t},t}(),Matrix2D=function(){function t(t,e,n,o,i,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=o,this.m31=i,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,o=t.m11*e.m12+t.m12*e.m22,i=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=o,t.m21=i,t.m22=r,t.m31=s,t.m32=a,t},t.multiplyTranslation=function(e,n,o){var i=t.createTranslation(n,o);return t.multiply(e,i)},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 o=1/e.determinant();return n.m11=e.m22*o,n.m12=-e.m12*o,n.m21=-e.m21*o,n.m22=e.m11*o,n.m31=(e.m32*e.m21-e.m31*e.m22)*o,n.m32=-(e.m32*e.m11-e.m31*e.m12)*o,n},t.createTranslation=function(e,n,o){return void 0===o&&(o=t.identity),o.m11=1,o.m12=0,o.m21=0,o.m22=1,o.m31=e,o.m32=n,o},t.createRotation=function(e,n){n=t.identity;var o=Math.cos(e),i=Math.sin(e);return n.m11=o,n.m12=i,n.m21=-i,n.m22=o,n},t.createScale=function(e,n,o){return void 0===o&&(o=t.identity),o.m11=e,o.m12=0,o.m21=0,o.m22=n,o.m31=0,o.m32=0,o},t._identity=new t(1,0,0,1,0,0),t}(),Point=function(){return function(t,e){this.x=t,this.y=e}}(),Vector2=function(){function t(t,e){this.x=0,this.y=0,this.x=t,this.y=e}return Object.defineProperty(t,"One",{get:function(){return this.unitVector2},enumerable:!0,configurable:!0}),t.add=function(t,e){return t.x+=e.x,t.y+=e.y,t},t.divide=function(t,e){return t.x/=e.x,t.y/=e.y,t},t.multiply=function(t,e){return t.x*=e.x,t.y*=e.y,t},t.subtract=function(t,e){return t.x-=e.x,t.y-=e.y,t},t.prototype.normalize=function(){var t=1/Math.sqrt(this.x*this.x+this.y*this.y);this.x*=t,this.y*=t},t.transform=function(e,n){return new t(e.x*n.m11+e.y*n.m21,e.x*n.m12+e.y*n.m22)},t.unitVector2=new t(1,1),t}(); \ No newline at end of file diff --git a/source/src/AI/Pathfinding/AStar/AStarPathfinder.ts b/source/src/AI/Pathfinding/AStar/AStarPathfinder.ts new file mode 100644 index 00000000..d2155c9c --- /dev/null +++ b/source/src/AI/Pathfinding/AStar/AStarPathfinder.ts @@ -0,0 +1,89 @@ +/// +/** + * 计算路径给定的IAstarGraph和开始/目标位置 + */ +class AStarPathfinder { + public static search(graph: IAstarGraph, start: T, goal: T){ + let foundPath = false; + let cameFrom = new Map(); + cameFrom.set(start, start); + + let costSoFar = new Map(); + let frontier = new PriorityQueue>(1000); + frontier.enqueue(new AStarNode(start), 0); + + costSoFar.set(start, 0); + + while (frontier.count > 0){ + let current = frontier.dequeue(); + + if (JSON.stringify(current.data) == JSON.stringify(goal)){ + foundPath = true; + break; + } + + graph.getNeighbors(current.data).forEach(next => { + let newCost = costSoFar.get(current.data) + graph.cost(current.data, next); + if (!this.hasKey(costSoFar, next) || newCost < costSoFar.get(next)){ + costSoFar.set(next, newCost); + let priority = newCost + graph.heuristic(next, goal); + frontier.enqueue(new AStarNode(next), priority); + cameFrom.set(next, current.data); + } + }); + } + + return foundPath ? this.recontructPath(cameFrom, start, goal) : null; + } + + private static hasKey(map: Map, compareKey: T){ + let iterator = map.keys(); + let r: IteratorResult; + while (r = iterator.next() , !r.done) { + if (JSON.stringify(r.value) == JSON.stringify(compareKey)) + return true; + } + + return false; + } + + private static getKey(map: Map, compareKey: T){ + let iterator = map.keys(); + let valueIterator = map.values(); + let r: IteratorResult; + let v: IteratorResult; + while (r = iterator.next(), v = valueIterator.next(), !r.done) { + if (JSON.stringify(r.value) == JSON.stringify(compareKey)) + return v.value; + } + + return null; + } + + public static recontructPath(cameFrom: Map, start: T, goal: T): T[]{ + let path = []; + let current = goal; + path.push(goal); + + while (current != start){ + current = this.getKey(cameFrom, current); + path.push(current); + } + + path.reverse(); + + return path; + } +} + +/** + * 使用PriorityQueue需要的额外字段将原始数据封装在一个小类中 + */ +class AStarNode extends PriorityQueueNode { + public data: T; + + constructor(data: T){ + super(); + this.data = data; + } +} \ No newline at end of file diff --git a/source/src/AI/Pathfinding/AStar/AstarGridGraph.ts b/source/src/AI/Pathfinding/AStar/AstarGridGraph.ts new file mode 100644 index 00000000..10b20a4d --- /dev/null +++ b/source/src/AI/Pathfinding/AStar/AstarGridGraph.ts @@ -0,0 +1,67 @@ +/** + * 基本静态网格图与A*一起使用 + * 将walls添加到walls HashSet,并将加权节点添加到weightedNodes + */ +class AstarGridGraph implements IAstarGraph { + public dirs: Point[] = [ + new Point(1, 0), + new Point(0, -1), + new Point(-1, 0), + new Point(0, 1) + ]; + + public walls: Point[] = []; + public weightedNodes: Point[] = []; + public defaultWeight: number = 1; + public weightedNodeWeight = 5; + + private _width; + private _height; + private _neighbors: Point[] = new Array(4); + + constructor(width: number, height: number){ + this._width = width; + this._height = height; + } + + /** + * 确保节点在网格图的边界内 + * @param node + */ + public isNodeInBounds(node: Point): boolean { + return 0 <= node.x && node.x < this._width && 0 <= node.y && node.y < this._height; + } + + /** + * 检查节点是否可以通过。墙壁是不可逾越的。 + * @param node + */ + public isNodePassable(node: Point): boolean { + return !this.walls.contains(node); + } + + public search(start: Point, goal: Point){ + return AStarPathfinder.search(this, start, goal); + } + + public getNeighbors(node: Point): Point[] { + this._neighbors.length = 0; + + this.dirs.forEach(dir => { + let next = new Point(node.x + dir.x, node.y + dir.y); + if (this.isNodeInBounds(next) && this.isNodePassable(next)) + this._neighbors.push(next); + }); + + return this._neighbors; + } + + public cost(from: Point, to: Point): number { + return this.weightedNodes.find((p)=> JSON.stringify(p) == JSON.stringify(to)) ? this.weightedNodeWeight : this.defaultWeight; + } + + public heuristic(node: Point, goal: Point) { + return Math.abs(node.x - goal.x) + Math.abs(node.y - goal.y); + } + +} \ No newline at end of file diff --git a/source/src/AI/Pathfinding/AStar/IAstarGraph.ts b/source/src/AI/Pathfinding/AStar/IAstarGraph.ts new file mode 100644 index 00000000..3630e3e1 --- /dev/null +++ b/source/src/AI/Pathfinding/AStar/IAstarGraph.ts @@ -0,0 +1,5 @@ +interface IAstarGraph { + getNeighbors(node: T): Array; + cost(from: T, to: T): number; + heuristic(node: T, goal: T); +} \ No newline at end of file diff --git a/source/src/AI/Pathfinding/AStar/PriorityQueue.ts b/source/src/AI/Pathfinding/AStar/PriorityQueue.ts new file mode 100644 index 00000000..5c40272a --- /dev/null +++ b/source/src/AI/Pathfinding/AStar/PriorityQueue.ts @@ -0,0 +1,150 @@ +class PriorityQueue { + private _numNodes: number; + private _nodes: T[]; + private _numNodesEverEnqueued; + + constructor(maxNodes: number) { + this._numNodes = 0; + this._nodes = new Array(maxNodes + 1); + this._numNodesEverEnqueued = 0; + } + + public clear() { + this._nodes.splice(1, this._numNodes); + this._numNodes = 0; + } + + public get count() { + return this._numNodes; + } + + public contains(node: T): boolean { + return (this._nodes[node.queueIndex] == node); + } + + public enqueue(node: T, priority: number) { + node.priority = priority; + this._numNodes++; + this._nodes[this._numNodes] = node; + node.queueIndex = this._numNodes; + node.insertionIndex = this._numNodesEverEnqueued++; + this.cascadeUp(this._nodes[this._numNodes]); + } + + public dequeue(): T { + let returnMe = this._nodes[1]; + this.remove(returnMe); + return returnMe; + } + + public remove(node: T) { + if (node.queueIndex == this._numNodes) { + this._nodes[this._numNodes] = null; + this._numNodes--; + return; + } + + let formerLastNode = this._nodes[this._numNodes]; + this.swap(node, formerLastNode); + delete this._nodes[this._numNodes]; + this._numNodes--; + + this.onNodeUpdated(formerLastNode); + } + + public isValidQueue(): boolean { + for (let i = 1; i < this._nodes.length; i++) { + if (this._nodes[i]) { + let childLeftIndex = 2 * i; + if (childLeftIndex < this._nodes.length && this._nodes[childLeftIndex] && + this.hasHigherPriority(this._nodes[childLeftIndex], this._nodes[i])) + return false; + + let childRightIndex = childLeftIndex + 1; + if (childRightIndex < this._nodes.length && this._nodes[childRightIndex] && + this.hasHigherPriority(this._nodes[childRightIndex], this._nodes[i])) + return false; + } + } + + return true; + } + + private onNodeUpdated(node: T) { + let parentIndex = Math.floor(node.queueIndex / 2); + let parentNode = this._nodes[parentIndex]; + + if (parentIndex > 0 && this.hasHigherPriority(node, parentNode)) { + this.cascadeUp(node); + } else { + this.cascadeDown(node); + } + } + + private cascadeDown(node: T) { + let newParent: T; + let finalQueueIndex = node.queueIndex; + while (true) { + newParent = node; + let childLeftIndex = 2 * finalQueueIndex; + + if (childLeftIndex > this._numNodes) { + node.queueIndex = finalQueueIndex; + this._nodes[finalQueueIndex] = node; + break; + } + + let childLeft = this._nodes[childLeftIndex]; + if (this.hasHigherPriority(childLeft, newParent)) { + newParent = childLeft; + } + + let childRightIndex = childLeftIndex + 1; + if (childRightIndex <= this._numNodes) { + let childRight = this._nodes[childRightIndex]; + if (this.hasHigherPriority(childRight, newParent)) { + newParent = childRight; + } + } + + if (newParent != node) { + this._nodes[finalQueueIndex] = newParent; + + let temp = newParent.queueIndex; + newParent.queueIndex = finalQueueIndex; + finalQueueIndex = temp; + } else { + node.queueIndex = finalQueueIndex; + this._nodes[finalQueueIndex] = node; + break; + } + } + } + + private cascadeUp(node: T) { + let parent = Math.floor(node.queueIndex / 2); + while (parent >= 1) { + let parentNode = this._nodes[parent]; + if (this.hasHigherPriority(parentNode, node)) + break; + + this.swap(node, parentNode); + + parent = Math.floor(node.queueIndex / 2); + } + } + + private swap(node1: T, node2: T) { + this._nodes[node1.queueIndex] = node2; + this._nodes[node2.queueIndex] = node1; + + let temp = node1.queueIndex; + node1.queueIndex = node2.queueIndex; + node2.queueIndex = temp; + } + + private hasHigherPriority(higher: T, lower: T) { + return (higher.priority < lower.priority || + (higher.priority == lower.priority && higher.insertionIndex < lower.insertionIndex)); + } +} \ No newline at end of file diff --git a/source/src/AI/Pathfinding/AStar/PriorityQueueNode.ts b/source/src/AI/Pathfinding/AStar/PriorityQueueNode.ts new file mode 100644 index 00000000..44edbc9e --- /dev/null +++ b/source/src/AI/Pathfinding/AStar/PriorityQueueNode.ts @@ -0,0 +1,14 @@ +class PriorityQueueNode { + /** + * 插入此节点的优先级。在将节点添加到队列之前必须设置 + */ + public priority: number = 0; + /** + * 由优先级队列使用-不要编辑此值。表示插入节点的顺序 + */ + public insertionIndex: number = 0; + /** + * 由优先级队列使用-不要编辑此值。表示队列中的当前位置 + */ + public queueIndex: number = 0; +} \ No newline at end of file diff --git a/source/src/Math/Point.ts b/source/src/Math/Point.ts new file mode 100644 index 00000000..e4189cff --- /dev/null +++ b/source/src/Math/Point.ts @@ -0,0 +1,9 @@ +class Point { + public x: number; + public y: number; + + constructor(x: number, y: number){ + this.x = x; + this.y = y; + } +} \ No newline at end of file