diff options
Diffstat (limited to 'engine/systems')
-rw-r--r-- | engine/systems/Input.ts | 144 | ||||
-rw-r--r-- | engine/systems/NetworkUpdate.ts | 40 | ||||
-rw-r--r-- | engine/systems/Physics.ts | 2 |
3 files changed, 123 insertions, 63 deletions
diff --git a/engine/systems/Input.ts b/engine/systems/Input.ts index 8a68905..9afd1ab 100644 --- a/engine/systems/Input.ts +++ b/engine/systems/Input.ts @@ -10,26 +10,111 @@ import { Game } from '../Game'; import { KeyConstants, PhysicsConstants } from '../config'; import { Action } from '../interfaces'; import { System, SystemNames } from '.'; +import { MessagePublisher, MessageType } from '../network'; +import { Entity } from '../entities'; export class Input extends System { public clientId: string; + private keys: Set<string>; private actionTimeStamps: Map<Action, number>; + private messagePublisher?: MessagePublisher; - constructor(clientId: string) { + constructor(clientId: string, messagePublisher?: MessagePublisher) { super(SystemNames.Input); this.clientId = clientId; - this.keys = new Set<string>(); - this.actionTimeStamps = new Map<Action, number>(); + this.keys = new Set(); + this.actionTimeStamps = new Map(); + + this.messagePublisher = messagePublisher; } public keyPressed(key: string) { this.keys.add(key); + + if (this.messagePublisher) { + this.messagePublisher.addMessage({ + type: MessageType.NEW_INPUT, + body: key + }); + } } public keyReleased(key: string) { this.keys.delete(key); + + if (this.messagePublisher) { + this.messagePublisher.addMessage({ + type: MessageType.REMOVE_INPUT, + body: key + }); + } + } + + public update(_dt: number, game: Game) { + game.forEachEntityWithComponent(ComponentNames.Control, (entity) => + this.handleInput(entity) + ); + } + + public handleInput(entity: Entity) { + const controlComponent = entity.getComponent<Control>( + ComponentNames.Control + ); + controlComponent.isControllable = + controlComponent.controllableBy === this.clientId; + + if (!controlComponent.isControllable) return; + + if (this.hasSomeKey(KeyConstants.ActionKeys.get(Action.MOVE_RIGHT))) { + controlComponent.controlVelocityComponent.velocity.dCartesian.dx += + PhysicsConstants.PLAYER_MOVE_VEL; + } + + if (this.hasSomeKey(KeyConstants.ActionKeys.get(Action.MOVE_LEFT))) { + controlComponent.controlVelocityComponent.velocity.dCartesian.dx += + -PhysicsConstants.PLAYER_MOVE_VEL; + } + + if ( + entity.hasComponent(ComponentNames.Jump) && + this.hasSomeKey(KeyConstants.ActionKeys.get(Action.JUMP)) + ) { + this.performJump(entity); + } + } + + private performJump(entity: Entity) { + const velocity = entity.getComponent<Velocity>( + ComponentNames.Velocity + ).velocity; + const jump = entity.getComponent<Jump>(ComponentNames.Jump); + + if (jump.canJump) { + this.actionTimeStamps.set(Action.JUMP, performance.now()); + + velocity.dCartesian.dy += PhysicsConstants.PLAYER_JUMP_INITIAL_VEL; + jump.canJump = false; + } + + if ( + performance.now() - (this.actionTimeStamps.get(Action.JUMP) || 0) < + PhysicsConstants.MAX_JUMP_TIME_MS + ) { + const mass = entity.getComponent<Mass>(ComponentNames.Mass).mass; + + const jumpForce = { + fCartesian: { + fy: mass * PhysicsConstants.PLAYER_JUMP_ACC, + fx: 0 + }, + torque: 0 + }; + entity + .getComponent<Forces>(ComponentNames.Forces) + ?.forces.push(jumpForce); + } } private hasSomeKey(keys?: string[]): boolean { @@ -38,57 +123,4 @@ export class Input extends System { } return false; } - - public update(_dt: number, game: Game) { - game.forEachEntityWithComponent(ComponentNames.Control, (entity) => { - const controlComponent = entity.getComponent<Control>( - ComponentNames.Control - ); - if (controlComponent.controllableBy != this.clientId) return; - - if (this.hasSomeKey(KeyConstants.ActionKeys.get(Action.MOVE_RIGHT))) { - controlComponent.controlVelocityComponent.velocity.dCartesian.dx += - PhysicsConstants.PLAYER_MOVE_VEL; - } - - if (this.hasSomeKey(KeyConstants.ActionKeys.get(Action.MOVE_LEFT))) { - controlComponent.controlVelocityComponent.velocity.dCartesian.dx += - -PhysicsConstants.PLAYER_MOVE_VEL; - } - - if (entity.hasComponent(ComponentNames.Jump)) { - const velocity = entity.getComponent<Velocity>( - ComponentNames.Velocity - ).velocity; - const jump = entity.getComponent<Jump>(ComponentNames.Jump); - - if (this.hasSomeKey(KeyConstants.ActionKeys.get(Action.JUMP))) { - if (jump.canJump) { - this.actionTimeStamps.set(Action.JUMP, performance.now()); - - velocity.dCartesian.dy += PhysicsConstants.PLAYER_JUMP_INITIAL_VEL; - jump.canJump = false; - } - - if ( - performance.now() - (this.actionTimeStamps.get(Action.JUMP) || 0) < - PhysicsConstants.MAX_JUMP_TIME_MS - ) { - const mass = entity.getComponent<Mass>(ComponentNames.Mass).mass; - - const jumpForce = { - fCartesian: { - fy: mass * PhysicsConstants.PLAYER_JUMP_ACC, - fx: 0 - }, - torque: 0 - }; - entity - .getComponent<Forces>(ComponentNames.Forces) - ?.forces.push(jumpForce); - } - } - } - }); - } } diff --git a/engine/systems/NetworkUpdate.ts b/engine/systems/NetworkUpdate.ts index bcfb71e..6d13574 100644 --- a/engine/systems/NetworkUpdate.ts +++ b/engine/systems/NetworkUpdate.ts @@ -1,10 +1,12 @@ import { System, SystemNames } from '.'; import { Game } from '../Game'; -import { ComponentNames, NetworkUpdateable } from '../components'; +import { ComponentNames } from '../components'; import { type MessageQueueProvider, type MessagePublisher, - type MessageProcessor + type MessageProcessor, + MessageType, + EntityUpdateBody } from '../network'; export class NetworkUpdate extends System { @@ -12,6 +14,8 @@ export class NetworkUpdate extends System { private publisher: MessagePublisher; private messageProcessor: MessageProcessor; + private entityUpdateTimers: Map<string, number>; + constructor( queueProvider: MessageQueueProvider, publisher: MessagePublisher, @@ -22,23 +26,47 @@ export class NetworkUpdate extends System { this.queueProvider = queueProvider; this.publisher = publisher; this.messageProcessor = messageProcessor; + + this.entityUpdateTimers = new Map(); } - public update(_dt: number, game: Game) { + public update(dt: number, game: Game) { + // 1. process new messages this.queueProvider .getNewMessages() .forEach((message) => this.messageProcessor.process(message)); this.queueProvider.clearMessages(); + // 2. send entity updates + const updateMessages: EntityUpdateBody[] = []; game.forEachEntityWithComponent( ComponentNames.NetworkUpdateable, (entity) => { - const networkUpdateComponent = entity.getComponent<NetworkUpdateable>( - ComponentNames.NetworkUpdateable - ); + let timer = this.entityUpdateTimers.get(entity.id) ?? dt; + timer -= dt; + this.entityUpdateTimers.set(entity.id, timer); + + if (timer > 0) return; + this.entityUpdateTimers.set(entity.id, this.getNextUpdateTimeMs()); + + if (entity.hasComponent(ComponentNames.NetworkUpdateable)) { + updateMessages.push({ + id: entity.id, + args: entity.serialize() + }); + } } ); + this.publisher.addMessage({ + type: MessageType.UPDATE_ENTITIES, + body: updateMessages + }); + // 3. publish changes this.publisher.publish(); } + + private getNextUpdateTimeMs() { + return Math.random() * 70 + 50; + } } diff --git a/engine/systems/Physics.ts b/engine/systems/Physics.ts index 35afb3f..b5df459 100644 --- a/engine/systems/Physics.ts +++ b/engine/systems/Physics.ts @@ -99,7 +99,7 @@ export class Physics extends System { : boundingBox.rotation) % 360; // clear the control velocity - if (control) { + if (control && control.isControllable) { control.controlVelocityComponent = new Velocity(); } }); |