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
95
96
97
98
99
100
101
102
103
|
import { System, SystemNames } from ".";
import { Game } from "..";
import { Entity, EntityNames } from "../entities";
import { BoundingBox, Colliding, ComponentNames, Grid } from "../components";
const collisionMap: Record<string, Set<string>> = {
[EntityNames.Key]: new Set([EntityNames.LockedDoor]),
[EntityNames.Curry]: new Set([EntityNames.Player]),
};
export class Collision extends System {
static canCollide(entityName: string, otherEntityName: string) {
if (collisionMap[entityName]) {
return collisionMap[entityName].has(otherEntityName);
}
return collisionMap[otherEntityName]?.has(entityName) ?? false;
}
constructor() {
super(SystemNames.Collision);
}
public update(_dt: number, game: Game) {
game.forEachEntityWithComponent(ComponentNames.Colliding, (entity) => {
if (!entity.hasComponent(ComponentNames.BoundingBox)) {
return;
}
const collidingBox = entity.getComponent<BoundingBox>(
ComponentNames.BoundingBox,
);
let collidingGrid = entity.hasComponent(ComponentNames.Grid)
? entity.getComponent<Grid>(ComponentNames.Grid)
: null;
const collidingWith: Entity[] = [];
game.forEachEntityWithComponent(
ComponentNames.BoundingBox,
(otherEntity) => {
const otherBoundingBox = otherEntity.getComponent<BoundingBox>(
ComponentNames.BoundingBox,
);
let otherGrid = otherEntity.hasComponent(ComponentNames.Grid)
? otherEntity.getComponent<Grid>(ComponentNames.Grid)
: null;
if (collidingGrid && otherGrid) {
if (
collidingGrid.gridPosition.x === otherGrid.gridPosition.x &&
collidingGrid.gridPosition.y === otherGrid.gridPosition.y
) {
collidingWith.push(otherEntity);
}
return;
}
if (collidingBox.isCollidingWith(otherBoundingBox)) {
collidingWith.push(otherEntity);
}
},
);
for (const collision of collidingWith) {
this.handleCollision(entity, collision, game);
}
});
}
private handleCollision(entity: Entity, otherEntity: Entity, game: Game) {
if (!Collision.canCollide(entity.name, otherEntity.name)) {
return;
}
const keyDoorPair = [EntityNames.Key, EntityNames.LockedDoor].map((x) =>
[entity, otherEntity].find((y) => y.name === x),
);
const [key, door] = keyDoorPair;
if (key && door) {
this.handleKeyDoorCollision(key, door, game);
}
const curryPlayerPair = [EntityNames.Curry, EntityNames.Player].map((x) =>
[entity, otherEntity].find((y) => y.name === x),
);
const [curry, player] = curryPlayerPair;
if (curry && player) {
this.handleCurryPlayerCollision(curry, player, game);
}
}
private handleKeyDoorCollision(key: Entity, door: Entity, game: Game) {
game.removeEntity(key.id);
game.removeEntity(door.id);
}
private handleCurryPlayerCollision(
curry: Entity,
_player: Entity,
game: Game,
) {
game.removeEntity(curry.id);
game.stop();
}
}
|