v0.6: Actor system (rigidbody) replaces pixel player

- New actors.rs: Rigidbody Actor with gravity, grid collision, powder displacement
- Actor rendered as colored rectangle on pixel buffer (zoom-scaled)
- WASM API: spawn_actor, move_actor, update_actor, actor_x/y
- WASD/Arrow keys control actor, camera follows with soft lerp
- displace_powders pushes sand/dirt out of actor area
- Collision: stops at solids, walks through powders
- Updated AGENTS.md with actor documentation
This commit is contained in:
2026-07-10 16:09:58 +02:00
parent a2700df292
commit f5d16ffe64
7 changed files with 244 additions and 12 deletions
+15
View File
@@ -8,6 +8,11 @@ import __wbg_init, {
render_buffer_len,
render_width,
render_height,
spawn_actor,
actor_x,
actor_y,
move_actor,
update_actor,
} from "../pkg/atomic_engine.js";
export const M = {
@@ -79,6 +84,11 @@ export interface Engine {
renderBufferLen: () => number;
renderWidth: () => number;
renderHeight: () => number;
spawnActor: (x: number, y: number) => void;
actorX: () => number;
actorY: () => number;
moveActor: (dx: number, dy: number) => void;
updateActor: (dt: number) => void;
memory: WebAssembly.Memory;
}
@@ -96,5 +106,10 @@ export async function createEngine(gridWidth: number, gridHeight: number): Promi
renderWidth: () => render_width(),
renderHeight: () => render_height(),
memory: wasm.memory,
spawnActor: (x, y) => spawn_actor(x, y),
actorX: () => actor_x(),
actorY: () => actor_y(),
moveActor: (dx, dy) => move_actor(dx, dy),
updateActor: (dt) => update_actor(dt),
};
}
+17 -7
View File
@@ -99,9 +99,9 @@ async function main() {
}
}
// === Spawn point: center on the castle ===
engine.spawnActor(400, 550);
camera.x = 400;
camera.y = 630;
camera.y = 550;
const rw = engine.renderWidth();
const rh = engine.renderHeight();
@@ -184,11 +184,21 @@ async function main() {
);
}
const speed = 200;
if (input.isDown("KeyA") || input.isDown("ArrowLeft")) camera.x -= speed * dt;
if (input.isDown("KeyD") || input.isDown("ArrowRight")) camera.x += speed * dt;
if (input.isDown("KeyW") || input.isDown("ArrowUp")) camera.y -= speed * dt;
if (input.isDown("KeyS") || input.isDown("ArrowDown")) camera.y += speed * dt;
let mx = 0;
let my = 0;
if (input.isDown("KeyA") || input.isDown("ArrowLeft")) mx = -1;
if (input.isDown("KeyD") || input.isDown("ArrowRight")) mx = 1;
if (input.isDown("KeyW") || input.isDown("ArrowUp")) my = -1;
engine.moveActor(mx, my);
engine.updateActor(dt);
const ax = engine.actorX();
const ay = engine.actorY();
if (ax > 0 || ay > 0) {
camera.x += (ax - camera.x) * 10 * dt;
camera.y += (ay - 60 - camera.y) * 10 * dt;
}
if (input.isDown("Equal")) camera.setZoom(camera.zoom + 2 * dt);
if (input.isDown("Minus")) camera.setZoom(camera.zoom - 2 * dt);
if (input.wheel !== 0) {