about summary refs log tree commit diff stats
path: root/html/rogue/js/game.js
diff options
context:
space:
mode:
Diffstat (limited to 'html/rogue/js/game.js')
-rw-r--r--html/rogue/js/game.js121
1 files changed, 121 insertions, 0 deletions
diff --git a/html/rogue/js/game.js b/html/rogue/js/game.js
new file mode 100644
index 0000000..48133d8
--- /dev/null
+++ b/html/rogue/js/game.js
@@ -0,0 +1,121 @@
+const FPS = 60;
+const FRAME_TIME = 1000 / FPS;
+let lastFrameTime = 0;
+
+const state = {
+    canvas: null,
+    ctx: null
+};
+
+async function init() {
+    state.canvas = document.getElementById('gameCanvas');
+    state.ctx = state.canvas.getContext('2d');
+    
+    await player.init();
+    Debug.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);
+    FogOfWar.init();
+    Items.init();
+}
+
+function drawHex(ctx, x, y, hex) {
+    const screen = HexGrid.toScreenCoordinates(hex, Camera);
+    
+    // Only draw if hex is visible on screen (with padding)
+    if (!HexGrid.isInViewport(screen.x, screen.y, state.canvas)) {
+        return;
+    }
+    
+    // Skip drawing completely if hex hasn't been revealed
+    if (!FogOfWar.isRevealed(hex)) {
+        return;
+    }
+    
+    // Draw the hex fill
+    HexGrid.drawHexPath(ctx, screen.x, screen.y);
+    ctx.fillStyle = Config.colors.HEX_FILL;
+    ctx.fill();
+    
+    // Only draw grid lines for currently visible hexes
+    // (fog of war will handle the grid lines for revealed but not visible hexes)
+    if (FogOfWar.isVisible(hex)) {
+        ctx.strokeStyle = Config.colors.GRID;
+        ctx.lineWidth = 1;
+        ctx.stroke();
+    }
+}
+
+function gameLoop(currentTime) {
+    requestAnimationFrame(gameLoop);
+    
+    if (currentTime - lastFrameTime < Config.game.FRAME_TIME) {
+        return;
+    }
+    
+    const deltaTime = Math.min(currentTime - lastFrameTime, Config.game.FRAME_TIME * 2);
+    lastFrameTime = currentTime;
+
+    // Update debug information
+    Debug.update(currentTime);
+
+    // Clear with background
+    state.ctx.fillStyle = Config.colors.BACKGROUND;
+    state.ctx.fillRect(0, 0, state.canvas.width, state.canvas.height);
+    
+    // Round camera position to prevent sub-pixel rendering
+    Camera.x = Math.round(Camera.x);
+    Camera.y = Math.round(Camera.y);
+    
+    player.update();
+    Camera.smoothFollow(player.getCurrentPosition());
+    
+    if (player.hasMoved) {
+        FogOfWar.updateVisibility(player.position);
+        player.hasMoved = false;
+    }
+    
+    // Draw everything in one pass to prevent flicker
+    HexGrid.getViewportHexes().forEach(hex => {
+        const pixel = HexGrid.toPixel(hex);
+        drawHex(state.ctx, Math.round(pixel.x), Math.round(pixel.y), hex);
+    });
+    
+    Items.draw(state.ctx, HexGrid.toPixel.bind(HexGrid), Camera, HexGrid.SIZE);
+    player.draw(state.ctx, HexGrid.toPixel.bind(HexGrid), Camera, HexGrid.SIZE);
+    FogOfWar.draw(state.ctx);
+    InventoryUI.draw(state.ctx);
+    Debug.draw(state.ctx);
+}
+
+function handleClick(event) {
+    if (InventoryUI.isOpen) {
+        InventoryUI.toggleInventory();
+        return;
+    }
+    
+    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);
+    
+    // Check if clicking on player's position
+    if (hexCoord.q === player.position.q && hexCoord.r === player.position.r) {
+        InventoryUI.toggleInventory();
+    } else {
+        player.moveTo(hexCoord);
+    }
+}
+
+init().catch(console.error);
\ No newline at end of file