use sevenx_engine::*;
use sevenx_engine::world::World;
struct AdvancedDemo {
lighting: LightingSystem,
player_light: usize,
pathfinder: Pathfinder,
enemy_pos: GridPos,
enemy_path: Option<Vec<GridPos>>,
post_processor: PostProcessor,
renderer3d: Renderer3D,
cube: Mesh3D,
particle_system_2d: ParticleSystem,
particle_system_3d: ParticleSystem3D,
shader_manager: ShaderManager,
player_pos: (f32, f32),
cell_size: i32,
time: f32,
toggle_cooldown: f32,
show_particles: bool,
}
impl GameState for AdvancedDemo {
fn new() -> Self {
let mut lighting = LightingSystem::new();
lighting.set_ambient(20, 20, 30, 0.2);
let player_light = lighting.add_light(
Light::point(400.0, 300.0, 200.0)
.with_color(255, 200, 100)
.with_intensity(1.0)
);
lighting.add_light(
Light::spot(100.0, 100.0, 135.0, 45.0, 250.0)
.with_color(100, 100, 255)
.with_intensity(0.8)
);
let mut pathfinder = Pathfinder::new(40, 30);
for x in 10..30 {
pathfinder.add_obstacle(x, 15);
}
for y in 5..20 {
pathfinder.add_obstacle(20, y);
}
let enemy_pos = GridPos::new(35, 25);
let mut post_processor = PostProcessor::new();
post_processor.add_effect(PostEffect::Bloom {
threshold: 0.7,
intensity: 0.3,
});
post_processor.add_effect(PostEffect::Vignette {
intensity: 0.4,
radius: 0.9,
});
let mut renderer3d = Renderer3D::new(200, 150);
renderer3d.camera.position = Vec3::new(0.0, 2.0, 5.0);
renderer3d.camera.look_at(Vec3::zero());
renderer3d.wireframe = true;
let mut cube = Mesh3D::cube(1.5);
cube.position = Vec3::new(0.0, 0.0, 0.0);
let particle_system_2d = ParticleSystem::new(1000)
.with_blend_mode(BlendMode::Additive);
let particle_system_3d = ParticleSystem3D::new(200);
let mut shader_manager = ShaderManager::new();
shader_manager.add_shader(
Shader::new(ShaderType::Bloom)
.with_parameter("threshold", 200.0)
.with_parameter("bloom_intensity", 1.2)
);
Self {
lighting,
player_light,
pathfinder,
enemy_pos,
enemy_path: None,
post_processor,
renderer3d,
cube,
particle_system_2d,
particle_system_3d,
shader_manager,
player_pos: (400.0, 300.0),
cell_size: 20,
time: 0.0,
toggle_cooldown: 0.0,
show_particles: true,
}
}
fn update(&mut self, dt: f32, input: &sevenx_engine::input::InputHandler, _world: &mut World) {
self.time += dt;
let (move_x, move_y) = input.get_movement_vector();
let speed = if input.is_shift_pressed() { 400.0 } else { 200.0 };
let mut moved = false;
if move_x != 0.0 || move_y != 0.0 {
self.player_pos.0 += move_x * speed * dt;
self.player_pos.1 += move_y * speed * dt;
moved = true;
}
self.lighting.lights[self.player_light].position = self.player_pos;
if moved && self.show_particles {
use rand::Rng;
let mut rng = rand::thread_rng();
for _ in 0..2 {
let particle = Particle::new(
self.player_pos.0,
self.player_pos.1,
rng.gen_range(-20.0..20.0),
rng.gen_range(-20.0..20.0),
rng.gen_range(0.5..1.0),
[100, 200, 255, 200],
rng.gen_range(3.0..6.0),
)
.with_scale(1.0, -0.5);
self.particle_system_2d.emit(particle);
}
}
if input.is_key_just_pressed(KeyCode::KeyP) {
self.show_particles = !self.show_particles;
println!("💫 Partículas: {}", if self.show_particles { "ON" } else { "OFF" });
}
if input.is_key_just_pressed(KeyCode::KeyX) {
self.particle_system_3d.explosion(Vec3::new(0.0, 0.0, 0.0));
println!("💥 Explosão 3D!");
}
if input.is_key_just_pressed(KeyCode::KeyF) {
self.particle_system_3d.fire(Vec3::new(0.0, 0.0, 0.0));
println!("🔥 Fogo!");
}
if input.is_key_just_pressed(KeyCode::KeyM) {
self.particle_system_3d.magic(Vec3::new(0.0, 0.0, 0.0));
println!("✨ Magia!");
}
self.particle_system_2d.update(dt, 100.0);
self.particle_system_3d.update(dt);
if moved || self.enemy_path.is_none() {
let player_grid = GridPos::new(
(self.player_pos.0 / self.cell_size as f32) as i32,
(self.player_pos.1 / self.cell_size as f32) as i32,
);
self.enemy_path = self.pathfinder.find_path(self.enemy_pos, player_grid);
}
if let Some(path) = &self.enemy_path {
if path.len() > 1 && self.time.fract() < 0.1 {
self.enemy_pos = path[1];
}
}
self.cube.rotation.y += dt;
self.cube.rotation.x += dt * 0.5;
if input.is_key_just_pressed(KeyCode::Space) {
self.post_processor.set_enabled(!self.post_processor.enabled);
println!("🎨 Post-Processing: {}", if self.post_processor.enabled { "ON" } else { "OFF" });
}
}
fn draw(&mut self, _world: &World, frame: &mut [u8]) {
let width = 800;
let height = 600;
for y in 0..self.pathfinder.grid_height {
for x in 0..self.pathfinder.grid_width {
let pos = GridPos::new(x, y);
let px = (x * self.cell_size) as f32;
let py = (y * self.cell_size) as f32;
let base_color = if self.pathfinder.obstacles.contains(&pos) {
[80, 50, 50, 255]
} else if pos == self.enemy_pos {
[255, 50, 50, 255]
} else {
let checker = ((x + y) % 2 == 0) as u8;
let c = 60 + checker * 20;
[c, c, c, 255]
};
for dy in 0..self.cell_size {
for dx in 0..self.cell_size {
let screen_x = px + dx as f32;
let screen_y = py + dy as f32;
if screen_x < width as f32 && screen_y < height as f32 {
let lit_color = self.lighting.apply_lighting(
screen_x,
screen_y,
base_color
);
let idx = ((screen_y as u32 * width + screen_x as u32) * 4) as usize;
if idx + 3 < frame.len() {
frame[idx..idx + 4].copy_from_slice(&lit_color);
}
}
}
}
}
}
if let Some(path) = &self.enemy_path {
for pos in path {
let px = pos.x * self.cell_size;
let py = pos.y * self.cell_size;
for dy in 2..(self.cell_size - 2) {
for dx in 2..(self.cell_size - 2) {
let x = px + dx;
let y = py + dy;
if x >= 0 && x < width as i32 && y >= 0 && y < height as i32 {
let idx = ((y * width as i32 + x) * 4) as usize;
if idx + 3 < frame.len() {
frame[idx] = 100;
frame[idx + 1] = 150;
frame[idx + 2] = 255;
frame[idx + 3] = 255;
}
}
}
}
}
}
let px = self.player_pos.0 as i32;
let py = self.player_pos.1 as i32;
for dy in -8..=8 {
for dx in -8..=8 {
if dx * dx + dy * dy <= 64 {
let x = px + dx;
let y = py + dy;
if x >= 0 && x < width as i32 && y >= 0 && y < height as i32 {
let idx = ((y * width as i32 + x) * 4) as usize;
if idx + 3 < frame.len() {
frame[idx] = 255;
frame[idx + 1] = 255;
frame[idx + 2] = 0;
frame[idx + 3] = 255;
}
}
}
}
}
let mut mini_frame = vec![0u8; 200 * 150 * 4];
for pixel in mini_frame.chunks_exact_mut(4) {
pixel.copy_from_slice(&[30, 30, 50, 255]);
}
self.renderer3d.render_mesh(&self.cube, &mut mini_frame, 200, 150);
for y in 0..150 {
for x in 0..200 {
let src_idx = ((y * 200 + x) * 4) as usize;
let dst_x = width - 210 + x;
let dst_y = 10 + y;
let dst_idx = ((dst_y * width + dst_x) * 4) as usize;
if dst_idx + 3 < frame.len() && src_idx + 3 < mini_frame.len() {
frame[dst_idx..dst_idx + 4].copy_from_slice(&mini_frame[src_idx..src_idx + 4]);
}
}
}
if self.show_particles {
self.particle_system_2d.render(frame, 0.0, 0.0, width, height);
}
self.shader_manager.apply_all(frame, width, height);
self.post_processor.apply(frame, width, height);
let text = format!(
"SPACE: Post-Processing {} | P: Particles {} | X: Explosion 3D | Particles: {}",
if self.post_processor.enabled { "ON" } else { "OFF" },
if self.show_particles { "ON" } else { "OFF" },
self.particle_system_2d.count()
);
for y in 550..580 {
for x in 10..300 {
let idx = ((y * width + x) * 4) as usize;
if idx + 3 < frame.len() {
frame[idx] = 0;
frame[idx + 1] = 0;
frame[idx + 2] = 0;
frame[idx + 3] = 200;
}
}
}
}
}
fn main() {
println!("🎮 SevenX Engine v0.2.7 - Advanced Features Demo");
println!("✨ Features:");
println!(" 💡 Sistema de Iluminação");
println!(" 🗺️ Pathfinding A*");
println!(" 🎨 Post-Processing");
println!(" 🎲 Renderização 3D");
println!(" 💫 Partículas 2D e 3D");
println!(" 🎨 Shaders Avançados");
println!();
println!("🎯 Controles:");
println!(" WASD/Setas - Mover (Shift para correr)");
println!(" Space - Toggle Post-Processing");
println!(" P - Toggle Partículas");
println!(" X - Explosão 3D");
println!(" F - Fogo 3D");
println!(" M - Magia 3D");
println!();
let config = EngineConfig::default()
.with_title("SevenX Engine v0.2.7 - Advanced Features Demo")
.with_size(800, 600);
let engine = Engine::with_config(config);
engine.run::<AdvancedDemo>();
}