use sevenx_engine::*;
use sevenx_engine::world::World;
struct PathfindingDemo {
pathfinder: Pathfinder,
start: GridPos,
goal: GridPos,
path: Option<Vec<GridPos>>,
cell_size: i32,
input_cooldown: f32,
}
impl GameState for PathfindingDemo {
fn new() -> Self {
let grid_width = 40;
let grid_height = 30;
let mut pathfinder = Pathfinder::new(grid_width, grid_height);
for x in 10..30 {
pathfinder.add_obstacle(x, 15);
}
for y in 5..20 {
pathfinder.add_obstacle(20, y);
}
for x in 5..15 {
pathfinder.add_obstacle(x, 10);
}
let start = GridPos::new(5, 5);
let goal = GridPos::new(35, 25);
let path = pathfinder.find_path(start, goal);
Self {
pathfinder,
start,
goal,
path,
cell_size: 20,
input_cooldown: 0.0,
}
}
fn update(&mut self, dt: f32, input: &sevenx_engine::input::InputHandler, _world: &mut World) {
self.input_cooldown -= dt;
let cooldown_time = if input.is_shift_pressed() { 0.05 } else { 0.15 };
if self.input_cooldown <= 0.0 {
let mut moved = false;
let (move_x, move_y) = input.get_movement_vector();
if move_y < 0.0 && self.goal.y > 0 {
self.goal.y -= 1;
moved = true;
}
if move_y > 0.0 && self.goal.y < self.pathfinder.grid_height - 1 {
self.goal.y += 1;
moved = true;
}
if move_x < 0.0 && self.goal.x > 0 {
self.goal.x -= 1;
moved = true;
}
if move_x > 0.0 && self.goal.x < self.pathfinder.grid_width - 1 {
self.goal.x += 1;
moved = true;
}
if input.is_key_just_pressed(KeyCode::Space) {
let pos = self.goal;
if self.pathfinder.obstacles.contains(&pos) {
self.pathfinder.remove_obstacle(pos.x, pos.y);
println!("🟩 Obstáculo removido em ({}, {})", pos.x, pos.y);
} else {
self.pathfinder.add_obstacle(pos.x, pos.y);
println!("🟫 Obstáculo adicionado em ({}, {})", pos.x, pos.y);
}
moved = true;
}
if moved {
self.path = self.pathfinder.find_path(self.start, self.goal);
if let Some(path) = &self.path {
println!("🗺️ Caminho encontrado com {} passos", path.len());
} else {
println!("❌ Nenhum caminho encontrado!");
}
self.input_cooldown = cooldown_time;
}
}
}
fn draw(&mut self, _world: &World, frame: &mut [u8]) {
let width = 800;
for pixel in frame.chunks_exact_mut(4) {
pixel[0] = 40;
pixel[1] = 40;
pixel[2] = 40;
pixel[3] = 255;
}
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;
let py = y * self.cell_size;
let color = if self.pathfinder.obstacles.contains(&pos) {
[100, 50, 50, 255] } else if pos == self.start {
[50, 255, 50, 255] } else if pos == self.goal {
[255, 50, 50, 255] } else {
[60, 60, 60, 255] };
self.draw_rect(frame, width, px, py, self.cell_size - 2, self.cell_size - 2, color);
}
}
if let Some(path) = &self.path {
for pos in path {
let px = pos.x * self.cell_size;
let py = pos.y * self.cell_size;
self.draw_rect(frame, width, px, py, self.cell_size - 2, self.cell_size - 2, [100, 150, 255, 255]);
}
}
}
}
impl PathfindingDemo {
fn draw_rect(&self, frame: &mut [u8], width: u32, x: i32, y: i32, w: i32, h: i32, color: [u8; 4]) {
for dy in 0..h {
for dx in 0..w {
let px = x + dx;
let py = y + dy;
if px >= 0 && px < width as i32 && py >= 0 && py < 600 {
let idx = ((py * width as i32 + px) * 4) as usize;
if idx + 3 < frame.len() {
frame[idx] = color[0];
frame[idx + 1] = color[1];
frame[idx + 2] = color[2];
frame[idx + 3] = color[3];
}
}
}
}
}
}
fn main() {
println!("🎮 SevenX Engine v0.2.7 - Pathfinding Demo");
println!("🗺️ Sistema de Pathfinding A*");
println!();
println!("🎯 Controles (com melhorias v0.2.7!):");
println!(" WASD/Setas - Mover objetivo");
println!(" Espaço - Toggle obstáculo");
println!(" Shift - Mover mais rápido (v0.2.7!)");
println!();
println!("🟢 Verde = Início | 🔴 Vermelho = Objetivo");
println!("🔵 Azul = Caminho | 🟤 Marrom = Obstáculo");
println!();
let config = EngineConfig::default()
.with_title("SevenX Engine v0.2.7 - Pathfinding A* Demo")
.with_size(800, 600);
let engine = Engine::with_config(config);
engine.run::<PathfindingDemo>();
}