sevenx_engine 0.2.11

Engine de jogos 2D/3D completa com suporte Android, física, áudio, partículas, tilemap, UI, eventos e sistema 3D avançado com PBR.
Documentation
use sevenx_engine::{
    collision::Collider,
    game_object::{Direction, GameObject, ObjectType, PlayerAction},
    input::InputHandler,
    sprite::SpriteSheet,
    ui::render_text,
    world::World,
    Engine, EngineConfig, GameState, KeyCode,
    GraphicsSettings, GraphicsQuality, PerformanceMonitor,
};

struct MyGame {
    score: u32,
    graphics: GraphicsSettings,
    performance: PerformanceMonitor,
    show_settings: bool,
    time: f32,
}

impl GameState for MyGame {
    fn new() -> Self {
        // Carrega ou usa configurações padrão (Muito Baixo)
        let graphics = GraphicsSettings::load("graphics_settings.json")
            .unwrap_or_else(|_| GraphicsSettings::default());
        
        println!("🎮 Jogo Teste - SevenX Engine v0.2.7");
        println!("📊 Qualidade Gráfica: {}", graphics.quality.name());
        println!("🎯 FPS Alvo: {}", graphics.target_fps);
        println!();
        println!("🎮 Controles:");
        println!("   WASD/Setas - Mover");
        println!("   Shift - Correr");
        println!("   F1 - Toggle Info");
        println!("   F2 - Ciclar Qualidade");
        println!("   Espaço - Ação");
        println!();
        
        MyGame { 
            score: 0,
            graphics,
            performance: PerformanceMonitor::new(),
            show_settings: false,
            time: 0.0,
        }
    }

    fn update(&mut self, dt: f32, input: &InputHandler, world: &mut World) {
        self.time += dt;
        
        // Atualiza monitor de performance
        let fps = 1.0 / dt;
        self.performance.update(fps, dt);
        
        // Ajuste dinâmico de qualidade
        self.graphics.dynamic_adjust(fps);
        
        // Toggle configurações com F1 (usando just_pressed!)
        if input.is_key_just_pressed(KeyCode::F1) {
            self.show_settings = !self.show_settings;
        }
        
        // Cicla qualidade gráfica com F2 (usando just_pressed!)
        if input.is_key_just_pressed(KeyCode::F2) {
            let current = self.graphics.quality.to_index();
            let new_quality = GraphicsQuality::from_index((current + 1) % 5);
            self.graphics.apply_preset(new_quality);
            println!("📊 Qualidade alterada para: {}", self.graphics.quality.name());
        }
        
        // Cria objetos na primeira execução
        if world.game_objects.is_empty() {
            self.setup_world(world);
        }

        // Encontra o jogador
        if let Some(player) = world
            .game_objects
            .iter_mut()
            .find(|obj| obj.object_type == ObjectType::Player && obj.active)
        {
            // Usa o novo sistema de eixos (v0.2.7!)
            let (axis_x, axis_y) = input.get_movement_vector();
            
            // Velocidade aumentada com Shift (v0.2.7!)
            let speed = if input.is_shift_pressed() { 400.0 } else { 200.0 };

            if axis_x != 0.0 || axis_y != 0.0 {
                player.current_action = PlayerAction::Walk;

                player.transform.translate(axis_x * speed * dt, axis_y * speed * dt);

                // Atualiza direção baseado no movimento
                if axis_y < 0.0 {
                    player.facing_direction = Direction::Up;
                } else if axis_y > 0.0 {
                    player.facing_direction = Direction::Down;
                } else if axis_x < 0.0 {
                    player.facing_direction = Direction::Left;
                } else if axis_x > 0.0 {
                    player.facing_direction = Direction::Right;
                }
            } else {
                player.current_action = PlayerAction::Idle;
            }
            
            // Ação com Espaço (usando just_pressed!)
            if input.is_key_just_pressed(KeyCode::Space) {
                println!("⚡ Ação executada!");
                self.score += 5;
            }
        }

        // Coleta moedas
        self.collect_coins(world);
    }

    fn draw(&mut self, _world: &World, pixels: &mut [u8]) {
        // Renderiza HUD
        let score_text = format!("SCORE: {}", self.score);
        render_text(&score_text, 10, 10, [255, 255, 255, 255], pixels, 800);

        // FPS com cores dinâmicas
        let fps = self.performance.average_fps();
        let fps_text = format!("FPS: {:.0}", fps);
        let fps_color = if fps >= 60.0 {
            [0, 255, 0, 255]
        } else if fps >= 30.0 {
            [255, 255, 0, 255]
        } else {
            [255, 0, 0, 255]
        };
        render_text(&fps_text, 10, 35, fps_color, pixels, 800);

        // Qualidade gráfica
        if self.show_settings {
            let quality_text = format!("Qualidade: {}", self.graphics.quality.name());
            render_text(&quality_text, 10, 60, [200, 200, 255, 255], pixels, 800);
            
            let target_text = format!("FPS Alvo: {}", self.graphics.target_fps);
            render_text(&target_text, 10, 85, [200, 200, 255, 255], pixels, 800);
            
            let particles_text = format!("Partículas Max: {}", self.graphics.get_particle_limit());
            render_text(&particles_text, 10, 110, [200, 200, 255, 255], pixels, 800);
            
            let resolution_text = format!("Resolução: {}%", (self.graphics.resolution_scale * 100.0) as i32);
            render_text(&resolution_text, 10, 135, [200, 200, 255, 255], pixels, 800);
            
            render_text("F1 - Ocultar Info | F2 - Ciclar Qualidade", 10, 160, [150, 150, 150, 255], pixels, 800);
        } else {
            render_text("F1 - Info | F2 - Qualidade", 10, 60, [150, 150, 150, 255], pixels, 800);
        }

        // Instruções com features v0.2.7
        render_text(
            "WASD/Setas: Mover | Shift: Correr | Espaco: Acao",
            150,
            550,
            [200, 200, 200, 255],
            pixels,
            800,
        );
        
        // Versão
        render_text(
            "SevenX Engine v0.2.7",
            650,
            10,
            [150, 150, 150, 255],
            pixels,
            800,
        );
    }
}

impl MyGame {
    fn setup_world(&self, world: &mut World) {
        // Cria jogador com sprite placeholder
        let mut player = GameObject::new(350.0, 250.0, ObjectType::Player)
            .with_collider(Collider::new(32.0, 32.0))
            .with_z_index(10);

        // Usa sprite placeholder (você pode substituir por seus próprios assets)
        player.sheets.insert(PlayerAction::Idle, SpriteSheet::create_placeholder());
        player.sheets.insert(PlayerAction::Walk, SpriteSheet::create_placeholder());

        world.add_object(player);

        // Cria algumas moedas
        for i in 0..5 {
            let mut coin = GameObject::new(100.0 + i as f32 * 150.0, 300.0, ObjectType::Coin)
                .with_collider(Collider::new(32.0, 32.0).as_trigger())
                .with_z_index(5);

            let coin_sprite = SpriteSheet::create_placeholder();
            coin.sheets.insert(PlayerAction::Idle, coin_sprite);
            world.add_object(coin);
        }
    }

    fn collect_coins(&mut self, world: &mut World) {
        let mut collected = Vec::new();

        if let Some(player) = world
            .game_objects
            .iter()
            .find(|obj| obj.object_type == ObjectType::Player)
        {
            if let Some(player_rect) = player.get_collision_rect() {
                for (i, obj) in world.game_objects.iter().enumerate() {
                    if obj.object_type == ObjectType::Coin && obj.active {
                        if let Some(coin_rect) = obj.get_collision_rect() {
                            if player_rect.intersects(&coin_rect) {
                                collected.push(i);
                                self.score += 10;
                                println!("💰 Moeda coletada! Score: {}", self.score);
                            }
                        }
                    }
                }
            }
        }

        for i in collected.iter().rev() {
            world.game_objects.remove(*i);
        }
    }
}

fn main() {
    println!("🎮 SevenX Engine v0.2.7 - Exemplo Básico");
    println!("📝 Use WASD ou setas para mover");
    println!("💡 Colete as moedas coloridas!");
    println!("⚡ Pressione Shift para correr!");
    println!("🎯 Pressione Espaço para ação!");
    println!();

    let config = EngineConfig::new()
        .with_title("SevenX Engine v0.2.7 - Exemplo Básico")
        .with_size(800, 600)
        .with_gravity(0.0);

    Engine::with_config(config).run::<MyGame>();
}