Path finder
How do I make an path finder?
How do a character get from one point to another in a tile based game ?. What is a path finder? How do you make a path finder? This script and codes were developed by Kevin Giguere on 30 November 2022, Wednesday.
Path finder - Script Codes HTML Codes
<!DOCTYPE html>
<html >
<head> <meta charset="UTF-8"> <title>Path finder</title> <link rel='stylesheet prefetch' href='css/lrpqxy.css'> <link rel="stylesheet" href="css/style.css">
</head>
<body> <div class="controls"> <label for="">Interval <select name="interval" id="interval"> <option value="1">1</option> <option value="10">10</option> <option value="50" selected>50</option> <option value="100">100</option> <option value="200">200</option> </select> </label> <a class="find bt">Find Path</a> <div class="legend"> <h3>Legend</h3> <dl> <dt><div class="tile floor"></div></dt> <dd>Floor</dd> <dt><div class="tile wall"></dt> <dd>Wall</dd> <dt><div class="tile start"></dt> <dd>Starting point</dd> <dt><div class="tile end"></dt> <dd>End point</dd> <dt><div class="tile path"></dt> <dd>Path</dd> <dt><div class="tile taped"></dt> <dd>Processed tile</dd> <dt><div class="tile best"></dt> <dd>Last Processed tile</dd> </dl> </div>
</div>
<div class="links"> <a href="https://codepen.io/kevthunder/pen/EPELJr" class="next" target="_top"> <span class="collection">Game Development Experiments</span> <span class="number">pt 2</span> : <span class="title">Room/Level Generator</span> </a>
</div> <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-alpha1/jquery.min.js'></script>
<script src='js/lrpqxy.js'></script> <script src="js/index.js"></script>
</body>
</html>
Path finder - Script Codes CSS Codes
body { background: #000; color: #666; font-family: Verdana, Geneva, sans-serif;
}
.tile { position: absolute; background: #333; width: 19px; height: 19px;
}
.tile.wall { background: #222;
}
.tile.floor { background: #444;
}
.tile.taped { background: #663;
}
.tile.path { background: #363;
}
.tile.best { background: #633;
}
.tile.start { background: #044;
}
.tile.end { background: #006;
}
.walker { position: absolute; background: #999; width: 3px; height: 3px; margin-top: -1px; margin-left: -1px;
}
.controls { position: absolute; padding: 10px; right: 0px;
}
.controls .bt { display: inline-block; padding: 5px; border: 1px solid #333; cursor: pointer;
}
.controls label { display: block; margin-bottom: 0.5em;
}
.legend dl dt { margin-top: 1px; clear: both; float: left;
}
.legend dl dt .tile { position: relative;
}
.legend dl dd { float: left; margin-left: 1em;
}
Path finder - Script Codes JS Codes
(function() { var $, PathFinder, Step, Tile, TileContainer, findPath, interval, path, reset, tiles, walkInterval, walkPath, walker; $ = jQuery; Tile = (function() { function Tile(x1, y1, type) { this.x = x1; this.y = y1; this.type = type != null ? type : 'floor'; this.draw(); } Tile.prototype.draw = function() { var newDiv; newDiv = document.createElement("div"); return this.display = jQuery(newDiv).addClass('tile').addClass(this.type).appendTo('body').css({ top: this.y * 20, left: this.x * 20 }); }; Tile.prototype.getConnected = function() { var connected, t; connected = []; if (t = tiles.getTile(this.x + 1, this.y)) { connected.push(t); } if (t = tiles.getTile(this.x - 1, this.y)) { connected.push(t); } if (t = tiles.getTile(this.x, this.y + 1)) { connected.push(t); } if (t = tiles.getTile(this.x, this.y - 1)) { connected.push(t); } return connected; }; Tile.prototype.getWalkable = function() { return this.type === 'floor'; }; return Tile; })(); Tile.createFromData = function(data) { var tile; return tile = new Tile(data.x, data.y, data.type); }; PathFinder = (function() { function PathFinder(tilesContainer, from1, to1) { this.tilesContainer = tilesContainer; this.from = from1; this.to = to1; this.reset(); } PathFinder.prototype.reset = function() { this.queue = []; this.paths = {}; this.solution = null; return this.started = false; }; PathFinder.prototype.calcul = function() { while (!this.solution && (!this.started || this.queue.length)) { this.step(); } return this.getPath(); }; PathFinder.prototype.step = function() { var next; if (this.queue.length) { next = this.queue.pop(); this.addNextSteps(next); return true; } else if (!this.started) { this.started = true; this.addNextSteps(); return true; } }; PathFinder.prototype.getPath = function() { var res, step; if (this.solution) { res = [this.solution]; step = this.solution; while (step.prev != null) { res.unshift(step.prev); step = step.prev; } return res; } }; PathFinder.prototype.getPosAtTime = function(time) { var prc, step; if (this.solution) { if (time >= this.solution.getTotalLength()) { return this.solution.getExit(); } else { step = this.solution; while (step.getStartLength() > time && (step.prev != null)) { step = step.prev; } prc = (time - step.getStartLength()) / step.getLength(); return { x: step.getEntry().x + (step.getExit().x - step.getEntry().x) * prc, y: step.getEntry().y + (step.getExit().y - step.getEntry().y) * prc }; } } }; PathFinder.prototype.tileIsValid = function(tile) { return tile.getWalkable(); }; PathFinder.prototype.addNextSteps = function(step) { var j, len, next, ref1, results, tile; if (step == null) { step = null; } tile = step != null ? step.nextTile : this.from; ref1 = tile.getConnected(); results = []; for (j = 0, len = ref1.length; j < len; j++) { next = ref1[j]; if (this.tileIsValid(next)) { results.push(this.addStep(new Step(this, (step != null ? step : null), tile, next))); } else { results.push(void 0); } } return results; }; PathFinder.prototype.addStep = function(step) { if (this.paths[step.getExit().x] == null) { this.paths[step.getExit().x] = {}; } if (!((this.paths[step.getExit().x][step.getExit().y] != null) && this.paths[step.getExit().x][step.getExit().y].getTotalLength() <= step.getTotalLength())) { if (this.paths[step.getExit().x][step.getExit().y] != null) { this.removeStep(this.paths[step.getExit().x][step.getExit().y]); } this.paths[step.getExit().x][step.getExit().y] = step; this.queue.splice(this.getStepRank(step), 0, step); if (step.nextTile === this.to && !((this.solution != null) && this.solution.prev.getTotalLength() <= step.getTotalLength())) { return this.solution = new Step(this, step, this.to, null); } } }; PathFinder.prototype.removeStep = function(step) { var index; index = this.queue.indexOf(step); if (index > -1) { return this.queue.splice(index, 1); } }; PathFinder.prototype.best = function() { return this.queue[this.queue.length - 1]; }; PathFinder.prototype.getStepRank = function(step) { if (this.queue.length === 0) { return 0; } else { return this._getStepRank(step.getEfficiency(), 0, this.queue.length - 1); } }; PathFinder.prototype._getStepRank = function(efficiency, min, max) { var ref, refPos; refPos = Math.floor((max - min) / 2) + min; ref = this.queue[refPos].getEfficiency(); if (ref === efficiency) { return refPos; } else if (ref > efficiency) { if (refPos === min) { return min; } else { return this._getStepRank(efficiency, min, refPos - 1); } } else { if (refPos === max) { return max + 1; } else { return this._getStepRank(efficiency, refPos + 1, max); } } }; return PathFinder; })(); Step = (function() { function Step(pathFinder, prev, tile1, nextTile) { var ref1; this.pathFinder = pathFinder; this.prev = prev; this.tile = tile1; this.nextTile = nextTile; if (((ref1 = this.nextTile) != null ? ref1.display : void 0) != null) { this.nextTile.display.addClass('taped'); } } Step.prototype.getExit = function() { if (this.exit == null) { if (this.nextTile != null) { this.exit = { x: (this.tile.x + this.nextTile.x + 1) / 2, y: (this.tile.y + this.nextTile.y + 1) / 2 }; } else { this.exit = { x: this.tile.x + 0.5, y: this.tile.y + 0.5 }; } } return this.exit; }; Step.prototype.getEntry = function() { if (this.entry == null) { if (this.prev != null) { this.entry = { x: (this.tile.x + this.prev.tile.x + 1) / 2, y: (this.tile.y + this.prev.tile.y + 1) / 2 }; } else { this.entry = { x: this.tile.x + 0.5, y: this.tile.y + 0.5 }; } } return this.entry; }; Step.prototype.getLength = function() { if (this.length == null) { this.length = (this.nextTile == null) || (this.prev == null) ? 0.5 : this.prev.tile.x === this.nextTile.x || this.prev.tile.y === this.nextTile.y ? 1 : Math.sqrt(0.5); } return this.length; }; Step.prototype.getStartLength = function() { if (this.startLength == null) { this.startLength = this.prev != null ? this.prev.getTotalLength() : 0; } return this.startLength; }; Step.prototype.getTotalLength = function() { if (this.totalLength == null) { this.totalLength = this.getStartLength() + this.getLength(); } return this.totalLength; }; Step.prototype.getEfficiency = function() { if (this.efficiency == null) { this.efficiency = -this.getRemaining() * 1.1 - this.getTotalLength(); } return this.efficiency; }; Step.prototype.getRemaining = function() { var from, to, x, y; if (this.remaining == null) { from = this.getExit(); to = { x: this.pathFinder.to.x + 0.5, y: this.pathFinder.to.y + 0.5 }; x = to.x - from.x; y = to.y - from.y; this.remaining = Math.sqrt(x * x + y * y); } return this.remaining; }; return Step; })(); TileContainer = (function() { function TileContainer() { this.coords = {}; this.tiles = []; } TileContainer.prototype.addTile = function(tile) { this.tiles.push(tile); if (this.coords[tile.x] == null) { this.coords[tile.x] = {}; } return this.coords[tile.x][tile.y] = tile; }; TileContainer.prototype.getTile = function(x, y) { var ref1; if (((ref1 = this.coords[x]) != null ? ref1[y] : void 0) != null) { return this.coords[x][y]; } }; TileContainer.prototype.loadMatrix = function(matrix) { var data, letter, results, row, types, x, y; types = { w: 'wall', f: 'floor' }; results = []; for (y in matrix) { row = matrix[y]; results.push((function() { var results1; results1 = []; for (x in row) { letter = row[x]; data = { x: parseInt(x), y: parseInt(y), type: types[letter] }; results1.push(this.addTile(Tile.createFromData(data))); } return results1; }).call(this)); } return results; }; TileContainer.prototype.allTiles = function() { return this.tiles.slice(); }; TileContainer.prototype.clearAll = function() { var j, len, ref1, tile; ref1 = this.tiles; for (j = 0, len = ref1.length; j < len; j++) { tile = ref1[j]; tile.remove(); } this.coords = {}; return this.tiles = []; }; return TileContainer; })(); this.tiles = tiles = new TileContainer(); interval = null; findPath = function() { var best, i; reset(); path.reset(); clearInterval(interval); clearInterval(walkInterval); i = 0; best = null; return interval = setInterval((function(_this) { return function() { var j, len, ref1, step, working; i++; if (best != null) { best.nextTile.display.removeClass('best'); } working = path.step(); best = path.best(); if (best != null) { best.nextTile.display.addClass('best'); } if (i > 100 || !working || (path.solution != null)) { clearInterval(interval); ref1 = path.getPath(); for (j = 0, len = ref1.length; j < len; j++) { step = ref1[j]; step.tile.display.addClass('path'); } return walkPath(); } }; })(this), $('#interval').val()); }; walker = null; walkInterval = null; walkPath = function() { var i, length; if (path.solution != null) { if (walker == null) { walker = jQuery(document.createElement("div")).addClass('walker').appendTo('body'); } clearInterval(walkInterval); i = 0; length = path.solution.getTotalLength() * 20; return walkInterval = setInterval((function(_this) { return function() { var pos; pos = path.getPosAtTime(i / 20); i++; walker.css({ top: pos.y * 20, left: pos.x * 20 }); if (i > length) { return clearInterval(walkInterval); } }; })(this), 30); } }; reset = function() { return tiles.allTiles().forEach(function(tile) { return tile.display.removeClass('path').removeClass('taped').removeClass('best'); }); }; tiles.loadMatrix([["w", "w", "w", "w", "w", "w", "w", "w", "w", "w", "w", "w", "w", "w", "w", "w", "w", "w"], ["w", "f", "f", "w", "f", "f", "f", "f", "f", "f", "f", "f", "f", "f", "f", "f", "f", "w"], ["w", "f", "f", "w", "f", "w", "w", "w", "w", "w", "w", "w", "f", "f", "f", "f", "f", "w"], ["w", "f", "f", "w", "f", "f", "f", "f", "f", "f", "f", "w", "f", "f", "f", "f", "f", "w"], ["w", "f", "w", "w", "w", "w", "w", "w", "w", "f", "f", "w", "f", "f", "f", "f", "f", "w"], ["w", "f", "w", "f", "f", "f", "w", "f", "f", "f", "f", "w", "f", "f", "f", "f", "f", "w"], ["w", "f", "w", "f", "w", "f", "w", "f", "f", "f", "f", "w", "f", "f", "f", "f", "f", "w"], ["w", "f", "w", "f", "w", "f", "w", "f", "f", "f", "f", "w", "f", "f", "f", "f", "f", "w"], ["w", "f", "f", "f", "w", "f", "f", "f", "f", "f", "w", "w", "f", "f", "f", "f", "f", "w"], ["w", "f", "w", "f", "w", "f", "w", "f", "f", "f", "w", "f", "f", "f", "f", "f", "f", "w"], ["w", "f", "w", "f", "f", "f", "w", "f", "f", "f", "w", "f", "f", "f", "f", "f", "f", "w"], ["w", "w", "w", "w", "w", "w", "w", "w", "w", "w", "w", "w", "w", "w", "w", "w", "w", "w"]]); this.path = path = new PathFinder(tiles, tiles.getTile(2, 2), tiles.getTile(16, 4)); path.from.display.addClass('start'); path.to.display.addClass('end'); $('.controls .find').click(function() { return findPath(); });
}).call(this);
Developer | Kevin Giguere |
Username | kevthunder |
Uploaded | November 30, 2022 |
Rating | 3.5 |
Size | 8,661 Kb |
Views | 16,192 |
Find the perfect freelance services for your business! Fiverr's mission is to change how the world works together. Fiverr connects businesses with freelancers offering digital services in 500+ categories. Find Developer!
Name | Size |
Wiring | 14,292 Kb |
Keyboard capture | 6,779 Kb |
Acronym Generator | 1,197 Kb |
Room Generator | 8,247 Kb |
Story | 14,309 Kb |
DamagePropagation | 10,559 Kb |
Brawl | 12,068 Kb |
Fog of war | 9,808 Kb |
Pen-Navigation | 3,063 Kb |
Targeting | 12,056 Kb |
Jasper is the AI Content Generator that helps you and your team break through creative blocks to create amazing, original content 10X faster. Discover all the ways the Jasper AI Content Platform can help streamline your creative workflows. Start For Free!
Name | Username | Size |
Button fills | Zubfatal | 5,205 Kb |
Force Counter | Kenlauguico | 2,732 Kb |
Social buttons | Flacu | 2,022 Kb |
Prism | Pyrografix | 2,843 Kb |
Break Out | AzazelN28 | 12,431 Kb |
Board Site | IndianaLuft | 10,542 Kb |
Mandelbrot Fractal | _Billy_Brown | 2,706 Kb |
Magnus 3 | ARocketfish | 7,944 Kb |
Virtual vinyl | Davidpanik | 3,474 Kb |
My Starter Kit For Codepen | Dkdesign | 2,012 Kb |
Surf anonymously, prevent hackers from acquiring your IP address, send anonymous email, and encrypt your Internet connection. High speed, ultra secure, and easy to use. Instant setup. Hide Your IP Now!