diff options
Diffstat (limited to 'html/rogue/js/game.js')
-rw-r--r-- | html/rogue/js/game.js | 121 |
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 |