use std::fs;
use std::io::Write;
use std::path::Path;
fn main() {
println!("========================================");
println!(" SevenX Engine v0.2.8 - CLI");
println!("========================================");
println!();
let args: Vec<String> = std::env::args().collect();
if args.len() < 2 {
print_help();
return;
}
match args[1].as_str() {
"new" => {
if args.len() < 3 {
println!("❌ Erro: Especifique o nome do projeto");
println!("Uso: sevenx new meu_jogo");
return;
}
create_project(&args[2]);
}
"template" => {
if args.len() < 3 {
list_templates();
} else {
create_from_template(&args[2], args.get(3).map(|s| s.as_str()));
}
}
"run" => {
run_project();
}
"build" => {
build_project();
}
"help" | "--help" | "-h" => {
print_help();
}
_ => {
println!("❌ Comando desconhecido: {}", args[1]);
print_help();
}
}
}
fn print_help() {
println!("📚 Comandos disponíveis:");
println!();
println!(" sevenx new <nome> - Cria um novo projeto");
println!(" sevenx template [tipo] - Lista ou cria projeto de template");
println!(" sevenx run - Roda o projeto atual");
println!(" sevenx build - Compila o projeto");
println!(" sevenx help - Mostra esta ajuda");
println!();
println!("📦 Templates disponíveis:");
println!(" platformer - Jogo de plataforma 2D");
println!(" topdown - Jogo top-down 2D");
println!(" fps - FPS 3D");
println!(" rpg - RPG com inventário e quests");
println!(" empty - Projeto vazio");
println!();
println!("Exemplos:");
println!(" sevenx new meu_jogo");
println!(" sevenx template platformer meu_platformer");
println!(" sevenx run");
}
fn create_project(name: &str) {
println!("✨ Criando projeto: {}", name);
if Path::new(name).exists() {
println!("❌ Erro: Pasta '{}' já existe!", name);
return;
}
fs::create_dir(name).expect("Falha ao criar pasta");
fs::create_dir(format!("{}/src", name)).expect("Falha ao criar src");
fs::create_dir(format!("{}/assets", name)).expect("Falha ao criar assets");
let cargo_toml = format!(r#"[package]
name = "{}"
version = "0.1.0"
edition = "2024"
[dependencies]
sevenx_engine = "0.2.8"
"#, name);
fs::write(format!("{}/Cargo.toml", name), cargo_toml)
.expect("Falha ao criar Cargo.toml");
let main_rs = r#"use sevenx_engine::*;
struct MeuJogo {
player_x: f32,
player_y: f32,
}
impl GameState for MeuJogo {
fn new() -> Self {
Self {
player_x: 400.0,
player_y: 300.0,
}
}
fn update(&mut self, dt: f32, input: &input::InputHandler, _world: &mut World) {
// Movimento com WASD
let (axis_x, axis_y) = input.get_movement_vector();
let speed = 200.0;
self.player_x += axis_x * speed * dt;
self.player_y += axis_y * speed * dt;
}
fn draw(&mut self, _world: &World, pixels: &mut [u8]) {
// Limpa tela
for pixel in pixels.chunks_exact_mut(4) {
pixel.copy_from_slice(&[20, 25, 35, 255]);
}
// Desenha player
let mut prims = Primitives2D::new(pixels, 800, 600);
prims.draw_circle_filled(
self.player_x as i32,
self.player_y as i32,
20,
[100, 200, 255, 255]
);
}
}
fn main() {
let config = EngineConfig {
window_title: "Meu Jogo".to_string(),
window_width: 800,
window_height: 600,
target_fps: 60,
clear_color: [20, 25, 35, 255],
gravity: 0.0,
};
Engine::with_config(config).run::<MeuJogo>();
}
"#;
fs::write(format!("{}/src/main.rs", name), main_rs)
.expect("Falha ao criar main.rs");
let readme = format!(r#"# {}
Projeto criado com SevenX Engine v0.2.8
## Como rodar
```bash
cargo run
```
## Como compilar
```bash
cargo build --release
```
O executável estará em `target/release/{}.exe`
## Documentação
- [Guia da Engine](https://github.com/sevenx777-dev/SevenX-Engine)
- [Exemplos](https://github.com/sevenx777-dev/SevenX-Engine/tree/main/examples)
"#, name, name);
fs::write(format!("{}/README.md", name), readme)
.expect("Falha ao criar README");
println!("✅ Projeto criado com sucesso!");
println!();
println!("📁 Estrutura:");
println!(" {}/", name);
println!(" ├── Cargo.toml");
println!(" ├── README.md");
println!(" ├── src/");
println!(" │ └── main.rs");
println!(" └── assets/");
println!();
println!("🚀 Próximos passos:");
println!(" cd {}", name);
println!(" cargo run");
}
fn list_templates() {
println!("📦 Templates disponíveis:");
println!();
println!(" 1. platformer - Jogo de plataforma 2D");
println!(" 2. topdown - Jogo top-down 2D");
println!(" 3. fps - FPS 3D");
println!(" 4. rpg - RPG com inventário e quests");
println!(" 5. empty - Projeto vazio");
println!();
println!("Uso: sevenx template <tipo> <nome>");
println!("Exemplo: sevenx template platformer meu_platformer");
}
fn create_from_template(template: &str, name: Option<&str>) {
let project_name = name.unwrap_or(template);
println!("✨ Criando projeto '{}' do template '{}'", project_name, template);
create_project(project_name);
let template_code = match template {
"platformer" => get_platformer_template(),
"topdown" => get_topdown_template(),
"fps" => get_fps_template(),
"rpg" => get_rpg_template(),
"empty" => return, _ => {
println!("❌ Template desconhecido: {}", template);
return;
}
};
fs::write(format!("{}/src/main.rs", project_name), template_code)
.expect("Falha ao criar template");
println!("✅ Projeto criado do template '{}'!", template);
println!();
println!("🚀 Para rodar:");
println!(" cd {}", project_name);
println!(" cargo run");
}
fn get_platformer_template() -> String {
r#"use sevenx_engine::*;
struct Platformer {
player_x: f32,
player_y: f32,
velocity_y: f32,
on_ground: bool,
}
impl GameState for Platformer {
fn new() -> Self {
Self {
player_x: 100.0,
player_y: 400.0,
velocity_y: 0.0,
on_ground: false,
}
}
fn update(&mut self, dt: f32, input: &input::InputHandler, _world: &mut World) {
// Movimento horizontal
if input.is_key_down(KeyCode::KeyA) {
self.player_x -= 200.0 * dt;
}
if input.is_key_down(KeyCode::KeyD) {
self.player_x += 200.0 * dt;
}
// Pulo
if input.is_key_pressed(KeyCode::Space) && self.on_ground {
self.velocity_y = -500.0;
self.on_ground = false;
}
// Gravidade
self.velocity_y += 980.0 * dt;
self.player_y += self.velocity_y * dt;
// Chão
if self.player_y >= 500.0 {
self.player_y = 500.0;
self.velocity_y = 0.0;
self.on_ground = true;
}
}
fn draw(&mut self, _world: &World, pixels: &mut [u8]) {
for pixel in pixels.chunks_exact_mut(4) {
pixel.copy_from_slice(&[135, 206, 235, 255]);
}
let mut prims = Primitives2D::new(pixels, 800, 600);
// Chão
prims.draw_rect_filled(0, 520, 800, 80, [100, 200, 100, 255]);
// Player
prims.draw_rect_filled(
self.player_x as i32 - 15,
self.player_y as i32 - 30,
30,
30,
[255, 100, 100, 255]
);
}
}
fn main() {
Engine::new().run::<Platformer>();
}
"#.to_string()
}
fn get_topdown_template() -> String {
r#"use sevenx_engine::*;
struct TopDown {
player_x: f32,
player_y: f32,
}
impl GameState for TopDown {
fn new() -> Self {
Self {
player_x: 400.0,
player_y: 300.0,
}
}
fn update(&mut self, dt: f32, input: &input::InputHandler, _world: &mut World) {
let (axis_x, axis_y) = input.get_movement_vector();
let speed = 200.0;
self.player_x += axis_x * speed * dt;
self.player_y += axis_y * speed * dt;
}
fn draw(&mut self, _world: &World, pixels: &mut [u8]) {
for pixel in pixels.chunks_exact_mut(4) {
pixel.copy_from_slice(&[50, 100, 50, 255]);
}
let mut prims = Primitives2D::new(pixels, 800, 600);
prims.draw_circle_filled(
self.player_x as i32,
self.player_y as i32,
20,
[255, 200, 100, 255]
);
}
}
fn main() {
Engine::new().run::<TopDown>();
}
"#.to_string()
}
fn get_fps_template() -> String {
r#"use sevenx_engine::*;
struct FPS {
renderer3d: Renderer3D,
cube: Mesh3D,
angle: f32,
}
impl GameState for FPS {
fn new() -> Self {
let mut renderer3d = Renderer3D::new(800, 600);
renderer3d.camera.position = Vec3::new(0.0, 2.0, 5.0);
let cube = Mesh3D::cube(2.0);
Self {
renderer3d,
cube,
angle: 0.0,
}
}
fn update(&mut self, dt: f32, _input: &input::InputHandler, _world: &mut World) {
self.angle += 50.0 * dt;
self.cube.rotation.y = self.angle;
}
fn draw(&mut self, _world: &World, pixels: &mut [u8]) {
for pixel in pixels.chunks_exact_mut(4) {
pixel.copy_from_slice(&[135, 206, 235, 255]);
}
self.renderer3d.clear_zbuffer();
self.renderer3d.render_mesh(&self.cube, pixels, 800, 600);
}
}
fn main() {
Engine::new().run::<FPS>();
}
"#.to_string()
}
fn get_rpg_template() -> String {
r#"use sevenx_engine::*;
struct RPG {
player_x: f32,
player_y: f32,
inventory: Inventory,
quests: QuestSystem,
}
impl GameState for RPG {
fn new() -> Self {
let mut inventory = Inventory::new(20);
inventory.add_item(Item::weapon("sword", "Espada", 10), 1);
inventory.add_gold(100);
let quests = QuestSystem::new();
Self {
player_x: 400.0,
player_y: 300.0,
inventory,
quests,
}
}
fn update(&mut self, dt: f32, input: &input::InputHandler, _world: &mut World) {
let (axis_x, axis_y) = input.get_movement_vector();
let speed = 150.0;
self.player_x += axis_x * speed * dt;
self.player_y += axis_y * speed * dt;
if input.is_key_pressed(KeyCode::KeyI) {
println!("💰 Gold: {}", self.inventory.gold);
}
}
fn draw(&mut self, _world: &World, pixels: &mut [u8]) {
for pixel in pixels.chunks_exact_mut(4) {
pixel.copy_from_slice(&[40, 60, 40, 255]);
}
let mut prims = Primitives2D::new(pixels, 800, 600);
prims.draw_rect_filled(
self.player_x as i32 - 10,
self.player_y as i32 - 10,
20,
20,
[200, 100, 255, 255]
);
}
}
fn main() {
Engine::new().run::<RPG>();
}
"#.to_string()
}
fn run_project() {
println!("🚀 Rodando projeto...");
std::process::Command::new("cargo")
.arg("run")
.status()
.expect("Falha ao rodar projeto");
}
fn build_project() {
println!("🔨 Compilando projeto...");
std::process::Command::new("cargo")
.args(&["build", "--release"])
.status()
.expect("Falha ao compilar projeto");
println!("✅ Compilado! Executável em: target/release/");
}