61 lines
2 KiB
TypeScript
61 lines
2 KiB
TypeScript
import { mts } from "../../common/mod.ts";
|
|
import { log_from, Vec2 } from "../../common/utils.ts";
|
|
import { World, WorldEntity } from "../engine.ts";
|
|
import { ClientInterface } from "../network.ts";
|
|
const log = log_from(import.meta);
|
|
|
|
export class Session {
|
|
client;
|
|
world;
|
|
player_entity;
|
|
|
|
constructor(client: ClientInterface, world: World, player_entity: WorldEntity) {
|
|
this.client = client;
|
|
this.world = world;
|
|
this.player_entity = player_entity;
|
|
}
|
|
|
|
async spin() {
|
|
try {
|
|
for await (const input of this.client.inputs.iter()) {
|
|
if (input.kind !== "request_display") log("Received", input);
|
|
|
|
if (input.kind === "ping") this.client.outputs.send({ kind: "ping_response", content: input.content });
|
|
if (input.kind === "request_display") this.send_display(input.content.width, input.content.height);
|
|
if (input.kind === "input") this.handle_input(input);
|
|
if (input.kind === "exit") this.world.kill(this.player_entity.identifier);
|
|
}
|
|
} catch (error) {
|
|
console.error("Session loop failed, ", error);
|
|
this.world.kill(this.player_entity.identifier);
|
|
}
|
|
}
|
|
|
|
send_display(width: number, height: number) {
|
|
const raw = this.world.render(this.player_entity.position, new Vec2(width, height));
|
|
this.client.outputs.send({ kind: "display", content: { raw } });
|
|
}
|
|
|
|
handle_input(input: mts.MsgInput) {
|
|
if (input.content.control === "up") this.world.move_collide(this.player_entity.identifier, new Vec2(0, 1));
|
|
if (input.content.control === "down") this.world.move_collide(this.player_entity.identifier, new Vec2(0, -1));
|
|
if (input.content.control === "left") this.world.move_collide(this.player_entity.identifier, new Vec2(-1, 0));
|
|
if (input.content.control === "right") this.world.move_collide(this.player_entity.identifier, new Vec2(1, 0));
|
|
}
|
|
}
|
|
|
|
export class PlayerComponent {
|
|
entity;
|
|
|
|
constructor(entity: WorldEntity) {
|
|
this.entity = entity;
|
|
}
|
|
|
|
move(direction: Vec2) {
|
|
return this.entity.world.move_collide(this.entity.identifier, direction);
|
|
}
|
|
|
|
render(res: Vec2) {
|
|
return this.entity.world.render(this.entity.position, res);
|
|
}
|
|
}
|