laya.pathfinding.js 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037
  1. (function(window,document,Laya){
  2. var __un=Laya.un,__uns=Laya.uns,__static=Laya.static,__class=Laya.class,__getset=Laya.getset,__newvec=Laya.__newvec;
  3. /**
  4. *...
  5. *@author dongketao
  6. */
  7. //class PathFinding.core.DiagonalMovement
  8. var DiagonalMovement=(function(){
  9. function DiagonalMovement(){}
  10. __class(DiagonalMovement,'PathFinding.core.DiagonalMovement');
  11. DiagonalMovement.Always=1;
  12. DiagonalMovement.Never=2;
  13. DiagonalMovement.IfAtMostOneObstacle=3;
  14. DiagonalMovement.OnlyWhenNoObstacles=4;
  15. return DiagonalMovement;
  16. })()
  17. /**
  18. *...
  19. *@author dongketao
  20. */
  21. //class PathFinding.core.Grid
  22. var Grid=(function(){
  23. function Grid(width_or_matrix,height,matrix){
  24. this.width=0;
  25. this.height=0;
  26. this.nodes=null;
  27. var width=0;
  28. if ((typeof width_or_matrix=='number')){
  29. width=width_or_matrix;
  30. }
  31. else{
  32. height=width_or_matrix.length;
  33. width=width_or_matrix[0].length;
  34. matrix=width_or_matrix;
  35. }
  36. this.width=width;
  37. this.height=height;
  38. this.nodes=this._buildNodes(width,height,matrix);
  39. }
  40. __class(Grid,'PathFinding.core.Grid');
  41. var __proto=Grid.prototype;
  42. /**
  43. *Build and return the nodes.
  44. *@private
  45. *@param {number}width
  46. *@param {number}height
  47. *@param {Array<Array<number|boolean>>}[matrix]-A 0-1 matrix representing
  48. *the walkable status of the nodes.
  49. *@see Grid
  50. */
  51. __proto._buildNodes=function(width,height,matrix){
  52. var i=0,j=0,nodes=[];
  53. for (i=0;i < height;++i){
  54. nodes[i]=[];
  55. for (j=0;j < width;++j){
  56. nodes[i][j]=new Node$1(j,i);
  57. }
  58. }
  59. if (matrix==null){
  60. return nodes;
  61. }
  62. if (matrix.length !=height || matrix[0].length !=width){
  63. throw new Error('Matrix size does not fit');
  64. }
  65. for (i=0;i < height;++i){
  66. for (j=0;j < width;++j){
  67. if (matrix[i][j]){
  68. nodes[i][j].walkable=false;
  69. }
  70. }
  71. }
  72. return nodes;
  73. }
  74. __proto.getNodeAt=function(x,y){
  75. return this.nodes[y][x];
  76. }
  77. /**
  78. *Determine whether the node at the given position is walkable.
  79. *(Also returns false if the position is outside the grid.)
  80. *@param {number}x-The x coordinate of the node.
  81. *@param {number}y-The y coordinate of the node.
  82. *@return {boolean}-The walkability of the node.
  83. */
  84. __proto.isWalkableAt=function(x,y){
  85. return this.isInside(x,y)&& this.nodes[y][x].walkable;
  86. }
  87. /**
  88. *Determine whether the position is inside the grid.
  89. *XXX:`grid.isInside(x,y)` is wierd to read.
  90. *It should be `(x,y)is inside grid`,but I failed to find a better
  91. *name for this method.
  92. *@param {number}x
  93. *@param {number}y
  94. *@return {boolean}
  95. */
  96. __proto.isInside=function(x,y){
  97. return (x >=0 && x < this.width)&& (y >=0 && y < this.height);
  98. }
  99. /**
  100. *Set whether the node on the given position is walkable.
  101. *NOTE:throws exception if the coordinate is not inside the grid.
  102. *@param {number}x-The x coordinate of the node.
  103. *@param {number}y-The y coordinate of the node.
  104. *@param {boolean}walkable-Whether the position is walkable.
  105. */
  106. __proto.setWalkableAt=function(x,y,walkable){
  107. this.nodes[y][x].walkable=walkable;
  108. }
  109. /**
  110. *Get the neighbors of the given node.
  111. *
  112. *offsets diagonalOffsets:
  113. *+---+---+---++---+---+---+
  114. *| | 0 | | | 0 | | 1 |
  115. *+---+---+---++---+---+---+
  116. *| 3 | | 1 | | | | |
  117. *+---+---+---++---+---+---+
  118. *| | 2 | | | 3 | | 2 |
  119. *+---+---+---++---+---+---+
  120. *
  121. *When allowDiagonal is true,if offsets[i] is valid,then
  122. *diagonalOffsets[i] and
  123. *diagonalOffsets[(i+1)% 4] is valid.
  124. *@param {Node}node
  125. *@param {diagonalMovement}diagonalMovement
  126. */
  127. __proto.getNeighbors=function(node,diagonalMovement){
  128. var x=node.x,y=node.y,neighbors=[],s0=false,d0=false,s1=false,d1=false,s2=false,d2=false,s3=false,d3=false,nodes=this.nodes;
  129. if (this.isWalkableAt(x,y-1)){
  130. neighbors.push(nodes[y-1][x]);
  131. s0=true;
  132. }
  133. if (this.isWalkableAt(x+1,y)){
  134. neighbors.push(nodes[y][x+1]);
  135. s1=true;
  136. }
  137. if (this.isWalkableAt(x,y+1)){
  138. neighbors.push(nodes[y+1][x]);
  139. s2=true;
  140. }
  141. if (this.isWalkableAt(x-1,y)){
  142. neighbors.push(nodes[y][x-1]);
  143. s3=true;
  144. }
  145. if (diagonalMovement==DiagonalMovement.Never){
  146. return neighbors;
  147. }
  148. if (diagonalMovement==DiagonalMovement.OnlyWhenNoObstacles){
  149. d0=s3 && s0;
  150. d1=s0 && s1;
  151. d2=s1 && s2;
  152. d3=s2 && s3;
  153. }
  154. else if (diagonalMovement==DiagonalMovement.IfAtMostOneObstacle){
  155. d0=s3 || s0;
  156. d1=s0 || s1;
  157. d2=s1 || s2;
  158. d3=s2 || s3;
  159. }
  160. else if (diagonalMovement==DiagonalMovement.Always){
  161. d0=true;
  162. d1=true;
  163. d2=true;
  164. d3=true;
  165. }
  166. else{
  167. throw new Error('Incorrect value of diagonalMovement');
  168. }
  169. if (d0 && this.isWalkableAt(x-1,y-1)){
  170. neighbors.push(nodes[y-1][x-1]);
  171. }
  172. if (d1 && this.isWalkableAt(x+1,y-1)){
  173. neighbors.push(nodes[y-1][x+1]);
  174. }
  175. if (d2 && this.isWalkableAt(x+1,y+1)){
  176. neighbors.push(nodes[y+1][x+1]);
  177. }
  178. if (d3 && this.isWalkableAt(x-1,y+1)){
  179. neighbors.push(nodes[y+1][x-1]);
  180. }
  181. return neighbors;
  182. }
  183. /**
  184. *Get a clone of this grid.
  185. *@return {Grid}Cloned grid.
  186. */
  187. __proto.clone=function(){
  188. var i=0,j=0,
  189. width=this.width,height=this.height,thisNodes=this.nodes,
  190. newGrid=new Grid(width,height),newNodes=[];
  191. for (i=0;i < height;++i){
  192. newNodes[i]=[];
  193. for (j=0;j < width;++j){
  194. newNodes[i][j]=new Node$1(j,i,thisNodes[i][j].walkable);
  195. }
  196. }
  197. newGrid.nodes=newNodes;
  198. return newGrid;
  199. }
  200. __proto.reset=function(){
  201. var _node;
  202. for (var i=0;i < this.height;++i){
  203. for (var j=0;j < this.width;++j){
  204. _node=this.nodes[i][j];
  205. _node.g=0;
  206. _node.f=0;
  207. _node.h=0;
  208. _node.by=0;
  209. _node.parent=null;
  210. _node.opened=null;
  211. _node.closed=null;
  212. _node.tested=null;
  213. }
  214. }
  215. }
  216. Grid.createGridFromAStarMap=function(texture){
  217. var textureWidth=texture.width;
  218. var textureHeight=texture.height;
  219. var pixelsInfo=texture.getPixels();
  220. var aStarArr=[];
  221. var index=0;
  222. for (var w=0;w < textureWidth;w++){
  223. var colaStarArr=aStarArr[w]=[];
  224. for (var h=0;h < textureHeight;h++){
  225. var r=pixelsInfo[index++];
  226. var g=pixelsInfo[index++];
  227. var b=pixelsInfo[index++];
  228. var a=pixelsInfo[index++];
  229. if (r==255 && g==255 && b==255 && a==255)
  230. colaStarArr[h]=1;
  231. else {
  232. colaStarArr[h]=0;
  233. }
  234. }
  235. };
  236. var gird=new Grid(textureWidth,textureHeight,aStarArr);
  237. return gird;
  238. }
  239. return Grid;
  240. })()
  241. /**
  242. *...
  243. *@author dongketao
  244. */
  245. //class PathFinding.core.Heuristic
  246. var Heuristic=(function(){
  247. function Heuristic(){}
  248. __class(Heuristic,'PathFinding.core.Heuristic');
  249. Heuristic.manhattan=function(dx,dy){
  250. return dx+dy;
  251. }
  252. Heuristic.euclidean=function(dx,dy){
  253. return Math.sqrt(dx *dx+dy *dy);
  254. }
  255. Heuristic.octile=function(dx,dy){
  256. var F=Math.SQRT2-1;
  257. return (dx < dy)? F *dx+dy :F *dy+dx;
  258. }
  259. Heuristic.chebyshev=function(dx,dy){
  260. return Math.max(dx,dy);
  261. }
  262. return Heuristic;
  263. })()
  264. /**
  265. *...
  266. *@author dongketao
  267. */
  268. //class PathFinding.core.Node
  269. var Node$1=(function(){
  270. function Node(x,y,walkable){
  271. this.x=0;
  272. this.y=0;
  273. this.g=0;
  274. this.f=0;
  275. this.h=0;
  276. this.by=0;
  277. this.parent=null;
  278. this.opened=null;
  279. this.closed=null;
  280. this.tested=null;
  281. this.retainCount=null;
  282. this.walkable=false;
  283. (walkable===void 0)&& (walkable=true);
  284. this.x=x;
  285. this.y=y;
  286. this.walkable=walkable;
  287. }
  288. __class(Node,'PathFinding.core.Node',null,'Node$1');
  289. return Node;
  290. })()
  291. /**
  292. *...
  293. *@author dongketao
  294. */
  295. //class PathFinding.core.Util
  296. var Util=(function(){
  297. function Util(){}
  298. __class(Util,'PathFinding.core.Util');
  299. Util.backtrace=function(node){
  300. var path=[[node.x,node.y]];
  301. while (node.parent){
  302. node=node.parent;
  303. path.push([node.x,node.y]);
  304. }
  305. return path.reverse();
  306. }
  307. Util.biBacktrace=function(nodeA,nodeB){
  308. var pathA=Util.backtrace(nodeA),pathB=Util.backtrace(nodeB);
  309. return pathA.concat(pathB.reverse());
  310. }
  311. Util.pathLength=function(path){
  312. var i=0,sum=0,a=0,b=0,dx=0,dy=0;
  313. for (i=1;i < path.length;++i){
  314. a=path[i-1];
  315. b=path[i];
  316. dx=a[0]-b[0];
  317. dy=a[1]-b[1];
  318. sum+=Math.sqrt(dx *dx+dy *dy);
  319. }
  320. return sum;
  321. }
  322. Util.interpolate=function(x0,y0,x1,y1){
  323. var abs=Math.abs,line=[],sx=0,sy=0,dx=0,dy=0,err=0,e2=0;
  324. dx=abs(x1-x0);
  325. dy=abs(y1-y0);
  326. sx=(x0 < x1)? 1 :-1;
  327. sy=(y0 < y1)? 1 :-1;
  328. err=dx-dy;
  329. while (true){
  330. line.push([x0,y0]);
  331. if (x0==x1 && y0==y1){
  332. break ;
  333. }
  334. e2=2 *err;
  335. if (e2 >-dy){
  336. err=err-dy;
  337. x0=x0+sx;
  338. }
  339. if (e2 < dx){
  340. err=err+dx;
  341. y0=y0+sy;
  342. }
  343. }
  344. return line;
  345. }
  346. Util.expandPath=function(path){
  347. var expanded=[],len=path.length,coord0,coord1,interpolated,interpolatedLen=0,i=0,j=0;
  348. if (len < 2){
  349. return expanded;
  350. }
  351. for (i=0;i < len-1;++i){
  352. coord0=path[i];
  353. coord1=path[i+1];
  354. interpolated=Util.interpolate(coord0[0],coord0[1],coord1[0],coord1[1]);
  355. interpolatedLen=interpolated.length;
  356. for (j=0;j < interpolatedLen-1;++j){
  357. expanded.push(interpolated[j]);
  358. }
  359. }
  360. expanded.push(path[len-1]);
  361. return expanded;
  362. }
  363. Util.smoothenPath=function(grid,path){
  364. var len=path.length,x0=path[0][0],
  365. y0=path[0][1],
  366. x1=path[len-1][0],
  367. y1=path[len-1][1],
  368. sx=0,sy=0,
  369. ex=0,ey=0,
  370. newPath,i=0,j=0,coord,line,testCoord,blocked=false,lastValidCoord;
  371. sx=x0;
  372. sy=y0;
  373. newPath=[[sx,sy]];
  374. for (i=2;i < len;++i){
  375. coord=path[i];
  376. ex=coord[0];
  377. ey=coord[1];
  378. line=Util.interpolate(sx,sy,ex,ey);
  379. blocked=false;
  380. for (j=1;j < line.length;++j){
  381. testCoord=line[j];
  382. if (!grid.isWalkableAt(testCoord[0],testCoord[1])){
  383. blocked=true;
  384. break ;
  385. }
  386. }
  387. if (blocked){
  388. lastValidCoord=path[i-1];
  389. newPath.push(lastValidCoord);
  390. sx=lastValidCoord[0];
  391. sy=lastValidCoord[1];
  392. }
  393. }
  394. newPath.push([x1,y1]);
  395. return newPath;
  396. }
  397. Util.compressPath=function(path){
  398. if (path.length < 3){
  399. return path;
  400. };
  401. var compressed=[],sx=path[0][0],
  402. sy=path[0][1],
  403. px=path[1][0],
  404. py=path[1][1],
  405. dx=px-sx,
  406. dy=py-sy,
  407. lx=0,ly=0,ldx=0,ldy=0,sq=NaN,i=0;
  408. sq=Math.sqrt(dx *dx+dy *dy);
  409. dx /=sq;
  410. dy /=sq;
  411. compressed.push([sx,sy]);
  412. for (i=2;i < path.length;i++){
  413. lx=px;
  414. ly=py;
  415. ldx=dx;
  416. ldy=dy;
  417. px=path[i][0];
  418. py=path[i][1];
  419. dx=px-lx;
  420. dy=py-ly;
  421. sq=Math.sqrt(dx *dx+dy *dy);
  422. dx /=sq;
  423. dy /=sq;
  424. if (dx!==ldx || dy!==ldy){
  425. compressed.push([lx,ly]);
  426. }
  427. }
  428. compressed.push([px,py]);
  429. return compressed;
  430. }
  431. return Util;
  432. })()
  433. /**
  434. *...
  435. *@author dongketao
  436. */
  437. //class PathFinding.finders.AStarFinder
  438. var AStarFinder=(function(){
  439. function AStarFinder(opt){
  440. this.allowDiagonal=false;
  441. this.dontCrossCorners=false;
  442. this.heuristic=null;
  443. this.weight=0;
  444. this.diagonalMovement=0;
  445. opt=opt || {};
  446. this.allowDiagonal=opt.allowDiagonal;
  447. this.dontCrossCorners=opt.dontCrossCorners;
  448. this.heuristic=opt.heuristic || Heuristic.manhattan;
  449. this.weight=opt.weight || 1;
  450. this.diagonalMovement=opt.diagonalMovement;
  451. if (!this.diagonalMovement){
  452. if (!this.allowDiagonal){
  453. this.diagonalMovement=DiagonalMovement.Never;
  454. }
  455. else{
  456. if (this.dontCrossCorners){
  457. this.diagonalMovement=DiagonalMovement.OnlyWhenNoObstacles;
  458. }
  459. else{
  460. this.diagonalMovement=DiagonalMovement.IfAtMostOneObstacle;
  461. }
  462. }
  463. }
  464. if (this.diagonalMovement===DiagonalMovement.Never){
  465. this.heuristic=opt.heuristic || Heuristic.manhattan;
  466. }
  467. else{
  468. this.heuristic=opt.heuristic || Heuristic.octile;
  469. }
  470. }
  471. __class(AStarFinder,'PathFinding.finders.AStarFinder');
  472. var __proto=AStarFinder.prototype;
  473. /**
  474. *Find and return the the path.
  475. *@return {Array<Array<number>>}The path,including both start and
  476. *end positions.
  477. */
  478. __proto.findPath=function(startX,startY,endX,endY,grid){
  479. var openList=new Heap(function(nodeA,nodeB){
  480. return nodeA.f-nodeB.f;
  481. }),startNode=grid.getNodeAt(startX,startY),endNode=grid.getNodeAt(endX,endY),heuristic=this.heuristic,diagonalMovement=this.diagonalMovement,weight=this.weight,abs=Math.abs,SQRT2=Math.SQRT2,node,neighbors,neighbor,i=0,l=0,x=0,y=0,ng=0;
  482. startNode.g=0;
  483. startNode.f=0;
  484. openList.push(startNode);
  485. startNode.opened=true;
  486. while (!openList.empty()){
  487. node=openList.pop();
  488. node.closed=true;
  489. if (node===endNode){
  490. return Util.backtrace(endNode);
  491. }
  492. neighbors=grid.getNeighbors(node,diagonalMovement);
  493. for (i=0,l=neighbors.length;i < l;++i){
  494. neighbor=neighbors[i];
  495. if (neighbor.closed){
  496. continue ;
  497. }
  498. x=neighbor.x;
  499. y=neighbor.y;
  500. ng=node.g+((x-node.x===0 || y-node.y===0)? 1 :SQRT2);
  501. if (!neighbor.opened || ng < neighbor.g){
  502. neighbor.g=ng;
  503. neighbor.h=neighbor.h || weight *heuristic(abs(x-endX),abs(y-endY));
  504. neighbor.f=neighbor.g+neighbor.h;
  505. neighbor.parent=node;
  506. if (!neighbor.opened){
  507. openList.push(neighbor);
  508. neighbor.opened=true;
  509. }
  510. else{
  511. openList.updateItem(neighbor);
  512. }
  513. }
  514. }
  515. }
  516. return [];
  517. }
  518. return AStarFinder;
  519. })()
  520. /**
  521. *...
  522. *@author ...
  523. */
  524. //class PathFinding.finders.BiAStarFinder
  525. var BiAStarFinder=(function(){
  526. function BiAStarFinder(opt){
  527. this.allowDiagonal=false;
  528. this.dontCrossCorners=false;
  529. this.diagonalMovement=0;
  530. this.heuristic=null;
  531. this.weight=0;
  532. opt=opt || {};
  533. this.allowDiagonal=opt.allowDiagonal;
  534. this.dontCrossCorners=opt.dontCrossCorners;
  535. this.diagonalMovement=opt.diagonalMovement;
  536. this.heuristic=opt.heuristic || Heuristic.manhattan;
  537. this.weight=opt.weight || 1;
  538. if (!this.diagonalMovement){
  539. if (!this.allowDiagonal){
  540. this.diagonalMovement=DiagonalMovement.Never;
  541. }
  542. else{
  543. if (this.dontCrossCorners){
  544. this.diagonalMovement=DiagonalMovement.OnlyWhenNoObstacles;
  545. }
  546. else{
  547. this.diagonalMovement=DiagonalMovement.IfAtMostOneObstacle;
  548. }
  549. }
  550. }
  551. if (this.diagonalMovement==DiagonalMovement.Never){
  552. this.heuristic=opt.heuristic || Heuristic.manhattan;
  553. }
  554. else{
  555. this.heuristic=opt.heuristic || Heuristic.octile;
  556. }
  557. }
  558. __class(BiAStarFinder,'PathFinding.finders.BiAStarFinder');
  559. var __proto=BiAStarFinder.prototype;
  560. /**
  561. *Find and return the the path.
  562. *@return {Array<Array<number>>}The path,including both start and
  563. *end positions.
  564. */
  565. __proto.findPath=function(startX,startY,endX,endY,grid){
  566. var cmp=function (nodeA,nodeB){
  567. return nodeA.f-nodeB.f;
  568. };
  569. var startOpenList=new Heap(cmp),endOpenList=new Heap(cmp),startNode=grid.getNodeAt(startX,startY),endNode=grid.getNodeAt(endX,endY),heuristic=this.heuristic,diagonalMovement=this.diagonalMovement,weight=this.weight,abs=Math.abs,SQRT2=Math.SQRT2,node,neighbors,neighbor,i=0,l=0,x=0,y=0,ng=0,BY_START=1,BY_END=2;
  570. startNode.g=0;
  571. startNode.f=0;
  572. startOpenList.push(startNode);
  573. startNode.opened=BY_START;
  574. endNode.g=0;
  575. endNode.f=0;
  576. endOpenList.push(endNode);
  577. endNode.opened=BY_END;
  578. while (!startOpenList.empty()&& !endOpenList.empty()){
  579. node=startOpenList.pop();
  580. node.closed=true;
  581. neighbors=grid.getNeighbors(node,diagonalMovement);
  582. for (i=0,l=neighbors.length;i < l;++i){
  583. neighbor=neighbors[i];
  584. if (neighbor.closed){
  585. continue ;
  586. }
  587. if (neighbor.opened===BY_END){
  588. return Util.biBacktrace(node,neighbor);
  589. }
  590. x=neighbor.x;
  591. y=neighbor.y;
  592. ng=node.g+((x-node.x===0 || y-node.y===0)? 1 :SQRT2);
  593. if (!neighbor.opened || ng < neighbor.g){
  594. neighbor.g=ng;
  595. neighbor.h=neighbor.h || weight *heuristic(abs(x-endX),abs(y-endY));
  596. neighbor.f=neighbor.g+neighbor.h;
  597. neighbor.parent=node;
  598. if (!neighbor.opened){
  599. startOpenList.push(neighbor);
  600. neighbor.opened=BY_START;
  601. }
  602. else{
  603. startOpenList.updateItem(neighbor);
  604. }
  605. }
  606. }
  607. node=endOpenList.pop();
  608. node.closed=true;
  609. neighbors=grid.getNeighbors(node,diagonalMovement);
  610. for (i=0,l=neighbors.length;i < l;++i){
  611. neighbor=neighbors[i];
  612. if (neighbor.closed){
  613. continue ;
  614. }
  615. if (neighbor.opened===BY_START){
  616. return Util.biBacktrace(neighbor,node);
  617. }
  618. x=neighbor.x;
  619. y=neighbor.y;
  620. ng=node.g+((x-node.x===0 || y-node.y===0)? 1 :SQRT2);
  621. if (!neighbor.opened || ng < neighbor.g){
  622. neighbor.g=ng;
  623. neighbor.h=neighbor.h || weight *heuristic(abs(x-startX),abs(y-startY));
  624. neighbor.f=neighbor.g+neighbor.h;
  625. neighbor.parent=node;
  626. if (!neighbor.opened){
  627. endOpenList.push(neighbor);
  628. neighbor.opened=BY_END;
  629. }
  630. else{
  631. endOpenList.updateItem(neighbor);
  632. }
  633. }
  634. }
  635. }
  636. return [];
  637. }
  638. return BiAStarFinder;
  639. })()
  640. /**
  641. *...
  642. *@author dongketao
  643. */
  644. //class PathFinding.finders.BiBreadthFirstFinder
  645. var BiBreadthFirstFinder=(function(){
  646. function BiBreadthFirstFinder(opt){
  647. this.allowDiagonal=false;
  648. this.dontCrossCorners=false;
  649. this.heuristic=null;
  650. this.weight=0;
  651. this.diagonalMovement=0;
  652. opt=opt || {};
  653. this.allowDiagonal=opt.allowDiagonal;
  654. this.dontCrossCorners=opt.dontCrossCorners;
  655. this.diagonalMovement=opt.diagonalMovement;
  656. if (!this.diagonalMovement){
  657. if (!this.allowDiagonal){
  658. this.diagonalMovement=DiagonalMovement.Never;
  659. }
  660. else{
  661. if (this.dontCrossCorners){
  662. this.diagonalMovement=DiagonalMovement.OnlyWhenNoObstacles;
  663. }
  664. else{
  665. this.diagonalMovement=DiagonalMovement.IfAtMostOneObstacle;
  666. }
  667. }
  668. }
  669. }
  670. __class(BiBreadthFirstFinder,'PathFinding.finders.BiBreadthFirstFinder');
  671. var __proto=BiBreadthFirstFinder.prototype;
  672. /**
  673. *Find and return the the path.
  674. *@return {Array<Array<number>>}The path,including both start and
  675. *end positions.
  676. */
  677. __proto.findPath=function(startX,startY,endX,endY,grid){
  678. var startNode=grid.getNodeAt(startX,startY),endNode=grid.getNodeAt(endX,endY),startOpenList=[],endOpenList=[],neighbors,neighbor,node,diagonalMovement=this.diagonalMovement,BY_START=0,BY_END=1,i=0,l=0;
  679. startOpenList.push(startNode);
  680. startNode.opened=true;
  681. startNode.by=BY_START;
  682. endOpenList.push(endNode);
  683. endNode.opened=true;
  684. endNode.by=BY_END;
  685. while (startOpenList.length && endOpenList.length){
  686. node=startOpenList.shift();
  687. node.closed=true;
  688. neighbors=grid.getNeighbors(node,diagonalMovement);
  689. for (i=0,l=neighbors.length;i < l;++i){
  690. neighbor=neighbors[i];
  691. if (neighbor.closed){
  692. continue ;
  693. }
  694. if (neighbor.opened){
  695. if (neighbor.by===BY_END){
  696. return Util.biBacktrace(node,neighbor);
  697. }
  698. continue ;
  699. }
  700. startOpenList.push(neighbor);
  701. neighbor.parent=node;
  702. neighbor.opened=true;
  703. neighbor.by=BY_START;
  704. }
  705. node=endOpenList.shift();
  706. node.closed=true;
  707. neighbors=grid.getNeighbors(node,diagonalMovement);
  708. for (i=0,l=neighbors.length;i < l;++i){
  709. neighbor=neighbors[i];
  710. if (neighbor.closed){
  711. continue ;
  712. }
  713. if (neighbor.opened){
  714. if (neighbor.by===BY_START){
  715. return Util.biBacktrace(neighbor,node);
  716. }
  717. continue ;
  718. }
  719. endOpenList.push(neighbor);
  720. neighbor.parent=node;
  721. neighbor.opened=true;
  722. neighbor.by=BY_END;
  723. }
  724. }
  725. return [];
  726. }
  727. return BiBreadthFirstFinder;
  728. })()
  729. /**
  730. *...
  731. *@author dongketao
  732. */
  733. //class PathFinding.finders.BreadthFirstFinder
  734. var BreadthFirstFinder=(function(){
  735. function BreadthFirstFinder(opt){
  736. this.allowDiagonal=false;
  737. this.dontCrossCorners=false;
  738. this.heuristic=null;
  739. this.weight=0;
  740. this.diagonalMovement=0;
  741. opt=opt || {};
  742. this.allowDiagonal=opt.allowDiagonal;
  743. this.dontCrossCorners=opt.dontCrossCorners;
  744. this.diagonalMovement=opt.diagonalMovement;
  745. if (!this.diagonalMovement){
  746. if (!this.allowDiagonal){
  747. this.diagonalMovement=DiagonalMovement.Never;
  748. }
  749. else{
  750. if (this.dontCrossCorners){
  751. this.diagonalMovement=DiagonalMovement.OnlyWhenNoObstacles;
  752. }
  753. else{
  754. this.diagonalMovement=DiagonalMovement.IfAtMostOneObstacle;
  755. }
  756. }
  757. }
  758. }
  759. __class(BreadthFirstFinder,'PathFinding.finders.BreadthFirstFinder');
  760. var __proto=BreadthFirstFinder.prototype;
  761. /**
  762. *Find and return the the path.
  763. *@return {Array<Array<number>>}The path,including both start and
  764. *end positions.
  765. */
  766. __proto.findPath=function(startX,startY,endX,endY,grid){
  767. var openList=[],diagonalMovement=this.diagonalMovement,startNode=grid.getNodeAt(startX,startY),endNode=grid.getNodeAt(endX,endY),neighbors,neighbor,node,i=0,l=0;
  768. openList.push(startNode);
  769. startNode.opened=true;
  770. while (openList.length){
  771. node=openList.shift();
  772. node.closed=true;
  773. if (node===endNode){
  774. return Util.backtrace(endNode);
  775. }
  776. neighbors=grid.getNeighbors(node,diagonalMovement);
  777. for (i=0,l=neighbors.length;i < l;++i){
  778. neighbor=neighbors[i];
  779. if (neighbor.closed || neighbor.opened){
  780. continue ;
  781. }
  782. openList.push(neighbor);
  783. neighbor.opened=true;
  784. neighbor.parent=node;
  785. }
  786. }
  787. return [];
  788. }
  789. return BreadthFirstFinder;
  790. })()
  791. /**
  792. *...
  793. *@author dongketao
  794. */
  795. //class PathFinding.finders.IDAStarFinder
  796. var IDAStarFinder=(function(){
  797. function IDAStarFinder(opt){
  798. this.allowDiagonal=false;
  799. this.dontCrossCorners=false;
  800. this.heuristic=null;
  801. this.weight=0;
  802. this.diagonalMovement=0;
  803. this.trackRecursion=false;
  804. this.timeLimit=NaN;
  805. opt=opt || {};
  806. this.allowDiagonal=opt.allowDiagonal;
  807. this.dontCrossCorners=opt.dontCrossCorners;
  808. this.diagonalMovement=opt.diagonalMovement;
  809. this.heuristic=opt.heuristic || Heuristic.manhattan;
  810. this.weight=opt.weight || 1;
  811. this.trackRecursion=opt.trackRecursion || false;
  812. this.timeLimit=opt.timeLimit || Infinity;
  813. if (!this.diagonalMovement){
  814. if (!this.allowDiagonal){
  815. this.diagonalMovement=DiagonalMovement.Never;
  816. }
  817. else{
  818. if (this.dontCrossCorners){
  819. this.diagonalMovement=DiagonalMovement.OnlyWhenNoObstacles;
  820. }
  821. else{
  822. this.diagonalMovement=DiagonalMovement.IfAtMostOneObstacle;
  823. }
  824. }
  825. }
  826. if (this.diagonalMovement===DiagonalMovement.Never){
  827. this.heuristic=opt.heuristic || Heuristic.manhattan;
  828. }
  829. else{
  830. this.heuristic=opt.heuristic || Heuristic.octile;
  831. }
  832. }
  833. __class(IDAStarFinder,'PathFinding.finders.IDAStarFinder');
  834. var __proto=IDAStarFinder.prototype;
  835. /**
  836. *Find and return the the path. When an empty array is returned,either
  837. *no path is possible,or the maximum execution time is reached.
  838. *
  839. *@return {Array<Array<number>>}The path,including both start and
  840. *end positions.
  841. */
  842. __proto.findPath=function(startX,startY,endX,endY,grid){
  843. var _$this=this;
  844. var nodesVisited=0;
  845. var startTime=new Date().getTime();
  846. var h=function (a,b){
  847. return _$this.heuristic(Math.abs(b.x-a.x),Math.abs(b.y-a.y));
  848. };
  849. var cost=function (a,b){
  850. return (a.x===b.x || a.y===b.y)? 1 :Math.SQRT2;
  851. };
  852. var search=function (node,g,cutoff,route,depth){
  853. nodesVisited++;
  854. if (_$this.timeLimit > 0 && new Date().getTime()-startTime > _$this.timeLimit *1000){
  855. return Infinity;
  856. };
  857. var f=g+h(node,end)*_$this.weight;
  858. if (f > cutoff){
  859. return f;
  860. }
  861. if (node==end){
  862. route[depth]=[node.x,node.y];
  863. return node;
  864. };
  865. var min=0,t=0,k=0,neighbour;
  866. var neighbours=grid.getNeighbors(node,_$this.diagonalMovement);
  867. for (k=0,min=Infinity;neighbour=neighbours[k];++k){
  868. if (_$this.trackRecursion){
  869. neighbour.retainCount=neighbour.retainCount+1 || 1;
  870. if (neighbour.tested !=true){
  871. neighbour.tested=true;
  872. }
  873. }
  874. t=search(neighbour,g+cost(node,neighbour),cutoff,route,depth+1);
  875. if ((t instanceof PathFinding.core.Node )){
  876. route[depth]=[node.x,node.y];
  877. return t;
  878. }
  879. if (_$this.trackRecursion && (--neighbour.retainCount)===0){
  880. neighbour.tested=false;
  881. }
  882. if (t < min){
  883. min=t;
  884. }
  885. }
  886. return min;
  887. };
  888. var start=grid.getNodeAt(startX,startY);
  889. var end=grid.getNodeAt(endX,endY);
  890. var cutOff=h(start,end);
  891. var j=0,route,t=0;
  892. for (j=0;true;++j){
  893. route=[];
  894. t=search(start,0,cutOff,route,0);
  895. if (t==Infinity){
  896. route=[];
  897. break ;
  898. }
  899. if ((t instanceof PathFinding.core.Node )){
  900. break ;
  901. }
  902. cutOff=t;
  903. }
  904. return route;
  905. }
  906. return IDAStarFinder;
  907. })()
  908. /**
  909. *...
  910. *@author ...
  911. */
  912. //class PathFinding.finders.JumpPointFinderBase
  913. var JumpPointFinderBase=(function(){
  914. function JumpPointFinderBase(opt){
  915. this.grid=null;
  916. this.openList=null;
  917. this.startNode=null;
  918. this.endNode=null;
  919. this.heuristic=null;
  920. this.trackJumpRecursion=false;
  921. opt=opt || {};
  922. this.heuristic=opt.heuristic || Heuristic.manhattan;
  923. this.trackJumpRecursion=opt.trackJumpRecursion || false;
  924. }
  925. __class(JumpPointFinderBase,'PathFinding.finders.JumpPointFinderBase');
  926. var __proto=JumpPointFinderBase.prototype;
  927. /**
  928. *Find and return the path.
  929. *@return {Array<Array<number>>}The path,including both start and
  930. *end positions.
  931. */
  932. __proto.findPath=function(startX,startY,endX,endY,grid){
  933. var openList=this.openList=new Heap(function(nodeA,nodeB){
  934. return nodeA.f-nodeB.f;
  935. }),startNode=this.startNode=grid.getNodeAt(startX,startY),endNode=this.endNode=grid.getNodeAt(endX,endY),node;
  936. this.grid=grid;
  937. startNode.g=0;
  938. startNode.f=0;
  939. openList.push(startNode);
  940. startNode.opened=true;
  941. while (!openList.empty()){
  942. node=openList.pop();
  943. node.closed=true;
  944. if (node==endNode){
  945. return Util.expandPath(Util.backtrace(endNode));
  946. }
  947. this._identifySuccessors(node);
  948. }
  949. return [];
  950. }
  951. /**
  952. *Identify successors for the given node. Runs a jump point search in the
  953. *direction of each available neighbor,adding any points found to the open
  954. *list.
  955. *@protected
  956. */
  957. __proto._identifySuccessors=function(node){
  958. var grid=this.grid,heuristic=this.heuristic,openList=this.openList,endX=this.endNode.x,endY=this.endNode.y,neighbors,neighbor,jumpPoint,i=0,l=0,x=node.x,y=node.y,jx=0,jy=0,dx=0,dy=0,d=0,ng=0,jumpNode,abs=Math.abs,max=Math.max;
  959. neighbors=this._findNeighbors(node);
  960. for (i=0,l=neighbors.length;i < l;++i){
  961. neighbor=neighbors[i];
  962. jumpPoint=this._jump(neighbor[0],neighbor[1],x,y);
  963. if (jumpPoint){
  964. jx=jumpPoint[0];
  965. jy=jumpPoint[1];
  966. jumpNode=grid.getNodeAt(jx,jy);
  967. if (jumpNode.closed){
  968. continue ;
  969. }
  970. d=Heuristic.octile(abs(jx-x),abs(jy-y));
  971. ng=node.g+d;
  972. if (!jumpNode.opened || ng < jumpNode.g){
  973. jumpNode.g=ng;
  974. jumpNode.h=jumpNode.h || heuristic(abs(jx-endX),abs(jy-endY));
  975. jumpNode.f=jumpNode.g+jumpNode.h;
  976. jumpNode.parent=node;
  977. if (!jumpNode.opened){
  978. openList.push(jumpNode);
  979. jumpNode.opened=true;
  980. }
  981. else{
  982. openList.updateItem(jumpNode);
  983. }
  984. }
  985. }
  986. }
  987. }
  988. __proto._jump=function(x,y,px,py){
  989. return [];
  990. }
  991. __proto._findNeighbors=function(node){
  992. return [];
  993. }
  994. return JumpPointFinderBase;
  995. })()
  996. /**
  997. *...
  998. *@author ...
  999. */
  1000. //class PathFinding.finders.JumpPointFinder
  1001. var JumpPointFinder=(function(){
  1002. /**
  1003. *Path finder using the Jump Point Search algorithm
  1004. *@param {Object}opt
  1005. *@param {function}opt.heuristic Heuristic function to estimate the distance
  1006. *(defaults to manhattan).
  1007. *@param {DiagonalMovement}opt.diagonalMovement Condition under which diagonal
  1008. *movement will be allowed.
  1009. */
  1010. function JumpPointFinder(opt){}
  1011. __class(JumpPointFinder,'PathFinding.finders.JumpPointFinder');
  1012. return JumpPointFinder;
  1013. })()
  1014. /**
  1015. *...
  1016. *@author dongketao
  1017. */
  1018. //class PathFinding.finders.TraceFinder
  1019. var TraceFinder=(function(){
  1020. function TraceFinder(opt){
  1021. this.allowDiagonal=false;
  1022. this.dontCrossCorners=false;
  1023. this.diagonalMovement=0;
  1024. this.heuristic=null;
  1025. opt=opt || {};
  1026. this.allowDiagonal=opt.allowDiagonal;
  1027. this.dontCrossCorners=opt.dontCrossCorners;
  1028. this.heuristic=opt.heuristic || Heuristic.manhattan;
  1029. this.diagonalMovement=opt.diagonalMovement;
  1030. if (!this.diagonalMovement){
  1031. if (!this.allowDiagonal){
  1032. this.diagonalMovement=DiagonalMovement.Never;
  1033. }
  1034. else{
  1035. if (this.dontCrossCorners){
  1036. this.diagonalMovement=DiagonalMovement.OnlyWhenNoObstacles;
  1037. }
  1038. else{
  1039. this.diagonalMovement=DiagonalMovement.IfAtMostOneObstacle;
  1040. }
  1041. }
  1042. }
  1043. if (this.diagonalMovement==DiagonalMovement.Never){
  1044. this.heuristic=opt.heuristic || Heuristic.manhattan;
  1045. }
  1046. else{
  1047. this.heuristic=opt.heuristic || Heuristic.octile;
  1048. }
  1049. }
  1050. __class(TraceFinder,'PathFinding.finders.TraceFinder');
  1051. var __proto=TraceFinder.prototype;
  1052. __proto.findPath=function(startX,startY,endX,endY,grid){
  1053. var openList=new Heap(function(nodeA,nodeB){
  1054. return nodeA.f-nodeB.f;
  1055. }),startNode=grid.getNodeAt(startX,startY),endNode=grid.getNodeAt(endX,endY),heuristic=this.heuristic,allowDiagonal=this.allowDiagonal,dontCrossCorners=this.dontCrossCorners,abs=Math.abs,SQRT2=Math.SQRT2,node,neighbors,neighbor,i=0,l=0,x=0,y=0,ng=0;
  1056. startNode.g=0;
  1057. startNode.f=0;
  1058. openList.push(startNode);
  1059. startNode.opened=true;
  1060. while (!openList.empty()){
  1061. node=openList.pop();
  1062. node.closed=true;
  1063. if (node===endNode){
  1064. return Util.backtrace(endNode);
  1065. }
  1066. neighbors=grid.getNeighbors(node,this.diagonalMovement);
  1067. for (i=0,l=neighbors.length;i < l;++i){
  1068. neighbor=neighbors[i];
  1069. if (neighbor.closed){
  1070. continue ;
  1071. }
  1072. x=neighbor.x;
  1073. y=neighbor.y;
  1074. ng=node.g+((x-node.x===0 || y-node.y===0)? 1 :SQRT2);
  1075. if (!neighbor.opened || ng < neighbor.g){
  1076. neighbor.g=ng *l / 9;
  1077. neighbor.h=neighbor.h || heuristic(abs(x-endX),abs(y-endY));
  1078. neighbor.f=neighbor.g+neighbor.h;
  1079. neighbor.parent=node;
  1080. if (!neighbor.opened){
  1081. openList.push(neighbor);
  1082. neighbor.opened=true;
  1083. }
  1084. else{
  1085. openList.updateItem(neighbor);
  1086. }
  1087. }
  1088. }
  1089. }
  1090. return [];
  1091. }
  1092. return TraceFinder;
  1093. })()
  1094. /**
  1095. *...
  1096. *@author dongketao
  1097. */
  1098. //class PathFinding.libs.Heap
  1099. var Heap=(function(){
  1100. function Heap(cmp){
  1101. this.cmp=null;
  1102. this.nodes=null;
  1103. this.heapFunction=new HeapFunction();
  1104. this.cmp=cmp !=null ? cmp :this.heapFunction.defaultCmp;
  1105. this.nodes=[];
  1106. }
  1107. __class(Heap,'PathFinding.libs.Heap');
  1108. var __proto=Heap.prototype;
  1109. __proto.push=function(x){
  1110. return this.heapFunction.heappush(this.nodes,x,this.cmp);
  1111. }
  1112. __proto.pop=function(){
  1113. return this.heapFunction.heappop(this.nodes,this.cmp);
  1114. }
  1115. __proto.peek=function(){
  1116. return this.nodes[0];
  1117. }
  1118. __proto.contains=function(x){
  1119. return this.nodes.indexOf(x)!==-1;
  1120. }
  1121. __proto.replace=function(x){
  1122. return this.heapFunction.heapreplace(this.nodes,x,this.cmp);
  1123. }
  1124. __proto.pushpop=function(x){
  1125. return this.heapFunction.heappushpop(this.nodes,x,this.cmp);
  1126. }
  1127. __proto.heapify=function(){
  1128. return this.heapFunction.heapify(this.nodes,this.cmp);
  1129. }
  1130. __proto.updateItem=function(x){
  1131. return this.heapFunction.updateItem(this.nodes,x,this.cmp);
  1132. }
  1133. __proto.clear=function(){
  1134. return this.nodes=[];
  1135. }
  1136. __proto.empty=function(){
  1137. return this.nodes.length===0;
  1138. }
  1139. __proto.size=function(){
  1140. return this.nodes.length;
  1141. }
  1142. __proto.clone=function(){
  1143. var heap=new Heap();
  1144. heap.nodes=this.nodes.slice(0);
  1145. return heap;
  1146. }
  1147. __proto.toArray=function(){
  1148. return this.nodes.slice(0);
  1149. }
  1150. return Heap;
  1151. })()
  1152. /**
  1153. *...
  1154. *@author dongketao
  1155. */
  1156. //class PathFinding.libs.HeapFunction
  1157. var HeapFunction=(function(){
  1158. function HeapFunction(){
  1159. //};
  1160. this.defaultCmp=function(x,y){
  1161. if (x < y){
  1162. return-1;
  1163. }
  1164. if (x > y){
  1165. return 1;
  1166. }
  1167. return 0;
  1168. }
  1169. }
  1170. __class(HeapFunction,'PathFinding.libs.HeapFunction');
  1171. var __proto=HeapFunction.prototype;
  1172. //};
  1173. __proto.insort=function(a,x,lo,hi,cmp){
  1174. var mid=NaN;
  1175. if (lo==null){
  1176. lo=0;
  1177. }
  1178. if (cmp==null){
  1179. cmp=this.defaultCmp;
  1180. }
  1181. if (lo < 0){
  1182. throw new Error('lo must be non-negative');
  1183. }
  1184. if (hi==null){
  1185. hi=a.length;
  1186. }
  1187. while (lo < hi){
  1188. mid=Math.floor((lo+hi)/ 2);
  1189. if (cmp(x,a[mid])< 0){
  1190. hi=mid;
  1191. }
  1192. else{
  1193. lo=mid+1;
  1194. }
  1195. }
  1196. return ([].splice.apply(a,[lo,lo-lo].concat(x)),x);
  1197. }
  1198. //};
  1199. __proto.heappush=function(array,item,cmp){
  1200. if (cmp==null){
  1201. cmp=this.defaultCmp;
  1202. }
  1203. array.push(item);
  1204. return this._siftdown(array,0,array.length-1,cmp);
  1205. }
  1206. //};
  1207. __proto.heappop=function(array,cmp){
  1208. var lastelt,returnitem;
  1209. if (cmp==null){
  1210. cmp=this.defaultCmp;
  1211. }
  1212. lastelt=array.pop();
  1213. if (array.length){
  1214. returnitem=array[0];
  1215. array[0]=lastelt;
  1216. this._siftup(array,0,cmp);
  1217. }
  1218. else{
  1219. returnitem=lastelt;
  1220. }
  1221. return returnitem;
  1222. }
  1223. //};
  1224. __proto.heapreplace=function(array,item,cmp){
  1225. var returnitem;
  1226. if (cmp==null){
  1227. cmp=this.defaultCmp;
  1228. }
  1229. returnitem=array[0];
  1230. array[0]=item;
  1231. this._siftup(array,0,cmp);
  1232. return returnitem;
  1233. }
  1234. //};
  1235. __proto.heappushpop=function(array,item,cmp){
  1236. var _ref;
  1237. if (cmp==null){
  1238. cmp=this.defaultCmp;
  1239. }
  1240. if (array.length && cmp(array[0],item)< 0){
  1241. _ref=[array[0],item],item=_ref[0],array[0]=_ref[1];
  1242. this._siftup(array,0,cmp);
  1243. }
  1244. return item;
  1245. }
  1246. //};
  1247. __proto.heapify=function(array,cmp){
  1248. var i=0,_i=0,_j=0,_len=0,_ref,_ref1,_results,_results1;
  1249. if (cmp==null){
  1250. cmp=this.defaultCmp;
  1251. }
  1252. _ref1=(function(){
  1253. _results1=[];
  1254. for (_j=0,_ref=Math.floor(array.length / 2);0 <=_ref ? _j < _ref :_j > _ref;0 <=_ref ? _j++:_j--){
  1255. _results1.push(_j);
  1256. }
  1257. return _results1;
  1258. }).apply(this).reverse();
  1259. _results=[];
  1260. for (_i=0,_len=_ref1.length;_i < _len;_i++){
  1261. i=_ref1[_i];
  1262. _results.push(this._siftup(array,i,cmp));
  1263. }
  1264. return _results;
  1265. }
  1266. //};
  1267. __proto.updateItem=function(array,item,cmp){
  1268. var pos=0;
  1269. if (cmp==null){
  1270. cmp=this.defaultCmp;
  1271. }
  1272. pos=array.indexOf(item);
  1273. if (pos===-1){
  1274. return null;
  1275. }
  1276. this._siftdown(array,0,pos,cmp);
  1277. return this._siftup(array,pos,cmp);
  1278. }
  1279. //};
  1280. __proto.nlargest=function(array,n,cmp){
  1281. var elem,result,_i=0,_len=0,_ref;
  1282. if (cmp==null){
  1283. cmp=this.defaultCmp;
  1284. }
  1285. result=array.slice(0,n);
  1286. if (!result.length){
  1287. return result;
  1288. }
  1289. this.heapify(result,cmp);
  1290. _ref=array.slice(n);
  1291. for (_i=0,_len=_ref.length;_i < _len;_i++){
  1292. elem=_ref[_i];
  1293. this.heappushpop(result,elem,cmp);
  1294. }
  1295. return result.sort(cmp).reverse();
  1296. }
  1297. //};
  1298. __proto.nsmallest=function(array,n,cmp){
  1299. var elem,i,los,result,_i=0,_j=0,_len,_ref,_ref1,_results;
  1300. if (cmp==null){
  1301. cmp=this.defaultCmp;
  1302. }
  1303. if (n *10 <=array.length){
  1304. result=array.slice(0,n).sort(cmp);
  1305. if (!result.length){
  1306. return result;
  1307. }
  1308. los=result[result.length-1];
  1309. _ref=array.slice(n);
  1310. for (_i=0,_len=_ref.length;_i < _len;_i++){
  1311. elem=_ref[_i];
  1312. if (cmp(elem,los)< 0){
  1313. this.insort(result,elem,0,null,cmp);
  1314. result.pop();
  1315. los=result[result.length-1];
  1316. }
  1317. }
  1318. return result;
  1319. }
  1320. this.heapify(array,cmp);
  1321. _results=[];
  1322. for (i=_j=0,_ref1=Math.min(n,array.length);0 <=_ref1 ? _j < _ref1 :_j > _ref1;i=0 <=_ref1 ?++_j :--_j){
  1323. _results.push(this.heappop(array,cmp));
  1324. }
  1325. return _results;
  1326. }
  1327. //};
  1328. __proto._siftdown=function(array,startpos,pos,cmp){
  1329. var newitem,parent,parentpos=0;
  1330. if (cmp==null){
  1331. cmp=this.defaultCmp;
  1332. }
  1333. newitem=array[pos];
  1334. while (pos > startpos){
  1335. parentpos=(pos-1)>> 1;
  1336. parent=array[parentpos];
  1337. if (cmp(newitem,parent)< 0){
  1338. array[pos]=parent;
  1339. pos=parentpos;
  1340. continue ;
  1341. }
  1342. break ;
  1343. }
  1344. return array[pos]=newitem;
  1345. }
  1346. //};
  1347. __proto._siftup=function(array,pos,cmp){
  1348. var childpos=0,endpos=0,newitem,rightpos=0,startpos=0;
  1349. if (cmp==null){
  1350. cmp=this.defaultCmp;
  1351. }
  1352. endpos=array.length;
  1353. startpos=pos;
  1354. newitem=array[pos];
  1355. childpos=2 *pos+1;
  1356. while (childpos < endpos){
  1357. rightpos=childpos+1;
  1358. if (rightpos < endpos && !(cmp(array[childpos],array[rightpos])< 0)){
  1359. childpos=rightpos;
  1360. }
  1361. array[pos]=array[childpos];
  1362. pos=childpos;
  1363. childpos=2 *pos+1;
  1364. }
  1365. array[pos]=newitem;
  1366. return this._siftdown(array,startpos,pos,cmp);
  1367. }
  1368. return HeapFunction;
  1369. })()
  1370. /**
  1371. *...
  1372. *@author ...
  1373. */
  1374. //class PathFinding.finders.BestFirstFinder extends PathFinding.finders.AStarFinder
  1375. var BestFirstFinder=(function(_super){
  1376. function BestFirstFinder(opt){
  1377. BestFirstFinder.__super.call(this,opt);
  1378. var orig=this.heuristic;
  1379. this.heuristic=function (dx,dy){
  1380. return orig(dx,dy)*1000000;
  1381. };
  1382. }
  1383. __class(BestFirstFinder,'PathFinding.finders.BestFirstFinder',_super);
  1384. return BestFirstFinder;
  1385. })(AStarFinder)
  1386. /**
  1387. *...
  1388. *@author ...
  1389. */
  1390. //class PathFinding.finders.BiBestFirstFinder extends PathFinding.finders.BiAStarFinder
  1391. var BiBestFirstFinder=(function(_super){
  1392. function BiBestFirstFinder(opt){
  1393. BiBestFirstFinder.__super.call(this,opt);
  1394. var orig=this.heuristic;
  1395. this.heuristic=function (dx,dy){
  1396. return orig(dx,dy)*1000000;
  1397. };
  1398. }
  1399. __class(BiBestFirstFinder,'PathFinding.finders.BiBestFirstFinder',_super);
  1400. return BiBestFirstFinder;
  1401. })(BiAStarFinder)
  1402. /**
  1403. *...
  1404. *@author ...
  1405. */
  1406. //class PathFinding.finders.BiDijkstraFinder extends PathFinding.finders.BiAStarFinder
  1407. var BiDijkstraFinder=(function(_super){
  1408. function BiDijkstraFinder(opt){
  1409. BiDijkstraFinder.__super.call(this,opt);
  1410. this.heuristic=function (dx,dy){
  1411. return 0;
  1412. };
  1413. }
  1414. __class(BiDijkstraFinder,'PathFinding.finders.BiDijkstraFinder',_super);
  1415. return BiDijkstraFinder;
  1416. })(BiAStarFinder)
  1417. /**
  1418. *...
  1419. *@author ...
  1420. */
  1421. //class PathFinding.finders.DijkstraFinder extends PathFinding.finders.AStarFinder
  1422. var DijkstraFinder=(function(_super){
  1423. function DijkstraFinder(opt){
  1424. DijkstraFinder.__super.call(this,opt);
  1425. this.heuristic=function (dx,dy){
  1426. return 0;
  1427. };
  1428. }
  1429. __class(DijkstraFinder,'PathFinding.finders.DijkstraFinder',_super);
  1430. return DijkstraFinder;
  1431. })(AStarFinder)
  1432. /**
  1433. *...
  1434. *@author ...
  1435. */
  1436. //class PathFinding.finders.JPFAlwaysMoveDiagonally extends PathFinding.finders.JumpPointFinderBase
  1437. var JPFAlwaysMoveDiagonally=(function(_super){
  1438. function JPFAlwaysMoveDiagonally(opt){
  1439. JPFAlwaysMoveDiagonally.__super.call(this,opt);
  1440. }
  1441. __class(JPFAlwaysMoveDiagonally,'PathFinding.finders.JPFAlwaysMoveDiagonally',_super);
  1442. var __proto=JPFAlwaysMoveDiagonally.prototype;
  1443. /**
  1444. *Search recursively in the direction (parent-> child),stopping only when a
  1445. *jump point is found.
  1446. *@protected
  1447. *@return {Array<Array<number>>}The x,y coordinate of the jump point
  1448. *found,or null if not found
  1449. */
  1450. __proto._jump=function(x,y,px,py){
  1451. var grid=this.grid,dx=x-px,dy=y-py;
  1452. if (!grid.isWalkableAt(x,y)){
  1453. return null;
  1454. }
  1455. if (this.trackJumpRecursion==true){
  1456. grid.getNodeAt(x,y).tested=true;
  1457. }
  1458. if (grid.getNodeAt(x,y)==this.endNode){
  1459. return [x,y];
  1460. }
  1461. if (dx!==0 && dy!==0){
  1462. if ((grid.isWalkableAt(x-dx,y+dy)&& !grid.isWalkableAt(x-dx,y))|| (grid.isWalkableAt(x+dx,y-dy)&& !grid.isWalkableAt(x,y-dy))){
  1463. return [x,y];
  1464. }
  1465. if (this._jump(x+dx,y,x,y)|| this._jump(x,y+dy,x,y)){
  1466. return [x,y];
  1467. }
  1468. }
  1469. else{
  1470. if (dx!==0){
  1471. if ((grid.isWalkableAt(x+dx,y+1)&& !grid.isWalkableAt(x,y+1))|| (grid.isWalkableAt(x+dx,y-1)&& !grid.isWalkableAt(x,y-1))){
  1472. return [x,y];
  1473. }
  1474. }
  1475. else{
  1476. if ((grid.isWalkableAt(x+1,y+dy)&& !grid.isWalkableAt(x+1,y))|| (grid.isWalkableAt(x-1,y+dy)&& !grid.isWalkableAt(x-1,y))){
  1477. return [x,y];
  1478. }
  1479. }
  1480. }
  1481. return this._jump(x+dx,y+dy,x,y);
  1482. }
  1483. /**
  1484. *Find the neighbors for the given node. If the node has a parent,
  1485. *prune the neighbors based on the jump point search algorithm,otherwise
  1486. *return all available neighbors.
  1487. *@return {Array<Array<number>>}The neighbors found.
  1488. */
  1489. __proto._findNeighbors=function(node){
  1490. var parent=node.parent,x=node.x,y=node.y,grid=this.grid,px=0,py=0,nx=0,ny=0,dx=0,dy=0,neighbors=[],neighborNodes,neighborNode,i=0,l=0;
  1491. if (parent){
  1492. px=parent.x;
  1493. py=parent.y;
  1494. dx=(x-px)/ Math.max(Math.abs(x-px),1);
  1495. dy=(y-py)/ Math.max(Math.abs(y-py),1);
  1496. if (dx!==0 && dy!==0){
  1497. if (grid.isWalkableAt(x,y+dy)){
  1498. neighbors.push([x,y+dy]);
  1499. }
  1500. if (grid.isWalkableAt(x+dx,y)){
  1501. neighbors.push([x+dx,y]);
  1502. }
  1503. if (grid.isWalkableAt(x+dx,y+dy)){
  1504. neighbors.push([x+dx,y+dy]);
  1505. }
  1506. if (!grid.isWalkableAt(x-dx,y)){
  1507. neighbors.push([x-dx,y+dy]);
  1508. }
  1509. if (!grid.isWalkableAt(x,y-dy)){
  1510. neighbors.push([x+dx,y-dy]);
  1511. }
  1512. }
  1513. else{
  1514. if (dx===0){
  1515. if (grid.isWalkableAt(x,y+dy)){
  1516. neighbors.push([x,y+dy]);
  1517. }
  1518. if (!grid.isWalkableAt(x+1,y)){
  1519. neighbors.push([x+1,y+dy]);
  1520. }
  1521. if (!grid.isWalkableAt(x-1,y)){
  1522. neighbors.push([x-1,y+dy]);
  1523. }
  1524. }
  1525. else{
  1526. if (grid.isWalkableAt(x+dx,y)){
  1527. neighbors.push([x+dx,y]);
  1528. }
  1529. if (!grid.isWalkableAt(x,y+1)){
  1530. neighbors.push([x+dx,y+1]);
  1531. }
  1532. if (!grid.isWalkableAt(x,y-1)){
  1533. neighbors.push([x+dx,y-1]);
  1534. }
  1535. }
  1536. }
  1537. }
  1538. else{
  1539. neighborNodes=grid.getNeighbors(node,DiagonalMovement.Always);
  1540. for (i=0,l=neighborNodes.length;i < l;++i){
  1541. neighborNode=neighborNodes[i];
  1542. neighbors.push([neighborNode.x,neighborNode.y]);
  1543. }
  1544. }
  1545. return neighbors;
  1546. }
  1547. return JPFAlwaysMoveDiagonally;
  1548. })(JumpPointFinderBase)
  1549. /**
  1550. *...
  1551. *@author ...
  1552. */
  1553. //class PathFinding.finders.JPFMoveDiagonallyIfAtMostOneObstacle extends PathFinding.finders.JumpPointFinderBase
  1554. var JPFMoveDiagonallyIfAtMostOneObstacle=(function(_super){
  1555. function JPFMoveDiagonallyIfAtMostOneObstacle(opt){
  1556. JPFMoveDiagonallyIfAtMostOneObstacle.__super.call(this,opt);
  1557. }
  1558. __class(JPFMoveDiagonallyIfAtMostOneObstacle,'PathFinding.finders.JPFMoveDiagonallyIfAtMostOneObstacle',_super);
  1559. var __proto=JPFMoveDiagonallyIfAtMostOneObstacle.prototype;
  1560. /**
  1561. *Search recursively in the direction (parent-> child),stopping only when a
  1562. *jump point is found.
  1563. *@protected
  1564. *@return {Array<Array<number>>}The x,y coordinate of the jump point
  1565. *found,or null if not found
  1566. */
  1567. __proto._jump=function(x,y,px,py){
  1568. var grid=this.grid,dx=x-px,dy=y-py;
  1569. if (!grid.isWalkableAt(x,y)){
  1570. return null;
  1571. }
  1572. if (this.trackJumpRecursion===true){
  1573. grid.getNodeAt(x,y).tested=true;
  1574. }
  1575. if (grid.getNodeAt(x,y)==this.endNode){
  1576. return [x,y];
  1577. }
  1578. if (dx!==0 && dy!==0){
  1579. if ((grid.isWalkableAt(x-dx,y+dy)&& !grid.isWalkableAt(x-dx,y))|| (grid.isWalkableAt(x+dx,y-dy)&& !grid.isWalkableAt(x,y-dy))){
  1580. return [x,y];
  1581. }
  1582. if (this._jump(x+dx,y,x,y)|| this._jump(x,y+dy,x,y)){
  1583. return [x,y];
  1584. }
  1585. }
  1586. else{
  1587. if (dx!==0){
  1588. if ((grid.isWalkableAt(x+dx,y+1)&& !grid.isWalkableAt(x,y+1))|| (grid.isWalkableAt(x+dx,y-1)&& !grid.isWalkableAt(x,y-1))){
  1589. return [x,y];
  1590. }
  1591. }
  1592. else{
  1593. if ((grid.isWalkableAt(x+1,y+dy)&& !grid.isWalkableAt(x+1,y))|| (grid.isWalkableAt(x-1,y+dy)&& !grid.isWalkableAt(x-1,y))){
  1594. return [x,y];
  1595. }
  1596. }
  1597. }
  1598. if (grid.isWalkableAt(x+dx,y)|| grid.isWalkableAt(x,y+dy)){
  1599. return this._jump(x+dx,y+dy,x,y);
  1600. }
  1601. else{
  1602. return null;
  1603. }
  1604. }
  1605. /**
  1606. *Find the neighbors for the given node. If the node has a parent,
  1607. *prune the neighbors based on the jump point search algorithm,otherwise
  1608. *return all available neighbors.
  1609. *@return {Array<Array<number>>}The neighbors found.
  1610. */
  1611. __proto._findNeighbors=function(node){
  1612. var parent=node.parent,x=node.x,y=node.y,grid=this.grid,px=0,py=0,nx=0,ny=0,dx=0,dy=0,neighbors=[],neighborNodes,neighborNode,i=0,l=0;
  1613. if (parent){
  1614. px=parent.x;
  1615. py=parent.y;
  1616. dx=(x-px)/ Math.max(Math.abs(x-px),1);
  1617. dy=(y-py)/ Math.max(Math.abs(y-py),1);
  1618. if (dx!==0 && dy!==0){
  1619. if (grid.isWalkableAt(x,y+dy)){
  1620. neighbors.push([x,y+dy]);
  1621. }
  1622. if (grid.isWalkableAt(x+dx,y)){
  1623. neighbors.push([x+dx,y]);
  1624. }
  1625. if (grid.isWalkableAt(x,y+dy)|| grid.isWalkableAt(x+dx,y)){
  1626. neighbors.push([x+dx,y+dy]);
  1627. }
  1628. if (!grid.isWalkableAt(x-dx,y)&& grid.isWalkableAt(x,y+dy)){
  1629. neighbors.push([x-dx,y+dy]);
  1630. }
  1631. if (!grid.isWalkableAt(x,y-dy)&& grid.isWalkableAt(x+dx,y)){
  1632. neighbors.push([x+dx,y-dy]);
  1633. }
  1634. }
  1635. else{
  1636. if (dx===0){
  1637. if (grid.isWalkableAt(x,y+dy)){
  1638. neighbors.push([x,y+dy]);
  1639. if (!grid.isWalkableAt(x+1,y)){
  1640. neighbors.push([x+1,y+dy]);
  1641. }
  1642. if (!grid.isWalkableAt(x-1,y)){
  1643. neighbors.push([x-1,y+dy]);
  1644. }
  1645. }
  1646. }
  1647. else{
  1648. if (grid.isWalkableAt(x+dx,y)){
  1649. neighbors.push([x+dx,y]);
  1650. if (!grid.isWalkableAt(x,y+1)){
  1651. neighbors.push([x+dx,y+1]);
  1652. }
  1653. if (!grid.isWalkableAt(x,y-1)){
  1654. neighbors.push([x+dx,y-1]);
  1655. }
  1656. }
  1657. }
  1658. }
  1659. }
  1660. else{
  1661. neighborNodes=grid.getNeighbors(node,DiagonalMovement.IfAtMostOneObstacle);
  1662. for (i=0,l=neighborNodes.length;i < l;++i){
  1663. neighborNode=neighborNodes[i];
  1664. neighbors.push([neighborNode.x,neighborNode.y]);
  1665. }
  1666. }
  1667. return neighbors;
  1668. }
  1669. return JPFMoveDiagonallyIfAtMostOneObstacle;
  1670. })(JumpPointFinderBase)
  1671. /**
  1672. *...
  1673. *@author ...
  1674. */
  1675. //class PathFinding.finders.JPFMoveDiagonallyIfNoObstacles extends PathFinding.finders.JumpPointFinderBase
  1676. var JPFMoveDiagonallyIfNoObstacles=(function(_super){
  1677. function JPFMoveDiagonallyIfNoObstacles(opt){
  1678. JPFMoveDiagonallyIfNoObstacles.__super.call(this,opt);
  1679. }
  1680. __class(JPFMoveDiagonallyIfNoObstacles,'PathFinding.finders.JPFMoveDiagonallyIfNoObstacles',_super);
  1681. var __proto=JPFMoveDiagonallyIfNoObstacles.prototype;
  1682. /**
  1683. *Search recursively in the direction (parent-> child),stopping only when a
  1684. *jump point is found.
  1685. *@protected
  1686. *@return {Array<Array<number>>}The x,y coordinate of the jump point
  1687. *found,or null if not found
  1688. */
  1689. __proto._jump=function(x,y,px,py){
  1690. var grid=this.grid,dx=x-px,dy=y-py;
  1691. if (!grid.isWalkableAt(x,y)){
  1692. return null;
  1693. }
  1694. if (this.trackJumpRecursion===true){
  1695. grid.getNodeAt(x,y).tested=true;
  1696. }
  1697. if (grid.getNodeAt(x,y)===this.endNode){
  1698. return [x,y];
  1699. }
  1700. if (dx!==0 && dy!==0){
  1701. if (this._jump(x+dx,y,x,y)|| this._jump(x,y+dy,x,y)){
  1702. return [x,y];
  1703. }
  1704. }
  1705. else{
  1706. if (dx!==0){
  1707. if ((grid.isWalkableAt(x,y-1)&& !grid.isWalkableAt(x-dx,y-1))|| (grid.isWalkableAt(x,y+1)&& !grid.isWalkableAt(x-dx,y+1))){
  1708. return [x,y];
  1709. }
  1710. }
  1711. else if (dy!==0){
  1712. if ((grid.isWalkableAt(x-1,y)&& !grid.isWalkableAt(x-1,y-dy))|| (grid.isWalkableAt(x+1,y)&& !grid.isWalkableAt(x+1,y-dy))){
  1713. return [x,y];
  1714. }
  1715. }
  1716. }
  1717. if (grid.isWalkableAt(x+dx,y)&& grid.isWalkableAt(x,y+dy)){
  1718. return this._jump(x+dx,y+dy,x,y);
  1719. }
  1720. else{
  1721. return null;
  1722. }
  1723. }
  1724. /**
  1725. *Find the neighbors for the given node. If the node has a parent,
  1726. *prune the neighbors based on the jump point search algorithm,otherwise
  1727. *return all available neighbors.
  1728. *@return {Array<Array<number>>}The neighbors found.
  1729. */
  1730. __proto._findNeighbors=function(node){
  1731. var parent=node.parent,x=node.x,y=node.y,grid=this.grid,px=0,py=0,nx=0,ny=0,dx=0,dy=0,neighbors=[],neighborNodes,neighborNode,i=0,l=0;
  1732. if (parent){
  1733. px=parent.x;
  1734. py=parent.y;
  1735. dx=(x-px)/ Math.max(Math.abs(x-px),1);
  1736. dy=(y-py)/ Math.max(Math.abs(y-py),1);
  1737. if (dx!==0 && dy!==0){
  1738. if (grid.isWalkableAt(x,y+dy)){
  1739. neighbors.push([x,y+dy]);
  1740. }
  1741. if (grid.isWalkableAt(x+dx,y)){
  1742. neighbors.push([x+dx,y]);
  1743. }
  1744. if (grid.isWalkableAt(x,y+dy)&& grid.isWalkableAt(x+dx,y)){
  1745. neighbors.push([x+dx,y+dy]);
  1746. }
  1747. }
  1748. else{
  1749. var isNextWalkable=false;
  1750. if (dx!==0){
  1751. isNextWalkable=grid.isWalkableAt(x+dx,y);
  1752. var isTopWalkable=grid.isWalkableAt(x,y+1);
  1753. var isBottomWalkable=grid.isWalkableAt(x,y-1);
  1754. if (isNextWalkable){
  1755. neighbors.push([x+dx,y]);
  1756. if (isTopWalkable){
  1757. neighbors.push([x+dx,y+1]);
  1758. }
  1759. if (isBottomWalkable){
  1760. neighbors.push([x+dx,y-1]);
  1761. }
  1762. }
  1763. if (isTopWalkable){
  1764. neighbors.push([x,y+1]);
  1765. }
  1766. if (isBottomWalkable){
  1767. neighbors.push([x,y-1]);
  1768. }
  1769. }
  1770. else if (dy!==0){
  1771. isNextWalkable=grid.isWalkableAt(x,y+dy);
  1772. var isRightWalkable=grid.isWalkableAt(x+1,y);
  1773. var isLeftWalkable=grid.isWalkableAt(x-1,y);
  1774. if (isNextWalkable){
  1775. neighbors.push([x,y+dy]);
  1776. if (isRightWalkable){
  1777. neighbors.push([x+1,y+dy]);
  1778. }
  1779. if (isLeftWalkable){
  1780. neighbors.push([x-1,y+dy]);
  1781. }
  1782. }
  1783. if (isRightWalkable){
  1784. neighbors.push([x+1,y]);
  1785. }
  1786. if (isLeftWalkable){
  1787. neighbors.push([x-1,y]);
  1788. }
  1789. }
  1790. }
  1791. }
  1792. else{
  1793. neighborNodes=grid.getNeighbors(node,DiagonalMovement.OnlyWhenNoObstacles);
  1794. for (i=0,l=neighborNodes.length;i < l;++i){
  1795. neighborNode=neighborNodes[i];
  1796. neighbors.push([neighborNode.x,neighborNode.y]);
  1797. }
  1798. }
  1799. return neighbors;
  1800. }
  1801. return JPFMoveDiagonallyIfNoObstacles;
  1802. })(JumpPointFinderBase)
  1803. /**
  1804. *...
  1805. *@author ...
  1806. */
  1807. //class PathFinding.finders.JPFNeverMoveDiagonally extends PathFinding.finders.JumpPointFinderBase
  1808. var JPFNeverMoveDiagonally=(function(_super){
  1809. function JPFNeverMoveDiagonally(opt){
  1810. JPFNeverMoveDiagonally.__super.call(this,opt);
  1811. }
  1812. __class(JPFNeverMoveDiagonally,'PathFinding.finders.JPFNeverMoveDiagonally',_super);
  1813. var __proto=JPFNeverMoveDiagonally.prototype;
  1814. /**
  1815. *Search recursively in the direction (parent-> child),stopping only when a
  1816. *jump point is found.
  1817. *@protected
  1818. *@return {Array<Array<number>>}The x,y coordinate of the jump point
  1819. *found,or null if not found
  1820. */
  1821. __proto._jump=function(x,y,px,py){
  1822. var grid=this.grid,dx=x-px,dy=y-py;
  1823. if (!grid.isWalkableAt(x,y)){
  1824. return null;
  1825. }
  1826. if (this.trackJumpRecursion===true){
  1827. grid.getNodeAt(x,y).tested=true;
  1828. }
  1829. if (grid.getNodeAt(x,y)==this.endNode){
  1830. return [x,y];
  1831. }
  1832. if (dx!==0){
  1833. if ((grid.isWalkableAt(x,y-1)&& !grid.isWalkableAt(x-dx,y-1))|| (grid.isWalkableAt(x,y+1)&& !grid.isWalkableAt(x-dx,y+1))){
  1834. return [x,y];
  1835. }
  1836. }
  1837. else if (dy!==0){
  1838. if ((grid.isWalkableAt(x-1,y)&& !grid.isWalkableAt(x-1,y-dy))|| (grid.isWalkableAt(x+1,y)&& !grid.isWalkableAt(x+1,y-dy))){
  1839. return [x,y];
  1840. }
  1841. if (this._jump(x+1,y,x,y)|| this._jump(x-1,y,x,y)){
  1842. return [x,y];
  1843. }
  1844. }
  1845. else{
  1846. throw new Error("Only horizontal and vertical movements are allowed");
  1847. }
  1848. return this._jump(x+dx,y+dy,x,y);
  1849. }
  1850. /**
  1851. *Find the neighbors for the given node. If the node has a parent,
  1852. *prune the neighbors based on the jump point search algorithm,otherwise
  1853. *return all available neighbors.
  1854. *@return {Array<Array<number>>}The neighbors found.
  1855. */
  1856. __proto._findNeighbors=function(node){
  1857. var parent=node.parent,x=node.x,y=node.y,grid=this.grid,px=0,py=0,nx=0,ny=0,dx=0,dy=0,neighbors=[],neighborNodes,neighborNode,i=0,l=0;
  1858. if (parent){
  1859. px=parent.x;
  1860. py=parent.y;
  1861. dx=(x-px)/ Math.max(Math.abs(x-px),1);
  1862. dy=(y-py)/ Math.max(Math.abs(y-py),1);
  1863. if (dx!==0){
  1864. if (grid.isWalkableAt(x,y-1)){
  1865. neighbors.push([x,y-1]);
  1866. }
  1867. if (grid.isWalkableAt(x,y+1)){
  1868. neighbors.push([x,y+1]);
  1869. }
  1870. if (grid.isWalkableAt(x+dx,y)){
  1871. neighbors.push([x+dx,y]);
  1872. }
  1873. }
  1874. else if (dy!==0){
  1875. if (grid.isWalkableAt(x-1,y)){
  1876. neighbors.push([x-1,y]);
  1877. }
  1878. if (grid.isWalkableAt(x+1,y)){
  1879. neighbors.push([x+1,y]);
  1880. }
  1881. if (grid.isWalkableAt(x,y+dy)){
  1882. neighbors.push([x,y+dy]);
  1883. }
  1884. }
  1885. }
  1886. else{
  1887. neighborNodes=grid.getNeighbors(node,DiagonalMovement.Never);
  1888. for (i=0,l=neighborNodes.length;i < l;++i){
  1889. neighborNode=neighborNodes[i];
  1890. neighbors.push([neighborNode.x,neighborNode.y]);
  1891. }
  1892. }
  1893. return neighbors;
  1894. }
  1895. return JPFNeverMoveDiagonally;
  1896. })(JumpPointFinderBase)
  1897. })(window,document,Laya);
  1898. if (typeof define === 'function' && define.amd){
  1899. define('laya.core', ['require', "exports"], function(require, exports) {
  1900. 'use strict';
  1901. Object.defineProperty(exports, '__esModule', { value: true });
  1902. for (var i in Laya) {
  1903. var o = Laya[i];
  1904. o && o.__isclass && (exports[i] = o);
  1905. }
  1906. });
  1907. }