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
|
const FogOfWar = {
// Set of revealed hex coordinates (as strings)
revealed: new Set(),
// Configuration
VISION_RANGE: Config.player.VISION_RANGE,
init() {
this.revealed.clear();
this.updateVisibility(player.position);
},
// Convert hex to string key for Set storage
hexToKey(hex) {
return `${hex.q},${hex.r}`;
},
// Check if a hex is currently visible
isVisible(hex) {
const playerPos = player.getCurrentPosition();
const distance = this.getHexDistance(hex, playerPos);
return distance <= this.VISION_RANGE;
},
// Check if a hex has been revealed
isRevealed(hex) {
return this.revealed.has(this.hexToKey(hex));
},
// Calculate distance between two hexes
getHexDistance(a, b) {
return Math.max(
Math.abs(a.q - b.q),
Math.abs(a.r - b.r),
Math.abs((a.q + a.r) - (b.q + b.r))
);
},
// Update visibility based on player position
updateVisibility(center) {
// Get all hexes within vision range
for (let q = -this.VISION_RANGE; q <= this.VISION_RANGE; q++) {
for (let r = -this.VISION_RANGE; r <= this.VISION_RANGE; r++) {
const hex = {
q: center.q + q,
r: center.r + r
};
if (this.getHexDistance(center, hex) <= this.VISION_RANGE) {
this.revealed.add(this.hexToKey(hex));
}
}
}
},
// Draw fog of war effect
draw(ctx) {
// Draw fog over unrevealed areas
HexGrid.getViewportHexes().forEach(hex => {
if (!this.isRevealed(hex) || !this.isVisible(hex)) {
const pixel = HexGrid.toPixel(hex);
const screenX = pixel.x - Camera.x;
const screenY = pixel.y - Camera.y;
ctx.fillStyle = this.isRevealed(hex) ?
'rgba(0, 0, 0, 0.5)' : // Darker fog for unexplored areas
'rgba(0, 0, 0, 0.8)'; // Lighter fog for explored but not visible
// Draw fog hex
ctx.beginPath();
for (let i = 0; i < 6; i++) {
const angle = 2 * Math.PI / 6 * i;
const xPos = screenX + HexGrid.SIZE * Math.cos(angle);
const yPos = screenY + HexGrid.SIZE * Math.sin(angle);
if (i === 0) {
ctx.moveTo(xPos, yPos);
} else {
ctx.lineTo(xPos, yPos);
}
}
ctx.closePath();
ctx.fill();
}
});
}
};
|