UNPKG

rot-js

Version:

A roguelike toolkit in JavaScript

105 lines (83 loc) 3.7 kB
<h2>Pathfinding algorithms</h2> <p>The <code>ROT.Path</code> namespace provides utils for pathfinding: retrieving a set of coordinates represeting shortest route between two points. All pathfinding algorithms share the same usage paradigm:</p> <ol> <li>Create an <em>input callback</em>; function that returns passability info (true/false) for a given coordinates</li> <li>Instantialize the pathfinder; pass the values of <code>targetX</code>, <code>targetY</code> and <code>inputCallback</code> to the constructor <ul> <li>Fourth constructor option is a configuration object; so far, only one key is supported: <code>topology</code> (values 4/6/8, default 8). A topology of 4 allows only orthagonal movement, 8 allows diagonal movement and 6 supports hexagonal grids.</li> </ul> </li> <li>Call the <code>compute</code> method with three arguments: <code>sourceX</code>, <code>sourceY</code> and <code>outputCallback</code></li> </ol> <p>The pathfinder will periodically call your <code>outputCallback</code>; once for every cell in the path from <code>[sourceX, sourceY]</code> to <code>[targetX, targetY]</code>. If no such path exists, <code>outputCallback</code> will never be called.</p> <p><strong>NOTE:</strong> you can call the <code>compute</code> method multiple times (which is especially useful, performance-wise, when using <code>ROT.Path.Dijkstra</code>), but you must make sure that the passability information of the map never changes once the pathfinder is created.</p> <h3>Dijkstra's algorithm</h3> <p>Simplified version of <a href="http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm">Dijkstra's algorithm</a>: all edges have a length of 1.</p> <div class="example"> var w = 150, h = 80; ROT.RNG.setSeed(12345); var display = new ROT.Display({width:w, height:h, fontSize:6}); SHOW(display.getContainer()); /* generate map and store its data */ var data = {}; var map = new ROT.Map.Uniform(w, h); map.create(function(x, y, value) { data[x+","+y] = value; display.DEBUG(x, y, value); }); /* input callback informs about map structure */ var passableCallback = function(x, y) { return (data[x+","+y] === 0); } /* prepare path to given coords */ var dijkstra = new ROT.Path.Dijkstra(98, 38, passableCallback); /* compute from given coords #1 */ dijkstra.compute(8, 45, function(x, y) { display.draw(x, y, "", "", "#800"); }); /* compute from given coords #2 */ dijkstra.compute(130, 8, function(x, y) { display.draw(x, y, "", "", "#800"); }); /* highlight */ display.draw(8, 45, "", "", "#3f3"); display.draw(130, 8, "", "", "#3f3"); display.draw(98, 38, "", "", "#f33"); </div> <h3>A* algorithm</h3> <p>Simplified version of <a href="http://en.wikipedia.org/wiki/A*">A* algorithm</a>: all edges have a length of 1.</p> <div class="example"> var w = 150, h = 80; ROT.RNG.setSeed(12345); var display = new ROT.Display({width:w, height:h, fontSize:6}); SHOW(display.getContainer()); /* generate map and store its data */ var data = {}; var map = new ROT.Map.Uniform(w, h); map.create(function(x, y, value) { data[x+","+y] = value; display.DEBUG(x, y, value); }); /* input callback informs about map structure */ var passableCallback = function(x, y) { return (data[x+","+y] === 0); } /* prepare path to given coords */ var astar = new ROT.Path.AStar(98, 38, passableCallback); /* compute from given coords #1 */ astar.compute(8, 45, function(x, y) { display.draw(x, y, "", "", "#800"); }); /* compute from given coords #2 */ astar.compute(130, 8, function(x, y) { display.draw(x, y, "", "", "#800"); }); /* highlight */ display.draw(8, 45, "", "", "#3f3"); display.draw(130, 8, "", "", "#3f3"); display.draw(98, 38, "", "", "#f33"); </div>