v0.7: A* pathfinding, mouse control, step-up, jump limits

- A* pathfinding for actor (find_path in actors.rs)
- Right-click sets target (actor_goto), finds ground below air clicks
- Actor follows path with horizontal velocity + jumping
- Step-up: actor climbs 1-4px small edges/obstacles
- Jump height limited to 40px in pathfinding (avoids unreachable targets)
- Powder displacement when walking through sand/dirt
- Actor collision: solids block, powders pass-through
- Fallback: direct movement if no path found
This commit is contained in:
2026-07-10 19:01:51 +02:00
parent f5d16ffe64
commit 1d467429da
5 changed files with 204 additions and 7 deletions
+3
View File
@@ -13,6 +13,7 @@ import __wbg_init, {
actor_y,
move_actor,
update_actor,
actor_goto,
} from "../pkg/atomic_engine.js";
export const M = {
@@ -89,6 +90,7 @@ export interface Engine {
actorY: () => number;
moveActor: (dx: number, dy: number) => void;
updateActor: (dt: number) => void;
actorGoto: (x: number, y: number) => void;
memory: WebAssembly.Memory;
}
@@ -111,5 +113,6 @@ export async function createEngine(gridWidth: number, gridHeight: number): Promi
actorY: () => actor_y(),
moveActor: (dx, dy) => move_actor(dx, dy),
updateActor: (dt) => update_actor(dt),
actorGoto: (x, y) => actor_goto(x, y),
};
}
+10 -1
View File
@@ -3,6 +3,7 @@ export class Input {
mouseX = 0;
mouseY = 0;
mouseDown = false;
mouseRight = false;
wheel = 0;
constructor() {
@@ -12,11 +13,19 @@ export class Input {
this.mouseX = e.clientX;
this.mouseY = e.clientY;
});
window.addEventListener("mousedown", () => (this.mouseDown = true));
window.addEventListener("mousedown", (e) => {
if (e.button === 2) {
this.mouseRight = true;
e.preventDefault();
} else {
this.mouseDown = true;
}
});
window.addEventListener("mouseup", () => (this.mouseDown = false));
window.addEventListener("wheel", (e) => {
this.wheel += e.deltaY > 0 ? -1 : 1;
});
window.addEventListener("contextmenu", (e) => e.preventDefault());
}
isDown(key: string): boolean {
+5
View File
@@ -210,6 +210,11 @@ async function main() {
const g = screenToGrid(input.mouseX, input.mouseY);
engine.fillCircle(g.x, g.y, 6, paintMat);
}
if (input.mouseRight) {
const g = screenToGrid(input.mouseX, input.mouseY);
engine.actorGoto(g.x, g.y);
input.mouseRight = false;
}
camera.update(dt);
engine.updateRender(