Created
May 6, 2024 00:36
-
-
Save MSGhero/3b20f71b0522231872a5c1696245399b to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// parseTileLevel at the beginning | |
// genPath kinda often | |
// orient frequently | |
function parseTileLevel() { | |
// put this in a more central place? | |
// parse tile level into graph | |
graph = new Graph(); | |
final lvl = CharVars.get().tileLevel; | |
final openSet = [for (s in lvl) false]; | |
final candidates = []; | |
function addCandidate(index:Int, from:Int, weight:Float = 1.0) { | |
if (from > -1) { | |
graph.add({ | |
from : from, | |
to : index, | |
weight : weight | |
}); | |
} | |
if (!openSet[index]) { | |
openSet[index] = true; | |
candidates.push(index); | |
} | |
} | |
function open(index:Int) { | |
// left | |
if ( | |
lvl.getRowOf(index) < lvl.rows - 1 | |
&& lvl.getColOf(index) > 0 | |
&& lvl.get1(index - 1) == 0 | |
&& lvl.get1(index - 1 + lvl.cols) != 0 | |
) addCandidate(index - 1, index); | |
// right | |
if ( | |
lvl.getRowOf(index) < lvl.rows - 1 | |
&& lvl.getColOf(index) < lvl.cols - 1 | |
&& lvl.get1(index + 1) == 0 | |
&& lvl.get1(index + 1 + lvl.cols) != 0 | |
) addCandidate(index + 1, index); | |
// up jump | |
if ( | |
lvl.getRowOf(index) >= 2 | |
&& lvl.get1(index - lvl.cols) == 1 | |
&& lvl.get1(index - lvl.cols * 2) == 0 | |
) addCandidate(index - lvl.cols * 2, index, 2.5); | |
// down drop | |
if ( | |
lvl.getRowOf(index) < lvl.rows - 2 | |
&& lvl.get1(index + lvl.cols) == 1 | |
&& lvl.get1(index + lvl.cols * 2) == 0 // could have longer drops too | |
&& lvl.get1(index + lvl.cols * 3) != 0 | |
) addCandidate(index + lvl.cols * 2, index, 1.5); | |
} | |
addCandidate(lvl.getIndexOf(1, 1), -1); | |
while (candidates.length > 0) { | |
open(candidates.shift()); | |
} | |
} | |
function genPath() { | |
if (!(state == RUN || state == STAND)) return; | |
var player = CharVars.get().players[0]; | |
// if seymour spans two tiles, path from both and choose the shorter? | |
// a bit wasteful but not too bad | |
// round down to the nearest potential platform tile | |
// needs more thought I think | |
// account for phantom tiles on the sides? | |
final ptx = Std.int(player.body.x / 32); | |
final pty = Std.int(player.body.y / 32 / 2) * 2 + 1; | |
final stxLeft = Std.int((proto.body.x - tileOffset) / 32); | |
final stxRight = Std.int((proto.body.x + tileOffset) / 32); | |
final sty = Std.int(proto.body.y / 32 / 2) * 2 + 1; | |
final lvl = CharVars.get().tileLevel; | |
final granularPathLeft = AStar.findPath(lvl.getIndexOf(sty, stxLeft), lvl.getIndexOf(pty, ptx), graph, manhattan); | |
final granularPathRight = AStar.findPath(lvl.getIndexOf(sty, stxRight), lvl.getIndexOf(pty, ptx), graph, manhattan); | |
final granularPath = granularPathLeft == null ? granularPathRight : granularPathRight == null ? granularPathLeft : granularPathLeft.length < granularPathRight.length ? granularPathLeft : granularPathRight; | |
path = []; | |
if (granularPath?.length <= 0) return; | |
var skipping = false, offByOne = false; | |
for (i in 1...granularPath.length) { | |
// ignore nodes horizontally right next to the previous one | |
offByOne = Math.abs(granularPath[i] - granularPath[i - 1]) == 1; | |
if (skipping && !offByOne) { | |
path.push(granularPath[i - 1]); | |
path.push(granularPath[i]); | |
} | |
else if (!offByOne) { | |
path.push(granularPath[i]); | |
} | |
skipping = offByOne; | |
} | |
path.push(granularPath[granularPath.length - 1]); | |
} | |
function manhattan(a:Int, b:Int) { | |
final lvl = CharVars.get().tileLevel; | |
return Math.abs(lvl.getRowOf(a) - lvl.getRowOf(b)) + Math.abs(lvl.getColOf(a) - lvl.getColOf(b)); | |
} | |
function orient() { | |
// re-orient | |
if (!(state == RUN || state == STAND)) return; | |
if (path == null || path.length == 0) { | |
/* | |
if (throwReady) { | |
onTransition(THROW); // mb more logic here | |
} | |
else | |
*/ | |
return; | |
} | |
final y = Std.int(proto.body.y / 32 / 2) * 2 * 32 + 32; | |
final currX = proto.body.x; // scroll offset... | |
final lvl = CharVars.get().tileLevel; | |
var targetX = lvl.getColOf(path[0]) * 32 + tileOffset; | |
var targetY = lvl.getRowOf(path[0]) * 32; | |
if (throwReady && y == targetY && Math.abs(currX - CharVars.get().players[0].body.x) < throwRadius) { | |
onTransition(THROW); // or so | |
return; | |
} | |
while (y == targetY && Math.abs(targetX - currX) < 4) { | |
proto.body.x = targetX; | |
proto.body.vx = 0; | |
path.shift(); | |
if (path.length == 0) return; | |
targetX = lvl.getColOf(path[0]) * 32; | |
targetY = lvl.getRowOf(path[0]) * 32; | |
} | |
if (Math.abs(targetX - currX) >= 4) { | |
// left/right | |
dirLeft = targetX < currX; | |
onTransition(RUN); | |
} | |
else if (targetY != y) { | |
// up/down | |
onTransition(targetY < y ? JUMP : DROP); | |
path.shift(); | |
} | |
else { | |
// | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Along with Amit Patel's blog https://www.redblobgames.com/pathfinding/a-star/introduction.html