use nightshade_api::prelude::*;
struct Lab {
cube: Entity,
pad: Entity,
banner: Entity,
friction: Entity,
restitution: Entity,
gravity: Entity,
mass: Entity,
hud: Entity,
impacts: u32,
}
fn main() {
run(setup, update).unwrap();
}
fn setup(world: &mut World) -> Lab {
spawn_floor(world, 24.0);
let cube = spawn_object(
world,
Object {
position: vec3(-2.0, 6.0, 0.0),
color: GREEN,
body: Body::Dynamic { mass: 1.0 },
..Object::default()
},
);
for index in 1..5 {
spawn_object(
world,
Object {
position: vec3(index as f32 - 2.0, 6.0 + index as f32, 0.0),
color: GREEN,
body: Body::Dynamic { mass: 1.0 },
..Object::default()
},
);
}
spawn_capsule_body(world, vec3(-6.0, 4.0, 0.0), 0.5, 0.4, 1.0, BLUE);
spawn_cylinder_body(world, vec3(6.0, 4.0, 0.0), 0.5, 0.5, 1.0, ORANGE);
let pad = spawn_object(
world,
Object {
position: vec3(0.0, 0.1, 6.0),
scale: vec3(2.0, 0.2, 2.0),
color: TEAL,
body: Body::Static,
..Object::default()
},
);
make_sensor(world, pad);
build_door(world);
build_spring(world);
let banner = spawn_cloth(world, vec3(-3.0, 6.0, -8.0), 6.0, 4.0, 16, 12);
set_wind(world, vec3(1.0, 0.0, 0.3), 6.0);
let panel = spawn_panel(world, ScreenAnchor::TopRight, 240.0, 200.0);
panel_label(world, panel, "friction restitution gravity mass");
let friction = panel_slider(world, panel, 0.0, 2.0, 0.7);
let restitution = panel_slider(world, panel, 0.0, 1.0, 0.2);
let gravity = panel_slider(world, panel, -1.0, 2.0, 1.0);
let mass = panel_slider(world, panel, 0.2, 8.0, 1.0);
let hud_panel = spawn_panel(world, ScreenAnchor::TopLeft, 380.0, 96.0);
let hud = panel_label(world, hud_panel, "physics");
set_text_size(world, hud, 16.0);
spawn_text(
world,
"Space kick cube R reset banner",
ScreenAnchor::BottomLeft,
);
Lab {
cube,
pad,
banner,
friction,
restitution,
gravity,
mass,
hud,
impacts: 0,
}
}
fn build_door(world: &mut World) {
let frame = spawn_object(
world,
Object {
position: vec3(-9.0, 2.0, 4.0),
scale: vec3(0.3, 4.0, 0.3),
color: STEEL,
body: Body::Static,
..Object::default()
},
);
let door = spawn_object(
world,
Object {
position: vec3(-7.5, 2.0, 4.0),
scale: vec3(3.0, 3.5, 0.2),
color: GOLD,
body: Body::Dynamic { mass: 2.0 },
..Object::default()
},
);
attach_hinge(world, frame, door, JointAxisDirection::Y);
}
fn build_spring(world: &mut World) {
let anchor = spawn_object(
world,
Object {
position: vec3(9.0, 7.0, 4.0),
scale: vec3(0.3, 0.3, 0.3),
color: STEEL,
body: Body::Static,
..Object::default()
},
);
let bob = spawn_object(
world,
Object {
shape: Shape::Sphere,
position: vec3(9.0, 4.0, 4.0),
scale: vec3(0.6, 0.6, 0.6),
color: PINK,
body: Body::Dynamic { mass: 1.5 },
},
);
attach_spring(world, anchor, bob, 3.0, 40.0, 1.5);
}
fn update(world: &mut World, state: &mut Lab) {
set_friction(world, state.cube, slider_value(world, state.friction));
set_restitution(world, state.cube, slider_value(world, state.restitution));
set_gravity_scale(world, state.cube, slider_value(world, state.gravity));
set_mass(world, state.cube, slider_value(world, state.mass));
if key_pressed(world, KeyCode::Space) {
apply_force(world, state.cube, vec3(0.0, 400.0, 0.0));
apply_torque(world, state.cube, vec3(0.0, 40.0, 0.0));
set_angular_velocity(world, state.cube, vec3(0.0, 6.0, 0.0));
}
if key_pressed(world, KeyCode::KeyR) {
reset_cloth(world, state.banner);
}
if !collisions(world).is_empty() {
state.impacts += collisions(world).len() as u32;
}
let on_pad = overlap_sphere(world, position(world, state.pad), 2.0).len();
let speed = velocity(world, state.cube).unwrap_or_default().magnitude();
let spin = angular_velocity(world, state.cube)
.unwrap_or_default()
.magnitude();
set_text(
world,
state.hud,
&format!(
"impacts {} on pad {} speed {:.1} spin {:.1}",
state.impacts, on_pad, speed, spin
),
);
}