shadowengine2d 1.2.0

A comprehensive 2D game engine built in Rust with ECS, rendering, audio, assets, animations, and scene management
Documentation

ShadowEngine2D

A comprehensive 2D game engine built in Rust, featuring Entity-Component-System (ECS) architecture, modern graphics rendering, audio systems, asset management, animations, and scene management.

Features

  • 🎮 Entity-Component-System (ECS) - Flexible and performant game object management
  • 🎨 Modern Graphics - GPU-accelerated rendering with WGPU
  • 🔊 Audio System - 3D positional audio, effects, and music playback
  • 📦 Asset Management - Hot-reloadable assets with multiple format support
  • 🎬 Animation System - Sprite animations and tweening with easing functions
  • 🎭 Scene Management - Hierarchical scenes with transitions and lifecycle management
  • ⌨️ Input Handling - Keyboard, mouse, and gamepad support
  • 🖼️ UI System - Immediate-mode GUI with flexible layouts
  • ⏱️ Time Management - Delta time, time scaling, and frame-rate independent logic

Quick Start

Add this to your Cargo.toml:

[dependencies]
shadowengine2d = "1.1.0"

Basic Usage

use shadowengine2d::prelude::*;

fn main() -> EngineResult<()> {
    App::new()
        .set_window(WindowConfig {
            title: "My Game".to_string(),
            width: 800,
            height: 600,
            resizable: true,
        })
        .add_startup_system(setup)
        .add_system(update)
        .build()
        .run()
}

fn setup(engine: &mut Engine, resources: &mut Resources) -> EngineResult<()> {
    engine.entities.spawn()
        .ball(400.0, 300.0, 100.0, -150.0, Color::RED, 50.0)
        .build();
    Ok(())
}

fn update(engine: &mut Engine, resources: &mut Resources) -> EngineResult<()> {
    if engine.input.is_key_pressed(KeyCode::Space) {
        engine.entities.spawn()
            .at_position(400.0, 100.0)
            .with_colored_square(Color::BLUE, 32.0)
            .with_movement(0.0, -200.0)
            .build();
    }
    Ok(())
}

Entity Creation

let entity = engine.entities.spawn()
    .at_position(100.0, 200.0)
    .with_colored_square(Color::GREEN, 64.0)
    .build();

let player = engine.entities.spawn()
    .game_object(
        Position::new(400.0, 300.0),
        Sprite::new(Color::WHITE, Size::new(32.0, 48.0))
    )
    .with_velocity(Velocity::zero())
    .build();

let ball = engine.entities.spawn()
    .ball(x, y, vel_x, vel_y, color, size)
    .build();

Resources

#[derive(Debug)]
struct GameState {
    score: u32,
    lives: u32,
}

app.insert_resource(GameState { score: 0, lives: 3 });

fn game_logic(engine: &mut Engine, resources: &mut Resources) -> EngineResult<()> {
    let mut state = resources.get_mut::<GameState>().unwrap();
    state.score += 10;
    Ok(())
}

UI

fn ui_system(engine: &mut Engine, resources: &mut Resources) -> EngineResult<()> {
    let mut ui = resources.get_mut::<UiContext>().unwrap();
    
    ui.panel(Rect::new(10.0, 10.0, 200.0, 100.0), Color::new(0.0, 0.0, 0.0, 0.7));
    ui.button(Rect::new(20.0, 30.0, 100.0, 30.0), "Start", ButtonStyle::primary());
    
    ui.render_to_entities(&mut engine.entities);
    Ok(())
}

Debug Output

use shadowengine2d::{Output, debug, info, warn, error};

// Enable/disable debug output
Output::set_enabled(true);

// Different log levels
Output::debug("Debug information");
Output::info("General information");
Output::warn("Warning message");
Output::error("Error message (always shown)");

// Or use convenient macros with formatting
debug!("Player at position ({}, {})", x, y);
info!("Score: {}, Lives: {}", score, lives);
warn!("Low health: {}%", health_percent);
error!("Failed to load asset: {}", filename);

Examples

cargo run --example bouncing_ball
cargo run --example modern_game
cargo run --example output_demo