aboutsummaryrefslogtreecommitdiff
path: root/static/src/engine/network.ts
diff options
context:
space:
mode:
Diffstat (limited to 'static/src/engine/network.ts')
-rw-r--r--static/src/engine/network.ts138
1 files changed, 138 insertions, 0 deletions
diff --git a/static/src/engine/network.ts b/static/src/engine/network.ts
new file mode 100644
index 0000000..850da65
--- /dev/null
+++ b/static/src/engine/network.ts
@@ -0,0 +1,138 @@
+import {
+ ComponentType,
+ PositionComponent,
+ TrailingPositionComponent,
+} from "./component";
+import { create_cat, create_laser, Entity, EntityType } from "./entity";
+import {
+ EntityBornEvent,
+ EntityDeathEvent,
+ EntityPositionUpdateEvent,
+ EventPublisher,
+ EventQueue,
+ EventType,
+ InitialStateEvent,
+ SetControllableEvent,
+} from "./events";
+import { Game } from "./game";
+import { InputSystem } from "./input";
+import { RenderSystem } from "./render";
+import { System, SystemType } from "./system";
+
+export class NetworkSystem extends System {
+ constructor(
+ private readonly event_queue: EventQueue,
+ private readonly event_publisher: EventPublisher,
+ ) {
+ super(SystemType.NETWORK);
+ }
+
+ public update(_dt: number, game: Game) {
+ const events = this.event_queue.peek();
+ for (const event of events) {
+ switch (event.event_type) {
+ case EventType.INITIAL_STATE:
+ this.process_initial_state_event(event as InitialStateEvent, game);
+ break;
+ case EventType.SET_CONTROLLABLE:
+ this.process_set_controllable_event(
+ event as SetControllableEvent,
+ game,
+ );
+ break;
+ case EventType.ENTITY_BORN:
+ this.process_entity_born_event(event as EntityBornEvent, game);
+ break;
+ case EventType.ENTITY_POSITION_UPDATE:
+ this.process_entity_position_update_event(
+ event as EntityPositionUpdateEvent,
+ game,
+ );
+ break;
+ case EventType.ENTITY_DEATH:
+ this.process_entity_death_event(event as EntityDeathEvent, game);
+ break;
+ }
+ }
+
+ this.event_queue.clear();
+ this.event_publisher.publish();
+ }
+
+ private process_initial_state_event(event: InitialStateEvent, game: Game) {
+ console.log("received initial state", event);
+ const { world, entities } = event.data;
+ const render_system = game.get_system<RenderSystem>(SystemType.RENDER);
+ if (!render_system) {
+ console.error("render system not found");
+ return;
+ }
+ render_system.set_world_dimensions(world.width, world.height);
+ Object.values(entities).forEach((entity) =>
+ game.put_entity(this.process_new_entity(entity)),
+ );
+ }
+
+ private process_entity_position_update_event(
+ event: EntityPositionUpdateEvent,
+ game: Game,
+ ) {
+ console.log("received entity position update", event);
+ const { position, id } = event.data;
+ const entity = game.get_entity(id);
+ if (typeof entity === "undefined") return;
+
+ const position_component = entity.components[
+ ComponentType.POSITION
+ ] as PositionComponent;
+ position_component.x = position.x;
+ position_component.y = position.y;
+
+ if (ComponentType.TRAILING_POSITION in entity.components) {
+ const trailing_position = entity.components[
+ ComponentType.TRAILING_POSITION
+ ] as TrailingPositionComponent;
+ trailing_position.trails.push({
+ x: position_component.x,
+ y: position_component.y,
+ time: Date.now(),
+ });
+ }
+ }
+
+ private process_entity_born_event(event: EntityBornEvent, game: Game) {
+ console.log("received a new entity", event);
+ const { entity } = event.data;
+ game.put_entity(this.process_new_entity(entity));
+ }
+
+ private process_new_entity(entity: Entity): Entity {
+ if (entity.entity_type === EntityType.LASER) {
+ return create_laser(entity);
+ }
+ if (entity.entity_type === EntityType.CAT) {
+ return create_cat(entity);
+ }
+ return entity;
+ }
+
+ private process_entity_death_event(event: EntityDeathEvent, game: Game) {
+ console.log("an entity died D:", event);
+ const { id } = event.data;
+ game.remove_entity(id);
+ }
+
+ private process_set_controllable_event(
+ event: SetControllableEvent,
+ game: Game,
+ ) {
+ console.log("got a controllable event", event);
+ if (event.data.client_id !== game.client_id) {
+ console.warn("got controllable event for client that is not us");
+ return;
+ }
+
+ const input_system = game.get_system<InputSystem>(SystemType.INPUT)!;
+ input_system.add_controllable_entity(event.data.id);
+ }
+}