import { GameRenderer } from './GameRenderer.js'; import { WebSocketClient } from './WebSocketClient.js'; import { InputHandler } from './InputHandler.js'; import { UIManager } from './UIManager.js'; export class App { constructor() { this.renderer = null; this.wsClient = null; this.inputHandler = null; this.uiManager = null; this.player = null; this.gameState = { players: {}, buildings: {} }; this.selectedBuildingType = null; this.isPlacingBuilding = false; } init() { console.log('Initializing City Builder...'); // Initialize UI Manager this.uiManager = new UIManager(this); this.uiManager.init(); // Show login screen this.uiManager.showLoginScreen(); } async startGame(nickname) { console.log(`Starting game for ${nickname}...`); // Hide login, show game UI this.uiManager.hideLoginScreen(); this.uiManager.showGameUI(); // Initialize renderer this.renderer = new GameRenderer(); this.renderer.init(); // Initialize input handler this.inputHandler = new InputHandler(this); this.inputHandler.init(); // Connect to WebSocket this.wsClient = new WebSocketClient(this); await this.wsClient.connect(nickname); // Start render loop this.renderer.startRenderLoop(); } onPlayerInit(playerData, gameState) { console.log('Player initialized:', playerData); this.player = playerData; this.gameState = gameState; // Update UI this.uiManager.updateStats(this.player); this.uiManager.updateBuildingToolbox(this.player); // Render initial state this.renderer.updateGameState(gameState); } onGameStateUpdate(state) { this.gameState = state; this.renderer.updateGameState(state); // Update own player stats if (this.player && state.players[this.player.player_id]) { this.player = state.players[this.player.player_id]; this.uiManager.updateStats(this.player); this.uiManager.updateBuildingToolbox(this.player); } } onCursorMove(playerId, x, y) { this.renderer.updateCursor(playerId, x, y); } onBuildingPlaced(building) { console.log('Building placed:', building); this.renderer.addBuilding(building); } onBuildingRemoved(x, y) { console.log('Building removed at:', x, y); this.renderer.removeBuilding(x, y); } onBuildingUpdated(x, y, name) { console.log('Building updated:', x, y, name); this.renderer.updateBuildingName(x, y, name); } onPlayerJoined(playerId, nickname) { console.log('Player joined:', nickname); this.uiManager.addChatMessage('system', `${nickname} joined the game`); } onPlayerLeft(playerId, nickname) { console.log('Player left:', nickname); this.uiManager.addChatMessage('system', `${nickname} left the game`); this.renderer.removeCursor(playerId); } onChatMessage(nickname, message, timestamp) { this.uiManager.addChatMessage(nickname, message, timestamp); } onError(message) { console.error('Error:', message); alert(message); } // Player actions selectBuilding(buildingType) { this.selectedBuildingType = buildingType; this.isPlacingBuilding = true; console.log('Selected building:', buildingType); } placeBuilding(x, y) { if (!this.selectedBuildingType) return; console.log('Placing building:', this.selectedBuildingType, 'at', x, y); this.wsClient.placeBuilding(this.selectedBuildingType, x, y); } removeBuilding(x, y) { console.log('Removing building at:', x, y); this.wsClient.removeBuilding(x, y); } editBuilding(x, y, name) { console.log('Editing building at:', x, y, 'new name:', name); this.wsClient.editBuilding(x, y, name); } sendChatMessage(message) { const timestamp = new Date().toTimeString().slice(0, 5); this.wsClient.sendChat(message, timestamp); } sendCursorPosition(x, y) { this.wsClient.sendCursorMove(x, y); } }