Skip to content

Instantly share code, notes, and snippets.

@MSGhero
Created May 6, 2024 00:36
Show Gist options
  • Save MSGhero/3b20f71b0522231872a5c1696245399b to your computer and use it in GitHub Desktop.
Save MSGhero/3b20f71b0522231872a5c1696245399b to your computer and use it in GitHub Desktop.
// 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 {
//
}
}
@MSGhero
Copy link
Author

MSGhero commented May 6, 2024

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment