diff options
-rw-r--r-- | client/src/JumpStorm.ts | 12 | ||||
-rw-r--r-- | engine/components/Control.ts | 5 | ||||
-rw-r--r-- | engine/config/constants.ts | 13 | ||||
-rw-r--r-- | engine/entities/Entity.ts | 4 | ||||
-rw-r--r-- | engine/entities/Player.ts | 12 | ||||
-rw-r--r-- | engine/systems/NetworkUpdate.ts | 7 | ||||
-rw-r--r-- | server/src/server.ts | 90 |
7 files changed, 100 insertions, 43 deletions
diff --git a/client/src/JumpStorm.ts b/client/src/JumpStorm.ts index e094a6f..ae99b8e 100644 --- a/client/src/JumpStorm.ts +++ b/client/src/JumpStorm.ts @@ -1,7 +1,5 @@ -import { Floor, Player } from "@engine/entities"; import { Game } from "@engine/Game"; import { Grid } from "@engine/structures"; -import { Miscellaneous } from "@engine/config"; import { WallBounds, FacingDirection, @@ -61,16 +59,14 @@ export class JumpStorm { this.game = new Game(); const socket = new WebSocket("ws://localhost:8080"); + setInterval(() => socket.send(JSON.stringify({ x: 1 })), 1_000); const clientSocketMessageQueueProvider = new ClientSocketMessageQueueProvider(socket); const clientSocketMessagePublisher = new ClientSocketMessagePublisher( socket ); - const grid = new Grid( - { width: Miscellaneous.WIDTH, height: Miscellaneous.HEIGHT }, - { width: 30, height: 30 } - ); + const grid = new Grid(); [ this.createInputSystem(), @@ -84,10 +80,6 @@ export class JumpStorm { ), new Render(ctx), ].forEach((system) => this.game.addSystem(system)); - - [new Floor(160), new Player()].forEach((entity) => - this.game.addEntity(entity) - ); } public play() { diff --git a/engine/components/Control.ts b/engine/components/Control.ts index fb7b916..a3621b0 100644 --- a/engine/components/Control.ts +++ b/engine/components/Control.ts @@ -3,7 +3,10 @@ import { Component, ComponentNames, Velocity } from "."; export class Control extends Component { public controlVelocityComponent: Velocity; - constructor(controlVelocityComponent: Velocity = new Velocity()) { + constructor( + controlVelocityComponent: Velocity = new Velocity(), + controllableBy: string + ) { super(ComponentNames.Control); this.controlVelocityComponent = controlVelocityComponent; diff --git a/engine/config/constants.ts b/engine/config/constants.ts index b3c3f62..fa3f81b 100644 --- a/engine/config/constants.ts +++ b/engine/config/constants.ts @@ -4,25 +4,28 @@ export namespace KeyConstants { export const KeyActions: Record<string, Action> = { a: Action.MOVE_LEFT, ArrowLeft: Action.MOVE_LEFT, + d: Action.MOVE_RIGHT, ArrowRight: Action.MOVE_RIGHT, + w: Action.JUMP, ArrowUp: Action.JUMP, }; + // value -> [key] from KeyActions export const ActionKeys: Map<Action, string[]> = Object.keys( KeyActions ).reduce((acc: Map<Action, string[]>, key) => { const action = KeyActions[key]; if (acc.has(action)) { - acc.get(action)?.push(key); + acc.get(action)!.push(key); return acc; } acc.set(action, [key]); return acc; - }, new Map<Action, string[]>()); + }, new Map()); } export namespace PhysicsConstants { @@ -37,6 +40,8 @@ export namespace Miscellaneous { export const WIDTH = 600; export const HEIGHT = 800; - export const DEFAULT_GRID_WIDTH = 40; - export const DEFAULT_GRID_HEIGHT = 40; + export const DEFAULT_GRID_WIDTH = 30; + export const DEFAULT_GRID_HEIGHT = 30; + + export const SERVER_TICK_RATE = 5 / 100; } diff --git a/engine/entities/Entity.ts b/engine/entities/Entity.ts index b2d875d..4e9df78 100644 --- a/engine/entities/Entity.ts +++ b/engine/entities/Entity.ts @@ -4,8 +4,8 @@ export abstract class Entity { public readonly id: string; public readonly components: Map<string, Component>; - constructor() { - this.id = crypto.randomUUID(); + constructor(id: string = crypto.randomUUID()) { + this.id = id; this.components = new Map(); } diff --git a/engine/entities/Player.ts b/engine/entities/Player.ts index 377e0ca..03fa69b 100644 --- a/engine/entities/Player.ts +++ b/engine/entities/Player.ts @@ -21,7 +21,7 @@ export class Player extends Entity { private static MOI: number = 100; private static spriteSpec: SpriteSpec = SPRITE_SPECS.get( - Sprites.COFFEE, + Sprites.COFFEE ) as SpriteSpec; constructor() { @@ -34,12 +34,12 @@ export class Player extends Entity { y: 100, }, { width: Player.spriteSpec.width, height: Player.spriteSpec.height }, - 0, - ), + 0 + ) ); this.addComponent( - new Velocity({ dCartesian: { dx: 0, dy: 0 }, dTheta: 0 }), + new Velocity({ dCartesian: { dx: 0, dy: 0 }, dTheta: 0 }) ); this.addComponent(new Mass(Player.MASS)); @@ -64,8 +64,8 @@ export class Player extends Entity { { x: 0, y: 0 }, { width: Player.spriteSpec.width, height: Player.spriteSpec.height }, Player.spriteSpec.msPerFrame, - Player.spriteSpec.frames, - ), + Player.spriteSpec.frames + ) ); this.addComponent(new FacingDirection(leftSprite, rightSprite)); diff --git a/engine/systems/NetworkUpdate.ts b/engine/systems/NetworkUpdate.ts index 6f8acb9..cdd6de7 100644 --- a/engine/systems/NetworkUpdate.ts +++ b/engine/systems/NetworkUpdate.ts @@ -18,7 +18,7 @@ export class NetworkUpdate extends System { constructor( queueProvider: MessageQueueProvider, - publisher: MessagePublisher, + publisher: MessagePublisher ) { super(SystemNames.NetworkUpdate); @@ -28,15 +28,16 @@ export class NetworkUpdate extends System { public update(_dt: number, game: Game) { const messages = this.queueProvider.getNewMessages(); + if (messages.length) console.log(messages); this.queueProvider.clearMessages(); game.forEachEntityWithComponent( ComponentNames.NetworkUpdateable, (entity) => { const networkUpdateComponent = entity.getComponent<NetworkUpdateable>( - ComponentNames.NetworkUpdateable, + ComponentNames.NetworkUpdateable ); - }, + } ); } } diff --git a/server/src/server.ts b/server/src/server.ts index 18829e4..713d3ed 100644 --- a/server/src/server.ts +++ b/server/src/server.ts @@ -4,50 +4,106 @@ import { WallBounds, Physics, Collision, + NetworkUpdate, MessageQueueProvider, MessagePublisher, } from "@engine/systems"; import { Grid } from "@engine/structures"; import { Miscellaneous } from "@engine/config"; +import { Server } from "bun"; -const TICK_RATE = 60 / 1000; +class ServerSocketMessageReceiver implements MessageQueueProvider { + private messages: any[]; -const game = new Game(); + constructor() { + this.messages = []; + } -[ - new Physics(), - new Collision(new Grid()), - new WallBounds(Miscellaneous.WIDTH), -].forEach((system) => game.addSystem(system)); + addMessage(message: any) { + this.messages.push(message); + } -[new Floor(160), new Player()].forEach((entity) => game.addEntity(entity)); + getNewMessages() { + return this.messages; + } -game.start(); + clearMessages() { + this.messages = []; + } +} -setInterval(() => { - game.doGameLoop(performance.now()); -}, TICK_RATE); +class ServerSocketMessagePublisher implements MessagePublisher { + private server: Server; + private messages: any[]; + + constructor(server: Server) { + this.server = server; + this.messages = []; + } + + addMessage(_message: any) {} -const server = Bun.serve({ + publish() {} +} + +const game = new Game(); + +const messageReceiver = new ServerSocketMessageReceiver(); + +const server = Bun.serve<{ sessionId: string }>({ port: 8080, fetch: async (req, server): Promise<string> => { - const sessionId = Math.floor(Math.random() * 1e10).toString(); + const sessionId = crypto.randomUUID(); server.upgrade(req, { headers: { "Set-Cookie": `SessionId=${sessionId}`, }, + data: { + sessionId, + }, }); - return "200 OK"; + return sessionId; }, websocket: { - open(ws) {}, + open(ws) { + const { sessionId } = ws.data; + + if (sessionControllableEntities.has(sessionId)) { + return; + } + + const player = new Player(); + game.addEntity(player); + + sessionControllableEntities.set(sessionId, new Set(player.id)); + }, message(ws, message) { - console.log(message); + console.log(JSON.parse(message)); + messageReceiver.addMessage(message); }, close(ws) {}, }, }); +const messagePublisher = new ServerSocketMessagePublisher(server); + +[ + new Physics(), + new Collision(new Grid()), + new WallBounds(Miscellaneous.WIDTH), + new NetworkUpdate(messageReceiver, messagePublisher), +].forEach((system) => game.addSystem(system)); + +[new Floor(160), new Player()].forEach((entity) => game.addEntity(entity)); + +game.start(); + +setInterval(() => { + game.doGameLoop(performance.now()); +}, Miscellaneous.SERVER_TICK_RATE); + +const sessionControllableEntities: Map<string, Set<string>> = new Map(); + console.log(`Listening on ${server.hostname}:${server.port}`); |