From d35ab6cc851d3fc85f55cfb5676f8dc3552fab24 Mon Sep 17 00:00:00 2001 From: Elizabeth Hunt Date: Mon, 2 Sep 2024 20:10:35 -0700 Subject: a bit more progress --- static/src/main.ts | 114 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 78 insertions(+), 36 deletions(-) (limited to 'static/src/main.ts') diff --git a/static/src/main.ts b/static/src/main.ts index fc04b72..eb98ba8 100644 --- a/static/src/main.ts +++ b/static/src/main.ts @@ -1,51 +1,93 @@ import $ from "jquery"; import { Vec2 } from "./vector"; -import { EventType, type SetControllableEvent, type Event } from "./event"; +import { + EventType, + type SetControllableEvent, + type Event, + type EventPublisher, +} from "./event"; import { MouseController } from "./mouse_controller"; +import { + EntityPositionUpdateEvent, + EventProcessor, + EventQueue, + WebSocketEventQueue, +} from "./network"; -$(document).ready(async () => { +class KennelClient { + private running: boolean; + private last_update: number; + + private controllable_entities: Set; + private mouse_controller: MouseController; + + constructor( + private readonly event_queue: EventQueue, + private readonly event_publisher: EventPublisher, + ) { + this.last_update = 0; + this.running = false; + + this.mouse_controller = new MouseController((position: Vec2) => + this.on_mouse_move(position), + ); + } + + public start() { + this.running = true; + this.last_update = performance.now(); + this.mouse_controller.start(); + + const loop = (timestamp: number) => { + const dt = timestamp - this.last_update; + this.propogate_state_after(dt); + requestAnimationFrame(loop); // tail call recursion! /s + }; + requestAnimationFrame(loop); + } + + public close() { + this.running = false; + this.mouse_controller.stop(); + this.controllable_entities.clear(); + } + + private propogate_state_after(dt: number) { + // TODO: interpolate cats and lasers and stuff + } + + private on_mouse_move(position: Vec2) { + for (const id of this.controllable_entities) { + const event: EntityPositionUpdateEvent = { + event_type: EventType.ENTITY_POSITION_UPDATE, + data: { id, position: { x: position.x, y: position.y } }, + }; + this.event_publisher.send(event); + } + } +} + +$(async () => { const session_id = await fetch("/assign", { credentials: "include", }) .then((res) => res.json()) .then(({ session }) => session); - const controllable_entities = new Set(); - const control_callback = (movement: Vec2) => { - for (const id of controllable_entities) { - const message = JSON.stringify({ - event_type: EventType.ENTITY_POSITION_UPDATE, - data: { id, position: movement }, - }); - ws.send(message); - } - }; - const mouse_controller = new MouseController(control_callback); + const ws = new WebSocket("/ws"); + await new Promise((resolve) => { + ws.onopen = () => resolve(); + }); + + const queue: EventQueue = new WebSocketEventQueue(ws); + + const kennel_client = new KennelClient(session_id, null); + + ws.onclose = () => kennel_client.close(); + + const mouse_controller = new MouseController(on_mouse_move); $(document).on("mousemove", (event) => { mouse_controller.move(event.clientX, event.clientY); }); mouse_controller.start(); - - const ws = new WebSocket("/ws"); - await new Promise((resolve) => { - ws.onopen = () => { - console.log("connected"); - resolve(); - }; - }); - ws.onmessage = ({ data }) => { - const [event_type, event_data] = JSON.parse(data); - const message = { event_type, data: event_data } as Event; - - console.log("Received message", message); - if (message.event_type === EventType.SET_CONTROLLABLE) { - const event = message as SetControllableEvent; - if (event.data.client_id === session_id) { - controllable_entities.add(event.data.id); - } - } - }; - ws.onclose = () => { - controllable_entities.clear(); - }; }); -- cgit v1.3