UNPKG

shellquest

Version:

Terminal-based procedurally generated dungeon crawler

216 lines (169 loc) 5.65 kB
# Lighting System Integration Guide This document describes how to integrate the lighting system into the game. ## Files Created 1. `LightingSystem.ts` - Core lighting engine with light sources and flicker 2. `DungeonLighting.ts` - High-level API for dungeon torch management 3. `LightingRenderer.ts` - Applies lighting to the rendered output 4. `index.ts` - Main exports ## Required Changes ### 1. DungeonLevel.ts - Add getGrid() method Add this method at the end of the DungeonLevel class: ```typescript /** * Get the internal grid for lighting system torch placement */ getGrid(): TileGrid { return this.grid; } ``` ### 2. ZombieAttackGame.ts - Full Integration #### Add imports at the top: ```typescript import {DungeonLighting} from './lighting/DungeonLighting.ts'; import {applyLighting} from './lighting/LightingRenderer.ts'; ``` #### Add class properties: ```typescript // Lighting system for dungeon levels private dungeonLighting: DungeonLighting | null = null; private lightingEnabled: boolean = true; ``` #### Add initialization in initializeSync() after setting player spawn: ```typescript // Initialize lighting system for dungeon if (this.level instanceof DungeonLevel) { this.initializeLighting(player); } ``` #### Add the initializeLighting method: ```typescript private initializeLighting(player: Player): void { if (!(this.level instanceof DungeonLevel)) return; // Create the lighting system this.dungeonLighting = new DungeonLighting({ ambientLight: 0.08, // Very dark in unlit areas maxBrightness: 1.0, falloffExponent: 1.5, }); // Get the dungeon grid for torch placement const grid = this.level.getGrid(); if (grid) { // Place wall torches throughout the dungeon const seed = this.hashString('default_torches'); this.dungeonLighting.placeTorches(grid, MAP_WIDTH, MAP_HEIGHT, seed, { minSpacing: 8, frequency: 0.15, maxTorches: 60, preferCorridors: true, }); } // Initialize player's torch this.dungeonLighting.initializePlayerTorch( player.x + TILE_SIZE / 2, player.y + TILE_SIZE / 2, ); console.log(`Lighting initialized: ${this.dungeonLighting.getStats().torches} torches placed`); } private hashString(str: string): number { let hash = 0; for (let i = 0; i < str.length; i++) { const char = str.charCodeAt(i); hash = (hash << 5) - hash + char; hash = hash & hash; } return Math.abs(hash); } ``` #### Update the update() method: ```typescript private update(deltaTime: number): void { // Update all entities for (const entity of this.level.getEntities()) { entity.update(deltaTime, this.level, this.collisionSystem); this.collisionSystem.updateEntity(entity); } // Update camera this.camera.update(this.level.player.x, this.level.player.y); // Update lighting system (handles flicker animation) if (this.dungeonLighting && this.lightingEnabled) { this.dungeonLighting.update(deltaTime); // Update player torch position to follow player this.dungeonLighting.updatePlayerTorch( this.level.player.x + TILE_SIZE / 2, this.level.player.y + TILE_SIZE / 2, ); } } ``` #### Add lighting toggle to setupInput() (optional): ```typescript case 'l': // Toggle lighting with 'L' key this.lightingEnabled = !this.lightingEnabled; console.log(`Lighting ${this.lightingEnabled ? 'enabled' : 'disabled'}`); break; ``` #### Add applyLightingEffect() call at the end of render(): ```typescript render(): void { // ... existing render code ... // Apply lighting after all layers are rendered this.applyLightingEffect(); } private applyLightingEffect(): void { if (!this.dungeonLighting || !this.lightingEnabled) return; // Compute light map for current viewport const lightMap = this.dungeonLighting.computeLightMap( this.mainCanvas.width, this.mainCanvas.height, this.camera.x, this.camera.y, ); // Apply lighting to the main canvas applyLighting(this.mainCanvas, lightMap, true); } ``` ## Configuration Options ### Lighting System Config ```typescript { ambientLight: 0.08, // Base visibility in darkness (0-1) maxBrightness: 1.0, // Maximum brightness cap falloffExponent: 1.5, // How sharply light fades (higher = sharper) } ``` ### Torch Placement Config ```typescript { minSpacing: 8, // Minimum tiles between torches frequency: 0.15, // Probability of placing torch maxTorches: 60, // Maximum torches per level preferCorridors: true, // Place more torches in corridors } ``` ### Torch Light Config (in LightingSystem.ts) ```typescript TORCH_LIGHT_CONFIG = { radius: 6, // Light radius in tiles intensity: 0.95, // Base brightness color: {r: 255, g: 200, b: 100}, // Warm orange flicker: true, flickerSpeed: 2.5, // How fast the flicker flickerIntensity: 0.15, // How much light varies }; PLAYER_TORCH_CONFIG = { radius: 5, intensity: 0.85, color: {r: 255, g: 220, b: 150}, // Slightly cooler flicker: true, flickerSpeed: 3.0, flickerIntensity: 0.12, }; ``` ## Performance Notes - Light map is computed only for visible viewport - Each frame updates flicker values using Perlin noise - Typical performance: 60fps with ~50 visible lights - Light map is cached and invalidated on camera movement ## Keyboard Controls - `L` - Toggle lighting on/off (if implemented)