very basic server messages - need to figure shit out still

This commit is contained in:
Elizabeth Hunt 2023-08-21 17:22:23 -06:00
parent b786fe1e72
commit d64ffb5016
7 changed files with 106 additions and 49 deletions

View File

@ -1,7 +1,5 @@
import { Floor, Player } from "@engine/entities";
import { Game } from "@engine/Game"; import { Game } from "@engine/Game";
import { Grid } from "@engine/structures"; import { Grid } from "@engine/structures";
import { Miscellaneous } from "@engine/config";
import { import {
WallBounds, WallBounds,
FacingDirection, FacingDirection,
@ -61,16 +59,14 @@ export class JumpStorm {
this.game = new Game(); this.game = new Game();
const socket = new WebSocket("ws://localhost:8080"); const socket = new WebSocket("ws://localhost:8080");
setInterval(() => socket.send(JSON.stringify({ x: 1 })), 1_000);
const clientSocketMessageQueueProvider = const clientSocketMessageQueueProvider =
new ClientSocketMessageQueueProvider(socket); new ClientSocketMessageQueueProvider(socket);
const clientSocketMessagePublisher = new ClientSocketMessagePublisher( const clientSocketMessagePublisher = new ClientSocketMessagePublisher(
socket socket
); );
const grid = new Grid( const grid = new Grid();
{ width: Miscellaneous.WIDTH, height: Miscellaneous.HEIGHT },
{ width: 30, height: 30 }
);
[ [
this.createInputSystem(), this.createInputSystem(),
@ -84,10 +80,6 @@ export class JumpStorm {
), ),
new Render(ctx), new Render(ctx),
].forEach((system) => this.game.addSystem(system)); ].forEach((system) => this.game.addSystem(system));
[new Floor(160), new Player()].forEach((entity) =>
this.game.addEntity(entity)
);
} }
public play() { public play() {

View File

@ -3,7 +3,10 @@ import { Component, ComponentNames, Velocity } from ".";
export class Control extends Component { export class Control extends Component {
public controlVelocityComponent: Velocity; public controlVelocityComponent: Velocity;
constructor(controlVelocityComponent: Velocity = new Velocity()) { constructor(
controlVelocityComponent: Velocity = new Velocity(),
controllableBy: string
) {
super(ComponentNames.Control); super(ComponentNames.Control);
this.controlVelocityComponent = controlVelocityComponent; this.controlVelocityComponent = controlVelocityComponent;

View File

@ -4,25 +4,28 @@ export namespace KeyConstants {
export const KeyActions: Record<string, Action> = { export const KeyActions: Record<string, Action> = {
a: Action.MOVE_LEFT, a: Action.MOVE_LEFT,
ArrowLeft: Action.MOVE_LEFT, ArrowLeft: Action.MOVE_LEFT,
d: Action.MOVE_RIGHT, d: Action.MOVE_RIGHT,
ArrowRight: Action.MOVE_RIGHT, ArrowRight: Action.MOVE_RIGHT,
w: Action.JUMP, w: Action.JUMP,
ArrowUp: Action.JUMP, ArrowUp: Action.JUMP,
}; };
// value -> [key] from KeyActions
export const ActionKeys: Map<Action, string[]> = Object.keys( export const ActionKeys: Map<Action, string[]> = Object.keys(
KeyActions KeyActions
).reduce((acc: Map<Action, string[]>, key) => { ).reduce((acc: Map<Action, string[]>, key) => {
const action = KeyActions[key]; const action = KeyActions[key];
if (acc.has(action)) { if (acc.has(action)) {
acc.get(action)?.push(key); acc.get(action)!.push(key);
return acc; return acc;
} }
acc.set(action, [key]); acc.set(action, [key]);
return acc; return acc;
}, new Map<Action, string[]>()); }, new Map());
} }
export namespace PhysicsConstants { export namespace PhysicsConstants {
@ -37,6 +40,8 @@ export namespace Miscellaneous {
export const WIDTH = 600; export const WIDTH = 600;
export const HEIGHT = 800; export const HEIGHT = 800;
export const DEFAULT_GRID_WIDTH = 40; export const DEFAULT_GRID_WIDTH = 30;
export const DEFAULT_GRID_HEIGHT = 40; export const DEFAULT_GRID_HEIGHT = 30;
export const SERVER_TICK_RATE = 5 / 100;
} }

View File

@ -4,8 +4,8 @@ export abstract class Entity {
public readonly id: string; public readonly id: string;
public readonly components: Map<string, Component>; public readonly components: Map<string, Component>;
constructor() { constructor(id: string = crypto.randomUUID()) {
this.id = crypto.randomUUID(); this.id = id;
this.components = new Map(); this.components = new Map();
} }

View File

@ -21,7 +21,7 @@ export class Player extends Entity {
private static MOI: number = 100; private static MOI: number = 100;
private static spriteSpec: SpriteSpec = SPRITE_SPECS.get( private static spriteSpec: SpriteSpec = SPRITE_SPECS.get(
Sprites.COFFEE, Sprites.COFFEE
) as SpriteSpec; ) as SpriteSpec;
constructor() { constructor() {
@ -34,12 +34,12 @@ export class Player extends Entity {
y: 100, y: 100,
}, },
{ width: Player.spriteSpec.width, height: Player.spriteSpec.height }, { width: Player.spriteSpec.width, height: Player.spriteSpec.height },
0, 0
), )
); );
this.addComponent( 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)); this.addComponent(new Mass(Player.MASS));
@ -64,8 +64,8 @@ export class Player extends Entity {
{ x: 0, y: 0 }, { x: 0, y: 0 },
{ width: Player.spriteSpec.width, height: Player.spriteSpec.height }, { width: Player.spriteSpec.width, height: Player.spriteSpec.height },
Player.spriteSpec.msPerFrame, Player.spriteSpec.msPerFrame,
Player.spriteSpec.frames, Player.spriteSpec.frames
), )
); );
this.addComponent(new FacingDirection(leftSprite, rightSprite)); this.addComponent(new FacingDirection(leftSprite, rightSprite));

View File

@ -18,7 +18,7 @@ export class NetworkUpdate extends System {
constructor( constructor(
queueProvider: MessageQueueProvider, queueProvider: MessageQueueProvider,
publisher: MessagePublisher, publisher: MessagePublisher
) { ) {
super(SystemNames.NetworkUpdate); super(SystemNames.NetworkUpdate);
@ -28,15 +28,16 @@ export class NetworkUpdate extends System {
public update(_dt: number, game: Game) { public update(_dt: number, game: Game) {
const messages = this.queueProvider.getNewMessages(); const messages = this.queueProvider.getNewMessages();
if (messages.length) console.log(messages);
this.queueProvider.clearMessages(); this.queueProvider.clearMessages();
game.forEachEntityWithComponent( game.forEachEntityWithComponent(
ComponentNames.NetworkUpdateable, ComponentNames.NetworkUpdateable,
(entity) => { (entity) => {
const networkUpdateComponent = entity.getComponent<NetworkUpdateable>( const networkUpdateComponent = entity.getComponent<NetworkUpdateable>(
ComponentNames.NetworkUpdateable, ComponentNames.NetworkUpdateable
); );
}, }
); );
} }
} }

View File

@ -4,20 +4,96 @@ import {
WallBounds, WallBounds,
Physics, Physics,
Collision, Collision,
NetworkUpdate,
MessageQueueProvider, MessageQueueProvider,
MessagePublisher, MessagePublisher,
} from "@engine/systems"; } from "@engine/systems";
import { Grid } from "@engine/structures"; import { Grid } from "@engine/structures";
import { Miscellaneous } from "@engine/config"; import { Miscellaneous } from "@engine/config";
import { Server } from "bun";
const TICK_RATE = 60 / 1000; class ServerSocketMessageReceiver implements MessageQueueProvider {
private messages: any[];
constructor() {
this.messages = [];
}
addMessage(message: any) {
this.messages.push(message);
}
getNewMessages() {
return this.messages;
}
clearMessages() {
this.messages = [];
}
}
class ServerSocketMessagePublisher implements MessagePublisher {
private server: Server;
private messages: any[];
constructor(server: Server) {
this.server = server;
this.messages = [];
}
addMessage(_message: any) {}
publish() {}
}
const game = new Game(); const game = new Game();
const messageReceiver = new ServerSocketMessageReceiver();
const server = Bun.serve<{ sessionId: string }>({
port: 8080,
fetch: async (req, server): Promise<string> => {
const sessionId = crypto.randomUUID();
server.upgrade(req, {
headers: {
"Set-Cookie": `SessionId=${sessionId}`,
},
data: {
sessionId,
},
});
return sessionId;
},
websocket: {
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(JSON.parse(message));
messageReceiver.addMessage(message);
},
close(ws) {},
},
});
const messagePublisher = new ServerSocketMessagePublisher(server);
[ [
new Physics(), new Physics(),
new Collision(new Grid()), new Collision(new Grid()),
new WallBounds(Miscellaneous.WIDTH), new WallBounds(Miscellaneous.WIDTH),
new NetworkUpdate(messageReceiver, messagePublisher),
].forEach((system) => game.addSystem(system)); ].forEach((system) => game.addSystem(system));
[new Floor(160), new Player()].forEach((entity) => game.addEntity(entity)); [new Floor(160), new Player()].forEach((entity) => game.addEntity(entity));
@ -26,28 +102,8 @@ game.start();
setInterval(() => { setInterval(() => {
game.doGameLoop(performance.now()); game.doGameLoop(performance.now());
}, TICK_RATE); }, Miscellaneous.SERVER_TICK_RATE);
const server = Bun.serve({ const sessionControllableEntities: Map<string, Set<string>> = new Map();
port: 8080,
fetch: async (req, server): Promise<string> => {
const sessionId = Math.floor(Math.random() * 1e10).toString();
server.upgrade(req, {
headers: {
"Set-Cookie": `SessionId=${sessionId}`,
},
});
return "200 OK";
},
websocket: {
open(ws) {},
message(ws, message) {
console.log(message);
},
close(ws) {},
},
});
console.log(`Listening on ${server.hostname}:${server.port}`); console.log(`Listening on ${server.hostname}:${server.port}`);