diff options
Diffstat (limited to 'html/tower/js/renderer.js')
-rw-r--r-- | html/tower/js/renderer.js | 56 |
1 files changed, 45 insertions, 11 deletions
diff --git a/html/tower/js/renderer.js b/html/tower/js/renderer.js index cf52ebc..f37b5f3 100644 --- a/html/tower/js/renderer.js +++ b/html/tower/js/renderer.js @@ -1,7 +1,25 @@ +/** + * Rendering Module + * + * This module handles all game rendering operations using HTML5 Canvas. + * Demonstrates key game development patterns: + * 1. Layer-based rendering + * 2. Particle systems + * 3. Visual state feedback + * 4. Canvas state management + */ + +/** + * Renders the game grid with path and hover previews + * Implements visual feedback for player actions + * + * @param {CanvasRenderingContext2D} ctx - Canvas rendering context + * @param {Array<Array<string>>} grid - Game grid state + */ function renderGrid(ctx, grid) { const cellSize = canvas.width / 20; - // Draw grid lines + // Draw grid lines for visual reference ctx.strokeStyle = '#ccc'; ctx.lineWidth = 1; @@ -19,7 +37,7 @@ function renderGrid(ctx, grid) { ctx.stroke(); } - // Draw cells + // Render grid cells with path highlighting grid.forEach((row, y) => { row.forEach((cell, x) => { if (cell === 'path') { @@ -29,12 +47,13 @@ function renderGrid(ctx, grid) { }); }); - // Draw hover preview + // Render tower placement preview if (gameState.phase === GamePhase.PLACEMENT && draggedTowerType && hoverCell) { const tower = TowerTypes[draggedTowerType]; const canPlace = grid[hoverCell.y][hoverCell.x] === 'empty' && gameState.playerCurrency >= tower.cost; + // Visual feedback for placement validity ctx.fillStyle = canPlace ? tower.color + '80' : 'rgba(255, 0, 0, 0.3)'; ctx.fillRect( hoverCell.x * cellSize, @@ -43,7 +62,7 @@ function renderGrid(ctx, grid) { cellSize ); - // Draw range preview + // Range indicator preview ctx.beginPath(); ctx.arc( (hoverCell.x + 0.5) * cellSize, @@ -57,19 +76,27 @@ function renderGrid(ctx, grid) { } } +/** + * Renders all enemies with health indicators and effects + * Implements visual state representation + * + * @param {CanvasRenderingContext2D} ctx - Canvas rendering context + * @param {Array<Object>} enemies - Array of enemy objects + */ function renderEnemies(ctx, enemies) { const cellSize = canvas.width / 20; enemies.forEach(enemy => { + // Health-based opacity for visual feedback const healthPercent = enemy.currentHealth / enemy.maxHealth; const opacity = 0.3 + (healthPercent * 0.7); - // Use enemy type color + // Dynamic color based on enemy state ctx.fillStyle = `${EnemyTypes[enemy.type].color}${Math.floor(opacity * 255).toString(16).padStart(2, '0')}`; ctx.strokeStyle = 'rgba(0, 0, 0, 0.8)'; ctx.lineWidth = 2; - // Draw enemy body + // Enemy body ctx.beginPath(); ctx.arc( (enemy.position.x + 0.5) * cellSize, @@ -81,7 +108,7 @@ function renderEnemies(ctx, enemies) { ctx.fill(); ctx.stroke(); - // Draw range indicator for ranged enemies + // Range indicator for special enemy types if (EnemyTypes[enemy.type].isRanged) { ctx.beginPath(); ctx.arc( @@ -97,6 +124,13 @@ function renderEnemies(ctx, enemies) { }); } +/** + * Renders game UI elements with clean state management + * Implements heads-up display (HUD) pattern + * + * @param {CanvasRenderingContext2D} ctx - Canvas rendering context + * @param {Object} gameState - Current game state + */ function renderUI(ctx, gameState) { const padding = 20; const lineHeight = 30; @@ -110,17 +144,17 @@ function renderUI(ctx, gameState) { // Reset any transformations ctx.setTransform(1, 0, 0, 1, 0, 0); - // Draw semi-transparent background + // Semi-transparent background for readability ctx.fillStyle = 'rgba(255, 255, 255, 0.8)'; ctx.fillRect(0, 0, width, height + padding); - // Set text properties + // Text rendering setup ctx.fillStyle = 'black'; ctx.font = '20px Arial'; ctx.textAlign = 'left'; - ctx.textBaseline = 'top'; // Add this to ensure consistent vertical alignment + ctx.textBaseline = 'top'; - // Draw UI elements + // Game state information ctx.fillText(`Level: ${gameState.level}`, padding, startY); ctx.fillText(`Currency: $${gameState.currency}`, padding, startY + lineHeight); ctx.fillText(`Phase: ${gameState.phase}`, padding, startY + lineHeight * 2); |