1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
import { Game } from '@engine/Game';
import { Grid } from '@engine/structures';
import {
WallBounds,
FacingDirection,
Render,
Physics,
Input,
Collision,
NetworkUpdate
} from '@engine/systems';
import {
ClientMessageProcessor,
ClientSocketMessagePublisher,
ClientSocketMessageQueueProvider
} from './network';
export class JumpStorm {
private game: Game;
private clientId: string;
constructor(game: Game) {
this.game = game;
}
public async init(
ctx: CanvasRenderingContext2D,
httpMethod: string,
wsMethod: string,
host: string
) {
this.clientId = await this.getAssignedCookie(
`${httpMethod}://${host}/assign`
);
const socket = new WebSocket(`${wsMethod}://${host}/game`);
const clientSocketMessageQueueProvider =
new ClientSocketMessageQueueProvider(socket);
const clientSocketMessagePublisher = new ClientSocketMessagePublisher(
socket
);
const clientMessageProcessor = new ClientMessageProcessor(this.game);
const inputSystem = new Input(this.clientId, clientSocketMessagePublisher);
this.addWindowEventListenersToInputSystem(inputSystem);
[
new Physics(),
new NetworkUpdate(
clientSocketMessageQueueProvider,
clientSocketMessagePublisher,
clientMessageProcessor
),
inputSystem,
new FacingDirection(),
new Collision(new Grid()),
new WallBounds(),
new Render(ctx)
].forEach((system) => this.game.addSystem(system));
}
public play() {
this.game.start();
const loop = (timestamp: number) => {
this.game.doGameLoop(timestamp);
requestAnimationFrame(loop); // tail call recursion! /s
};
requestAnimationFrame(loop);
}
private addWindowEventListenersToInputSystem(input: Input) {
window.addEventListener('keydown', (e) => {
if (!e.repeat) {
input.keyPressed(e.key.toLowerCase());
}
});
window.addEventListener('keyup', (e) =>
input.keyReleased(e.key.toLowerCase())
);
}
private async getAssignedCookie(endpoint: string): Promise<string> {
return fetch(endpoint)
.then((resp) => {
if (resp.ok) {
return resp.text();
}
throw resp;
})
.then((cookie) => cookie);
}
}
|