use shadow_engine_2d::prelude::*;
use winit::keyboard::KeyCode;
fn main() {
env_logger::init();
let mut engine = Engine::builder()
.title("Shadow Engine 2D - Particles & Camera Demo")
.size(1280, 720)
.build();
let mut particle_system = ParticleSystem::new();
let physics = PhysicsSystem::new();
let camera_entity = engine.world_mut().spawn();
if let Some(entity) = engine.world_mut().entity_mut(camera_entity) {
entity.add(Camera::new(1280.0, 720.0).with_zoom(1.0));
}
let player = engine.world_mut().spawn();
if let Some(entity) = engine.world_mut().entity_mut(player) {
entity.add(Transform::new(0.0, -200.0));
entity.add(Sprite::new(50.0, 50.0).with_color(Color::CYAN));
entity.add(RigidBody::dynamic().with_drag(0.5));
entity.add(Collider::box_collider(50.0, 50.0));
}
let platforms = vec![
(-400.0, 250.0, 200.0, 30.0),
(-100.0, 150.0, 200.0, 30.0),
(200.0, 50.0, 200.0, 30.0),
(-200.0, -50.0, 600.0, 30.0),
];
for (x, y, w, h) in platforms {
let platform = engine.world_mut().spawn();
if let Some(entity) = engine.world_mut().entity_mut(platform) {
entity.add(Transform::new(x, y));
entity.add(Sprite::new(w, h).with_color(Color::GREEN));
entity.add(Collider::box_collider(w, h));
}
}
let walls = vec![
(-640.0, 0.0, 20.0, 720.0),
(640.0, 0.0, 20.0, 720.0),
(0.0, 360.0, 1280.0, 20.0),
];
for (x, y, w, h) in walls {
let wall = engine.world_mut().spawn();
if let Some(entity) = engine.world_mut().entity_mut(wall) {
entity.add(Transform::new(x, y));
entity.add(Sprite::new(w, h).with_color(Color::rgb(0.3, 0.3, 0.3)));
entity.add(Collider::box_collider(w, h));
}
}
let fire_emitter_entity = engine.world_mut().spawn();
if let Some(entity) = engine.world_mut().entity_mut(fire_emitter_entity) {
entity.add(Transform::new(-300.0, 200.0));
entity.add(ParticleEmitter::fire(Vec2::new(-300.0, 200.0)));
}
let sparkle_emitter_entity = engine.world_mut().spawn();
if let Some(entity) = engine.world_mut().entity_mut(sparkle_emitter_entity) {
entity.add(Transform::new(300.0, 100.0));
entity.add(ParticleEmitter::sparkles(Vec2::new(300.0, 100.0)));
}
let mut explosion_timer = 0.0;
let mut player_trail_emitter = ParticleEmitter::trail(Vec2::ZERO);
engine.run(move |world, input, time| {
let dt = time.delta();
let move_force = 5000.0;
let jump_impulse = 400.0;
let mut player_pos = Vec2::ZERO;
if let Some(player_entity) = world.entity(player) {
if let Some(transform) = player_entity.get::<Transform>() {
player_pos = transform.position;
}
}
if let Some(camera_entity) = world.entity_mut(camera_entity) {
if let Some(camera) = camera_entity.get_mut::<Camera>() {
camera.follow(player_pos, 5.0, dt);
if input.key_pressed(KeyCode::Equal) || input.key_pressed(KeyCode::NumpadAdd) {
camera.zoom = (camera.zoom + dt * 2.0).min(3.0);
}
if input.key_pressed(KeyCode::Minus) || input.key_pressed(KeyCode::NumpadSubtract) {
camera.zoom = (camera.zoom - dt * 2.0).max(0.5);
}
}
}
let mut should_spawn_explosion = false;
for entity in world.entities_mut() {
if let Some(sprite) = entity.get::<Sprite>() {
if sprite.color.b > 0.9 && sprite.color.r < 0.1 {
if let Some(body) = entity.get_mut::<RigidBody>() {
if input.key_pressed(KeyCode::KeyA) || input.key_pressed(KeyCode::ArrowLeft) {
body.apply_force(Vec2::new(-move_force, 0.0));
}
if input.key_pressed(KeyCode::KeyD) || input.key_pressed(KeyCode::ArrowRight) {
body.apply_force(Vec2::new(move_force, 0.0));
}
if input.key_just_pressed(KeyCode::Space) || input.key_just_pressed(KeyCode::KeyW) {
body.apply_impulse(Vec2::new(0.0, -jump_impulse));
}
if input.key_just_pressed(KeyCode::KeyE) {
should_spawn_explosion = true;
}
}
}
}
}
if should_spawn_explosion {
let explosion = world.spawn();
if let Some(entity) = world.entity_mut(explosion) {
entity.add(Transform::new(player_pos.x, player_pos.y));
entity.add(ParticleEmitter::explosion(player_pos));
}
}
player_trail_emitter.position = player_pos;
let mut emitters_vec: Vec<&mut ParticleEmitter> = Vec::new();
for entity in world.entities_mut() {
if let Some(emitter) = entity.get_mut::<ParticleEmitter>() {
emitters_vec.push(emitter);
}
}
emitters_vec.push(&mut player_trail_emitter);
particle_system.update(&mut emitters_vec, dt);
physics.update(world, dt);
let collisions = physics.detect_collisions(world);
physics.resolve_collisions(world, &collisions);
if time.elapsed() - explosion_timer > 0.1 {
println!("Active particles: {}", particle_system.particle_count());
explosion_timer = time.elapsed();
}
});
}