class GameState { constructor() { this.resources = { gold: 0, wood: 100, stone: 50, population: 10 }; this.buildings = { house: { level: 0, production: 1, cost: { wood: 10, stone: 5 } }, farm: { level: 0, production: 2, cost: { wood: 20, stone: 10 } }, mine: { level: 0, production: 5, cost: { wood: 30, stone: 20 } } }; this.upgrades = {}; this.lastUpdate = Date.now(); this.gameSpeed = 1; } canAfford(cost) { return Object.entries(cost).every(([resource, amount]) => this.resources[resource] >= amount ); } purchase(cost) { if (this.canAfford(cost)) { Object.entries(cost).forEach(([resource, amount]) => { this.resources[resource] -= amount; }); return true; } return false; } updateResources() { const now = Date.now(); const deltaTime = (now - this.lastUpdate) / 1000; // Auto-generate resources from buildings Object.values(this.buildings).forEach(building => { if (building.level > 0) { this.resources.gold += building.production * building.level * deltaTime * this.gameSpeed; } }); this.lastUpdate = now; this.saveGame(); } saveGame() { localStorage.setItem('idleEmpireSave', JSON.stringify({ resources: this.resources, buildings: this.buildings, upgrades: this.upgrades, lastUpdate: this.lastUpdate })); } loadGame() { const save = localStorage.getItem('idleEmpireSave'); if (save) { const data = JSON.parse(save); Object.assign(this, data); // Calculate offline progress const offlineTime = (Date.now() - this.lastUpdate) / 1000; if (offlineTime > 1) { Object.values(this.buildings).forEach(building => { if (building.level > 0) { this.resources.gold += building.production * building.level * offlineTime * 0.5; // 50% offline efficiency } }); } } } } class GameManager { constructor() { this.gameState = new GameState(); this.uiComponents = []; this.isRunning = false; } init() { this.gameState.loadGame(); this.startGameLoop(); this.setupEventListeners(); } startGameLoop() { this.isRunning = true; this.gameLoop(); } gameLoop() { if (this.isRunning) { this.gameState.updateResources(); this.updateUI(); requestAnimationFrame(() => this.gameLoop()); } } updateUI() { this.uiComponents.forEach(component => { if (typeof component.update === 'function') { component.update(this.gameState); } }); } registerUIComponent(component) { this.uiComponents.push(component); } setupEventListeners() { // Global keyboard shortcuts document.addEventListener('keydown', (e) => { if (e.ctrlKey && e.key === 's') { e.preventDefault(); this.gameState.saveGame(); this.showNotification('Game saved!', 'success'); } }); } showNotification(message, type = 'info') { const notification = document.createElement('div'); notification.className = `fixed top-4 right-4 glass-effect p-4 rounded-lg shadow-lg transform translate-x-full transition-transform duration-300 z-50 ${ type === 'success' ? 'border-l-4 border-green-400' : type === 'error' ? 'border-l-4 border-red-400' : 'border-l-4 border-primary-400' }`; notification.innerHTML = `
${message}
`; document.body.appendChild(notification); feather.replace(); setTimeout(() => { notification.classList.remove('translate-x-full'); notification.classList.add('translate-x-0'); }, 100); setTimeout(() => { notification.classList.remove('translate-x-0'); notification.classList.add('translate-x-full'); setTimeout(() => notification.remove(), 300); }, 3000); } } // Initialize game manager const gameManager = new GameManager(); // Utility functions function formatNumber(num) { if (num >= 1000000) { return (num / 1000000).toFixed(1) + 'M'; } if (num >= 1000) { return (num / 1000).toFixed(1) + 'K'; } return Math.floor(num).toString(); } function createResourceDisplay(resource, amount) { return `
${resource}
${formatNumber(amount)}
`; } function getResourceIcon(resource) { const icons = { gold: 'dollar-sign', wood: 'tree', stone: 'square', population: 'users' }; return icons[resource] || 'circle'; } // Export for use in components window.gameManager = gameManager; window.formatNumber = formatNumber; window.createResourceDisplay = createResourceDisplay; window.getResourceIcon = getResourceIcon;