A modular 2D physics engine and game framework written in Rust. Designed for real-time simulations, games, and educational exploration of physics concepts.
-
🔬 Physics Simulation
- Rigid body dynamics with linear and angular motion
- Collision detection (circles, AABBs)
- Contact resolution with friction and restitution
- Pluggable integrators (Semi-implicit Euler, Verlet)
- Configurable gravity and damping
-
🧮 Math Library
- Dependency-free 2D vector math (
Vec2) - Axis-aligned bounding boxes (
AABB) - Circles, rays, and transforms
- Utility functions: lerp, clamp, remap, smooth_step
- Dependency-free 2D vector math (
-
🎨 Renderer
- Minimal CPU-based 2D rendering
- Drawing primitives: circles, lines, rectangles
- Frame buffer rendering via pixels
-
🎮 Game Collections
- Pre-built game objects: Stickman, Spaceship, Planet
- Ready-to-use animated characters with movement logic
-
🌐 Cross-Platform
- Native: macOS (ARM64/x86_64), Linux (ARM64/x86_64)
- Web: WebAssembly (wasm32-unknown-unknown)
gravita/
├── crates/
│ ├── math/ # 2D vector math, geometry primitives
│ ├── physics/ # Rigid body dynamics, collision detection
│ ├── renderer/ # Minimal 2D rendering utilities
│ ├── collections/ # Pre-built game objects (Stickman, Spaceship, etc.)
│ ├── engine-core/ # Core engine orchestration (WIP)
│ ├── input/ # Input handling abstraction (WIP)
│ └── assets/ # Asset loading utilities (WIP)
└── examples/
├── bouncing-balls/ # Physics demo with bouncing balls
├── gravity-arena/ # Orbital mechanics with spaceship
├── rotating-rod/ # Angular momentum demonstration
├── stickman-walk/ # Animated character with controls
└── tetris/ # Classic Tetris implementation
- Rust nightly (2025-08-08 or later)
The project uses rust-toolchain.toml to automatically select the correct toolchain.
# Clone the repository
git clone https://github.com/cantoramann/gravita.git
cd gravita
# Run the bouncing balls demo
cargo run --example bouncing-balls
# Run the gravity arena (spaceship simulation)
cargo run -p gravity-arena
# Run the stickman walking demo
cargo run -p stickman-walkAdd the crates you need to your Cargo.toml:
[dependencies]
gravita-math = { git = "https://github.com/cantoramann/gravita" }
gravita-physics = { git = "https://github.com/cantoramann/gravita" }use gravita_math::{Vec2, Circle};
use gravita_physics::{PhysicsWorld, RigidBody, CollisionShape, BodyType};
fn main() {
// Create a physics world
let mut world = PhysicsWorld::new();
world.set_gravity(Vec2::new(0.0, -500.0));
// Create a static ground
let ground = RigidBody::new(0, CollisionShape::AABB(
AABB::from_center_size(Vec2::ZERO, Vec2::new(800.0, 50.0))
))
.with_type(BodyType::Static)
.with_position(Vec2::new(400.0, 25.0));
world.add_body(ground);
// Create a bouncing ball
let ball = RigidBody::new(0, CollisionShape::Circle(
Circle::new(Vec2::ZERO, 20.0)
))
.with_position(Vec2::new(400.0, 300.0))
.with_density(1.0);
world.add_body(ball);
// Simulate
let dt = 1.0 / 60.0;
for _ in 0..600 {
world.step(dt);
for body in world.get_bodies() {
println!("Body {} at {:?}", body.id, body.position);
}
}
}use gravita_math::{Vec2, lerp, clamp};
let a = Vec2::new(3.0, 4.0);
let b = Vec2::new(1.0, 2.0);
// Basic operations
let sum = a + b; // Vec2(4.0, 6.0)
let scaled = a * 2.0; // Vec2(6.0, 8.0)
let length = a.length(); // 5.0
let normalized = a.normalize(); // Vec2(0.6, 0.8)
let dot = a.dot(b); // 11.0
// Rotation
let rotated = Vec2::RIGHT.rotate(std::f32::consts::FRAC_PI_2); // Vec2(0.0, 1.0)
// Interpolation
let mid = a.lerp(b, 0.5); // Vec2(2.0, 3.0)// After stepping the physics world
for event in world.get_collision_events() {
println!(
"Collision between {} and {} with impulse {}",
event.body_a,
event.body_b,
event.impulse_magnitude
);
// Use impulse_magnitude for sound/damage systems
if event.impulse_magnitude > 100.0 {
play_impact_sound(event.impulse_magnitude);
}
}# Build all crates
cargo build --workspace
# Build in release mode
cargo build --workspace --release
# Build for WebAssembly
cargo build --target wasm32-unknown-unknown -p stickman-walk# Run all tests
cargo test --workspace
# Run tests with output
cargo test --workspace -- --nocapture# Check formatting
cargo fmt --check
# Run clippy
cargo clippy --workspace --all-targets# Generate documentation
cargo doc --workspace --no-deps --open| Example | Description | Controls |
|---|---|---|
bouncing-balls |
Physics demo with bouncing balls | Click to spawn balls, Esc to exit |
gravity-arena |
Orbital mechanics simulation | Arrow keys to thrust/turn, Esc to exit |
rotating-rod |
Angular momentum demonstration | Mouse to interact |
stickman-walk |
Animated stickman character | A/D to walk, Space to jump |
tetris |
Classic Tetris game | Arrow keys, Space to drop |
- Polygon collision shapes
- Constraint/joint system
- Spatial hashing broad-phase optimization
- GPU-accelerated rendering (wgpu)
- Audio integration
- ECS integration (bevy compatibility)
This project is licensed under the MIT License.
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.