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
104
105
|
const FPS = 60;
const FRAME_TIME = 1000 / FPS;
let lastFrameTime = 0;
const state = {
canvas: null,
ctx: null
};
function init() {
state.canvas = document.getElementById('gameCanvas');
state.ctx = state.canvas.getContext('2d');
player.init();
function resize() {
state.canvas.width = window.innerWidth;
state.canvas.height = window.innerHeight;
Camera.centerOn(player.position);
}
window.addEventListener('resize', resize);
resize();
state.canvas.addEventListener('click', handleClick);
requestAnimationFrame(gameLoop);
}
// Draw a single hex
function drawHex(ctx, x, y, hex) {
const screenX = x - Camera.x;
const screenY = y - Camera.y;
// Only draw if hex is visible on screen (with some padding)
if (screenX < -HexGrid.WIDTH || screenX > state.canvas.width + HexGrid.WIDTH ||
screenY < -HexGrid.HEIGHT || screenY > state.canvas.height + HexGrid.HEIGHT) {
return;
}
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();
// Fill hex with appropriate color
if (HexGrid.isPassable(hex)) {
ctx.fillStyle = Config.colors.HEX_FILL;
} else {
ctx.fillStyle = Config.colors.BACKGROUND;
}
ctx.fill();
// Draw border
ctx.strokeStyle = HexGrid.COLOR;
ctx.lineWidth = 1;
ctx.stroke();
}
function gameLoop(currentTime) {
if (currentTime - lastFrameTime < Config.game.FRAME_TIME) {
requestAnimationFrame(gameLoop);
return;
}
const deltaTime = currentTime - lastFrameTime;
lastFrameTime = currentTime;
// Clear the entire canvas first
state.ctx.clearRect(0, 0, state.canvas.width, state.canvas.height);
// Then fill with background color
state.ctx.fillStyle = Config.colors.BACKGROUND;
state.ctx.fillRect(0, 0, state.canvas.width, state.canvas.height);
player.update();
Camera.smoothFollow(player.getCurrentPosition());
HexGrid.getViewportHexes().forEach(hex => {
const pixel = HexGrid.toPixel(hex);
drawHex(state.ctx, pixel.x, pixel.y, hex);
});
player.draw(state.ctx, HexGrid.toPixel.bind(HexGrid), Camera, HexGrid.SIZE);
requestAnimationFrame(gameLoop);
}
function handleClick(event) {
const rect = state.canvas.getBoundingClientRect();
const x = event.clientX - rect.left;
const y = event.clientY - rect.top;
const hexCoord = HexGrid.fromPixel(x + Camera.x, y + Camera.y);
player.moveTo(hexCoord);
}
init();
|