-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
101 lines (87 loc) · 2.19 KB
/
index.js
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
class Grid {
constructor(cellsize) {
this.grid = [];
this.cellsize = cellsize;
}
// add unit to grid
add(unit) {
let x = this.getAxis(unit.xPosition);
let y = this.getAxis(unit.yPosition);
// add unit
this.allocate(x, y);
this.grid[x][y].push(unit);
}
// remove unit from grid
remove(unit) {
let x = this.getAxis(unit.xPosition);
let y = this.getAxis(unit.yPosition);
// remove unit
let idx = this.getCell(x, y)
.map(u => u.id).indexOf(unit.id);
if (idx >= 0) {
this.grid[x][y].splice(idx, 1);
}
}
// move unit to another cell
move(unit, x, y) {
// remove unit from current cell
this.remove(unit);
// update unit position
let newUnit = Object.assign(unit, {
xPosition: x,
yPosition: y
});
this.add(newUnit);
return newUnit;
}
// find collisions with a unit
checkCollisions(unit, detectCollision) {
// check neighborhood for collisions
return this.searchNeighborhood(unit, (u) => {
return u.id !== unit.id && detectCollision(unit, u);
});
}
// helpers
searchNeighborhood(unit, filter) {
// check home cell and neighboring cells
return [
{ x: 0, y: 0 },
{ x: 0, y: -1 },
{ x: 1, y: -1 },
{ x: 1, y: 0 },
{ x: 1, y: 1 },
{ x: 0, y: 1 },
{ x: -1, y: 1 },
{ x: -1, y: 0 },
{ x: -1, y: -1 }
].map((cell) => {
return this.getUnitCell(unit, cell.x, cell.y)
.filter((u) => {
// filter by callback
return filter(u);
});
}).reduce((flatten, arr) => {
return [...flatten, ...arr];
}, []);
}
getUnitCell(unit, vx, vy) {
let wx = vx || 0;
let wy = vy || 0;
let x = this.getAxis(unit.xPosition) + wx;
let y = this.getAxis(unit.yPosition) + wy;
return this.getCell(x, y);
}
getCell(x, y) {
this.allocate(x, y);
return this.grid[x][y];
}
getAxis(n) {
return Math.floor(n / this.cellsize);
}
allocate(x, y) {
// allocate un-allocated locations
if (typeof this.grid[x] === 'undefined') { this.grid[x] = []; }
if (typeof this.grid[x][y] === 'undefined') { this.grid[x][y] = []; }
}
}
module.exports = Grid;