diff options
Diffstat (limited to 'html/rogue/js/game.js')
-rw-r--r-- | html/rogue/js/game.js | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/html/rogue/js/game.js b/html/rogue/js/game.js new file mode 100644 index 0000000..29b5037 --- /dev/null +++ b/html/rogue/js/game.js @@ -0,0 +1,169 @@ +// Constants for hex grid +const HEX_SIZE = 20; // Fixed hex size +const HEX_WIDTH = HEX_SIZE * 2; +const HEX_HEIGHT = Math.sqrt(3) * HEX_SIZE; +const GRID_SIZE = 100; // Number of hexes in each dimension + +// Game state +const state = { + canvas: null, + ctx: null, + camera: { x: 0, y: 0 }, // Camera position in pixel coordinates + hexGrid: [], // Will store hex grid data +}; + +// Initialize the game +function init() { + state.canvas = document.getElementById('gameCanvas'); + state.ctx = state.canvas.getContext('2d'); + + // Initialize player + player.init(); + + function resize() { + state.canvas.width = window.innerWidth; + state.canvas.height = window.innerHeight; + // Center camera on player initially + centerCameraOnHex(player.position); + } + + window.addEventListener('resize', resize); + resize(); + state.canvas.addEventListener('click', handleClick); + requestAnimationFrame(gameLoop); +} + +// Center camera on a specific hex +function centerCameraOnHex(hex) { + const pixelCoord = hexToPixel(hex); + state.camera.x = pixelCoord.x - state.canvas.width / 2; + state.camera.y = pixelCoord.y - state.canvas.height / 2; +} + +// Smoothly move camera to target position +function updateCamera() { + const currentPos = player.getCurrentPosition(); + const targetPixel = hexToPixel(currentPos); + const targetCameraX = targetPixel.x - state.canvas.width / 2; + const targetCameraY = targetPixel.y - state.canvas.height / 2; + + // Smooth camera movement + state.camera.x += (targetCameraX - state.camera.x) * 0.1; + state.camera.y += (targetCameraY - state.camera.y) * 0.1; +} + +// Convert hex coordinates to pixel coordinates +function hexToPixel(hex) { + const x = HEX_SIZE * (3/2 * hex.q); + const y = HEX_SIZE * (Math.sqrt(3)/2 * hex.q + Math.sqrt(3) * hex.r); + return {x, y}; +} + +// Convert pixel coordinates to hex coordinates (adjusted for camera position) +function pixelToHex(screenX, screenY) { + const x = screenX + state.camera.x; + const y = screenY + state.camera.y; + + const q = (2/3 * x) / HEX_SIZE; + const r = (-1/3 * x + Math.sqrt(3)/3 * y) / HEX_SIZE; + return hexRound(q, r); +} + +// Draw a single hex +function drawHex(ctx, x, y) { + // Adjust position for camera + const screenX = x - state.camera.x; + const screenY = y - state.camera.y; + + // Only draw if hex is visible on screen (with padding) + if (screenX < -HEX_WIDTH || screenX > state.canvas.width + HEX_WIDTH || + screenY < -HEX_HEIGHT || screenY > state.canvas.height + HEX_HEIGHT) { + return; + } + + ctx.beginPath(); + for (let i = 0; i < 6; i++) { + const angle = 2 * Math.PI / 6 * i; + const xPos = screenX + HEX_SIZE * Math.cos(angle); + const yPos = screenY + HEX_SIZE * Math.sin(angle); + if (i === 0) { + ctx.moveTo(xPos, yPos); + } else { + ctx.lineTo(xPos, yPos); + } + } + ctx.closePath(); + ctx.stroke(); +} + +// Calculate which hexes should be drawn +function calculateViewportHexes() { + const hexes = []; + const halfGrid = Math.floor(GRID_SIZE / 2); + + for (let r = -halfGrid; r < halfGrid; r++) { + for (let q = -halfGrid; q < halfGrid; q++) { + hexes.push({q, r}); + } + } + return hexes; +} + +// Main game loop +function gameLoop() { + state.ctx.clearRect(0, 0, state.canvas.width, state.canvas.height); + + // Update game state + player.update(); + updateCamera(); + + // Draw hex grid + const viewportHexes = calculateViewportHexes(); + viewportHexes.forEach(hex => { + const pixel = hexToPixel(hex); + drawHex(state.ctx, pixel.x, pixel.y); + }); + + // Draw player + player.draw(state.ctx, hexToPixel, state.camera, HEX_SIZE); + + requestAnimationFrame(gameLoop); +} + +// Handle click/tap with camera offset +function handleClick(event) { + const rect = state.canvas.getBoundingClientRect(); + const x = event.clientX - rect.left; + const y = event.clientY - rect.top; + + const hexCoord = pixelToHex(x, y); + player.moveTo(hexCoord); +} + +// Round hex coordinates to nearest hex +function hexRound(q, r) { + let x = q; + let z = r; + let y = -x-z; + + let rx = Math.round(x); + let ry = Math.round(y); + let rz = Math.round(z); + + const x_diff = Math.abs(rx - x); + const y_diff = Math.abs(ry - y); + const z_diff = Math.abs(rz - z); + + if (x_diff > y_diff && x_diff > z_diff) { + rx = -ry-rz; + } else if (y_diff > z_diff) { + ry = -rx-rz; + } else { + rz = -rx-ry; + } + + return {q: rx, r: rz}; +} + +// Start the game +init(); \ No newline at end of file |