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::{
    input::InputHandler,
    save_system::GameSave,
    ui::{self, render_text},
    world::World,
    Engine, EngineConfig, GameState, KeyCode,
};

struct SaveDemo {
    save: GameSave,
    message: String,
    message_timer: f32,
}

impl GameState for SaveDemo {
    fn new() -> Self {
        SaveDemo {
            save: GameSave::new(),
            message: String::new(),
            message_timer: 0.0,
        }
    }

    fn update(&mut self, dt: f32, input: &InputHandler, _world: &mut World) {
        // Atualiza tempo de jogo
        self.save.game_progress.playtime_seconds += dt as u64;

        // Simula movimento do jogador
        let speed = 100.0;
        if input.is_key_pressed(KeyCode::ArrowUp) {
            self.save.player_data.position.1 -= speed * dt;
        }
        if input.is_key_pressed(KeyCode::ArrowDown) {
            self.save.player_data.position.1 += speed * dt;
        }
        if input.is_key_pressed(KeyCode::ArrowLeft) {
            self.save.player_data.position.0 -= speed * dt;
        }
        if input.is_key_pressed(KeyCode::ArrowRight) {
            self.save.player_data.position.0 += speed * dt;
        }

        // Salvar (S)
        if input.is_key_pressed(KeyCode::KeyS) {
            match self.save.save_json("saves/save1.json") {
                Ok(_) => {
                    self.show_message("💾 Jogo salvo com sucesso!");
                    println!("✅ Jogo salvo em saves/save1.json");
                }
                Err(e) => {
                    self.show_message(&format!("❌ Erro ao salvar: {}", e));
                }
            }
        }

        // Carregar (L)
        if input.is_key_pressed(KeyCode::KeyL) {
            match GameSave::load_json("saves/save1.json") {
                Ok(loaded_save) => {
                    self.save = loaded_save;
                    self.show_message("📂 Jogo carregado com sucesso!");
                    println!("✅ Jogo carregado de saves/save1.json");
                }
                Err(e) => {
                    self.show_message(&format!("❌ Erro ao carregar: {}", e));
                }
            }
        }

        // Ganhar XP (X)
        if input.is_key_pressed(KeyCode::KeyX) {
            self.save.player_data.experience += 100;
            self.show_message("⭐ +100 XP!");
        }

        // Aumentar score (P)
        if input.is_key_pressed(KeyCode::KeyP) {
            self.save.game_progress.score += 50;
            self.show_message("🎯 +50 pontos!");
        }

        // Atualiza timer da mensagem
        if self.message_timer > 0.0 {
            self.message_timer -= dt;
            if self.message_timer <= 0.0 {
                self.message.clear();
            }
        }
    }

    fn draw(&mut self, _world: &World, pixels: &mut [u8]) {
        // HUD
        let player_info = format!(
            "JOGADOR: {} | NIVEL: {} | XP: {}",
            self.save.player_data.name,
            self.save.player_data.level,
            self.save.player_data.experience
        );
        render_text(&player_info, 10, 10, [255, 255, 255, 255], pixels, 800);

        let progress_info = format!(
            "SCORE: {} | TEMPO: {}s",
            self.save.game_progress.score, self.save.game_progress.playtime_seconds
        );
        render_text(&progress_info, 10, 30, [255, 255, 255, 255], pixels, 800);

        let pos_info = format!(
            "POSICAO: ({:.0}, {:.0})",
            self.save.player_data.position.0, self.save.player_data.position.1
        );
        render_text(&pos_info, 10, 50, [255, 255, 255, 255], pixels, 800);

        // Desenha "jogador"
        ui::render_rect(
            self.save.player_data.position.0 as i32,
            self.save.player_data.position.1 as i32,
            32,
            32,
            [0, 255, 0, 255],
            pixels,
            800,
        );

        // Mensagem temporária
        if !self.message.is_empty() {
            render_text(&self.message, 250, 300, [255, 255, 0, 255], pixels, 800);
        }

        // Instruções
        render_text(
            "SETAS: MOVER | S: SALVAR | L: CARREGAR",
            150,
            550,
            [200, 200, 200, 255],
            pixels,
            800,
        );
        render_text(
            "X: +XP | P: +PONTOS",
            250,
            570,
            [200, 200, 200, 255],
            pixels,
            800,
        );
    }
}

impl SaveDemo {
    fn show_message(&mut self, message: &str) {
        self.message = message.to_string();
        self.message_timer = 2.0;
    }
}

fn main() {
    println!("💾 Sistema de Save/Load");
    println!("S - Salvar jogo");
    println!("L - Carregar jogo");
    println!("X - Ganhar XP");
    println!("P - Ganhar pontos");

    // Cria diretório de saves se não existir
    std::fs::create_dir_all("saves").ok();

    let config = EngineConfig::new()
        .with_title("SevenX Engine - Save/Load System")
        .with_size(800, 600);

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