Path finder

Developer
Size
8,661 Kb
Views
16,192

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 Previews

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);
Path finder - Script Codes
Path finder - Script Codes
Home Page Home
Developer Kevin Giguere
Username kevthunder
Uploaded November 30, 2022
Rating 3.5
Size 8,661 Kb
Views 16,192
Do you need developer help for Path finder?

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!

Kevin Giguere (kevthunder) Script Codes
Name
Wiring
Keyboard capture
Acronym Generator
Room Generator
Story
DamagePropagation
Brawl
Fog of war
Pen-Navigation
Targeting
Create amazing marketing copy with AI!

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!