/** * Main Application Entry Point * Orchestrates canvas setup, simulation loop, frame timing, and UI binding. */ import { configManager } from './config.js'; import { Simulation } from './simulation.js'; import { UIManager } from './ui.js'; window.addEventListener('DOMContentLoaded', () => { const canvas = document.getElementById('simCanvas'); const container = canvas.parentElement; // Determine initial container dimensions (100% of open play area) const initialWidth = Math.max(400, Math.floor(container.clientWidth || window.innerWidth - 330)); const initialHeight = Math.max(300, Math.floor(container.clientHeight || window.innerHeight - 60)); canvas.width = initialWidth; canvas.height = initialHeight; // Initialize Simulation and UI const sim = new Simulation(canvas, configManager.current); const ui = new UIManager(sim, configManager); // Dynamic screen resize synchronization function syncCanvasSize() { const w = Math.max(400, Math.floor(container.clientWidth)); const h = Math.max(300, Math.floor(container.clientHeight)); if (w > 0 && h > 0 && (canvas.width !== w || canvas.height !== h)) { canvas.width = w; canvas.height = h; sim.resize(w, h); } } window.addEventListener('resize', syncCanvasSize); if (window.ResizeObserver) { const ro = new ResizeObserver(() => syncCanvasSize()); ro.observe(container); } // Wire simulation callbacks sim.onStatsChange = (stats, sheep, wolves, plants) => { ui.updateHUD(stats, sheep, wolves, plants); }; sim.onExtinction = (stats) => { ui.showExtinctionModal(stats); }; // Main Animation Loop let lastTime = performance.now(); function loop(currentTime) { const rawDt = (currentTime - lastTime) / 1000.0; lastTime = currentTime; // Advance simulation step sim.update(rawDt); // Render frame sim.draw(); requestAnimationFrame(loop); } requestAnimationFrame(loop); });