├── README.md ├── assets ├── car.png ├── gridChallenge.json └── tileset01.png ├── asyncPath └── asyncPath.js ├── demo.js ├── index.html └── lib └── phaser.js /README.md: -------------------------------------------------------------------------------- 1 | # Async. Path Finding 1.0.0 2 | PhaserJS Path Finding plugin, with optional use of web worker configuration. Fast and Easy to use. 3 | 4 | 5 | ### | Quick sample | 6 | 7 | ```javascript 8 | var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create }); 9 | 10 | function preload() { 11 | 12 | } 13 | 14 | function create() { 15 | var asyncPath = game.plugins.add(Phaser.Plugin.asyncPath); 16 | var PointA = {x: 13, y: 14}; // works fine with Sprite, Point, or any object with x and y properties 17 | PointB = {x: 22, y: 44}; 18 | Block = { 19 | Origin: PointA, 20 | Destination: PointB, 21 | found: function(path){ 22 | console.log(path); 23 | }, 24 | notfound: function(){ 25 | console.log('No path found'); 26 | } 27 | } 28 | asyncPath.getPath(Block); 29 | 30 | } 31 | ``` 32 | 33 | 34 | 35 | 36 | #### Plugin Initialization 37 | ```javascript 38 | 39 | asyncPath = game.plugins.add(Phaser.Plugin.asyncPath); 40 | 41 | ``` 42 | 43 | #### Block Configuration 44 | 45 | ``` javascript 46 | Block = { 47 | Origin: {x:{number}, y:{number}}, 48 | Destination: {x:{number}, y:{number}}, 49 | keepTrack: {boolean}, Optional 50 | trackBy: {string}, Optional 51 | Diagonals: {boolean}, Optional 52 | debugpath: {boolean}, Optional 53 | Algorithm: {string}, Optional 54 | forcemain: {boolean}, Optional 55 | found: {Function}, Optional 56 | notfound: {Function} Optional 57 | } 58 | ``` 59 | 60 | # 61 | ``` javascript 62 | Origin: {x:{number}, y:{number}} 63 | Destination: {x:{number}, y:{number}} 64 | ``` 65 | # 66 | 67 | ``` javascript 68 | keepTrack: {boolean} 69 | ``` 70 | 71 | # 72 | The offset is Calculated on tracked blocks and property. 73 | If tracked property is greater than or less than offset then new path is calculated from Origin to detination 74 | 75 | ``` javascript 76 | trackBy: {string} 'Origin' OR 'Destination' 77 | ``` 78 | 79 | # 80 | Forces path Manager to set new Diagonal setting for this block 81 | ``` javascript 82 | Diagonals: {boolean} 83 | ``` 84 | 85 | # 86 | Set the debugging for this block 87 | ``` javascript 88 | debugpath: {boolean} 89 | ``` 90 | 91 | 92 | # 93 | Set the Algorithm for this block 94 | ``` javascript 95 | Algorithm: {string} 'Manhattan' OR 'Euclidean' 96 | ``` 97 | 98 | # 99 | Forces this block to be solved on the main UI thread even if there is a web worker 100 | ``` javascript 101 | forcemain: {boolean} 102 | ``` 103 | 104 | 105 | # 106 | ```found``` function is fired each time a path is found 107 | ``` javascript 108 | found: {Function} 109 | ``` 110 | 111 | # 112 | ```notfound``` function is fired each time a path is not found 113 | ``` javascript 114 | notfound: {Function} 115 | ``` 116 | 117 | 118 | ##Plugin Configurations 119 | 120 | Setting the plugin with a map 121 | ```javascript 122 | map = game.add.tilemap('mapJSON'); 123 | asyncPath.tileMap = map; 124 | ``` 125 | 126 | 127 | Setting up Default watchers offset values in X and Y directions that would trigger a pathfinding calculation on tracked blocks 128 | 129 | ```javascript 130 | asyncPath.xyOffset = {number} 131 | ``` 132 | 133 | X offset trigger 134 | ```javascript 135 | asyncPath.xOffset = {number} 136 | ``` 137 | 138 | Y offset trigger 139 | ```javascript 140 | asyncPath.xOffset = {number} 141 | ``` 142 | 143 | Setting up the returned path configuration default pixel 144 | ```javascript 145 | asyncPath.xOffset = {string} 'units' OR 'pixel' 146 | ``` 147 | 148 | 149 | Setting up the algorithm to use in pathFinding 150 | ```javascript 151 | asyncPath.algorithm = {string} 'Manhattan' OR 'Euclidean' 152 | ``` 153 | 154 | 155 | Setting up the return path configuration (if the return path should point to the center of each tile or the edges) default true 156 | ```javascript 157 | asyncPath.centerPaths = {boolean} true OR false 158 | ``` 159 | 160 | 161 | Setting up the number of paths to be solved on each Phaser frame 162 | ```javascript 163 | asyncPath.pathsPerFrame = {numeber} 164 | ``` 165 | 166 | 167 | Would debug each block except turned off on a block 168 | ```javascript 169 | asyncPath.defaultdebug = {boolean} true OR false 170 | ``` 171 | 172 | 173 | Setting custom Cost for vertical and Horizontal movement 174 | Default set to 10 175 | ```javascript 176 | asyncPath.VertHorCost = {number} 177 | ``` 178 | 179 | Setting Diagonal movement 180 | Default set to false 181 | ```javascript 182 | asyncPath.useDiagonal = {boolean} true OR false 183 | ``` 184 | 185 | 186 | Setting Non walkable tiles 187 | ```javascript 188 | asyncPath.nonWalkableTile = {number} OR {[number]} 189 | ``` 190 | 191 | 192 | 193 | Setting Path Debuging color 194 | ```javascript 195 | asyncPath.debugColor = {HEX_NUMBER} 196 | ``` 197 | 198 | 199 | 200 | Setting non walkable layer 201 | ```javascript 202 | asyncPath.nonWalkableLayer = {string} 203 | ``` 204 | 205 | 206 | #Creating a web worker for faster path calculations 207 | A good choice will be using a web Worker only if you have too many path 208 | finding calculations to be done instantly, else setting timers for number of calculations to be done in each Phaser Display frame would be much more efficient. The 209 | ``` newWorker() ``` method returns a new webworker instance. Webworkers are managed internally by the plugin; 210 | 211 | ### Note 212 | If there are no web workers, all path finding calculations run on the main UI thread. 213 | The returned webworker instance is managed internally by the plugin 214 | 215 | 216 | ```javascript 217 | asyncPath.newWorker(); 218 | ``` 219 | 220 | Sets Algorithm for webworker 221 | ```javascript 222 | asyncPath.webWorkerAlgorithm = {string} 'Manhattan' OR 'Euclidean' 223 | ``` 224 | 225 | Set the use of Diagonals in webWorker 226 | ```javascript 227 | asyncPath.webWorkerDiagonals = {boolean} true OR false 228 | ``` 229 | 230 | Set the cost of Vertical and Horizontal movement in webWorker 231 | ```javascript 232 | asyncPath.webWorkerVerHorCost = {number} 233 | ``` 234 | 235 | Set the cost of Diagonal movement in webWorker 236 | ```javascript 237 | asyncPath.webWorkerDiagonalsCost = {number} 238 | ``` 239 | 240 | 241 | -------------------------------------------------------------------------------- /assets/car.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/2p4b/asyncpaths/483e208131abc1b1167039c11a3080dcf960fe12/assets/car.png -------------------------------------------------------------------------------- /assets/gridChallenge.json: -------------------------------------------------------------------------------- 1 | { "height":25, 2 | "layers":[ 3 | { 4 | "data":[7, 7, 7, 7, 7, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 6, 6, 6, 6, 7, 8, 8, 6, 6, 7, 7, 7, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 7, 6, 7, 8, 7, 7, 7, 7, 7, 6, 7, 8, 7, 7, 6, 8, 8, 8, 8, 8, 8, 8, 8, 9, 6, 7, 6, 6, 8, 9, 8, 8, 7, 7, 6, 7, 7, 7, 7, 8, 7, 9, 6, 7, 7, 8, 8, 6, 8, 7, 6, 8, 7, 9, 8, 8, 7, 6, 6, 8, 8, 8, 8, 8, 6, 6, 7, 7, 8, 8, 9, 8, 7, 7, 7, 8, 7, 6, 8, 8, 8, 8, 8, 8, 8, 7, 6, 6, 8, 7, 8, 7, 7, 7, 6, 7, 6, 6, 8, 7, 8, 8, 8, 7, 6, 6, 6, 6, 8, 8, 8, 8, 8, 8, 8, 7, 9, 7, 7, 8, 8, 7, 6, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 6, 7, 6, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 8, 7, 6, 6, 7, 7, 6, 7, 8, 7, 6, 7, 8, 8, 8, 7, 6, 6, 7, 6, 6, 6, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 6, 9, 8, 6, 7, 6, 6, 7, 7, 6, 7, 6, 7, 6, 8, 6, 7, 8, 7, 9, 7, 7, 6, 6, 6, 7, 8, 8, 6, 6, 9, 8, 7, 7, 6, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 6, 7, 6, 6, 8, 7, 7, 7, 7, 6, 6, 7, 7, 7, 7, 7, 7, 7, 6, 8, 8, 8, 8, 8, 8, 8, 8, 7, 8, 7, 6, 7, 7, 6, 7, 8, 8, 8, 8, 7, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 7, 7, 7, 7, 7, 8, 8, 6, 7, 8, 7, 6, 7, 6, 7, 6, 7, 7, 6, 8, 8, 7, 6, 9, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 7, 6, 7, 7, 7, 8, 8, 6, 6, 7, 7, 8, 7, 7, 6, 7, 9, 6, 7, 6, 6, 8, 7, 6, 7, 6, 6, 6, 7, 8, 8, 6, 6, 6, 7, 7, 8, 7, 6, 7, 7, 8, 6, 7, 7, 6, 7, 8, 7, 7, 6, 7, 6, 7, 6, 6, 6, 7, 7, 6, 6, 7, 7, 8, 8, 8, 8, 8, 6, 6, 7, 7, 7, 8, 7, 7, 7, 8, 7, 9, 6, 6, 7, 7, 8, 6, 6, 7, 7, 6, 6, 6, 6, 7, 7, 6, 6, 7, 7, 8, 8, 8, 8, 8, 8, 8, 9, 7, 7, 7, 8, 7, 7, 8, 7, 7, 6, 6, 7, 8, 8, 8, 8, 8, 8, 8, 6, 6, 6, 7, 6, 8, 8, 8, 8, 8, 9, 7, 7, 7, 7, 8, 8, 8, 7, 7, 8, 6, 7, 8, 7, 7, 7, 7, 8, 8, 8, 6, 7, 7, 6, 6, 8, 6, 6, 7, 6, 8, 7, 6, 8, 8, 6, 6, 6, 7, 6, 8, 6, 6, 8, 7, 8, 8, 6, 7, 8, 6, 7, 8, 8, 8, 7, 7, 9, 6, 6, 6, 6, 8, 8, 8, 6, 8, 6, 8, 8, 8, 6, 6, 6, 6, 6, 8, 6, 6, 8, 6, 7, 8, 6, 7, 6, 8, 8, 8, 6, 6, 7, 6, 9, 6, 6, 6, 6, 6, 6, 8, 6, 8, 9, 8, 7, 8, 6, 6, 6, 6, 8, 8, 6, 9, 6, 8, 6, 7, 8, 8, 8, 9, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 8, 8, 6, 8, 6, 8, 6, 6, 6, 8, 8, 6, 6, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 6, 6, 7, 7, 6, 6, 6, 6, 6, 6, 6, 7, 6, 7, 8, 7, 6, 6, 8, 8, 8, 6, 6, 6, 8, 6, 6, 8, 6, 6, 6, 6, 6, 8, 8, 8, 8, 8, 8, 8, 8, 6, 6, 6, 6, 8, 8, 7, 7, 6, 7, 8, 8, 8, 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 6, 6, 6, 6, 7, 7, 6, 7, 8, 8, 8, 8, 6, 7, 7, 7, 7, 7, 7, 7, 6, 8, 8, 6, 7, 6, 6, 6, 8, 6, 8, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 6, 7, 6, 9, 6, 6, 6, 7, 7, 6, 7, 7, 7, 7, 6, 6, 6, 6, 7, 6, 6, 6, 8, 6, 8, 6, 6, 6, 6, 6, 9, 9, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 6, 8, 8, 8, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 6, 7, 7, 7, 7, 7, 7, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], 5 | "height":25, 6 | "name":"ground", 7 | "opacity":1, 8 | "type":"tilelayer", 9 | "visible":true, 10 | "width":36, 11 | "x":0, 12 | "y":0 13 | }, 14 | { 15 | "data":[0, 0, 0, 350, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 352, 0, 0, 0, 0, 0, 0, 0, 370, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 370, 0, 350, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 352, 0, 0, 0, 0, 0, 0, 0, 250, 0, 0, 0, 0, 0, 0, 0, 370, 0, 370, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 372, 0, 0, 350, 352, 0, 0, 0, 270, 0, 0, 0, 0, 0, 0, 0, 370, 0, 370, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 350, 351, 351, 352, 0, 372, 0, 0, 370, 372, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 370, 0, 370, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 370, 0, 0, 372, 0, 372, 0, 0, 370, 372, 0, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 370, 0, 370, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 370, 0, 0, 372, 0, 372, 0, 0, 370, 372, 0, 0, 0, 250, 0, 0, 0, 0, 0, 0, 0, 370, 0, 370, 0, 0, 350, 351, 351, 351, 351, 351, 351, 352, 0, 0, 370, 0, 0, 372, 0, 372, 0, 0, 370, 372, 0, 0, 0, 270, 0, 0, 0, 0, 0, 0, 0, 370, 0, 370, 0, 0, 370, 0, 0, 0, 0, 0, 0, 372, 0, 0, 370, 0, 0, 372, 0, 372, 0, 0, 370, 372, 0, 350, 351, 351, 351, 352, 0, 0, 0, 0, 0, 370, 0, 370, 0, 0, 370, 0, 0, 0, 0, 0, 0, 372, 0, 0, 370, 0, 0, 372, 0, 372, 0, 0, 370, 372, 0, 370, 0, 0, 0, 372, 0, 0, 0, 0, 0, 370, 0, 370, 0, 0, 370, 0, 350, 351, 351, 0, 0, 372, 0, 0, 370, 0, 0, 372, 0, 372, 0, 0, 370, 372, 0, 370, 0, 0, 0, 372, 0, 0, 0, 0, 0, 370, 0, 370, 0, 0, 370, 0, 370, 0, 0, 0, 0, 372, 0, 0, 370, 0, 0, 372, 0, 372, 0, 0, 370, 372, 0, 370, 0, 0, 0, 372, 0, 0, 0, 0, 0, 370, 0, 370, 0, 0, 370, 0, 370, 0, 0, 0, 0, 372, 0, 0, 370, 0, 0, 372, 0, 372, 0, 0, 370, 372, 0, 0, 0, 0, 0, 372, 0, 0, 0, 0, 0, 370, 0, 370, 0, 0, 370, 0, 390, 391, 391, 391, 391, 392, 0, 0, 370, 0, 0, 372, 0, 372, 0, 0, 370, 372, 391, 391, 391, 391, 391, 392, 0, 0, 0, 0, 0, 370, 0, 370, 0, 0, 370, 0, 0, 0, 0, 0, 0, 0, 0, 0, 370, 0, 0, 372, 0, 372, 0, 0, 370, 372, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 370, 0, 370, 0, 0, 370, 0, 0, 0, 0, 0, 0, 0, 0, 0, 370, 0, 391, 392, 0, 372, 0, 0, 370, 372, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 370, 0, 370, 0, 0, 370, 0, 0, 0, 0, 0, 0, 0, 0, 0, 370, 0, 0, 0, 0, 372, 0, 0, 370, 372, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 370, 0, 370, 0, 0, 390, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 392, 0, 0, 370, 372, 0, 0, 372, 373, 0, 374, 357, 0, 0, 0, 0, 370, 0, 370, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 370, 372, 0, 0, 372, 393, 0, 394, 370, 0, 0, 0, 0, 370, 0, 370, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 370, 372, 0, 0, 372, 0, 0, 0, 370, 0, 0, 0, 0, 370, 0, 390, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 392, 0, 0, 372, 0, 0, 0, 370, 0, 0, 0, 0, 370, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 372, 0, 0, 0, 370, 0, 0, 0, 0, 390, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 391, 392, 0, 0, 0, 370, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 370, 0, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 351, 390, 391], 16 | "height":25, 17 | "name":"wall", 18 | "opacity":1, 19 | "type":"tilelayer", 20 | "visible":true, 21 | "width":36, 22 | "x":0, 23 | "y":0 24 | }], 25 | "orientation":"orthogonal", 26 | "properties": 27 | { 28 | 29 | }, 30 | "renderorder":"right-down", 31 | "tileheight":32, 32 | "tilesets":[ 33 | { 34 | "firstgid":1, 35 | "image":"tileset01.png", 36 | "imageheight":640, 37 | "imagewidth":640, 38 | "margin":0, 39 | "name":"tileset01", 40 | "properties": 41 | { 42 | 43 | }, 44 | "spacing":0, 45 | "tileheight":32, 46 | "tilewidth":32 47 | }], 48 | "tilewidth":32, 49 | "version":1, 50 | "width":36 51 | } 52 | -------------------------------------------------------------------------------- /assets/tileset01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/2p4b/asyncpaths/483e208131abc1b1167039c11a3080dcf960fe12/assets/tileset01.png -------------------------------------------------------------------------------- /asyncPath/asyncPath.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * The MIT License (MIT) 4 | * Copyright (c) 2015 Mfoncho Che 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | * 23 | * 24 | * 25 | */ 26 | 27 | 28 | 29 | /** 30 | * @author Mfoncho Che 31 | * @copyright 2015 Mfoncho Che 32 | * @license {@link http://opensource.org/licenses/MIT} 33 | */ 34 | 35 | 36 | 37 | 38 | /** 39 | * @class Phaser.Plugin.asyncPath 40 | * @constructor 41 | * @param {Any} parent - The object that owns this plugin, usually Phaser.PluginManager. 42 | **/ 43 | 44 | 45 | 46 | Phaser.Plugin.asyncPath = function (parent) { 47 | Phaser.Plugin.call(this, parent); 48 | 49 | this._parent = parent; 50 | 51 | /** 52 | * [worker] 53 | * @type {Array} 54 | */ 55 | var worker = [Phaser.Plugin.asyncPath.worker_nameSpace_main + Phaser.Plugin.asyncPath.worker_CalculatePath + Phaser.Plugin.asyncPath.worker_getSoroundingNodes + Phaser.Plugin.asyncPath.worker_sortHeap + Phaser.Plugin.asyncPath.worker_sortHeapGroup + Phaser.Plugin.asyncPath.worker_algorithm + Phaser.Plugin.asyncPath.worker_setNodesCost + Phaser.Plugin.asyncPath.worker_findpathTo]; 56 | 57 | 58 | /** 59 | * [worker_file] 60 | * @type {Blob} 61 | * @private 62 | */ 63 | this.worker_file = new Blob(worker,{type: 'script/js'}); 64 | 65 | /** 66 | * [_start blocks origin points] 67 | * @private 68 | * @type {asyncPoint} 69 | */ 70 | this._start = { X: null, Y: null }; 71 | 72 | 73 | 74 | /** 75 | * [_webWorker is plugin using webworker] 76 | * @private 77 | * @default false 78 | * @type {Boolean} 79 | */ 80 | this._webWorker = false; 81 | 82 | 83 | 84 | /** 85 | * [this_workerSize] 86 | * @private 87 | * @default 0 88 | * @type {Number} 89 | */ 90 | 91 | this._workerSize = 0; 92 | 93 | 94 | 95 | /** 96 | * [_specific layer] 97 | * @type {Boolean} 98 | */ 99 | this._specific = false 100 | 101 | 102 | 103 | 104 | 105 | 106 | /** 107 | * [_specific_layer_name] 108 | * @type {string} 109 | */ 110 | this._specific_layer_name = null 111 | 112 | 113 | 114 | 115 | 116 | 117 | /** 118 | * [_stop blocks destination points] 119 | * @private 120 | * @type {asyncPoint} 121 | */ 122 | this._stop = { X: null, Y: null }; 123 | 124 | 125 | /** 126 | * [_map 2D Map] 127 | * @private 128 | * @default null 129 | * @type {Phaser.Tilemap} 130 | */ 131 | this._map = null; 132 | 133 | 134 | /** 135 | * [_mapHeight Phaser.Tilemap.Height] 136 | * @private 137 | * @default null 138 | * @type {number} 139 | */ 140 | this._mapHeight = null; 141 | 142 | 143 | /** 144 | * [_mapWidth Phaser.Tilemap.Width] 145 | * @private 146 | * @default null 147 | * @type {number} 148 | */ 149 | this._mapWidth = null; 150 | 151 | 152 | /** 153 | * [_avoidTile] 154 | * @default [] 155 | * @private 156 | * @type {[number]} 157 | */ 158 | this._avoidTile = []; 159 | 160 | 161 | /** 162 | * [_version_ ] 163 | * @type {String} 164 | * @private 165 | */ 166 | this._version_ = "1.0.0"; 167 | 168 | 169 | 170 | /** 171 | * [_centerPoints makes paths returned to point to tile center] 172 | * @default true 173 | * @private 174 | * @type {Boolean} 175 | */ 176 | this._centerPoints = true; 177 | 178 | 179 | /** 180 | * [_mapset state of Phaser.Tilemap in plugin] 181 | * @default false 182 | * @private 183 | * @type {Boolean} 184 | */ 185 | this._mapset = false; 186 | 187 | 188 | 189 | /** 190 | * [this_debugPathcolor] 191 | * @private 192 | * @default 0xFFFF00 193 | * @type {Base16 number} 194 | */ 195 | this_debugPathcolor = 0xFFFF00 196 | 197 | 198 | 199 | 200 | /** 201 | * [_DiagonalCost Diagonal movement cost] 202 | * @default 14 203 | * @private 204 | * @type {Number} 205 | */ 206 | this._diagonalCost = 14; 207 | 208 | 209 | /** 210 | * [_verticalCost vertical movement cost] 211 | * @default 10 212 | * @private 213 | * @type {Number} 214 | */ 215 | this._verticalCost = 10; 216 | 217 | 218 | /** 219 | * [_horizontalCost horizontal movement cost] 220 | * @default 10 221 | * @private 222 | * @type {Number} 223 | */ 224 | this._horizontalCost = 10; 225 | 226 | 227 | /** 228 | * [_gridSet state of asyncNodeGrid 229 | * @default false 230 | * @private 231 | * @type {Boolean} 232 | */ 233 | this._gridSet = false; 234 | 235 | 236 | /** 237 | * [_paths_per_sec number of path finding calculation to do per frame] 238 | * @private 239 | * @default 2 240 | * @type {Number} 241 | */ 242 | this._paths_per_sec = 2; 243 | 244 | 245 | 246 | /** 247 | * [_pathpixel path return type] 248 | * @private 249 | * @default true 250 | * @type {Boolean} 251 | */ 252 | this._pathpixel = true; 253 | 254 | 255 | 256 | /** 257 | * [_findQueue list of block to be calculated] 258 | * @private 259 | * @default [] 260 | * @type {Array} 261 | */ 262 | this._findQueue = []; 263 | 264 | /** 265 | * [_gird Nodegride stored as string] 266 | * @private 267 | * @default null 268 | * @type {string} 269 | */ 270 | this._grid = null; 271 | 272 | /** 273 | * [_config hold persistent configurations] 274 | * @private 275 | * @default {Algorithm:'Manhattan', debugpath:false, Diagonals:false} 276 | * @type {Object} 277 | */ 278 | this._config = {Algorithm:'Manhattan', debugpath:false, Diagonals:false}; 279 | 280 | 281 | /** 282 | * [_cycletime increamented on each frame] 283 | * @type {Number} 284 | */ 285 | this._cycletime = 0; 286 | 287 | /** 288 | * [_X_Offset Change in X-Tracking that would triger a pathfing calculation] 289 | * @private 290 | * @default 0 291 | * @type {Number} 292 | */ 293 | this._X_Offset = 0; 294 | 295 | /** 296 | * [_Y_Offset Change in Y-Tracking that would triger a pathfing calculation] 297 | * @private 298 | * @default 0 299 | * @type {Number} 300 | */ 301 | this._Y_Offset = 0; 302 | 303 | 304 | /** 305 | * [Diagonals Sets the use of Diagonals] 306 | * @private 307 | * @default false 308 | * @type {Boolean} 309 | */ 310 | this.Diagonals= false; 311 | 312 | 313 | /** 314 | * [Algorithm Sets the Algorithm to used] 315 | * @private 316 | * @default Manhattan 317 | * @type {string} 318 | */ 319 | this.Algorithm = 'Manhattan'; //Euclidean,Manhattan 320 | 321 | 322 | /** 323 | * [debugpath sets the debuger as active or in active on each path calculation] 324 | * @private 325 | * @default true 326 | * @type {Boolean} 327 | */ 328 | this.debugpath = true; 329 | 330 | 331 | /** 332 | * [pathResolvedCache holds calculated cache] 333 | * @private 334 | * @type {Object} 335 | */ 336 | this.pathResolvedCache = {}; 337 | 338 | 339 | 340 | /** 341 | * [workerCache web worker Cache] 342 | * @private 343 | * @type {Array} 344 | */ 345 | this.workerCache = []; 346 | 347 | 348 | 349 | /** 350 | * [pathCache] 351 | * @private 352 | * @type {Object} 353 | */ 354 | this.pathCache = {}; 355 | 356 | 357 | 358 | /** 359 | * [_webWorker main worker state] 360 | * @private 361 | * @type {Object} 362 | */ 363 | this._webWorker = {active: false, count: 0}; 364 | 365 | 366 | 367 | /** 368 | * [_webWorkerDiagonals] 369 | * @private 370 | * @default false 371 | * @type {Boolean} 372 | */ 373 | this._webWorkerDiagonals = false; 374 | 375 | 376 | 377 | /** 378 | * [_webWorkerDiagonalsCost] 379 | * @private 380 | * @default 14 381 | * @type {Number} 382 | */ 383 | this._webWorkerDiagonalsCost = 14 384 | 385 | 386 | 387 | /** 388 | * [_webWorkerverhorCost ] 389 | * @private 390 | * @default 10 391 | * @type {Number} 392 | */ 393 | this._webWorkerverhorCost = 10; 394 | 395 | } 396 | 397 | 398 | Phaser.Plugin.asyncPath.prototype = Object.create(Phaser.Plugin.prototype); 399 | Phaser.Plugin.asyncPath.prototype.constructor = Phaser.Plugin.asyncPath; 400 | 401 | 402 | 403 | 404 | 405 | 406 | /** 407 | * [get description] 408 | * @method Phaser.Plugin.asyncPath.version 409 | * @return {string} [Version] 410 | */ 411 | Object.defineProperty(Phaser.Plugin.asyncPath.prototype, "version", { 412 | get: function () { 413 | return this._version_; 414 | }, 415 | enumerable: false, 416 | configurable: false 417 | }); 418 | 419 | 420 | 421 | 422 | 423 | /** 424 | * returns the number of webWorkers. 425 | * @prop Phaser.Plugin.async.getbWorkers 426 | * @public 427 | * @param {number} 428 | */ 429 | Object.defineProperty(Phaser.Plugin.asyncPath.prototype, "getWorkers", { 430 | get: function () { 431 | return this._webWorker.count 432 | }, 433 | enumerable: true, 434 | configurable: true 435 | }); 436 | 437 | 438 | 439 | 440 | 441 | 442 | /** 443 | * returns the number of webWorkers. 444 | * @prop Phaser.Plugin.async.workerSize 445 | * @public 446 | * @param {number} 447 | */ 448 | Object.defineProperty(Phaser.Plugin.asyncPath.prototype, "getWorkersSize", { 449 | get: function () { 450 | return (this._workerSize/1000) + "kb"; 451 | }, 452 | enumerable: true, 453 | configurable: true 454 | }); 455 | 456 | 457 | 458 | 459 | 460 | /** 461 | * returns the number of webWorkers. 462 | * @prop Phaser.Plugin.async.getbWorkerState 463 | * @public 464 | * @param {number} 465 | */ 466 | Object.defineProperty(Phaser.Plugin.asyncPath.prototype, "getWorkerState", { 467 | get: function () { 468 | return this._webWorker.active 469 | }, 470 | enumerable: true, 471 | configurable: true 472 | }); 473 | 474 | 475 | 476 | 477 | /** 478 | * [webWorkerDiagonals] 479 | * @property Phaser.Plugin.asyncPath.webWorkerDiagonals 480 | * @public 481 | * @type {Boolean} 482 | */ 483 | Object.defineProperty(Phaser.Plugin.asyncPath.prototype, "webWorkerDiagonals", { 484 | set: function (bool) { 485 | this._webWorkerDiagonals = bool; 486 | }, 487 | enumerable: true, 488 | configurable: true 489 | }); 490 | 491 | 492 | 493 | 494 | /** 495 | * Sets the cost of the Horizantal and Veritical Movement. 496 | * @prop Phaser.Plugin.async.webWorkerVerHorCost 497 | * @public 498 | * @param {number} [movement cost] 499 | */ 500 | 501 | Object.defineProperty(Phaser.Plugin.asyncPath.prototype, "webWorkerVerHorCost", { 502 | set: function (cost) { 503 | this._webWorkerverhorCost = cost; 504 | }, 505 | enumerable: true, 506 | configurable: true 507 | }); 508 | 509 | 510 | 511 | 512 | 513 | /** 514 | * Sets the cost of the Horizantal and Veritical Movement. 515 | * @prop Phaser.Plugin.async.webWorkerDiagonalsCost 516 | * @public 517 | * @param {number} [movement cost] 518 | */ 519 | 520 | Object.defineProperty(Phaser.Plugin.asyncPath.prototype, "webWorkerDiagonalsCost", { 521 | set: function (cost) { 522 | this._webWorkerDiagonalsCost = cost; 523 | }, 524 | enumerable: true, 525 | configurable: true 526 | }); 527 | 528 | 529 | 530 | 531 | 532 | 533 | /** 534 | * Sets map, Tile Width and Height 535 | * @prop Phaser.Plugin.async.yOffset 536 | * @public 537 | * @param {Phaser.Tilemap} 538 | */ 539 | Object.defineProperty(Phaser.Plugin.asyncPath.prototype, "tileMap", { 540 | set: function (map) { 541 | this._map = map; 542 | this.TileHeight = map.tileHeight; 543 | this.TileWidth = map.tileWidth; 544 | this._mapset = true; 545 | }, 546 | enumerable: true, 547 | configurable: true 548 | }); 549 | 550 | 551 | 552 | 553 | /** 554 | * Change in XY-Tracking that would triger a pathfing calculation 555 | * @prop Phaser.Plugin.async.xyOffset 556 | * @public 557 | * @param {number} 558 | */ 559 | 560 | Object.defineProperty(Phaser.Plugin.asyncPath.prototype, "xyOffset", { 561 | set: function (offset) { 562 | this._X_Offset = offset; 563 | this._Y_Offset = offset; 564 | }, 565 | enumerable: true, 566 | configurable: true 567 | }); 568 | 569 | 570 | 571 | 572 | /** 573 | * Change in X-Tracking that would triger a pathfing calculation 574 | * @prop Phaser.Plugin.async.xOffset 575 | * @public 576 | * @param {number} 577 | */ 578 | 579 | Object.defineProperty(Phaser.Plugin.asyncPath.prototype, "xOffset", { 580 | set: function (offset) { 581 | this._X_Offset = offset; 582 | }, 583 | enumerable: true, 584 | configurable: true 585 | }); 586 | 587 | 588 | 589 | 590 | 591 | 592 | /** 593 | * Change in Y-Tracking that would triger a pathfing calculation 594 | * @prop Phaser.Plugin.async.yOffset 595 | * @public 596 | * @param {number} 597 | */ 598 | 599 | Object.defineProperty(Phaser.Plugin.asyncPath.prototype, "yOffset", { 600 | set: function (offset) { 601 | this._Y_Offset = offset; 602 | }, 603 | enumerable: true, 604 | configurable: true 605 | }); 606 | 607 | 608 | 609 | 610 | 611 | /** 612 | * Set the path retured to be in units or pixels. 613 | * @prop Phaser.Plugin.async.use 614 | * @public 615 | * @param {string} [units, pixel] 616 | */ 617 | 618 | Object.defineProperty(Phaser.Plugin.asyncPath.prototype, "use", { 619 | set: function (scale) { 620 | switch (scale){ 621 | case 'units': 622 | this._pathpixel = false; 623 | break; 624 | case 'pixel': 625 | this.pathixel = true; 626 | break; 627 | default: 628 | this._pathpixel = true; 629 | } 630 | }, 631 | enumerable: true, 632 | configurable: true 633 | }); 634 | 635 | 636 | 637 | /** 638 | * Set the path retured to point to tile centers than edges. 639 | * @prop Phaser.Plugin.async.centerPaths 640 | * @public 641 | * @param {boolean} 642 | */ 643 | 644 | Object.defineProperty(Phaser.Plugin.asyncPath.prototype, "centerPaths", { 645 | set: function (bool) { 646 | this._centerPoints = bool 647 | }, 648 | enumerable: true, 649 | configurable: true 650 | }); 651 | 652 | 653 | 654 | 655 | /** 656 | * Set the path retured to point to tile centers than edges. 657 | * @prop Phaser.Plugin.async.centerPaths 658 | * @public 659 | * @param {boolean} 660 | */ 661 | 662 | Object.defineProperty(Phaser.Plugin.asyncPath.prototype, "debugColor", { 663 | set: function (hex_color) { 664 | this_debugPathcolor = hex_color; 665 | }, 666 | enumerable: true, 667 | configurable: true 668 | }); 669 | 670 | 671 | 672 | 673 | /** 674 | * sets the number of paths to be calculated on every frame. 675 | * @prop Phaser.Plugin.async.pathsPerSec 676 | * @public 677 | * @param {number} 678 | */ 679 | 680 | Object.defineProperty(Phaser.Plugin.asyncPath.prototype, "pathsPerSec", { 681 | set: function (numberofPaths) { 682 | this._paths_per_sec = numberofPaths; 683 | }, 684 | enumerable: true, 685 | configurable: true 686 | }); 687 | 688 | 689 | 690 | 691 | 692 | 693 | /** 694 | * Switches the debuger On or Off. 695 | * @prop Phaser.Plugin.async.defaultdebug 696 | * @public 697 | * @param {boolean} 698 | */ 699 | 700 | Object.defineProperty(Phaser.Plugin.asyncPath.prototype, "defaultdebug", { 701 | set: function (on) { 702 | if(on){ 703 | this._config.debugpath = on; 704 | this.debugpath = on; 705 | 706 | } 707 | }, 708 | enumerable: true, 709 | configurable: true 710 | }); 711 | 712 | 713 | 714 | 715 | 716 | /** 717 | * Sets the cost of the Horizantal and Veritical Movement. 718 | * @prop Phaser.Plugin.async.VertHorCost 719 | * @public 720 | * @param {number} [movement cost] 721 | */ 722 | 723 | Object.defineProperty(Phaser.Plugin.asyncPath.prototype, "VertHorCost", { 724 | set: function (cost) { 725 | this._verticalCost = cost; 726 | this._horizontalCost = cost; 727 | this._config.VertHorCost = cost; 728 | }, 729 | enumerable: true, 730 | configurable: true 731 | }); 732 | 733 | 734 | 735 | 736 | 737 | 738 | /** 739 | * Sets the non walkable tile index. 740 | * @prop Phaser.Plugin.async.nonWalkableTile 741 | * @public 742 | * @param {number} [tile index] 743 | */ 744 | 745 | Object.defineProperty(Phaser.Plugin.asyncPath.prototype, "nonWalkableTile", { 746 | set: function (tile) { 747 | if(tile instanceof Object){ 748 | for(var i = 0; i < tile.length; i++){ 749 | this._avoidTile.push(tile[i]); 750 | } 751 | } 752 | else{ 753 | this._avoidTile.push(tile); 754 | } 755 | 756 | }, 757 | enumerable: true, 758 | configurable: true 759 | }); 760 | 761 | 762 | 763 | 764 | 765 | /** 766 | * Sets the use of Diagonals . 767 | * @prop Phaser.Plugin.async.useDiagonals 768 | * @public 769 | * @param {boolean} [Diagonals use] 770 | */ 771 | 772 | Object.defineProperty(Phaser.Plugin.asyncPath.prototype, "useDiagonals", { 773 | set: function (bool) { 774 | this._config.Diagonals = bool; 775 | this.Diagonals= bool; 776 | }, 777 | enumerable: true, 778 | configurable: true 779 | }); 780 | 781 | 782 | 783 | 784 | /** 785 | * Sets the layer to be avoided . 786 | * @prop Phaser.Plugin.async.nonWalkableLayer 787 | * @public 788 | * @param {string} 789 | */ 790 | 791 | Object.defineProperty(Phaser.Plugin.asyncPath.prototype, "nonWalkableLayer", { 792 | set: function (layer) { 793 | if(this._mapset){ 794 | for(var i = 0; i < this._map.layers.length; i++){ 795 | if(this._map.layers[i].name === layer){ 796 | var _avoidLayer = this._map.layers[i]; 797 | var _nodeGrid = []; 798 | for (var y = 0; y < _avoidLayer.height; y++){ 799 | _nodeGrid[y] = []; 800 | for (var x = 0; x < _avoidLayer.width; x++){ 801 | var Node = {}; 802 | var alreadyIn = this.shouldAvoid(_avoidLayer.data[y][x].index); 803 | if(_avoidLayer.data[y][x].index !== -1){ 804 | if(!alreadyIn){this._avoidTile.push(_avoidLayer.data[y][x].index);} 805 | Node = this.setasNonWalkable(x,y); 806 | } 807 | else{ 808 | Node = this.setasWalkable(x,y); 809 | } 810 | _nodeGrid[y].push(Node); 811 | } 812 | } 813 | 814 | this._grid = JSON.stringify(_nodeGrid); 815 | this._gridSet = true; 816 | break; 817 | } 818 | } 819 | } 820 | else{ 821 | console.warn("Please Set TileMap first"); 822 | } 823 | }, 824 | enumerable: true, 825 | configurable: true 826 | }); 827 | 828 | 829 | 830 | 831 | 832 | /** 833 | * [useSpecific description] 834 | * @param {array} tile_Array 835 | * @param {string} layer_Name 836 | * @return {[type]} 837 | */ 838 | Phaser.Plugin.asyncPath.prototype.useSpecific = function (tile_Array, layer_Name){ 839 | this._specific_layer_name = layer_Name; 840 | this.nonWalkableTile = tile_Array; 841 | this._specific = true; 842 | this.setNodeGrid(); 843 | } 844 | 845 | 846 | 847 | 848 | 849 | 850 | /** 851 | * Determines if the tile if tile is approved or not . 852 | * @method Phaser.Plugin.async.getPath 853 | * @private 854 | * @param {number} tile index 855 | * @return {bool} 856 | */ 857 | 858 | Phaser.Plugin.asyncPath.prototype.shouldAvoid = function (tile) { 859 | for(var i = 0; i < this._avoidTile.length; i++){ 860 | if(tile === this._avoidTile[i]){ 861 | return true; 862 | } 863 | } 864 | 865 | return false; 866 | } 867 | 868 | 869 | 870 | /** 871 | * Adds new block to the pathfind Queue . 872 | * @method Phaser.Plugin.async.getPath 873 | * @public 874 | * @param {block} asynCords 875 | * @return {void} 876 | */ 877 | 878 | Phaser.Plugin.asyncPath.prototype.getPath = function(block){ 879 | var uid = this.get_uid("acyncPath-xxxx-xx-xxx", "x"); 880 | this.pathResolvedCache[uid] = block 881 | this.pathResolvedCache[uid].path_uid = uid; 882 | this.updatequeue(uid); 883 | } 884 | 885 | 886 | 887 | 888 | 889 | 890 | /** 891 | * Adds new block to the pathfind Queue . 892 | * @method Phaser.Plugin.async.updatequeue 893 | * @private 894 | * @param {block} asynCords 895 | * @return {void} 896 | */ 897 | Phaser.Plugin.asyncPath.prototype.updatequeue = function(block){ 898 | this._findQueue.push(block); 899 | } 900 | 901 | 902 | 903 | 904 | 905 | /** 906 | * update method called by game in each Frame. 907 | * @method Phaser.Plugin.async.update 908 | * @private 909 | * @param {} asynCords 910 | * @return {void} 911 | */ 912 | 913 | Phaser.Plugin.asyncPath.prototype.update = function(){ 914 | if(this._findQueue.length > 0 && this.game.time.now > this._cycletime){ 915 | this._cycletime = this.game.time.now + (1000/this._paths_per_sec); 916 | var block, path; 917 | block = this.pathResolvedCache[this._findQueue.shift()]; 918 | if(block !== undefined){ 919 | this.asyncConfig(block); 920 | 921 | if(block.keepTrack !== undefined && block.keepTrack){ 922 | this.pathManager(block); 923 | } 924 | else{ 925 | this.onetimePath(block); 926 | } 927 | this.resolevedPathManager(); 928 | this.reset(); 929 | } 930 | 931 | } 932 | 933 | } 934 | 935 | 936 | 937 | 938 | 939 | /** 940 | * fires the found or notfound function when path has been resoved in block. 941 | * @method Phaser.Plugin.async.asyncfire 942 | * @private 943 | * @param {block} asynCords 944 | * @return {void} 945 | */ 946 | Phaser.Plugin.asyncPath.prototype.asyncfire = function(block){ 947 | if(block.change){ 948 | if(block.path.length > 0 && block.found instanceof Function){ 949 | block.found(block.path); 950 | } 951 | else if(block.notfound instanceof Function){ 952 | block.notfound(); 953 | } 954 | block.change = false; 955 | } 956 | 957 | if(block.keepTrack === undefined || block.keepTrack === false){ 958 | this.removePath(block.path_uid); 959 | } 960 | } 961 | 962 | 963 | 964 | 965 | 966 | 967 | /** 968 | * Manages untracked block. 969 | * @method Phaser.Plugin.async.onetimePath 970 | * @private 971 | * @param {block} asynCords 972 | * @return {void} 973 | */ 974 | Phaser.Plugin.asyncPath.prototype.onetimePath = function(block){ 975 | 976 | if((block.forcemain !== undefined && block.forcemain) || !this._webWorker.active ){ 977 | block.path = this.findpathTo(block.Origin, block.Destination); 978 | } 979 | else{ 980 | var _block = { 981 | Origin: {x: block.Origin.x, y: block.Origin.y}, 982 | Destination: {x: block.Destination.x, y: block.Destination.y}, 983 | id: block.path_uid 984 | }; 985 | var worker = this.workerCache[0]; 986 | worker.postMessage(_block); 987 | } 988 | block.change = true; 989 | } 990 | 991 | 992 | 993 | 994 | 995 | /** 996 | * [removePath description] 997 | * @method Phaser.Plugin.asyncPath.removePath 998 | * @private 999 | * @param {string} uid 1000 | * @return {void} 1001 | */ 1002 | Phaser.Plugin.asyncPath.prototype.removePath = function (uid) { 1003 | delete this.pathResolvedCache[uid]; 1004 | } 1005 | 1006 | 1007 | 1008 | 1009 | 1010 | 1011 | 1012 | 1013 | 1014 | 1015 | /** 1016 | * Configues Plugin for Cords. 1017 | * @method Phaser.Plugin.async.asyncConfig 1018 | * @private 1019 | * @param {cords} asynCords 1020 | * @return {void} 1021 | */ 1022 | Phaser.Plugin.asyncPath.prototype.asyncConfig = function(cords){ 1023 | var configs = ['Diagonals','Algorithm','debugpath']; 1024 | var _this = this; 1025 | configs.forEach(function(configuraion){ 1026 | if(cords[configuraion] !== undefined){ 1027 | _this[configuraion] = cords[configuraion]; 1028 | } 1029 | }); 1030 | } 1031 | 1032 | 1033 | 1034 | 1035 | /** 1036 | * Manages the path finding Queue. 1037 | * @method Phaser.Plugin.async.pathManager 1038 | * @private 1039 | * @param {cords} asynCords 1040 | * @return {void} 1041 | */ 1042 | Phaser.Plugin.asyncPath.prototype.pathManager = function(block){ 1043 | var _block = { 1044 | Origin: {x: block.Origin.x, y: block.Origin.y}, 1045 | Destination: {x:block.Destination.x, y: block.Destination.y}, 1046 | id: block.path_uid 1047 | } 1048 | 1049 | var worker = this.workerCache[0]; 1050 | 1051 | if(block.lastx !== undefined && block.lasty !== undefined){ 1052 | var x_off = block.x_off || this._X_Offset; 1053 | var y_off = block.y_off || this._Y_Offset; 1054 | var xChanged = (block.lastx > (block[block.trackBy].x + x_off)) || (block.lastx < (block[block.trackBy].x - x_off)); 1055 | var yChanged = (block.lasty > (block[block.trackBy].y + y_off)) || (block.lasty < (block[block.trackBy].y - y_off)); 1056 | 1057 | 1058 | if( xChanged || yChanged ){ 1059 | block.change = true; 1060 | block.lastx = block[block.trackBy].x; 1061 | block.lasty = block[block.trackBy].y; 1062 | if((block.forcemain !== undefined && block.forcemain) || !this._webWorker.active ){ 1063 | block.path = this.findpathTo(block.Origin, block.Destination); 1064 | } 1065 | else{ 1066 | 1067 | worker.postMessage(_block); 1068 | } 1069 | } 1070 | } 1071 | 1072 | 1073 | else { 1074 | block.lastx = block[block.trackBy].x; 1075 | block.lasty = block[block.trackBy].y; 1076 | block.path = []; 1077 | block.change = true; 1078 | if((block.forcemain !== undefined && block.forcemain) || !this._webWorker.active ){ 1079 | block.path = this.findpathTo(block.Origin, block.Destination); 1080 | } 1081 | else{ 1082 | worker.postMessage(_block); 1083 | } 1084 | } 1085 | 1086 | this.updatequeue(block.path_uid); 1087 | } 1088 | 1089 | 1090 | 1091 | 1092 | 1093 | 1094 | 1095 | /** 1096 | * Clears Path drawn on canvas by debuger. 1097 | * @method Phaser.Plugin.async.clearVisual 1098 | * @private 1099 | * @param {} 1100 | * @return {void} 1101 | */ 1102 | Phaser.Plugin.asyncPath.prototype.clearVisual = function(){ 1103 | if(this.debugpath && this.graphics !== undefined){ 1104 | this.graphics.clear(); 1105 | } 1106 | } 1107 | 1108 | 1109 | 1110 | 1111 | 1112 | 1113 | 1114 | /** 1115 | * Finds the path form PointA to PointB. 1116 | * @method Phaser.Plugin.async.findpathTo 1117 | * @private 1118 | * @param {Origin} asynPoint 1119 | * @param {Destination} asynPoint 1120 | * @return {array} An array of Phaser.Plugin.asyncPoints unit 1121 | */ 1122 | Phaser.Plugin.asyncPath.prototype.findpathTo = function (Origin, Destination) { 1123 | var designation = ['_start','_stop']; 1124 | var axis = ['X','Y']; 1125 | var NodeGrid; 1126 | var Path = []; 1127 | 1128 | this._start.X = Math.floor(Origin.x / this._map.tileWidth); 1129 | this._start.Y = Math.floor(Origin.y / this._map.tileHeight); 1130 | 1131 | 1132 | 1133 | this._stop.X = Math.floor(Destination.x / this._map.tileWidth); 1134 | this._stop.Y = Math.floor(Destination.y / this._map.tileHeight); 1135 | 1136 | 1137 | for(var i = 0; i < 2; i++){ 1138 | for(var j = 0; j < 2; j++){ 1139 | if(this[designation[i]][axis[j]] < 0){ 1140 | this[designation[i]][axis[j]] = 0; 1141 | } 1142 | } 1143 | } 1144 | 1145 | 1146 | NodeGrid = this.setNodeGrid(); 1147 | NodeGrid = this.setTeminalNodes(NodeGrid); 1148 | Path = this.CalculatePath(NodeGrid); 1149 | 1150 | 1151 | return Path; 1152 | } 1153 | 1154 | 1155 | 1156 | 1157 | 1158 | 1159 | 1160 | /** 1161 | * Sets asyncNodeGrid. 1162 | * @method Phaser.Plugin.async.setNodeGrid 1163 | * @private 1164 | * @param {} 1165 | * @return {asyncNodeGrid} asyncNodeGrid 1166 | */ 1167 | Phaser.Plugin.asyncPath.prototype.setNodeGrid = function () { 1168 | var NodeGrid = []; 1169 | 1170 | if(!this._gridSet){ 1171 | var tile; 1172 | var _avoidLayer; 1173 | if(this._specific){ 1174 | for(var i = 0; i < this._map.layers.length; i++){ 1175 | if(this._map.layers[i].name === this._specific_layer_name){ 1176 | _avoidLayer = this._map.layers[i]; 1177 | break; 1178 | } 1179 | } 1180 | } 1181 | else{ 1182 | _avoidLayer = this._map.layers[0]; 1183 | } 1184 | for (var y = 0; y < this._map.height; y++) { 1185 | NodeGrid[y] = []; 1186 | for (var x = 0; x < this._map.width; x++) { 1187 | var Node = {}; 1188 | tile = _avoidLayer.data[y][x].index; 1189 | var badTile = this.shouldAvoid(tile); 1190 | if (badTile) { 1191 | Node = this.setasNonWalkable(x, y); 1192 | } 1193 | else { 1194 | Node = this.setasWalkable(x, y); 1195 | } 1196 | NodeGrid[y].push(Node); 1197 | } 1198 | } 1199 | this._grid = JSON.stringify(NodeGrid); 1200 | this._gridSet = true; 1201 | } 1202 | else{ 1203 | 1204 | NodeGrid = JSON.parse(this._grid); 1205 | } 1206 | 1207 | return NodeGrid; 1208 | } 1209 | 1210 | 1211 | 1212 | 1213 | 1214 | 1215 | 1216 | /** 1217 | * Sets Teminal Nodes and Node costs on asyncNodeGrid. 1218 | * @method Phaser.Plugin.async.setTeminalNodes 1219 | * @private 1220 | * @param {asyncNodeGrid} asyncNodeGrid 1221 | * @return {asyncNodeGrid} asyncNodeGrid 1222 | */ 1223 | Phaser.Plugin.asyncPath.prototype.setTeminalNodes = function (NodeGrid) { 1224 | var Distance; 1225 | NodeGrid[this._start.Y][this._start.X].StartNode = true; 1226 | NodeGrid[this._start.Y][this._start.X].Gcost = 0; 1227 | 1228 | NodeGrid[this._stop.Y][this._stop.X].StopNode = true; 1229 | NodeGrid[this._stop.Y][this._stop.X].Hcost = 0; 1230 | 1231 | Distance = this[this.Algorithm](NodeGrid[this._start.Y][this._start.X], NodeGrid[this._stop.Y][this._stop.X]); 1232 | NodeGrid[this._start.Y][this._start.X].Hcost = Distance; 1233 | NodeGrid[this._stop.Y][this._stop.X].Gcost = Distance; 1234 | NodeGrid[this._start.Y][this._start.X].Fcost = Distance; 1235 | NodeGrid[this._stop.Y][this._stop.X].Fcost = Distance; 1236 | 1237 | return NodeGrid; 1238 | } 1239 | 1240 | 1241 | 1242 | 1243 | 1244 | 1245 | 1246 | 1247 | /** 1248 | * Calculate the path. 1249 | * @method Phaser.Plugin.async.CalculatePath 1250 | * @private 1251 | * @param {asyncNodeGrid} asyncNodeGrid 1252 | * @return {array} An array of Phaser.Plugin.ascny.points unit 1253 | */ 1254 | Phaser.Plugin.asyncPath.prototype.CalculatePath = function (NodeGrid) { 1255 | 1256 | var list ={ Open: [], Target: null, SortType:'Fcost'}; 1257 | 1258 | var listCandidate = NodeGrid[this._start.Y][this._start.X]; 1259 | 1260 | var suroundingNodes; 1261 | 1262 | var Path = []; 1263 | 1264 | var pathFound = false; 1265 | 1266 | while (!pathFound) { 1267 | 1268 | suroundingNodes = this.getSoroundingNodes(listCandidate, NodeGrid); 1269 | 1270 | list = this.setNodesCost(listCandidate, suroundingNodes, list, NodeGrid); 1271 | 1272 | list = this.sortHeap(list,'Fcost'); 1273 | 1274 | list = this.sortHeapGroup(list,'Hcost'); 1275 | 1276 | listCandidate = list.Open.shift(); 1277 | 1278 | if (listCandidate === undefined) { 1279 | break; 1280 | } 1281 | 1282 | if(listCandidate.StopNode){ 1283 | 1284 | pathFound = true; 1285 | 1286 | list.Target = listCandidate; 1287 | 1288 | break; 1289 | } 1290 | 1291 | 1292 | } 1293 | if (list.Target !== null) { 1294 | Path = this.pathMap(list, NodeGrid); 1295 | 1296 | } 1297 | return Path; 1298 | } 1299 | 1300 | 1301 | 1302 | 1303 | 1304 | /** 1305 | * [resolevedPathManager Manages Resolved Paths] 1306 | * @method Phaser.Plugin.async.resolevedPathManager 1307 | * @public 1308 | * @return {void} 1309 | */ 1310 | Phaser.Plugin.asyncPath.prototype.resolevedPathManager = function (){ 1311 | _this = this; 1312 | Object.keys(this.pathResolvedCache).forEach( function (uid){ 1313 | if(_this.pathResolvedCache[uid] !== undefined){ 1314 | var Path = _this.pathResolvedCache[uid].path; 1315 | if(Path !== undefined){ 1316 | Path = _this.makePoints(Path); 1317 | _this.asyncfire(_this.pathResolvedCache[uid]); 1318 | _this.clearVisual(); 1319 | if(_this.debugpath && Path.length>0){ 1320 | _this.debugger(Path); 1321 | } 1322 | } 1323 | } 1324 | }); 1325 | } 1326 | 1327 | 1328 | 1329 | 1330 | 1331 | 1332 | 1333 | 1334 | 1335 | 1336 | /** 1337 | * Makes nonWalkable asyncNode. 1338 | * @method Phaser.Plugin.async.setasNonWalkable 1339 | * @private 1340 | * @param {x} number 1341 | * @param {y} number 1342 | * @return {asyncNode} A Unit asyncNode 1343 | */ 1344 | Phaser.Plugin.asyncPath.prototype.setasNonWalkable = function (x, y) { 1345 | var Node = {}; 1346 | Node.Acceptable = false; 1347 | Node.StartNode = false; 1348 | Node.StopNode = false; 1349 | Node.X = x; 1350 | Node.Y = y; 1351 | return Node; 1352 | } 1353 | 1354 | 1355 | 1356 | 1357 | 1358 | 1359 | 1360 | /** 1361 | * Makes Walkable asyncNode. 1362 | * @method Phaser.Plugin.async.setasWalkable 1363 | * @private 1364 | * @param {x} number 1365 | * @param {y} number 1366 | * @return {asyncNode} A Unit asyncNode 1367 | */ 1368 | Phaser.Plugin.asyncPath.prototype.setasWalkable = function (x, y) { 1369 | var Node = {}; 1370 | Node.Parent = null; 1371 | Node.Gcost = 0; 1372 | Node.Hcost = 0; 1373 | Node.Fcost = 0; 1374 | Node.Acceptable = true; 1375 | Node.StartNode = false; 1376 | Node.StopNode = false; 1377 | Node.X = x; 1378 | Node.Y = y; 1379 | return Node; 1380 | } 1381 | 1382 | 1383 | 1384 | 1385 | 1386 | 1387 | 1388 | /** 1389 | * Crawl the results list Target backwards: crawling its Parents. 1390 | * @method Phaser.Plugin.ascny.pathMap 1391 | * @private 1392 | * @param {list} n - list with target node ued to crawl to the start node child. 1393 | * @return {array} An array of Phaser.Plugin.ascny.pathMapUnitNode 1394 | */ 1395 | Phaser.Plugin.asyncPath.prototype.pathMap = function (list) { 1396 | var Path = []; 1397 | var Node = list.Target; 1398 | var traced = false; 1399 | 1400 | while (!traced) { 1401 | var Point = { X: Node.X, Y: Node.Y }; 1402 | Path.unshift(Point); 1403 | Node = Node.Parent; 1404 | if (Node.StartNode) { 1405 | traced = true; 1406 | } 1407 | } 1408 | 1409 | Path.unshift(this._start); 1410 | 1411 | return Path; 1412 | } 1413 | 1414 | 1415 | 1416 | 1417 | 1418 | 1419 | 1420 | /** 1421 | * Sets path in unit or pixel format. 1422 | * @method Phaser.Plugin.ascny.makePoints 1423 | * @private 1424 | * @param {list} n - list of path . 1425 | * @return {array} An array of Phaser.Plugin.ascny.points unit || pixel 1426 | */ 1427 | Phaser.Plugin.asyncPath.prototype.makePoints = function (path) { 1428 | var Points = []; 1429 | for (var i = 0; i < path.length; i++) { 1430 | var Point = {}; 1431 | 1432 | Point.x = path[i].X 1433 | Point.y = path[i].Y 1434 | 1435 | if(this._pathpixel || this.debugpath){ 1436 | Point.x *= this.TileWidth; 1437 | Point.y *= this.TileHeight; 1438 | } 1439 | 1440 | if(this._centerPoints){ 1441 | Point.x += (this.TileWidth / 2) 1442 | Point.y += (this.TileHeight / 2) 1443 | } 1444 | 1445 | Points.push(Point); 1446 | } 1447 | 1448 | return Points; 1449 | } 1450 | 1451 | 1452 | 1453 | 1454 | 1455 | 1456 | 1457 | /** 1458 | * Sort path list heap. 1459 | * @method Phaser.Plugin.ascny.sortHeap 1460 | * @private 1461 | * @param {heap} list of asyncNodes . 1462 | * @param {prop} key of the property to be sorted by. 1463 | * @return {array} An array of sorted list of asyncNodes. 1464 | */ 1465 | Phaser.Plugin.asyncPath.prototype.sortHeap = function (heap, prop) { 1466 | for (var i = 0; i < heap.Open.length; i++) { 1467 | for (var j = 0; j < heap.Open.length; j++) { 1468 | if (heap.Open[i][prop] < heap.Open[j][prop]) { 1469 | var temp = heap.Open[i]; 1470 | heap.Open[i] = heap.Open[j]; 1471 | heap.Open[j] = temp; 1472 | } 1473 | } 1474 | } 1475 | return heap; 1476 | } 1477 | 1478 | 1479 | 1480 | 1481 | 1482 | 1483 | 1484 | /** 1485 | * Sort path list heap presice list. 1486 | * @method Phaser.Plugin.ascny.sortHeap 1487 | * @private 1488 | * @param {heap} list of asyncNodes . 1489 | * @param {prop} key of the property to be sorted by. 1490 | * @return {array} An array of presice sorted list of asyncNodes. 1491 | */ 1492 | Phaser.Plugin.asyncPath.prototype.sortHeapGroup = function (heap, prop) { 1493 | for (var i = 0; i < heap.Open.length; i++) { 1494 | var cost = heap.Open[i].Fcost; 1495 | var j = i; 1496 | while ((j + 1) < heap.Open.length && heap.Open[j + 1].Fcost === cost) { 1497 | var p = i; 1498 | while ((p + 1) < heap.Open.length && heap.Open[p + 1].Fcost === cost) { 1499 | if (heap.Open[j][prop] > heap.Open[p + 1][prop]) { 1500 | var temp = heap.Open[j]; 1501 | heap.Open[j] = heap.Open[p + 1]; 1502 | heap.Open[p + 1] = temp; 1503 | } 1504 | p++; 1505 | } 1506 | j++; 1507 | } 1508 | i = j; 1509 | } 1510 | 1511 | return heap; 1512 | } 1513 | 1514 | 1515 | 1516 | 1517 | 1518 | 1519 | 1520 | 1521 | /** 1522 | * Get the sourounding nodes in a grid. 1523 | * @method Phaser.Plugin.ascny.getSoroundingNodes 1524 | * @private 1525 | * @param {Node} asyncNode . 1526 | * @param {NodeGrid} asyncNodeGrid. 1527 | * @return {array} An array sorounding asyncNodes. 1528 | */ 1529 | Phaser.Plugin.asyncPath.prototype.getSoroundingNodes = function (Node, NodeGrid) { 1530 | var SoroundingNodes = []; 1531 | var NodeUpRight = false; 1532 | var NodeUpLeft = false; 1533 | var NodeDownRight = false; 1534 | var NodeDownLeft = false; 1535 | /// seting null tiles....... 1536 | if (Node.Y !== 0 && NodeGrid[Node.Y - 1][Node.X].Acceptable && !NodeGrid[Node.Y - 1][Node.X].StartNode) { 1537 | ///NodeAbove = true; 1538 | NodeUpLeft = true; 1539 | NodeUpRight = true; 1540 | if (NodeGrid[Node.Y - 1][Node.X].Parent === null) { 1541 | NodeGrid[Node.Y - 1][Node.X].Gcost = Node.Gcost + this._verticalCost; 1542 | } 1543 | SoroundingNodes.push(NodeGrid[Node.Y - 1][Node.X]); 1544 | } 1545 | //else { NodeAbove.Tile = NodeGrid[Node.Tile.x][Node.Tile.y - 1] } 1546 | if (Node.X !== 0 && NodeGrid[Node.Y][Node.X - 1].Acceptable && !NodeGrid[Node.Y][Node.X - 1].StartNode) { 1547 | //NodeLeft.Tile = null; 1548 | NodeUpLeft = true; 1549 | NodeDownLeft = true; 1550 | if (NodeGrid[Node.Y][Node.X - 1].Parent === null) { 1551 | NodeGrid[Node.Y][Node.X - 1].Gcost = Node.Gcost + this._horizontalCost ; 1552 | } 1553 | SoroundingNodes.push(NodeGrid[Node.Y][Node.X - 1]); 1554 | } 1555 | //else { NodeLeft.Tile = NodeGrid[Node.Tile.x - 1][Node.Tile.y] } 1556 | if (Node.Y !== NodeGrid.length - 1 && NodeGrid[Node.Y + 1][Node.X].Acceptable && !NodeGrid[Node.Y + 1][Node.X].StartNode) { 1557 | //NodeBelow.Tile = null; 1558 | NodeDownLeft = true; 1559 | NodeDownRight = true; 1560 | if (NodeGrid[Node.Y + 1][Node.X].Parent === null) { 1561 | NodeGrid[Node.Y + 1][Node.X].Gcost = Node.Gcost + this._verticalCost ; 1562 | } 1563 | SoroundingNodes.push(NodeGrid[Node.Y + 1][Node.X]); 1564 | } 1565 | //else { NodeBelow.Tile = NodeGrid[Node.Tile.x][Node.Tile.y + 1] } 1566 | if (Node.X !== NodeGrid[0].length - 1 && NodeGrid[Node.Y][Node.X + 1].Acceptable && !NodeGrid[Node.Y][Node.X + 1].StartNode) { 1567 | //NodeRight.Tile = null 1568 | if (NodeGrid[Node.Y][Node.X + 1].Parent === null) { 1569 | NodeGrid[Node.Y][Node.X + 1].Gcost = Node.Gcost + this._horizontalCost; 1570 | } 1571 | SoroundingNodes.push(NodeGrid[Node.Y][Node.X + 1]); 1572 | } 1573 | // else { NodeRight.Tile = NodeGrid[Node.Tile.x + 1][Node.Tile.y] } 1574 | 1575 | if (this.Diagonals) { 1576 | 1577 | 1578 | if (Node.X === 0) { 1579 | NodeDownLeft = false; 1580 | NodeUpLeft = false; 1581 | } 1582 | if (Node.Y === 0) { 1583 | NodeUpLeft = false; 1584 | NodeUpRight = false; 1585 | } 1586 | if (Node.Y === NodeGrid.length - 1) { 1587 | NodeDownLeft = false; 1588 | NodeDownRight = false; 1589 | } 1590 | if (Node.X === NodeGrid[0].length - 1) { 1591 | NodeDownRight = false; 1592 | NodeUpRight = false; 1593 | } 1594 | 1595 | 1596 | 1597 | if (NodeDownRight && NodeGrid[Node.Y + 1][Node.X + 1].Acceptable && !NodeGrid[Node.Y + 1][Node.X + 1].StartNode) { 1598 | if (NodeGrid[Node.Y + 1][Node.X + 1].Parent === null) { 1599 | NodeGrid[Node.Y + 1][Node.X + 1].Gcost = Node.Gcost + this._diagonalCost; 1600 | } 1601 | SoroundingNodes.push(NodeGrid[Node.Y + 1][Node.X + 1]); 1602 | } 1603 | if (NodeDownLeft && NodeGrid[Node.Y + 1][Node.X - 1].Acceptable && !NodeGrid[Node.Y + 1][Node.X - 1].StartNode) { 1604 | if (NodeGrid[Node.Y + 1][Node.X - 1].Parent === null) { 1605 | NodeGrid[Node.Y + 1][Node.X - 1].Gcost = Node.Gcost + this._diagonalCost; 1606 | } 1607 | SoroundingNodes.push(NodeGrid[Node.Y + 1][Node.X - 1]); 1608 | } 1609 | if (NodeUpLeft && NodeGrid[Node.Y - 1][Node.X - 1].Acceptable && !NodeGrid[Node.Y - 1][Node.X - 1].StartNode) { 1610 | if (NodeGrid[Node.Y - 1][Node.X - 1].Parent === null) { 1611 | NodeGrid[Node.Y - 1][Node.X - 1].Gcost = Node.Gcost + this._diagonalCost; 1612 | } 1613 | SoroundingNodes.push(NodeGrid[Node.Y - 1][Node.X - 1]); 1614 | } 1615 | if (NodeUpRight && NodeGrid[Node.Y - 1][Node.X + 1].Acceptable && !NodeGrid[Node.Y - 1][Node.X + 1].StartNode) { 1616 | if (NodeGrid[Node.Y - 1][Node.X + 1].Parent === null) { 1617 | NodeGrid[Node.Y - 1][Node.X + 1].Gcost = Node.Gcost + this._diagonalCost; 1618 | } 1619 | SoroundingNodes.push(NodeGrid[Node.Y - 1][Node.X + 1]); 1620 | } 1621 | } 1622 | 1623 | 1624 | 1625 | return SoroundingNodes; 1626 | 1627 | } 1628 | 1629 | 1630 | 1631 | 1632 | /** 1633 | * Set cost of the sorounding and update the Open list. 1634 | * @method Phaser.Plugin.ascny.setNodesCost 1635 | * @private 1636 | * @param {Node} asyncNode . 1637 | * @param {SoroundingNodes} asyncNode array 1638 | * @param {list} array of asyncNodes. 1639 | * @param {NodeGrid} asyncNodeGrid. 1640 | * @return {array} An array of asyncNodes. 1641 | */ 1642 | Phaser.Plugin.asyncPath.prototype.setNodesCost = function (Node, SoroundingNodes, list, NodeGrid) { 1643 | 1644 | for (var i = 0; i < SoroundingNodes.length; i++) { 1645 | 1646 | var tempHcost = this[this.Algorithm](SoroundingNodes[i], NodeGrid[this._stop.Y][this._stop.X]); 1647 | var tempFcost = SoroundingNodes[i].Gcost + tempHcost; 1648 | 1649 | SoroundingNodes[i].Hcost = tempHcost; 1650 | SoroundingNodes[i].Fcost = tempFcost; 1651 | 1652 | if (SoroundingNodes[i].Parent === null) { 1653 | SoroundingNodes[i].Parent = Node; 1654 | list.Open.push(SoroundingNodes[i]); 1655 | } 1656 | 1657 | else if (SoroundingNodes[i].Parent.Gcost > Node.Gcost){ 1658 | for(var j = 0; j < list.Open.length; j++){ 1659 | if(list.Open[j].X === SoroundingNodes[i].X && list.Open[j].Y === SoroundingNodes[i].Y){ 1660 | list.Open[j].Parent = Node; 1661 | break; 1662 | } 1663 | } 1664 | } 1665 | } 1666 | 1667 | return list; 1668 | } 1669 | 1670 | 1671 | 1672 | /** 1673 | * Euclidean algorithm 1674 | * @method Phaser.Plugin.ascny.Euclidean 1675 | * @private 1676 | * @param {Node1} asyncNode . 1677 | * @param {Node2} asyncNode . 1678 | * @return {number} Distance from Node1 to Node2. 1679 | */ 1680 | Phaser.Plugin.asyncPath.prototype.Euclidean = function (Node1, Node2) { 1681 | var Distance, X, Y; 1682 | X = Node1.X - Node2.X; 1683 | Y = Node1.Y - Node2.Y; 1684 | Distance = Math.floor(Math.sqrt((X * X) + (Y * Y))); 1685 | return Distance; 1686 | } 1687 | 1688 | 1689 | 1690 | 1691 | 1692 | /** 1693 | * Manhattan algorithm 1694 | * @method Phaser.Plugin.ascny.Manhattan 1695 | * @private 1696 | * @param {Node1} asyncNode . 1697 | * @param {Node2} asyncNode . 1698 | * @return {number} Distance from Node1 to Node2. 1699 | */ 1700 | Phaser.Plugin.asyncPath.prototype.Manhattan = function (Node1, Node2) { 1701 | var H, X, Y; 1702 | X = Math.abs(Node1.X - Node2.X); 1703 | Y = Math.abs(Node1.Y - Node2.Y); 1704 | H = X + Y; 1705 | return H; 1706 | } 1707 | 1708 | 1709 | 1710 | 1711 | 1712 | 1713 | /** 1714 | * Path Debuger 1715 | * @method Phaser.Plugin.ascny.debugger 1716 | * @private 1717 | * @param {path} Array/List of asyncNode . 1718 | * @return {void}. 1719 | */ 1720 | Phaser.Plugin.asyncPath.prototype.debugger = function (path) { 1721 | var length = path.length; 1722 | this.graphics = this.game.add.graphics(path[0].x, path[0].y); 1723 | this.graphics.beginFill(this_debugPathcolor); 1724 | this.graphics.lineStyle(1, this_debugPathcolor, 1); 1725 | var x = 0; 1726 | var y = 0; 1727 | for (var i = 0; i < length; i++) { 1728 | var j = i + 1; 1729 | if (j < path.length) { 1730 | var X = path[j].x - path[i].x; 1731 | var Y = path[j].y - path[i].y; 1732 | x = x + X; 1733 | y = y + Y; 1734 | this.graphics.lineTo(x, y); 1735 | this.graphics.moveTo(x, y); 1736 | } 1737 | } 1738 | this.graphics.endFill(); 1739 | } 1740 | 1741 | 1742 | 1743 | /** 1744 | * Reset to default configuration setting 1745 | * @method Phaser.Plugin.ascny.reset 1746 | * @private 1747 | * @param {} 1748 | * @return {void}. 1749 | */ 1750 | Phaser.Plugin.asyncPath.prototype.reset = function () { 1751 | var _this = this; 1752 | Object.keys(this._config).forEach(function (configuraion){ 1753 | _this[configuraion] = _this._config[configuraion]; 1754 | }); 1755 | 1756 | } 1757 | 1758 | 1759 | 1760 | 1761 | 1762 | /** 1763 | * [newWorker sets/registers new web workers] 1764 | * @public 1765 | * @param {} 1766 | * @return {void} 1767 | */ 1768 | Phaser.Plugin.asyncPath.prototype.newWorker = function(){ 1769 | var _this = this; 1770 | var workerID = this.get_uid("acyncWorker-xxxx-xx-xxx", "x"); 1771 | var _init_= { 1772 | tileHeight: this.TileHeight, 1773 | tileWidth: this.TileWidth, 1774 | init: true, 1775 | grid: this._grid, 1776 | id: workerID, 1777 | Diagonals: this._webWorkerDiagonals, 1778 | DiagonalCost: this._webWorkerDiagonalsCost, 1779 | StraightCost: this._webWorkerverhorCost 1780 | } 1781 | 1782 | var workerUrl = window.URL.createObjectURL(this.worker_file); 1783 | this.workerCache.unshift(new Worker(workerUrl)); 1784 | 1785 | this._workerSize += this.worker_file.size; 1786 | 1787 | 1788 | this.workerCache[0].postMessage(_init_); 1789 | this.workerCache[0]._uid = workerID; 1790 | this.workerCache[0].onmessage = function(data){ 1791 | if(data.data.state){ 1792 | for(var i = 0; i < _this.workerCache.length; i++){ 1793 | if(_this.workerCache[i]._uid === data.data.uid){ 1794 | _this.workerCache[i].state = data.data; 1795 | } 1796 | } 1797 | } 1798 | else{ 1799 | _this.pathResolvedCache[data.data.path_uid].path = data.data.path; 1800 | _this.priotiesFreeWorkers(); 1801 | _this.priotiesWorkersQueue(); 1802 | } 1803 | }; 1804 | this._webWorker.active = true; 1805 | this._webWorker.count += 1; 1806 | 1807 | 1808 | return this.workerCache[0]; 1809 | } 1810 | 1811 | 1812 | 1813 | /** 1814 | * [priotiesFreeWorkers] 1815 | * @private 1816 | * @return {void} 1817 | */ 1818 | Phaser.Plugin.asyncPath.prototype.priotiesFreeWorkers = function(){ 1819 | var length = this.workerCache.length; 1820 | for(var i = 0; i < length; i++){ 1821 | for(var j = 0; j < length; j++){ 1822 | if(!this.workerCache[i].state.isfree && this.workerCache[j].state.isfree){ 1823 | var temp = this.workerCache[i]; 1824 | this.workerCache[i] = this.workerCache[j]; 1825 | this.workerCache[j] = temp; 1826 | } 1827 | } 1828 | } 1829 | } 1830 | 1831 | 1832 | 1833 | 1834 | 1835 | 1836 | 1837 | /** 1838 | * [priotiesWorkersQueue] 1839 | * @private 1840 | * @return {void} 1841 | */ 1842 | Phaser.Plugin.asyncPath.prototype.priotiesWorkersQueue = function(){ 1843 | var length = this.workerCache.length; 1844 | for(var i = 0; i < length; i++){ 1845 | for(var j = 0; j < length; j++){ 1846 | if(!this.workerCache[i].state.isfree && this.workerCache[i].state.Queue > this.workerCache[j].state.Queue){ 1847 | var temp = this.workerCache[i]; 1848 | this.workerCache[i] = this.workerCache[j]; 1849 | this.workerCache[j] = temp; 1850 | } 1851 | } 1852 | } 1853 | } 1854 | 1855 | 1856 | 1857 | 1858 | 1859 | 1860 | 1861 | 1862 | /** 1863 | * [pathCacheRegister register new blocks] 1864 | * @param {Object} block 1865 | * @return {Object} 1866 | */ 1867 | Phaser.Plugin.asyncPath.prototype.pathCacheRegister = function(block){ 1868 | var _uid = this.get_uid("acyncPath-xxxx-xx-xxx", "x"); 1869 | this.pathCache[_uid] = block; 1870 | block.uid = _uid; 1871 | return block 1872 | } 1873 | 1874 | 1875 | 1876 | 1877 | 1878 | 1879 | 1880 | /** 1881 | * [get_uid] 1882 | * @param {string} format [return format] 1883 | * @param {string} IDnamespace [char to replace] 1884 | * @return {string} [uid string] 1885 | */ 1886 | Phaser.Plugin.asyncPath.prototype.get_uid= function (format, IDnamespace) { 1887 | var _this = this; 1888 | var seed = new Date().getTime(); 1889 | var regEx = new RegExp('[' + IDnamespace + ']', 'g'); 1890 | var UID = format.replace(regEx, function (c) { 1891 | var r = (seed + Math.random() * 16) % 16 | 0; 1892 | return (c === IDnamespace.split("")[_this.setBy] ? r : (r & 0x3 | 0x8)).toString(16); 1893 | }); 1894 | return UID; 1895 | }; 1896 | 1897 | 1898 | 1899 | 1900 | 1901 | 1902 | 1903 | /******************************************************************** 1904 | * [asyncWoker] 1905 | * @param {} 1906 | * @return {string} 1907 | ********************************************************************/ 1908 | 1909 | Phaser.Plugin.asyncPath.worker_nameSpace_main = "\nasyncWoker = function(data) {\n\ 1910 | this.Algorithm = \"Manhattan\" \n\ 1911 | this._grid = data.grid;\n\ 1912 | this._tileWidth = data.tileWidth;\n\ 1913 | this._tileHeight = data.tileHeight;\n\ 1914 | this._start = {}\n\ 1915 | this._stop = {}\n\ 1916 | this._uid = data.id\n\ 1917 | this._verticalCost = data.StraightCost\n\ 1918 | this._horizontalCost = data.StraightCost\n\ 1919 | this._diagonalCost = data.DiagonalCost\n\ 1920 | this._free_ = true\n\ 1921 | this.Diagonals= data.Diagonals\n\ 1922 | this._Queue = []\n\ 1923 | }"; 1924 | 1925 | Phaser.Plugin.asyncPath.worker_CalculatePath = "\n\ 1926 | \nasyncWoker.prototype.CalculatePath = function (NodeGrid) { \n\ 1927 | var list = { Open: [], Target: null, SortType:'Fcost'};\n\ 1928 | var listCandidate = NodeGrid[this._start.Y][this._start.X];\n\ 1929 | var suroundingNodes;\n\ 1930 | var Path = [];\n\ 1931 | var pathFound = false;\n\ 1932 | while (!pathFound) {\n\ 1933 | suroundingNodes = this.getSoroundingNodes(listCandidate, NodeGrid);\n\ 1934 | this.setNodesCost(listCandidate, suroundingNodes, list, NodeGrid);\n\ 1935 | list = this.sortHeap(list,'Fcost');\n\ 1936 | list = this.sortHeapGroup(list,'Hcost');\n\ 1937 | listCandidate = list.Open.shift();\n\ 1938 | if (listCandidate === undefined) {\n\ 1939 | break;\n\ 1940 | }\n\ 1941 | if(listCandidate.StopNode){\n\ 1942 | pathFound = true;\n\ 1943 | list.Target = listCandidate;\n\ 1944 | break;\n\ 1945 | }\n\ 1946 | }\n\ 1947 | if (list.Target !== null) {\n\ 1948 | Path = this.pathMap(list, NodeGrid);\n\ 1949 | }\n\ 1950 | return Path;\n\ 1951 | };\n\ 1952 | asyncWoker.prototype.pathresolveQueue = function (){\n\ 1953 | if(this._Queue.length > 0){\n\ 1954 | this._free_ = false;\n\ 1955 | self.postMessage({state:true, uid:this._uid, isfree:this._free_, Queue:this._Queue.length})\n\ 1956 | var _block = this._Queue.shift();\n\ 1957 | var _path = this.findpathTo(_block.Origin, _block.Destination);\n\ 1958 | self.postMessage({path_uid:_block.id, path:_path})\n\ 1959 | }\n\ 1960 | else{\n\ 1961 | this._free_ = true;\n\ 1962 | self.postMessage({state:true, uid:this._uid, isfree:this._free_, Queue:this._Queue.length})\n\ 1963 | }\n\ 1964 | \n\ 1965 | }" 1966 | 1967 | 1968 | Phaser.Plugin.asyncPath.worker_getSoroundingNodes = "\nasyncWoker.prototype.getSoroundingNodes = function (Node, NodeGrid) {\n\ 1969 | var SoroundingNodes = [];\n\ 1970 | var NodeUpRight = false;\n\ 1971 | var NodeUpLeft = false;\n\ 1972 | var NodeDownRight = false;\n\ 1973 | var NodeDownLeft = false;\n\ 1974 | if (Node.Y !== 0 && NodeGrid[Node.Y - 1][Node.X].Acceptable && !NodeGrid[Node.Y - 1][Node.X].StartNode) {\n\ 1975 | ///NodeAbove = true;\n\ 1976 | NodeUpLeft = true;\n\ 1977 | NodeUpRight = true;\n\ 1978 | if (NodeGrid[Node.Y - 1][Node.X].Parent === null) {\n\ 1979 | NodeGrid[Node.Y - 1][Node.X].Gcost = Node.Gcost + this._verticalCost;\n\ 1980 | }\n\ 1981 | SoroundingNodes.push(NodeGrid[Node.Y - 1][Node.X]);\n\ 1982 | }\n\ 1983 | if (Node.X !== 0 && NodeGrid[Node.Y][Node.X - 1].Acceptable && !NodeGrid[Node.Y][Node.X - 1].StartNode) {\n\ 1984 | NodeUpLeft = true;\n\ 1985 | NodeDownLeft = true;\n\ 1986 | if (NodeGrid[Node.Y][Node.X - 1].Parent === null) {\n\ 1987 | NodeGrid[Node.Y][Node.X - 1].Gcost = Node.Gcost + this._horizontalCost ;\n\ 1988 | }\n\ 1989 | SoroundingNodes.push(NodeGrid[Node.Y][Node.X - 1]);\n\ 1990 | }\n\ 1991 | if (Node.Y !== NodeGrid.length - 1 && NodeGrid[Node.Y + 1][Node.X].Acceptable && !NodeGrid[Node.Y + 1][Node.X].StartNode) {\n\ 1992 | NodeDownLeft = true;\n\ 1993 | NodeDownRight = true;\n\ 1994 | if (NodeGrid[Node.Y + 1][Node.X].Parent === null) {\n\ 1995 | NodeGrid[Node.Y + 1][Node.X].Gcost = Node.Gcost + this._verticalCost ;\n\ 1996 | }\n\ 1997 | SoroundingNodes.push(NodeGrid[Node.Y + 1][Node.X]);\n\ 1998 | }\n\ 1999 | if (Node.X !== NodeGrid[0].length - 1 && NodeGrid[Node.Y][Node.X + 1].Acceptable && !NodeGrid[Node.Y][Node.X + 1].StartNode) {\n\ 2000 | if (NodeGrid[Node.Y][Node.X + 1].Parent === null) {\n\ 2001 | NodeGrid[Node.Y][Node.X + 1].Gcost = Node.Gcost + this._horizontalCost;\n\ 2002 | }\n\ 2003 | SoroundingNodes.push(NodeGrid[Node.Y][Node.X + 1]);\n\ 2004 | }\n\ 2005 | if (this.Diagonals) {\n\ 2006 | if (Node.X === 0) {\n\ 2007 | NodeDownLeft = false;\n\ 2008 | NodeUpLeft = false;\n\ 2009 | }\n\ 2010 | if (Node.Y === 0) {\n\ 2011 | NodeUpLeft = false;\n\ 2012 | NodeUpRight = false;\n\ 2013 | }\n\ 2014 | if (Node.Y === NodeGrid.length - 1) {\n\ 2015 | NodeDownLeft = false;\n\ 2016 | NodeDownRight = false;\n\ 2017 | }\n\ 2018 | if (Node.X === NodeGrid[0].length - 1) {\n\ 2019 | NodeDownRight = false;\n\ 2020 | NodeUpRight = false;\n\ 2021 | }\n\ 2022 | if (NodeDownRight && NodeGrid[Node.Y + 1][Node.X + 1].Acceptable && !NodeGrid[Node.Y + 1][Node.X + 1].StartNode) {\n\ 2023 | if (NodeGrid[Node.Y + 1][Node.X + 1].Parent === null) {\n\ 2024 | NodeGrid[Node.Y + 1][Node.X + 1].Gcost = Node.Gcost + this._diagonalCost;\n\ 2025 | }\n\ 2026 | SoroundingNodes.push(NodeGrid[Node.Y + 1][Node.X + 1]);\n\ 2027 | }\n\ 2028 | if (NodeDownLeft && NodeGrid[Node.Y + 1][Node.X - 1].Acceptable && !NodeGrid[Node.Y + 1][Node.X - 1].StartNode) {\n\ 2029 | if (NodeGrid[Node.Y + 1][Node.X - 1].Parent === null) {\n\ 2030 | NodeGrid[Node.Y + 1][Node.X - 1].Gcost = Node.Gcost + this._diagonalCost;\n\ 2031 | }\n\ 2032 | SoroundingNodes.push(NodeGrid[Node.Y + 1][Node.X - 1]);\n\ 2033 | }\n\ 2034 | if (NodeUpLeft && NodeGrid[Node.Y - 1][Node.X - 1].Acceptable && !NodeGrid[Node.Y - 1][Node.X - 1].StartNode) {\n\ 2035 | if (NodeGrid[Node.Y - 1][Node.X - 1].Parent === null) {\n\ 2036 | NodeGrid[Node.Y - 1][Node.X - 1].Gcost = Node.Gcost + this._diagonalCost;\n\ 2037 | }\n\ 2038 | SoroundingNodes.push(NodeGrid[Node.Y - 1][Node.X - 1]);\n\ 2039 | }\n\ 2040 | if (NodeUpRight && NodeGrid[Node.Y - 1][Node.X + 1].Acceptable && !NodeGrid[Node.Y - 1][Node.X + 1].StartNode) {\n\ 2041 | if (NodeGrid[Node.Y - 1][Node.X + 1].Parent === null) {\n\ 2042 | NodeGrid[Node.Y - 1][Node.X + 1].Gcost = Node.Gcost + this._diagonalCost;\n\ 2043 | }\n\ 2044 | SoroundingNodes.push(NodeGrid[Node.Y - 1][Node.X + 1]);\n\ 2045 | }\n\ 2046 | }\n\ 2047 | return SoroundingNodes;\n\ 2048 | }"; 2049 | 2050 | 2051 | Phaser.Plugin.asyncPath.worker_sortHeapGroup = "\nasyncWoker.prototype.sortHeapGroup = function (heap, prop) {\n\ 2052 | for (var i = 0; i < heap.Open.length; i++) {\n\ 2053 | var cost = heap.Open[i].Fcost;\n\ 2054 | var j = i;\n\ 2055 | while ((j + 1) < heap.Open.length && heap.Open[j + 1].Fcost === cost) {\n\ 2056 | var p = i;\n\ 2057 | while ((p + 1) < heap.Open.length && heap.Open[p + 1].Fcost === cost) {\n\ 2058 | if (heap.Open[j][prop] > heap.Open[p + 1][prop]) {\n\ 2059 | var temp = heap.Open[j];\n\ 2060 | heap.Open[j] = heap.Open[p + 1];\n\ 2061 | heap.Open[p + 1] = temp;\n\ 2062 | }\n\ 2063 | p++;\n\ 2064 | }\n\ 2065 | j++;\n\ 2066 | }\n\ 2067 | i = j;\n\ 2068 | }\n\ 2069 | return heap;\n\ 2070 | }\n\ 2071 | \n\ 2072 | asyncWoker.prototype.getNodeGrid = function(){\n\ 2073 | return JSON.parse(this._grid);\n\ 2074 | }\n\ 2075 | \n\ 2076 | asyncWoker.prototype.setTeminalNodes = function (NodeGrid) {\n\ 2077 | var Distance;\n\ 2078 | NodeGrid[this._start.Y][this._start.X].StartNode = true;\n\ 2079 | NodeGrid[this._start.Y][this._start.X].Gcost = 0;\n\ 2080 | \n\ 2081 | NodeGrid[this._stop.Y][this._stop.X].StopNode = true;\n\ 2082 | NodeGrid[this._stop.Y][this._stop.X].Hcost = 0;\n\ 2083 | \n\ 2084 | Distance = this[this.Algorithm](NodeGrid[this._start.Y][this._start.X], NodeGrid[this._stop.Y][this._stop.X]);\n\ 2085 | NodeGrid[this._start.Y][this._start.X].Hcost = Distance;\n\ 2086 | NodeGrid[this._stop.Y][this._stop.X].Gcost = Distance;\n\ 2087 | NodeGrid[this._start.Y][this._start.X].Fcost = Distance;\n\ 2088 | NodeGrid[this._stop.Y][this._stop.X].Fcost = Distance;\n\ 2089 | \n\ 2090 | return NodeGrid;\n\ 2091 | }\n\ 2092 | asyncWoker.prototype.pathMap = function (list) {\n\ 2093 | var Path = [];\n\ 2094 | var Node = list.Target;\n\ 2095 | var traced = false;\n\ 2096 | \n\ 2097 | while (!traced) {\n\ 2098 | var Point = { X: Node.X, Y: Node.Y };\n\ 2099 | Path.unshift(Point);\n\ 2100 | Node = Node.Parent;\n\ 2101 | if (Node.StartNode) {\n\ 2102 | traced = true;\n\ 2103 | }\n\ 2104 | }\n\ 2105 | \n\ 2106 | Path.unshift(this._start);\n\ 2107 | \n\ 2108 | return Path;\n\ 2109 | }"; 2110 | 2111 | 2112 | 2113 | Phaser.Plugin.asyncPath.worker_sortHeap = "\nasyncWoker.prototype.sortHeap = function (heap, prop) {\n\ 2114 | for (var i = 0; i < heap.Open.length; i++) {\n\ 2115 | for (var j = 0; j < heap.Open.length; j++) {\n\ 2116 | if (heap.Open[i][prop] < heap.Open[j][prop]) {\n\ 2117 | var temp = heap.Open[i];\n\ 2118 | heap.Open[i] = heap.Open[j];\n\ 2119 | heap.Open[j] = temp;\n\ 2120 | }\n\ 2121 | }\n\ 2122 | }\n\ 2123 | return heap;\n\ 2124 | }"; 2125 | 2126 | 2127 | Phaser.Plugin.asyncPath.worker_setNodesCost = "\nasyncWoker.prototype.setNodesCost = function (Node, SoroundingNodes, list, NodeGrid) {\n\ 2128 | for (var i = 0; i < SoroundingNodes.length; i++) {\n\ 2129 | var tempHcost = this[this.Algorithm](SoroundingNodes[i], NodeGrid[this._stop.Y][this._stop.X]);\n\ 2130 | var tempFcost = SoroundingNodes[i].Gcost + tempHcost;\n\ 2131 | SoroundingNodes[i].Hcost = tempHcost;\n\ 2132 | SoroundingNodes[i].Fcost = tempFcost;\n\ 2133 | if (SoroundingNodes[i].Parent === null || SoroundingNodes[i].Parent.Gcost > Node.Gcost) {\n\ 2134 | SoroundingNodes[i].Parent = Node;\n\ 2135 | list.Open.push(SoroundingNodes[i]);\n\ 2136 | }\n\ 2137 | }\n\ 2138 | return list;\n\ 2139 | }"; 2140 | 2141 | 2142 | Phaser.Plugin.asyncPath.worker_algorithm = "\nasyncWoker.prototype.Manhattan = function (Node1, Node2) {\n\ 2143 | var H, X, Y;\n\ 2144 | X = Math.abs(Node1.X - Node2.X);\n\ 2145 | Y = Math.abs(Node1.Y - Node2.Y);\n\ 2146 | H = X + Y;\n\ 2147 | return H;\n\ 2148 | }\n\ 2149 | \n asyncWoker.prototype.Euclidean = function (Node1, Node2) {\n\ 2150 | var Distance, X, Y;\n\ 2151 | X = Node1.X - Node2.X;\n\ 2152 | Y = Node1.Y - Node2.Y;\n\ 2153 | Distance = Math.floor(Math.sqrt((X * X) + (Y * Y)));\n\ 2154 | return Distance;\n\ 2155 | }\n\ 2156 | \n asyncWoker.prototype.tick = function () {\n\ 2157 | var _this = this;\n\ 2158 | setInterval(function(){\n\ 2159 | _this.pathresolveQueue();\n\ 2160 | });\n\ 2161 | }\n\ 2162 | self.onmessage = function (block){\n\ 2163 | if(block.data.init){\n\ 2164 | asyncWoker.worker = new asyncWoker(block.data)\n\ 2165 | asyncWoker.worker.tick();\n\ 2166 | self.postMessage({state:true, uid:block.data.id, isfree:true})\n\ 2167 | }\n\ 2168 | else{\n\ 2169 | asyncWoker.worker.updateQueue(block.data)\n\ 2170 | }\n\ 2171 | \n\ 2172 | }\n\ 2173 | asyncWoker.prototype.updateQueue = function (block){\n\ 2174 | this._Queue.push(block)\n\ 2175 | \n\ 2176 | }" 2177 | 2178 | 2179 | 2180 | Phaser.Plugin.asyncPath.worker_findpathTo = "\nasyncWoker.prototype.findpathTo = function (Origin, Destination) {\n\ 2181 | var designation = ['_start','_stop'];\n\ 2182 | var axis = ['X','Y'];\n\ 2183 | var NodeGrid;\n\ 2184 | var Path = [];\n\ 2185 | \n\ 2186 | this._start.X = Math.floor(Origin.x / this._tileWidth);\n\ 2187 | this._start.Y = Math.floor(Origin.y / this._tileHeight);\n\ 2188 | \n\ 2189 | \n\ 2190 | this._stop.X = Math.floor(Destination.x / this._tileWidth);\n\ 2191 | this._stop.Y = Math.floor(Destination.y / this._tileHeight);\n\ 2192 | \n\ 2193 | \n\ 2194 | for(var i = 0; i < 2; i++){\n\ 2195 | for(var j = 0; j < 2; j++){\n\ 2196 | if(this[designation[i]][axis[j]] < 0){\n\ 2197 | this[designation[i]][axis[j]] = 0;\n\ 2198 | }\n\ 2199 | }\n\ 2200 | }\n\ 2201 | \n\ 2202 | \n\ 2203 | NodeGrid = this.getNodeGrid();\n\ 2204 | NodeGrid = this.setTeminalNodes(NodeGrid);\n\ 2205 | Path = this.CalculatePath(NodeGrid);\n\ 2206 | \n\ 2207 | \n\ 2208 | return Path;\n\ 2209 | }"; 2210 | 2211 | 2212 | -------------------------------------------------------------------------------- /demo.js: -------------------------------------------------------------------------------- 1 | var game = new Phaser.Game(1150, 800, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update }); 2 | 3 | function preload() { 4 | game.load.tilemap('demoMapJSON', 'assets/gridChallenge.json', null, Phaser.Tilemap.TILED_JSON); 5 | game.load.image('map_TileSET', 'assets/tileset01.png'); 6 | game.load.image('car', 'assets/car.png'); 7 | } 8 | 9 | function create() { 10 | game.physics.startSystem(Phaser.Physics.ARCADE); 11 | 12 | map = game.add.tilemap('demoMapJSON'); 13 | 14 | map.addTilesetImage('tileset01', 'map_TileSET'); 15 | 16 | ground = map.createLayer('ground'); 17 | 18 | wall = map.createLayer('wall'); 19 | 20 | 21 | badTiles = [350,351,352,370,230,250,372,270,391,390, 392, 373, 374, 393]; 22 | 23 | map.setCollision(badTiles, true, 'wall', true)//collison tile list far from perfect but plugin reads them just fine 24 | 25 | ground.resizeWorld(); 26 | 27 | 28 | 29 | 30 | 31 | asyncPath = game.plugins.add(Phaser.Plugin.asyncPath); 32 | /*********creates a new Web Worker to handle path finding; 33 | If worker web worker exist then all calculations with be done on that worker 34 | 35 | asyncPath.newWorker(); 36 | **********************/ 37 | 38 | asyncPath.tileMap = map; 39 | asyncPath.useSpecific(badTiles,"wall"); 40 | //asyncPath.nonWalkableLayer = "wall"; //set all tiles on layer as non walk able 41 | 42 | 43 | cursors = game.input.keyboard.createCursorKeys(); 44 | 45 | car = game.add.sprite(40, 40, 'car'); 46 | 47 | game.physics.enable(car); 48 | 49 | car.body.collideWorldBounds = true 50 | 51 | 52 | 53 | game.camera.follow(car); 54 | 55 | game.input.onDown.add(findpath, this); 56 | 57 | 58 | } 59 | 60 | 61 | findpath = function(){ 62 | 63 | block = { 64 | Origin: car, 65 | Destination: game.input, 66 | debugpath: true, 67 | Diagonals: true, 68 | found: function (path){ 69 | 70 | }, 71 | notfound: function (){ 72 | console.log('notfound'); 73 | } 74 | } 75 | asyncPath.getPath(block) 76 | } 77 | 78 | 79 | function update() { 80 | 81 | game.physics.arcade.collide(car, wall); 82 | 83 | car.body.velocity.x = 0; 84 | car.body.velocity.y = 0; 85 | car.body.angularVelocity = 0; 86 | 87 | if (cursors.left.isDown) 88 | { 89 | car.body.angularVelocity = -100; 90 | } 91 | else if (cursors.right.isDown) 92 | { 93 | car.body.angularVelocity = 100; 94 | } 95 | 96 | if (cursors.up.isDown) 97 | { 98 | car.body.velocity.copyFrom(game.physics.arcade.velocityFromAngle(car.angle, 200)); 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | asyncPath Plugin Demo 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 |
15 | 16 | --------------------------------------------------------------------------------