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();
}
});
}
};