summaryrefslogtreecommitdiff
path: root/engine/systems
diff options
context:
space:
mode:
Diffstat (limited to 'engine/systems')
-rw-r--r--engine/systems/Input.ts144
-rw-r--r--engine/systems/NetworkUpdate.ts40
-rw-r--r--engine/systems/Physics.ts2
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();
}
});