// Main game variables and initialization let canvas, ctx; let currentTool = SAND; let lastFrameTime = 0; let fps = 0; let debugMode = false; // Initialize the simulation window.onload = function() { canvas = document.getElementById('simulation-canvas'); ctx = canvas.getContext('2d'); // Set canvas size to fill the screen resizeCanvas(); window.addEventListener('resize', resizeCanvas); // Tool selection document.getElementById('sand-btn').addEventListener('click', () => setTool(SAND)); document.getElementById('water-btn').addEventListener('click', () => setTool(WATER)); document.getElementById('dirt-btn').addEventListener('click', () => setTool(DIRT)); document.getElementById('stone-btn').addEventListener('click', () => setTool(STONE)); document.getElementById('grass-btn').addEventListener('click', () => setTool(GRASS)); document.getElementById('wood-btn').addEventListener('click', () => setTool(WOOD)); document.getElementById('seed-btn').addEventListener('click', () => setTool(SEED)); document.getElementById('tree-seed-btn').addEventListener('click', () => setTool(TREE_SEED)); document.getElementById('fire-btn').addEventListener('click', () => setTool(FIRE)); document.getElementById('lava-btn').addEventListener('click', () => setTool(LAVA)); document.getElementById('eraser-btn').addEventListener('click', () => setTool(EMPTY)); // Navigation controls document.getElementById('move-left').addEventListener('click', () => moveWorld(-CHUNK_SIZE/2, 0)); document.getElementById('move-right').addEventListener('click', () => moveWorld(CHUNK_SIZE/2, 0)); document.getElementById('move-up').addEventListener('click', () => moveWorld(0, -CHUNK_SIZE/2)); document.getElementById('move-down').addEventListener('click', () => moveWorld(0, CHUNK_SIZE/2)); document.getElementById('debug-btn').addEventListener('click', toggleDebug); // Drawing events canvas.addEventListener('mousedown', handleMouseDown); canvas.addEventListener('mousemove', handleMouseMove); canvas.addEventListener('mouseup', handleMouseUp); canvas.addEventListener('mouseleave', handleMouseUp); // Touch events for mobile canvas.addEventListener('touchstart', handleTouchStart); canvas.addEventListener('touchmove', handleTouchMove); canvas.addEventListener('touchend', handleMouseUp); // Initialize the first chunk and generate terrain around it getOrCreateChunk(0, 0); // Explicitly create and mark the stone layer as dirty for (let dx = -5; dx <= 5; dx++) { const chunkX = dx; const chunkY = 1; // Stone layer const key = getChunkKey(chunkX, chunkY); getOrCreateChunk(chunkX, chunkY); dirtyChunks.add(key); } generateChunksAroundPlayer(); // Start the simulation loop requestAnimationFrame(simulationLoop); }; function resizeCanvas() { canvas.width = window.innerWidth; canvas.height = window.innerHeight - document.querySelector('.controls').offsetHeight; } function simulationLoop(timestamp) { // Calculate FPS const deltaTime = timestamp - lastFrameTime; lastFrameTime = timestamp; fps = Math.round(1000 / deltaTime); document.getElementById('fps').textContent = `FPS: ${fps}`; // Update physics with timestamp for rate limiting updatePhysics(timestamp); // Render render(); // Continue the loop requestAnimationFrame(simulationLoop); }