diff --git a/bin/easystar-0.3.0.min.js b/bin/easystar-0.3.0.min.js deleted file mode 100644 index 8251739..0000000 --- a/bin/easystar-0.3.0.min.js +++ /dev/null @@ -1 +0,0 @@ -var EasyStar=function(t){function n(o){if(e[o])return e[o].exports;var i=e[o]={exports:{},id:o,loaded:!1};return t[o].call(i.exports,i,i.exports,n),i.loaded=!0,i.exports}var e={};return n.m=t,n.c=e,n.p="",n(0)}([function(t,n,e){var o={},i=e(1),r=e(2),s=e(3);const a=0,u=1;t.exports=o,o.js=function(){var t,n,e,o=1,c=1.4,l=!1,h={},p={},f={},d=!0,y=[],v=Number.MAX_VALUE,g=!1;this.setAcceptableTiles=function(t){t instanceof Array?e=t:!isNaN(parseFloat(t))&&isFinite(t)&&(e=[t])},this.enableSync=function(){l=!0},this.disableSync=function(){l=!1},this.enableDiagonals=function(){g=!0},this.disableDiagonals=function(){g=!1},this.setGrid=function(n){t=n;for(var e=0;en||0>r||0>a||0>u||n>t[0].length-1||r>t.length-1||a>t[0].length-1||u>t.length-1)throw new Error("Your start or end point is outside the scope of your grid.");if(n===a&&r===u)return void h([]);for(var p=t[u][a],f=!1,d=0;dn;n++){if(0===y.length)return;if(l&&(n=0),0!==y[0].openList.size()){var i=y[0].openList.pop();if(y[0].endX===i.x&&y[0].endY===i.y){y[0].isDoneCalculating=!0;var r=[];r.push({x:i.x,y:i.y});for(var s=i.parent;null!=s;)r.push({x:s.x,y:s.y}),s=s.parent;r.reverse();var u=y[0],h=r;return void u.callback(h)}var p=[];i.list=a,i.y>0&&p.push({instance:y[0],searchNode:i,x:0,y:-1,cost:o*m(i.x,i.y-1)}),i.x0&&p.push({instance:y[0],searchNode:i,x:-1,y:0,cost:o*m(i.x-1,i.y)}),g&&(i.x>0&&i.y>0&&(d||b(t,e,i.x,i.y-1)&&b(t,e,i.x-1,i.y))&&p.push({instance:y[0],searchNode:i,x:-1,y:-1,cost:c*m(i.x-1,i.y-1)}),i.x0&&(d||b(t,e,i.x,i.y-1)&&b(t,e,i.x+1,i.y))&&p.push({instance:y[0],searchNode:i,x:1,y:-1,cost:c*m(i.x+1,i.y-1)}),i.x>0&&i.yi?c*i+r:c*r+i}var i=Math.abs(t-e),r=Math.abs(n-o);return i+r}}},function(t,n){t.exports=function(){this.isDoneCalculating=!0,this.pointsToAvoid={},this.startX,this.callback,this.startY,this.endX,this.endY,this.nodeHash={},this.openList}},function(t,n){t.exports=function(t,n,e,o,i){this.parent=t,this.x=n,this.y=e,this.costSoFar=o,this.simpleDistanceToTarget=i,this.bestGuessDistance=function(){return this.costSoFar+this.simpleDistanceToTarget}}},function(t,n,e){t.exports=e(4)},function(t,n,e){var o,i,r;(function(){var e,s,a,u,c,l,h,p,f,d,y,v,g,x,b;a=Math.floor,d=Math.min,s=function(t,n){return n>t?-1:t>n?1:0},f=function(t,n,e,o,i){var r;if(null==e&&(e=0),null==i&&(i=s),0>e)throw new Error("lo must be non-negative");for(null==o&&(o=t.length);o>e;)r=a((e+o)/2),i(n,t[r])<0?o=r:e=r+1;return[].splice.apply(t,[e,e-e].concat(n)),n},l=function(t,n,e){return null==e&&(e=s),t.push(n),x(t,0,t.length-1,e)},c=function(t,n){var e,o;return null==n&&(n=s),e=t.pop(),t.length?(o=t[0],t[0]=e,b(t,0,n)):o=e,o},p=function(t,n,e){var o;return null==e&&(e=s),o=t[0],t[0]=n,b(t,0,e),o},h=function(t,n,e){var o;return null==e&&(e=s),t.length&&e(t[0],n)<0&&(o=[t[0],n],n=o[0],t[0]=o[1],b(t,0,e)),n},u=function(t,n){var e,o,i,r,u,c;for(null==n&&(n=s),r=function(){c=[];for(var n=0,e=a(t.length/2);e>=0?e>n:n>e;e>=0?n++:n--)c.push(n);return c}.apply(this).reverse(),u=[],o=0,i=r.length;i>o;o++)e=r[o],u.push(b(t,e,n));return u},g=function(t,n,e){var o;return null==e&&(e=s),o=t.indexOf(n),-1!==o?(x(t,0,o,e),b(t,o,e)):void 0},y=function(t,n,e){var o,i,r,a,c;if(null==e&&(e=s),i=t.slice(0,n),!i.length)return i;for(u(i,e),c=t.slice(n),r=0,a=c.length;a>r;r++)o=c[r],h(i,o,e);return i.sort(e).reverse()},v=function(t,n,e){var o,i,r,a,l,h,p,y,v,g;if(null==e&&(e=s),10*n<=t.length){if(a=t.slice(0,n).sort(e),!a.length)return a;for(r=a[a.length-1],y=t.slice(n),l=0,p=y.length;p>l;l++)o=y[l],e(o,r)<0&&(f(a,o,0,null,e),a.pop(),r=a[a.length-1]);return a}for(u(t,e),g=[],i=h=0,v=d(n,t.length);v>=0?v>h:h>v;i=v>=0?++h:--h)g.push(c(t,e));return g},x=function(t,n,e,o){var i,r,a;for(null==o&&(o=s),i=t[e];e>n&&(a=e-1>>1,r=t[a],o(i,r)<0);)t[e]=r,e=a;return t[e]=i},b=function(t,n,e){var o,i,r,a,u;for(null==e&&(e=s),i=t.length,u=n,r=t[n],o=2*n+1;i>o;)a=o+1,i>a&&!(e(t[o],t[a])<0)&&(o=a),t[n]=t[o],n=o,o=2*n+1;return t[n]=r,x(t,u,n,e)},e=function(){function t(t){this.cmp=null!=t?t:s,this.nodes=[]}return t.push=l,t.pop=c,t.replace=p,t.pushpop=h,t.heapify=u,t.updateItem=g,t.nlargest=y,t.nsmallest=v,t.prototype.push=function(t){return l(this.nodes,t,this.cmp)},t.prototype.pop=function(){return c(this.nodes,this.cmp)},t.prototype.peek=function(){return this.nodes[0]},t.prototype.contains=function(t){return-1!==this.nodes.indexOf(t)},t.prototype.replace=function(t){return p(this.nodes,t,this.cmp)},t.prototype.pushpop=function(t){return h(this.nodes,t,this.cmp)},t.prototype.heapify=function(){return u(this.nodes,this.cmp)},t.prototype.updateItem=function(t){return g(this.nodes,t,this.cmp)},t.prototype.clear=function(){return this.nodes=[]},t.prototype.empty=function(){return 0===this.nodes.length},t.prototype.size=function(){return this.nodes.length},t.prototype.clone=function(){var n;return n=new t,n.nodes=this.nodes.slice(0),n},t.prototype.toArray=function(){return this.nodes.slice(0)},t.prototype.insert=t.prototype.push,t.prototype.top=t.prototype.peek,t.prototype.front=t.prototype.peek,t.prototype.has=t.prototype.contains,t.prototype.copy=t.prototype.clone,t}(),function(e,s){return i=[],o=s,r="function"==typeof o?o.apply(n,i):o,!(void 0!==r&&(t.exports=r))}(this,function(){return e})}).call(this)}]); \ No newline at end of file diff --git a/bin/easystar-0.3.0.js b/bin/easystar-0.3.1.js similarity index 92% rename from bin/easystar-0.3.0.js rename to bin/easystar-0.3.1.js index 1e0f601..bba7e1b 100644 --- a/bin/easystar-0.3.0.js +++ b/bin/easystar-0.3.1.js @@ -49,7 +49,7 @@ var EasyStar = * EasyStar.js * github.com/prettymuchbryce/EasyStarJS * Licensed under the MIT license. - * + * * Implementation By Bryce Neal (@prettymuchbryce) **/ @@ -71,6 +71,7 @@ var EasyStar = var collisionGrid; var costMap = {}; var pointsToCost = {}; + var directionalConditions = {}; var allowCornerCutting = true; var iterationsSoFar; var instances = []; @@ -80,8 +81,8 @@ var EasyStar = /** * Sets the collision grid that EasyStar uses. - * - * @param {Array|Number} tiles An array of numbers that represent + * + * @param {Array|Number} tiles An array of numbers that represent * which tiles in your grid should be considered * acceptable, or "walkable". **/ @@ -126,8 +127,8 @@ var EasyStar = /** * Sets the collision grid that EasyStar uses. - * - * @param {Array} grid The collision grid that this EasyStar instance will read from. + * + * @param {Array} grid The collision grid that this EasyStar instance will read from. * This should be a 2D Array of Numbers. **/ this.setGrid = function (grid) { @@ -183,11 +184,30 @@ var EasyStar = }; /** - * Sets the number of search iterations per calculation. - * A lower number provides a slower result, but more practical if you + * Sets a directional condition on a tile + * + * @param {Number} x The x value of the point. + * @param {Number} y The y value of the point. + * @param {Array.} allowedDirections A list of all the allowed directions that can access + * the tile. + **/ + this.setDirectionalCondition = function (x, y, allowedDirections) { + directionalConditions[x + '_' + y] = allowedDirections; + }; + + /** + * Remove all directional conditions + **/ + this.removeAllDirectionalConditions = function () { + directionalConditions = {}; + }; + + /** + * Sets the number of search iterations per calculation. + * A lower number provides a slower result, but more practical if you * have a large tile-map and don't want to block your thread while * finding a path. - * + * * @param {Number} iterations The number of searches to prefrom per calculate() call. **/ this.setIterationsPerCalculation = function (iterations) { @@ -195,7 +215,7 @@ var EasyStar = }; /** - * Avoid a particular point on the grid, + * Avoid a particular point on the grid, * regardless of whether or not it is an acceptable tile. * * @param {Number} x The x value of the point to avoid. @@ -238,14 +258,14 @@ var EasyStar = /** * Find a path. - * + * * @param {Number} startX The X position of the starting point. * @param {Number} startY The Y position of the starting point. * @param {Number} endX The X position of the ending point. * @param {Number} endY The Y position of the ending point. * @param {Function} callback A function that is called when your path * is found, or no path is found. - * + * **/ this.findPath = function (startX, startY, endX, endY, callback) { // Wraps the callback for sync vs async logic @@ -436,7 +456,7 @@ var EasyStar = var adjacentCoordinateX = searchNode.x + x; var adjacentCoordinateY = searchNode.y + y; - if (pointsToAvoid[adjacentCoordinateX + "_" + adjacentCoordinateY] === undefined && isTileWalkable(collisionGrid, acceptableTiles, adjacentCoordinateX, adjacentCoordinateY)) { + if (pointsToAvoid[adjacentCoordinateX + "_" + adjacentCoordinateY] === undefined && isTileWalkable(collisionGrid, acceptableTiles, adjacentCoordinateX, adjacentCoordinateY, searchNode)) { var node = coordinateToNode(instance, adjacentCoordinateX, adjacentCoordinateY, searchNode, cost); if (node.list === undefined) { @@ -451,7 +471,17 @@ var EasyStar = }; // Helpers - var isTileWalkable = function (collisionGrid, acceptableTiles, x, y) { + var isTileWalkable = function (collisionGrid, acceptableTiles, x, y, sourceNode) { + if (directionalConditions[x + "_" + y]) { + var direction = calculateDirection(sourceNode.x - x, sourceNode.y - y); + var directionIncluded = function () { + for (var i = 0; i < directionalConditions[x + "_" + y].length; i++) { + if (directionalConditions[x + "_" + y][i] === direction) return true; + } + return false; + }; + if (!directionIncluded()) return false; + } for (var i = 0; i < acceptableTiles.length; i++) { if (collisionGrid[y][x] === acceptableTiles[i]) { return true; @@ -461,6 +491,16 @@ var EasyStar = return false; }; + /** + * -1, -1 | 0, -1 | 1, -1 + * -1, 0 | SOURCE | 1, 0 + * -1, 1 | 0, 1 | 1, 1 + */ + var calculateDirection = function (diffX, diffY) { + if (diffX === 0, diffY === -1) return EasyStar.BOTTOM;else if (diffX === 1, diffY === -1) return EasyStar.BOTTOM_LEFT;else if (diffX === 1, diffY === 0) return EasyStar.LEFT;else if (diffX === 1, diffY === 1) return EasyStar.TOP_LEFT;else if (diffX === 0, diffY === 1) return EasyStar.TOP;else if (diffX === -1, diffY === 1) return EasyStar.TOP_RIGHT;else if (diffX === -1, diffY === 0) return EasyStar.RIGHT;else if (diffX === -1, diffY === -1) return EasyStar.BOTTOM_RIGHT; + throw new Error('These differences are not valid: ' + diffX + ', ' + diffY); + }; + var getTileCost = function (x, y) { return pointsToCost[x + '_' + y] || costMap[collisionGrid[y][x]]; }; @@ -499,6 +539,15 @@ var EasyStar = }; }; + EasyStar.TOP = 'TOP'; + EasyStar.TOP_RIGHT = 'TOP_RIGHT'; + EasyStar.RIGHT = 'RIGHT'; + EasyStar.BOTTOM_RIGHT = 'BOTTOM_RIGHT'; + EasyStar.BOTTOM = 'BOTTOM'; + EasyStar.BOTTOM_LEFT = 'BOTTOM_LEFT'; + EasyStar.LEFT = 'LEFT'; + EasyStar.TOP_LEFT = 'TOP_LEFT'; + /***/ }, /* 1 */ /***/ function(module, exports) { diff --git a/bin/easystar-0.3.1.min.js b/bin/easystar-0.3.1.min.js new file mode 100644 index 0000000..049c37c --- /dev/null +++ b/bin/easystar-0.3.1.min.js @@ -0,0 +1 @@ +var EasyStar=function(t){function n(o){if(e[o])return e[o].exports;var r=e[o]={exports:{},id:o,loaded:!1};return t[o].call(r.exports,r,r.exports,n),r.loaded=!0,r.exports}var e={};return n.m=t,n.c=e,n.p="",n(0)}([function(t,n,e){var o={},r=e(1),i=e(2),s=e(3);const u=0,a=1;t.exports=o,o.js=function(){var t,n,e,c=1,l=1.4,h=!1,p={},f={},d={},y={},v=!0,T=[],g=Number.MAX_VALUE,x=!1;this.setAcceptableTiles=function(t){t instanceof Array?e=t:!isNaN(parseFloat(t))&&isFinite(t)&&(e=[t])},this.enableSync=function(){h=!0},this.disableSync=function(){h=!1},this.enableDiagonals=function(){x=!0},this.disableDiagonals=function(){x=!1},this.setGrid=function(n){t=n;for(var e=0;en||0>o||0>i||0>u||n>t[0].length-1||o>t.length-1||i>t[0].length-1||u>t.length-1)throw new Error("Your start or end point is outside the scope of your grid.");if(n===i&&o===u)return void l([]);for(var p=t[u][i],f=!1,d=0;dn;n++){if(0===T.length)return;if(h&&(n=0),0!==T[0].openList.size()){var o=T[0].openList.pop();if(T[0].endX===o.x&&T[0].endY===o.y){T[0].isDoneCalculating=!0;var r=[];r.push({x:o.x,y:o.y});for(var i=o.parent;null!=i;)r.push({x:i.x,y:i.y}),i=i.parent;r.reverse();var s=T[0],a=r;return void s.callback(a)}var p=[];o.list=u,o.y>0&&p.push({instance:T[0],searchNode:o,x:0,y:-1,cost:c*m(o.x,o.y-1)}),o.x0&&p.push({instance:T[0],searchNode:o,x:-1,y:0,cost:c*m(o.x-1,o.y)}),x&&(o.x>0&&o.y>0&&(v||_(t,e,o.x,o.y-1)&&_(t,e,o.x-1,o.y))&&p.push({instance:T[0],searchNode:o,x:-1,y:-1,cost:l*m(o.x-1,o.y-1)}),o.x0&&(v||_(t,e,o.x,o.y-1)&&_(t,e,o.x+1,o.y))&&p.push({instance:T[0],searchNode:o,x:1,y:-1,cost:l*m(o.x+1,o.y-1)}),o.x>0&&o.yr?l*r+i:l*i+r}var r=Math.abs(t-e),i=Math.abs(n-o);return r+i}},o.TOP="TOP",o.TOP_RIGHT="TOP_RIGHT",o.RIGHT="RIGHT",o.BOTTOM_RIGHT="BOTTOM_RIGHT",o.BOTTOM="BOTTOM",o.BOTTOM_LEFT="BOTTOM_LEFT",o.LEFT="LEFT",o.TOP_LEFT="TOP_LEFT"},function(t,n){t.exports=function(){this.isDoneCalculating=!0,this.pointsToAvoid={},this.startX,this.callback,this.startY,this.endX,this.endY,this.nodeHash={},this.openList}},function(t,n){t.exports=function(t,n,e,o,r){this.parent=t,this.x=n,this.y=e,this.costSoFar=o,this.simpleDistanceToTarget=r,this.bestGuessDistance=function(){return this.costSoFar+this.simpleDistanceToTarget}}},function(t,n,e){t.exports=e(4)},function(t,n,e){var o,r,i;(function(){var e,s,u,a,c,l,h,p,f,d,y,v,T,g,x;u=Math.floor,d=Math.min,s=function(t,n){return n>t?-1:t>n?1:0},f=function(t,n,e,o,r){var i;if(null==e&&(e=0),null==r&&(r=s),0>e)throw new Error("lo must be non-negative");for(null==o&&(o=t.length);o>e;)i=u((e+o)/2),r(n,t[i])<0?o=i:e=i+1;return[].splice.apply(t,[e,e-e].concat(n)),n},l=function(t,n,e){return null==e&&(e=s),t.push(n),g(t,0,t.length-1,e)},c=function(t,n){var e,o;return null==n&&(n=s),e=t.pop(),t.length?(o=t[0],t[0]=e,x(t,0,n)):o=e,o},p=function(t,n,e){var o;return null==e&&(e=s),o=t[0],t[0]=n,x(t,0,e),o},h=function(t,n,e){var o;return null==e&&(e=s),t.length&&e(t[0],n)<0&&(o=[t[0],n],n=o[0],t[0]=o[1],x(t,0,e)),n},a=function(t,n){var e,o,r,i,a,c;for(null==n&&(n=s),i=function(){c=[];for(var n=0,e=u(t.length/2);e>=0?e>n:n>e;e>=0?n++:n--)c.push(n);return c}.apply(this).reverse(),a=[],o=0,r=i.length;r>o;o++)e=i[o],a.push(x(t,e,n));return a},T=function(t,n,e){var o;return null==e&&(e=s),o=t.indexOf(n),-1!==o?(g(t,0,o,e),x(t,o,e)):void 0},y=function(t,n,e){var o,r,i,u,c;if(null==e&&(e=s),r=t.slice(0,n),!r.length)return r;for(a(r,e),c=t.slice(n),i=0,u=c.length;u>i;i++)o=c[i],h(r,o,e);return r.sort(e).reverse()},v=function(t,n,e){var o,r,i,u,l,h,p,y,v,T;if(null==e&&(e=s),10*n<=t.length){if(u=t.slice(0,n).sort(e),!u.length)return u;for(i=u[u.length-1],y=t.slice(n),l=0,p=y.length;p>l;l++)o=y[l],e(o,i)<0&&(f(u,o,0,null,e),u.pop(),i=u[u.length-1]);return u}for(a(t,e),T=[],r=h=0,v=d(n,t.length);v>=0?v>h:h>v;r=v>=0?++h:--h)T.push(c(t,e));return T},g=function(t,n,e,o){var r,i,u;for(null==o&&(o=s),r=t[e];e>n&&(u=e-1>>1,i=t[u],o(r,i)<0);)t[e]=i,e=u;return t[e]=r},x=function(t,n,e){var o,r,i,u,a;for(null==e&&(e=s),r=t.length,a=n,i=t[n],o=2*n+1;r>o;)u=o+1,r>u&&!(e(t[o],t[u])<0)&&(o=u),t[n]=t[o],n=o,o=2*n+1;return t[n]=i,g(t,a,n,e)},e=function(){function t(t){this.cmp=null!=t?t:s,this.nodes=[]}return t.push=l,t.pop=c,t.replace=p,t.pushpop=h,t.heapify=a,t.updateItem=T,t.nlargest=y,t.nsmallest=v,t.prototype.push=function(t){return l(this.nodes,t,this.cmp)},t.prototype.pop=function(){return c(this.nodes,this.cmp)},t.prototype.peek=function(){return this.nodes[0]},t.prototype.contains=function(t){return-1!==this.nodes.indexOf(t)},t.prototype.replace=function(t){return p(this.nodes,t,this.cmp)},t.prototype.pushpop=function(t){return h(this.nodes,t,this.cmp)},t.prototype.heapify=function(){return a(this.nodes,this.cmp)},t.prototype.updateItem=function(t){return T(this.nodes,t,this.cmp)},t.prototype.clear=function(){return this.nodes=[]},t.prototype.empty=function(){return 0===this.nodes.length},t.prototype.size=function(){return this.nodes.length},t.prototype.clone=function(){var n;return n=new t,n.nodes=this.nodes.slice(0),n},t.prototype.toArray=function(){return this.nodes.slice(0)},t.prototype.insert=t.prototype.push,t.prototype.top=t.prototype.peek,t.prototype.front=t.prototype.peek,t.prototype.has=t.prototype.contains,t.prototype.copy=t.prototype.clone,t}(),function(e,s){return r=[],o=s,i="function"==typeof o?o.apply(n,r):o,!(void 0!==i&&(t.exports=i))}(this,function(){return e})}).call(this)}]); \ No newline at end of file diff --git a/bower.json b/bower.json index 7c53922..20c8335 100644 --- a/bower.json +++ b/bower.json @@ -1,9 +1,9 @@ { "name": "easystarjs", - "version": "0.3.0", + "version": "0.3.1", "homepage": "https://github.com/prettymuchbryce/easystarjs", "description": "Asynchronous A* Pathfinding API", - "main": "./bin/easystar-0.3.0.min.js", + "main": "./bin/easystar-0.3.1.min.js", "keywords": [ "A*", "pathfinding", diff --git a/karma.conf.js b/karma.conf.js index 388059b..5cb943c 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -20,7 +20,7 @@ module.exports = function(config) { // list of files / patterns to load in the browser files: [ - './bin/easystar-0.3.0.js', + './bin/easystar-0.3.1.js', './test/easystartest.js' ], diff --git a/package.json b/package.json index 40c4999..7b8ebdf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "easystarjs", - "version": "0.3.0", + "version": "0.3.1", "main": "./src/easystar.js", "typings": "./index.d.ts", "description": "Asynchronous A* Pathfinding API",