/** * UI Handlers Module * * This module manages user interactions and UI state. * Implements: * 1. Drag and Drop system * 2. Event handling * 3. UI state management * 4. Input validation * * @module uiHandlers */ /** * Initializes drag and drop functionality for tower placement * Implements HTML5 Drag and Drop API * * @param {HTMLCanvasElement} canvas - Game canvas element * @param {Object} gameState - Current game state * @returns {Object} Drag handlers and state information */ function initializeDragAndDrop(canvas, gameState) { let draggedTowerType = null; let hoverCell = null; const dragHandlers = { /** * Handles start of tower drag operation * Sets up drag data and visual feedback */ onDragStart: (e) => { draggedTowerType = e.target.dataset.towerType; e.dataTransfer.setData('text/plain', ''); }, /** * Handles end of drag operation * Cleans up drag state */ onDragEnd: () => { draggedTowerType = null; hoverCell = null; }, /** * Handles drag over canvas * Updates hover position and preview */ onDragOver: (e) => { e.preventDefault(); const rect = canvas.getBoundingClientRect(); const x = Math.floor((e.clientX - rect.left) / (canvas.width / 20)); const y = Math.floor((e.clientY - rect.top) / (canvas.height / 20)); hoverCell = (x >= 0 && x < 20 && y >= 0 && y < 20) ? { x, y } : null; }, /** * Handles tower placement on drop * Validates placement and updates game state */ onDrop: (e) => { e.preventDefault(); if (!draggedTowerType || !hoverCell) return; placeTower(gameState, draggedTowerType, hoverCell); draggedTowerType = null; hoverCell = null; } }; return { dragHandlers, getHoverInfo: () => ({ draggedTowerType, hoverCell }) }; } /** * Places a tower in the game grid * Implements tower placement validation and state updates * * @param {Object} gameState - Current game state * @param {string} towerType - Type of tower to place * @param {Object} position - Grid position for placement */ function placeTower(gameState, towerType, position) { const tower = TowerTypes[towerType]; if ( gameState.grid[position.y][position.x] === 'empty' && gameState.currency >= tower.cost ) { gameState.grid[position.y][position.x] = 'tower'; gameState.towers.push(createTower(towerType, { ...position })); gameState.currency -= tower.cost; } }