2023-07-19 23:38:24 -04:00
|
|
|
import {
|
|
|
|
Jump,
|
|
|
|
Forces,
|
|
|
|
ComponentNames,
|
|
|
|
Velocity,
|
|
|
|
Mass,
|
2023-08-25 18:48:17 -04:00
|
|
|
Control
|
|
|
|
} from '../components';
|
|
|
|
import { Game } from '../Game';
|
|
|
|
import { KeyConstants, PhysicsConstants } from '../config';
|
|
|
|
import { Action } from '../interfaces';
|
|
|
|
import { System, SystemNames } from '.';
|
2023-08-26 19:55:27 -04:00
|
|
|
import { MessagePublisher, MessageType } from '../network';
|
|
|
|
import { Entity } from '../entities';
|
2023-07-19 23:38:24 -04:00
|
|
|
|
|
|
|
export class Input extends System {
|
2023-08-23 21:44:59 -04:00
|
|
|
public clientId: string;
|
2023-08-26 19:55:27 -04:00
|
|
|
|
2023-07-19 23:38:24 -04:00
|
|
|
private keys: Set<string>;
|
|
|
|
private actionTimeStamps: Map<Action, number>;
|
2023-08-26 19:55:27 -04:00
|
|
|
private messagePublisher?: MessagePublisher;
|
2023-07-19 23:38:24 -04:00
|
|
|
|
2023-08-26 19:55:27 -04:00
|
|
|
constructor(clientId: string, messagePublisher?: MessagePublisher) {
|
2023-07-19 23:38:24 -04:00
|
|
|
super(SystemNames.Input);
|
|
|
|
|
2023-08-23 21:44:59 -04:00
|
|
|
this.clientId = clientId;
|
2023-08-26 19:55:27 -04:00
|
|
|
this.keys = new Set();
|
|
|
|
this.actionTimeStamps = new Map();
|
|
|
|
|
|
|
|
this.messagePublisher = messagePublisher;
|
2023-07-19 23:38:24 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
public keyPressed(key: string) {
|
|
|
|
this.keys.add(key);
|
2023-08-26 19:55:27 -04:00
|
|
|
|
|
|
|
if (this.messagePublisher) {
|
|
|
|
this.messagePublisher.addMessage({
|
|
|
|
type: MessageType.NEW_INPUT,
|
|
|
|
body: key
|
|
|
|
});
|
|
|
|
}
|
2023-07-19 23:38:24 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
public keyReleased(key: string) {
|
|
|
|
this.keys.delete(key);
|
2023-08-26 19:55:27 -04:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
2023-07-19 23:38:24 -04:00
|
|
|
}
|
|
|
|
|
2023-08-12 15:49:16 -04:00
|
|
|
private hasSomeKey(keys?: string[]): boolean {
|
|
|
|
if (keys) {
|
|
|
|
return keys.some((key) => this.keys.has(key));
|
|
|
|
}
|
|
|
|
return false;
|
2023-07-19 23:38:24 -04:00
|
|
|
}
|
|
|
|
}
|