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
|
// This that witchy shit -- we be hexin!
const HexGrid = {
get SIZE() { return Config.hex.SIZE },
get WIDTH() { return Config.hex.WIDTH },
get HEIGHT() { return Config.hex.HEIGHT },
get GRID_SIZE() { return Config.hex.GRID_SIZE },
COLOR: Config.colors.GRID,
// hex to pixel
toPixel(hex) {
const x = this.SIZE * (3/2 * hex.q);
const y = this.SIZE * (Math.sqrt(3)/2 * hex.q + Math.sqrt(3) * hex.r);
return {x, y};
},
// pixel to hex
fromPixel(x, y) {
const q = (2/3 * x) / this.SIZE;
const r = (-1/3 * x + Math.sqrt(3)/3 * y) / this.SIZE;
return this.round(q, r);
},
// Round hex coordinates to nearest hex
round(q, r) {
let x = q;
let z = r;
let y = -x-z;
let rx = Math.round(x);
let ry = Math.round(y);
let rz = Math.round(z);
const x_diff = Math.abs(rx - x);
const y_diff = Math.abs(ry - y);
const z_diff = Math.abs(rz - z);
if (x_diff > y_diff && x_diff > z_diff) {
rx = -ry-rz;
} else if (y_diff > z_diff) {
ry = -rx-rz;
} else {
rz = -rx-ry;
}
return {q: rx, r: rz};
},
// Is this hex in the viewport?
getViewportHexes() {
const hexes = [];
const halfGrid = Math.floor(this.GRID_SIZE / 2);
for (let r = -halfGrid; r < halfGrid; r++) {
for (let q = -halfGrid; q < halfGrid; q++) {
hexes.push({q, r});
}
}
return hexes;
},
// Check if a hex is passable
isPassable(hex) {
const halfGrid = Math.floor(this.GRID_SIZE / 2);
return Math.abs(hex.q) <= halfGrid && Math.abs(hex.r) <= halfGrid;
},
// Centralized hex drawing function
drawHexPath(ctx, x, y, size = this.SIZE, padding = 0) {
ctx.beginPath();
for (let i = 0; i < 6; i++) {
const angle = 2 * Math.PI / 6 * i;
const xPos = Math.round(x + (size + padding) * Math.cos(angle));
const yPos = Math.round(y + (size + padding) * Math.sin(angle));
if (i === 0) {
ctx.moveTo(xPos, yPos);
} else {
ctx.lineTo(xPos, yPos);
}
}
ctx.closePath();
},
toScreenCoordinates(hex, camera) {
const pixel = this.toPixel(hex);
return {
x: Math.round(pixel.x - camera.x),
y: Math.round(pixel.y - camera.y)
};
},
isInViewport(screenX, screenY, canvas) {
return !(screenX < -this.WIDTH ||
screenX > canvas.width + this.WIDTH ||
screenY < -this.HEIGHT ||
screenY > canvas.height + this.HEIGHT);
}
};
|