# Guia de Sistema de Iluminação 2D
## 💡 Visão Geral
O sistema de iluminação 2D permite criar ambientes dinâmicos com luzes coloridas, sombras suaves e efeitos atmosféricos.
## 🔦 Tipos de Luz
### Point Light (Luz Pontual)
Emite luz em todas as direções a partir de um ponto:
```rust
use sevenx_engine::{Light, LightingSystem};
let mut lighting = LightingSystem::new();
// Luz branca básica
let light = Light::point(400.0, 300.0, 200.0);
lighting.add_light(light);
// Luz colorida
let red_light = Light::point(100.0, 100.0, 150.0)
.with_color(255, 50, 50)
.with_intensity(0.8);
lighting.add_light(red_light);
```
### Spot Light (Luz Direcional)
Emite luz em forma de cone:
```rust
// Spot light apontando para baixo
let spotlight = Light::spot(
400.0, // x
100.0, // y
90.0, // direção em graus (90 = para baixo)
45.0, // ângulo do cone
300.0 // raio
)
.with_color(255, 255, 100)
.with_intensity(1.0);
lighting.add_light(spotlight);
```
### Directional Light (Luz Ambiente Direcional)
Iluminação uniforme em toda a cena:
```rust
use sevenx_engine::LightType;
let sun = Light {
position: (0.0, 0.0),
color: [255, 255, 200],
intensity: 0.5,
radius: 0.0,
light_type: LightType::Directional,
direction: 0.0,
cone_angle: 0.0,
enabled: true,
};
lighting.add_light(sun);
```
## 🌙 Luz Ambiente
Configure a iluminação base da cena:
```rust
// Ambiente escuro azulado
lighting.set_ambient(30, 30, 50, 0.3);
// Ambiente claro
lighting.set_ambient(200, 200, 200, 0.8);
// Sem luz ambiente (escuridão total)
lighting.set_ambient(0, 0, 0, 0.0);
```
## 🎨 Aplicando Iluminação
### Método Básico
```rust
impl GameState for MyGame {
fn draw(&mut self, _world: &World, frame: &mut [u8]) {
let width = 800;
let height = 600;
for y in 0..height {
for x in 0..width {
let idx = ((y * width + x) * 4) as usize;
// Cor base do pixel
let base_color = [100, 100, 100, 255];
// Aplica iluminação
let lit_color = self.lighting.apply_lighting(
x as f32,
y as f32,
base_color
);
frame[idx..idx + 4].copy_from_slice(&lit_color);
}
}
}
}
```
### Com Sprites
```rust
// Renderiza sprite com iluminação
for y in 0..sprite_height {
for x in 0..sprite_width {
let screen_x = sprite_x + x;
let screen_y = sprite_y + y;
let sprite_color = get_sprite_pixel(x, y);
// Aplica iluminação ao sprite
let lit_color = self.lighting.apply_lighting(
screen_x as f32,
screen_y as f32,
sprite_color
);
draw_pixel(screen_x, screen_y, lit_color);
}
}
```
## 🎮 Exemplo Completo: Tocha do Jogador
```rust
use sevenx_engine::*;
struct DungeonGame {
lighting: LightingSystem,
player_pos: (f32, f32),
torch_light: usize,
}
impl GameState for DungeonGame {
fn new() -> Self {
let mut lighting = LightingSystem::new();
// Ambiente muito escuro
lighting.set_ambient(10, 10, 15, 0.1);
// Tocha do jogador
let torch = Light::point(400.0, 300.0, 180.0)
.with_color(255, 180, 80)
.with_intensity(1.0);
let torch_light = lighting.add_light(torch);
// Tochas nas paredes
lighting.add_light(
Light::point(100.0, 100.0, 120.0)
.with_color(255, 150, 50)
.with_intensity(0.7)
);
Self {
lighting,
player_pos: (400.0, 300.0),
torch_light,
}
}
fn update(&mut self, dt: f32, input: &sevenx_engine::input::InputHandler, _world: &mut World) {
let speed = 200.0;
// Move jogador
if input.is_key_pressed(KeyCode::ArrowUp) {
self.player_pos.1 -= speed * dt;
}
if input.is_key_pressed(KeyCode::ArrowDown) {
self.player_pos.1 += speed * dt;
}
if input.is_key_pressed(KeyCode::ArrowLeft) {
self.player_pos.0 -= speed * dt;
}
if input.is_key_pressed(KeyCode::ArrowRight) {
self.player_pos.0 += speed * dt;
}
// Atualiza posição da tocha
self.lighting.lights[self.torch_light].position = self.player_pos;
}
fn draw(&mut self, _world: &World, frame: &mut [u8]) {
let width = 800;
let height = 600;
// Desenha dungeon com iluminação
for y in 0..height {
for x in 0..width {
let idx = ((y * width + x) * 4) as usize;
// Padrão de pedra
let base_color = if (x / 32 + y / 32) % 2 == 0 {
[60, 60, 60, 255]
} else {
[80, 80, 80, 255]
};
let lit_color = self.lighting.apply_lighting(
x as f32,
y as f32,
base_color
);
frame[idx..idx + 4].copy_from_slice(&lit_color);
}
}
// Desenha jogador
draw_circle(frame, width, self.player_pos, 8.0, [255, 255, 0, 255]);
}
}
```
## ✨ Efeitos Especiais
### Luz Pulsante
```rust
fn update(&mut self, dt: f32, ...) {
self.time += dt;
// Luz que pulsa
let pulse = (self.time * 3.0).sin() * 0.3 + 0.7;
self.lighting.lights[0].intensity = pulse;
}
```
### Luz que Segue o Mouse
```rust
if let Some((mx, my)) = input.mouse_position() {
self.lighting.lights[0].position = (mx as f32, my as f32);
}
```
### Lanterna (Spotlight que Rotaciona)
```rust
// Rotaciona spotlight baseado na direção do movimento
let angle = player_velocity.y.atan2(player_velocity.x).to_degrees();
self.lighting.lights[self.flashlight].direction = angle;
```
## 🎨 Combinando com Post-Processing
```rust
fn draw(&mut self, _world: &World, frame: &mut [u8]) {
// 1. Renderiza cena com iluminação
render_with_lighting(frame);
// 2. Aplica bloom para luzes brilhantes
self.post_processor.apply(frame, 800, 600);
}
```
## ⚡ Performance
Dicas para melhor performance:
- Limite o número de luzes ativas (< 10 para 60fps)
- Use raios menores quando possível
- Desabilite luzes fora da tela: `light.enabled = false`
- Considere atualizar iluminação a cada 2-3 frames
```rust
// Otimização: desabilita luzes distantes
for light in &mut self.lighting.lights {
let dist = distance(light.position, camera_center);
light.enabled = dist < screen_diagonal;
}
```
Execute o exemplo:
```bash
cargo run --example lighting_demo
```