ecs refactor
This commit is contained in:
parent
28b026a614
commit
f2e5d13000
8 changed files with 410 additions and 170 deletions
6
server/components/display.ts
Normal file
6
server/components/display.ts
Normal file
|
@ -0,0 +1,6 @@
|
|||
export class CompDisplay {
|
||||
display;
|
||||
constructor(display: string) {
|
||||
this.display = display;
|
||||
}
|
||||
}
|
101
server/components/world.ts
Normal file
101
server/components/world.ts
Normal file
|
@ -0,0 +1,101 @@
|
|||
import { spiral } from "../../common/utils.ts";
|
||||
import { chunks, enumerate, log_from, Vec2 } from "../../common/utils.ts";
|
||||
import { Engine, Entity, Query } from "../engine.ts";
|
||||
import { CompDisplay } from "./display.ts";
|
||||
const log = log_from(import.meta);
|
||||
|
||||
export class CompPos {
|
||||
position;
|
||||
entity;
|
||||
|
||||
constructor(entity: Entity, position: Vec2) {
|
||||
this.position = position;
|
||||
this.entity = entity;
|
||||
}
|
||||
|
||||
move(displacement: Vec2) {
|
||||
this.position = this.position.add(displacement);
|
||||
}
|
||||
|
||||
move_collide(engine: Engine, displacement: Vec2) {
|
||||
let result = false;
|
||||
for (const step of displacement_steps(this.position, displacement)) {
|
||||
const collider_exists = engine.query_one(query_at(step)) !== null;
|
||||
if (collider_exists) return result;
|
||||
this.position = step;
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
function* displacement_steps(position: Vec2, displacement: Vec2) {
|
||||
let pos = position;
|
||||
let left = displacement;
|
||||
while (left.len() >= 1) {
|
||||
if (left.x() >= 1) {
|
||||
pos = pos.add(new Vec2(1, 0));
|
||||
left = left.sub(new Vec2(1, 0));
|
||||
}
|
||||
if (left.x() <= -1) {
|
||||
pos = pos.add(new Vec2(-1, 0));
|
||||
left = left.sub(new Vec2(-1, 0));
|
||||
}
|
||||
if (left.y() >= 1) {
|
||||
pos = pos.add(new Vec2(0, 1));
|
||||
left = left.sub(new Vec2(0, 1));
|
||||
}
|
||||
if (left.y() <= -1) {
|
||||
pos = pos.add(new Vec2(0, -1));
|
||||
left = left.sub(new Vec2(0, -1));
|
||||
}
|
||||
yield pos;
|
||||
}
|
||||
}
|
||||
|
||||
export function query_at(pos: Vec2) {
|
||||
return Query.filter(CompPos, (c) => c.position.overlaps(pos));
|
||||
}
|
||||
|
||||
export function query_in_rect(min: Vec2, max: Vec2) {
|
||||
return Query.filter(CompPos, (c) => c.position.inside(min, max));
|
||||
}
|
||||
|
||||
class CompStructure {}
|
||||
|
||||
export function sys_spawn_obstacle(pos: Vec2, display: string) {
|
||||
return (engine: Engine) =>
|
||||
engine.spawn((entity) =>
|
||||
entity.insert(
|
||||
new CompStructure(),
|
||||
new CompDisplay(display),
|
||||
new CompPos(entity, pos),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export async function sys_spawn_structure(file_path: string, origin: Vec2) {
|
||||
const content = await Deno.readTextFile(file_path);
|
||||
return (engine: Engine) => {
|
||||
let count = 0;
|
||||
for (const [y, line] of enumerate(content.split("\n"))) {
|
||||
for (const [x, chars] of enumerate(chunks(line, 2))) {
|
||||
const display = chars[0] + chars[1];
|
||||
if (display === " ") continue;
|
||||
engine.run(sys_spawn_obstacle(origin.add(new Vec2(x, y)), display));
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
log("Spawned", count, "tiles from", file_path);
|
||||
};
|
||||
}
|
||||
|
||||
export function sys_find_free_pos(target: Vec2) {
|
||||
return (engine: Engine) => {
|
||||
for (const pos of spiral(target)) {
|
||||
const found = engine.query_one(query_at(pos));
|
||||
if (found === null) return pos;
|
||||
}
|
||||
throw new Error("Unreachable.");
|
||||
};
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue