pub struct Body {Show 17 fields
pub position: Vec3,
pub velocity: Vec3,
pub shape: Shape,
pub kind: BodyKind,
pub gravity_scale: f32,
pub bounciness: f32,
pub friction: f32,
pub damping: f32,
pub tag: String,
pub user_data: u64,
pub facing: f32,
pub pitch: f32,
pub mass: f32,
pub max_speed: f32,
pub on_ground: bool,
pub ground: Option<BodyId>,
pub vehicle: Option<Vehicle>,
/* private fields */
}Expand description
A physical object.
Fields§
§position: Vec3Center of the body in meters (+x east, +y north, +z up).
velocity: Vec3Velocity in meters per second. Ignored for fixed bodies and sensors.
shape: ShapeCollision shape.
kind: BodyKindHow the body is simulated.
gravity_scale: f32Multiplier for world gravity (dynamic bodies only). Default 1.0; 0.0 ignores gravity, 0.5 floats, negative values rise.
bounciness: f32How much speed is kept when bouncing off something, 0.0 (stops dead, the default) to 1.0 (bounces back at full speed). When two bodies touch, the larger value counts.
friction: f32Fraction of the sideways speed removed per second while standing on the ground. Default 8.0 (stops within about a quarter second), 0.0 = ice. Never slows down jumps or falls. Dynamic bodies only.
damping: f32Fraction of the speed removed per second at all times and in every direction (air or water resistance). Default 0.0; 0.1–0.5 is light air drag, 2–5 feels like water. Dynamic bodies only.
tag: StringFree text to recognize bodies in events, e.g. "wall" or "coin".
user_data: u64Free number for your own data, e.g. an index into your entity list.
facing: f32Compass direction the body faces in degrees (0 = north, 90 = east). Shapes never
rotate; this is used by World::move_forward, World::turn and the listener
when a body is followed with Context::follow.
pitch: f32How far the body looks up or down in degrees: 0 = level (the default), 90 = straight
up, -90 = straight down. Like facing, it does not rotate the shape. Used by
World::move_forward (so a body can fly or swim up and down) and by the listener
when the body is followed.
mass: f32Mass (weight) in kilograms, default 1.0. For dynamic bodies: heavier bodies push
lighter ones further and lose less speed when they collide, and forces move them
less. Kinematic bodies push dynamic ones regardless of mass. For vehicles it is the
empty weight, see Body::vehicle.
max_speed: f32Speed limit in meters per second, e.g. a terminal velocity when falling.
f32::INFINITY (the default) means no limit.
on_ground: boolWhether the body touched the ground (something below it) during the last step. Only updated for dynamic bodies.
ground: Option<BodyId>The body this one stands on, if any. Bodies standing on a moving kinematic body (a lift, a platform) are carried along.
vehicle: Option<Vehicle>Makes the body a car or truck (optional, None for every other body). The physics
world then drives it from the vehicle’s pedals and steering; see
crate::vehicle. Vehicle bodies are kinematic.
Implementations§
Source§impl Body
impl Body
Sourcepub fn dynamic(position: Vec3) -> Self
pub fn dynamic(position: Vec3) -> Self
A body moved by velocity, gravity, forces and collisions, such as a ball, a crate or the player in a platformer. Default shape: 1 meter cube.
Examples found in repository?
19 fn new(ctx: &mut Context) -> Self {
20 let audio = &mut ctx.audio;
21 audio.register("jump", Synth::square(300.0).sweep_to(700.0).length(0.15).decay(10.0).volume(0.2));
22 audio.register("land", Synth::noise().length(0.1).decay(40.0).with(Synth::sine(90.0).length(0.1).decay(30.0)));
23 audio.register("coin", Synth::triangle(988.0).length(0.08).then(Synth::triangle(1319.0).length(0.17).decay(15.0)));
24 audio.register("run", Synth::noise().length(0.06).decay(60.0).volume(0.3).then(Synth::silence(0.09)));
25 audio.register("lift", Synth::saw(55.0).length(1.0).volume(0.1));
26 audio.register("push", Synth::noise().length(0.3).volume(0.15));
27
28 let physics = &mut ctx.physics;
29 physics.add(Body::fixed(vec3(0.0, 0.0, -0.5)).with_box(200.0, 4.0, 1.0).with_tag("ground"));
30 for (x, z) in [(8.0, 2.0), (14.0, 4.0), (20.0, 2.5)] {
31 physics.add(Body::fixed(vec3(x, 0.0, z)).with_box(4.0, 4.0, 0.5).with_tag("platform"));
32 }
33 // A lift going up and down at x = 40, and a heavy crate at x = 30.
34 let lift = physics.add(Body::kinematic(vec3(40.0, 0.0, 0.0)).with_box(3.0, 4.0, 0.5).with_tag("lift"));
35 physics.add(Body::dynamic(vec3(30.0, 0.0, 0.5)).with_box(1.0, 1.0, 1.0).with_mass(5.0).with_tag("crate"));
36 // Facing north, so x maps to left and right in the ears.
37 let player = physics
38 .add(Body::dynamic(vec3(0.0, 0.0, 1.0)).with_box(0.8, 0.8, 1.6).with_max_speed(25.0).with_tag("player"));
39
40 ctx.follow(player);
41 ctx.loop_on(lift, "lift");
42 // Coins are sensors with a looping sound, so you can hear where they are.
43 for (x, z) in [(5.0, 1.0), (14.0, 5.5), (25.0, 1.0), (40.0, 8.0)] {
44 let coin = ctx.physics.add(Body::sensor(vec3(x, 0.0, z)).with_sphere(0.6).with_tag("coin"));
45 ctx.loop_on(coin, "coin").set_volume(0.3);
46 }
47
48 let run_sound = ctx.audio.sound("run").looped().volume(0.0).play();
49 Self { player, lift, run_sound, score: 0 }
50 }Sourcepub fn fixed(position: Vec3) -> Self
pub fn fixed(position: Vec3) -> Self
An immovable body such as a wall or floor.
Examples found in repository?
31 fn new(ctx: &mut Context) -> Self {
32 ctx.audio.register("bird", Synth::sine(2200.0).sweep_to(3200.0).length(0.07).then(Synth::silence(0.05)).then(Synth::sine(2600.0).length(0.06)).then(Synth::silence(0.7)));
33 ctx.audio.register("hum", Synth::saw(70.0).length(1.0).volume(0.08));
34 ctx.audio.register("bump", Synth::sine(80.0).length(0.15).decay(25.0).volume(0.8));
35 ctx.audio.register("found", Synth::triangle(660.0).sweep_to(1320.0).length(0.4).decay(6.0).volume(0.3));
36
37 // A hall of 40 x 40 meters and 16 meters high: floor, roof and four walls.
38 // A box is given by its center and its full width (x), depth (y) and height (z).
39 let physics = &mut ctx.physics;
40 physics.add(Body::fixed(vec3(0.0, 0.0, -0.5)).with_box(40.0, 40.0, 1.0).with_tag("floor"));
41 physics.add(Body::fixed(vec3(0.0, 0.0, 16.5)).with_box(40.0, 40.0, 1.0).with_tag("roof"));
42 physics.add(Body::fixed(vec3(0.0, 20.5, 8.0)).with_box(40.0, 1.0, 16.0).with_tag("north wall"));
43 physics.add(Body::fixed(vec3(0.0, -20.5, 8.0)).with_box(40.0, 1.0, 16.0).with_tag("south wall"));
44 physics.add(Body::fixed(vec3(20.5, 0.0, 8.0)).with_box(1.0, 40.0, 16.0).with_tag("east wall"));
45 physics.add(Body::fixed(vec3(-20.5, 0.0, 8.0)).with_box(1.0, 40.0, 16.0).with_tag("west wall"));
46
47 // The drone starts in the middle, 2 meters above the floor. No gravity: it hovers.
48 let drone = ctx.physics.add(Body::kinematic(vec3(0.0, 0.0, 2.0)).with_sphere(0.5).with_tag("drone"));
49 ctx.follow(drone); // the ears use the drone's position, facing and pitch
50 ctx.audio.play_looped("hum");
51
52 for spot in BIRDS {
53 let bird = ctx.physics.add(Body::sensor(spot).with_sphere(1.0).with_tag("bird"));
54 ctx.loop_on(bird, "bird");
55 }
56 Self { drone, birds: BIRDS.len(), blocked: false }
57 }More examples
19 fn new(ctx: &mut Context) -> Self {
20 let audio = &mut ctx.audio;
21 audio.register("jump", Synth::square(300.0).sweep_to(700.0).length(0.15).decay(10.0).volume(0.2));
22 audio.register("land", Synth::noise().length(0.1).decay(40.0).with(Synth::sine(90.0).length(0.1).decay(30.0)));
23 audio.register("coin", Synth::triangle(988.0).length(0.08).then(Synth::triangle(1319.0).length(0.17).decay(15.0)));
24 audio.register("run", Synth::noise().length(0.06).decay(60.0).volume(0.3).then(Synth::silence(0.09)));
25 audio.register("lift", Synth::saw(55.0).length(1.0).volume(0.1));
26 audio.register("push", Synth::noise().length(0.3).volume(0.15));
27
28 let physics = &mut ctx.physics;
29 physics.add(Body::fixed(vec3(0.0, 0.0, -0.5)).with_box(200.0, 4.0, 1.0).with_tag("ground"));
30 for (x, z) in [(8.0, 2.0), (14.0, 4.0), (20.0, 2.5)] {
31 physics.add(Body::fixed(vec3(x, 0.0, z)).with_box(4.0, 4.0, 0.5).with_tag("platform"));
32 }
33 // A lift going up and down at x = 40, and a heavy crate at x = 30.
34 let lift = physics.add(Body::kinematic(vec3(40.0, 0.0, 0.0)).with_box(3.0, 4.0, 0.5).with_tag("lift"));
35 physics.add(Body::dynamic(vec3(30.0, 0.0, 0.5)).with_box(1.0, 1.0, 1.0).with_mass(5.0).with_tag("crate"));
36 // Facing north, so x maps to left and right in the ears.
37 let player = physics
38 .add(Body::dynamic(vec3(0.0, 0.0, 1.0)).with_box(0.8, 0.8, 1.6).with_max_speed(25.0).with_tag("player"));
39
40 ctx.follow(player);
41 ctx.loop_on(lift, "lift");
42 // Coins are sensors with a looping sound, so you can hear where they are.
43 for (x, z) in [(5.0, 1.0), (14.0, 5.5), (25.0, 1.0), (40.0, 8.0)] {
44 let coin = ctx.physics.add(Body::sensor(vec3(x, 0.0, z)).with_sphere(0.6).with_tag("coin"));
45 ctx.loop_on(coin, "coin").set_volume(0.3);
46 }
47
48 let run_sound = ctx.audio.sound("run").looped().volume(0.0).play();
49 Self { player, lift, run_sound, score: 0 }
50 }Sourcepub fn kinematic(position: Vec3) -> Self
pub fn kinematic(position: Vec3) -> Self
A body only moved by your code: the player in a top down game (move it with
World::move_by), doors, lifts and moving platforms (move them with
World::set_velocity). Default shape: 1 meter cube.
Examples found in repository?
32 fn new(ctx: &mut Context) -> Self {
33 ctx.audio.register("step", Synth::noise().length(0.08).decay(60.0));
34 ctx.audio.register("wall", Synth::sine(90.0).length(0.15).decay(25.0).volume(0.8));
35 ctx.audio.register("beacon", Synth::sine(1320.0).length(0.08).then(Synth::silence(0.04)).then(Synth::sine(1320.0).length(0.08)).then(Synth::silence(0.8)));
36 ctx.audio.register("found", Synth::sine(440.0).sweep_to(1200.0).length(0.6).decay(4.0).volume(0.3));
37
38 // Every character is a 2 meter tile: walls, the player start and three beacons.
39 let level = ctx.physics.build_level(MAP, 2.0);
40 let player = ctx.physics.add(Body::kinematic(level.point('P').unwrap()).with_sphere(0.4).with_tag("player"));
41 ctx.follow(player); // the ears go wherever the player goes and face where it faces
42
43 let mut beacons = Vec::new();
44 for spot in level.points('B') {
45 let beacon = ctx.physics.add(Body::sensor(spot).with_sphere(0.8).with_tag("beacon"));
46 ctx.loop_on(beacon, "beacon"); // stops by itself when the beacon is removed
47 beacons.push(beacon);
48 }
49 Self { player, beacons, clock: Timer::new() }
50 }More examples
31 fn new(ctx: &mut Context) -> Self {
32 ctx.audio.register("bird", Synth::sine(2200.0).sweep_to(3200.0).length(0.07).then(Synth::silence(0.05)).then(Synth::sine(2600.0).length(0.06)).then(Synth::silence(0.7)));
33 ctx.audio.register("hum", Synth::saw(70.0).length(1.0).volume(0.08));
34 ctx.audio.register("bump", Synth::sine(80.0).length(0.15).decay(25.0).volume(0.8));
35 ctx.audio.register("found", Synth::triangle(660.0).sweep_to(1320.0).length(0.4).decay(6.0).volume(0.3));
36
37 // A hall of 40 x 40 meters and 16 meters high: floor, roof and four walls.
38 // A box is given by its center and its full width (x), depth (y) and height (z).
39 let physics = &mut ctx.physics;
40 physics.add(Body::fixed(vec3(0.0, 0.0, -0.5)).with_box(40.0, 40.0, 1.0).with_tag("floor"));
41 physics.add(Body::fixed(vec3(0.0, 0.0, 16.5)).with_box(40.0, 40.0, 1.0).with_tag("roof"));
42 physics.add(Body::fixed(vec3(0.0, 20.5, 8.0)).with_box(40.0, 1.0, 16.0).with_tag("north wall"));
43 physics.add(Body::fixed(vec3(0.0, -20.5, 8.0)).with_box(40.0, 1.0, 16.0).with_tag("south wall"));
44 physics.add(Body::fixed(vec3(20.5, 0.0, 8.0)).with_box(1.0, 40.0, 16.0).with_tag("east wall"));
45 physics.add(Body::fixed(vec3(-20.5, 0.0, 8.0)).with_box(1.0, 40.0, 16.0).with_tag("west wall"));
46
47 // The drone starts in the middle, 2 meters above the floor. No gravity: it hovers.
48 let drone = ctx.physics.add(Body::kinematic(vec3(0.0, 0.0, 2.0)).with_sphere(0.5).with_tag("drone"));
49 ctx.follow(drone); // the ears use the drone's position, facing and pitch
50 ctx.audio.play_looped("hum");
51
52 for spot in BIRDS {
53 let bird = ctx.physics.add(Body::sensor(spot).with_sphere(1.0).with_tag("bird"));
54 ctx.loop_on(bird, "bird");
55 }
56 Self { drone, birds: BIRDS.len(), blocked: false }
57 }19 fn new(ctx: &mut Context) -> Self {
20 let audio = &mut ctx.audio;
21 audio.register("jump", Synth::square(300.0).sweep_to(700.0).length(0.15).decay(10.0).volume(0.2));
22 audio.register("land", Synth::noise().length(0.1).decay(40.0).with(Synth::sine(90.0).length(0.1).decay(30.0)));
23 audio.register("coin", Synth::triangle(988.0).length(0.08).then(Synth::triangle(1319.0).length(0.17).decay(15.0)));
24 audio.register("run", Synth::noise().length(0.06).decay(60.0).volume(0.3).then(Synth::silence(0.09)));
25 audio.register("lift", Synth::saw(55.0).length(1.0).volume(0.1));
26 audio.register("push", Synth::noise().length(0.3).volume(0.15));
27
28 let physics = &mut ctx.physics;
29 physics.add(Body::fixed(vec3(0.0, 0.0, -0.5)).with_box(200.0, 4.0, 1.0).with_tag("ground"));
30 for (x, z) in [(8.0, 2.0), (14.0, 4.0), (20.0, 2.5)] {
31 physics.add(Body::fixed(vec3(x, 0.0, z)).with_box(4.0, 4.0, 0.5).with_tag("platform"));
32 }
33 // A lift going up and down at x = 40, and a heavy crate at x = 30.
34 let lift = physics.add(Body::kinematic(vec3(40.0, 0.0, 0.0)).with_box(3.0, 4.0, 0.5).with_tag("lift"));
35 physics.add(Body::dynamic(vec3(30.0, 0.0, 0.5)).with_box(1.0, 1.0, 1.0).with_mass(5.0).with_tag("crate"));
36 // Facing north, so x maps to left and right in the ears.
37 let player = physics
38 .add(Body::dynamic(vec3(0.0, 0.0, 1.0)).with_box(0.8, 0.8, 1.6).with_max_speed(25.0).with_tag("player"));
39
40 ctx.follow(player);
41 ctx.loop_on(lift, "lift");
42 // Coins are sensors with a looping sound, so you can hear where they are.
43 for (x, z) in [(5.0, 1.0), (14.0, 5.5), (25.0, 1.0), (40.0, 8.0)] {
44 let coin = ctx.physics.add(Body::sensor(vec3(x, 0.0, z)).with_sphere(0.6).with_tag("coin"));
45 ctx.loop_on(coin, "coin").set_volume(0.3);
46 }
47
48 let run_sound = ctx.audio.sound("run").looped().volume(0.0).play();
49 Self { player, lift, run_sound, score: 0 }
50 }Sourcepub fn sensor(position: Vec3) -> Self
pub fn sensor(position: Vec3) -> Self
An invisible trigger area that does not block anything. Read
World::entered / World::entered_tag to learn when a body walks in.
Examples found in repository?
32 fn new(ctx: &mut Context) -> Self {
33 ctx.audio.register("step", Synth::noise().length(0.08).decay(60.0));
34 ctx.audio.register("wall", Synth::sine(90.0).length(0.15).decay(25.0).volume(0.8));
35 ctx.audio.register("beacon", Synth::sine(1320.0).length(0.08).then(Synth::silence(0.04)).then(Synth::sine(1320.0).length(0.08)).then(Synth::silence(0.8)));
36 ctx.audio.register("found", Synth::sine(440.0).sweep_to(1200.0).length(0.6).decay(4.0).volume(0.3));
37
38 // Every character is a 2 meter tile: walls, the player start and three beacons.
39 let level = ctx.physics.build_level(MAP, 2.0);
40 let player = ctx.physics.add(Body::kinematic(level.point('P').unwrap()).with_sphere(0.4).with_tag("player"));
41 ctx.follow(player); // the ears go wherever the player goes and face where it faces
42
43 let mut beacons = Vec::new();
44 for spot in level.points('B') {
45 let beacon = ctx.physics.add(Body::sensor(spot).with_sphere(0.8).with_tag("beacon"));
46 ctx.loop_on(beacon, "beacon"); // stops by itself when the beacon is removed
47 beacons.push(beacon);
48 }
49 Self { player, beacons, clock: Timer::new() }
50 }More examples
31 fn new(ctx: &mut Context) -> Self {
32 ctx.audio.register("bird", Synth::sine(2200.0).sweep_to(3200.0).length(0.07).then(Synth::silence(0.05)).then(Synth::sine(2600.0).length(0.06)).then(Synth::silence(0.7)));
33 ctx.audio.register("hum", Synth::saw(70.0).length(1.0).volume(0.08));
34 ctx.audio.register("bump", Synth::sine(80.0).length(0.15).decay(25.0).volume(0.8));
35 ctx.audio.register("found", Synth::triangle(660.0).sweep_to(1320.0).length(0.4).decay(6.0).volume(0.3));
36
37 // A hall of 40 x 40 meters and 16 meters high: floor, roof and four walls.
38 // A box is given by its center and its full width (x), depth (y) and height (z).
39 let physics = &mut ctx.physics;
40 physics.add(Body::fixed(vec3(0.0, 0.0, -0.5)).with_box(40.0, 40.0, 1.0).with_tag("floor"));
41 physics.add(Body::fixed(vec3(0.0, 0.0, 16.5)).with_box(40.0, 40.0, 1.0).with_tag("roof"));
42 physics.add(Body::fixed(vec3(0.0, 20.5, 8.0)).with_box(40.0, 1.0, 16.0).with_tag("north wall"));
43 physics.add(Body::fixed(vec3(0.0, -20.5, 8.0)).with_box(40.0, 1.0, 16.0).with_tag("south wall"));
44 physics.add(Body::fixed(vec3(20.5, 0.0, 8.0)).with_box(1.0, 40.0, 16.0).with_tag("east wall"));
45 physics.add(Body::fixed(vec3(-20.5, 0.0, 8.0)).with_box(1.0, 40.0, 16.0).with_tag("west wall"));
46
47 // The drone starts in the middle, 2 meters above the floor. No gravity: it hovers.
48 let drone = ctx.physics.add(Body::kinematic(vec3(0.0, 0.0, 2.0)).with_sphere(0.5).with_tag("drone"));
49 ctx.follow(drone); // the ears use the drone's position, facing and pitch
50 ctx.audio.play_looped("hum");
51
52 for spot in BIRDS {
53 let bird = ctx.physics.add(Body::sensor(spot).with_sphere(1.0).with_tag("bird"));
54 ctx.loop_on(bird, "bird");
55 }
56 Self { drone, birds: BIRDS.len(), blocked: false }
57 }29 fn new(ctx: &mut Context) -> Self {
30 // Engine: a low buzz that loops without clicks (whole cycles, no fades).
31 let engine = Synth::saw(55.0).length(1.0).attack(0.0).release(0.0).volume(0.25)
32 .with(Synth::square(110.0).length(1.0).attack(0.0).release(0.0).volume(0.08));
33 ctx.audio.register("engine", engine);
34 ctx.audio.register("horn", Synth::square(415.0).length(0.5).volume(0.25).with(Synth::square(523.0).length(0.5).volume(0.2)));
35 ctx.audio.register("shift", Synth::noise().length(0.04).decay(90.0).volume(0.3));
36 ctx.audio.register("crash", Synth::noise().length(0.4).decay(10.0).volume(0.8).with(Synth::sine(80.0).sweep_to(30.0).length(0.3)));
37 ctx.audio.register("start", Synth::saw(40.0).sweep_to(55.0).length(0.6).volume(0.3));
38 ctx.audio.register("garage", Synth::sine(880.0).length(0.15).decay(10.0));
39
40 let level = ctx.physics.build_level(MAP, 6.0);
41 let sounds = |v: Vehicle| {
42 v.with_engine_sound("engine")
43 .with_horn_sound("horn")
44 .with_shift_sound("shift")
45 .with_crash_sound("crash")
46 .with_start_sound("start")
47 };
48 let car_start = level.point('P').unwrap_or(Vec3::ZERO);
49 let car = ctx.physics.add(Body::car(car_start).with_facing(90.0).with_vehicle(sounds(Vehicle::car().with_fuel(5.0, 8.0))));
50 let truck_start = level.point('T').unwrap_or(Vec3::ZERO);
51 let truck = ctx.physics.add(
52 Body::truck(truck_start).with_facing(90.0).with_vehicle(sounds(Vehicle::truck()).engine_off()),
53 );
54 let garage_at = level.point('G').unwrap_or(Vec3::ZERO);
55 let garage = ctx.physics.add(Body::sensor(garage_at).with_box(6.0, 6.0, 3.0).with_tag("garage"));
56 ctx.loop_on(garage, "garage");
57 ctx.follow(car);
58 Self { car, truck, driving: car, garage }
59 }19 fn new(ctx: &mut Context) -> Self {
20 let audio = &mut ctx.audio;
21 audio.register("jump", Synth::square(300.0).sweep_to(700.0).length(0.15).decay(10.0).volume(0.2));
22 audio.register("land", Synth::noise().length(0.1).decay(40.0).with(Synth::sine(90.0).length(0.1).decay(30.0)));
23 audio.register("coin", Synth::triangle(988.0).length(0.08).then(Synth::triangle(1319.0).length(0.17).decay(15.0)));
24 audio.register("run", Synth::noise().length(0.06).decay(60.0).volume(0.3).then(Synth::silence(0.09)));
25 audio.register("lift", Synth::saw(55.0).length(1.0).volume(0.1));
26 audio.register("push", Synth::noise().length(0.3).volume(0.15));
27
28 let physics = &mut ctx.physics;
29 physics.add(Body::fixed(vec3(0.0, 0.0, -0.5)).with_box(200.0, 4.0, 1.0).with_tag("ground"));
30 for (x, z) in [(8.0, 2.0), (14.0, 4.0), (20.0, 2.5)] {
31 physics.add(Body::fixed(vec3(x, 0.0, z)).with_box(4.0, 4.0, 0.5).with_tag("platform"));
32 }
33 // A lift going up and down at x = 40, and a heavy crate at x = 30.
34 let lift = physics.add(Body::kinematic(vec3(40.0, 0.0, 0.0)).with_box(3.0, 4.0, 0.5).with_tag("lift"));
35 physics.add(Body::dynamic(vec3(30.0, 0.0, 0.5)).with_box(1.0, 1.0, 1.0).with_mass(5.0).with_tag("crate"));
36 // Facing north, so x maps to left and right in the ears.
37 let player = physics
38 .add(Body::dynamic(vec3(0.0, 0.0, 1.0)).with_box(0.8, 0.8, 1.6).with_max_speed(25.0).with_tag("player"));
39
40 ctx.follow(player);
41 ctx.loop_on(lift, "lift");
42 // Coins are sensors with a looping sound, so you can hear where they are.
43 for (x, z) in [(5.0, 1.0), (14.0, 5.5), (25.0, 1.0), (40.0, 8.0)] {
44 let coin = ctx.physics.add(Body::sensor(vec3(x, 0.0, z)).with_sphere(0.6).with_tag("coin"));
45 ctx.loop_on(coin, "coin").set_volume(0.3);
46 }
47
48 let run_sound = ctx.audio.sound("run").looped().volume(0.0).play();
49 Self { player, lift, run_sound, score: 0 }
50 }Sourcepub fn car(position: Vec3) -> Self
pub fn car(position: Vec3) -> Self
A car at position, tagged "car": a kinematic body with Vehicle::car, a mass
of 1300 kg and a sphere of 1 m radius. Shapes never rotate, so a sphere fits a car
facing any direction. Change the settings with Body::with_vehicle and
Body::with_mass.
Examples found in repository?
29 fn new(ctx: &mut Context) -> Self {
30 // Engine: a low buzz that loops without clicks (whole cycles, no fades).
31 let engine = Synth::saw(55.0).length(1.0).attack(0.0).release(0.0).volume(0.25)
32 .with(Synth::square(110.0).length(1.0).attack(0.0).release(0.0).volume(0.08));
33 ctx.audio.register("engine", engine);
34 ctx.audio.register("horn", Synth::square(415.0).length(0.5).volume(0.25).with(Synth::square(523.0).length(0.5).volume(0.2)));
35 ctx.audio.register("shift", Synth::noise().length(0.04).decay(90.0).volume(0.3));
36 ctx.audio.register("crash", Synth::noise().length(0.4).decay(10.0).volume(0.8).with(Synth::sine(80.0).sweep_to(30.0).length(0.3)));
37 ctx.audio.register("start", Synth::saw(40.0).sweep_to(55.0).length(0.6).volume(0.3));
38 ctx.audio.register("garage", Synth::sine(880.0).length(0.15).decay(10.0));
39
40 let level = ctx.physics.build_level(MAP, 6.0);
41 let sounds = |v: Vehicle| {
42 v.with_engine_sound("engine")
43 .with_horn_sound("horn")
44 .with_shift_sound("shift")
45 .with_crash_sound("crash")
46 .with_start_sound("start")
47 };
48 let car_start = level.point('P').unwrap_or(Vec3::ZERO);
49 let car = ctx.physics.add(Body::car(car_start).with_facing(90.0).with_vehicle(sounds(Vehicle::car().with_fuel(5.0, 8.0))));
50 let truck_start = level.point('T').unwrap_or(Vec3::ZERO);
51 let truck = ctx.physics.add(
52 Body::truck(truck_start).with_facing(90.0).with_vehicle(sounds(Vehicle::truck()).engine_off()),
53 );
54 let garage_at = level.point('G').unwrap_or(Vec3::ZERO);
55 let garage = ctx.physics.add(Body::sensor(garage_at).with_box(6.0, 6.0, 3.0).with_tag("garage"));
56 ctx.loop_on(garage, "garage");
57 ctx.follow(car);
58 Self { car, truck, driving: car, garage }
59 }Sourcepub fn truck(position: Vec3) -> Self
pub fn truck(position: Vec3) -> Self
A truck at position, tagged "truck": a kinematic body with Vehicle::truck,
an empty mass of 12 t and a sphere of 1.5 m radius.
Examples found in repository?
29 fn new(ctx: &mut Context) -> Self {
30 // Engine: a low buzz that loops without clicks (whole cycles, no fades).
31 let engine = Synth::saw(55.0).length(1.0).attack(0.0).release(0.0).volume(0.25)
32 .with(Synth::square(110.0).length(1.0).attack(0.0).release(0.0).volume(0.08));
33 ctx.audio.register("engine", engine);
34 ctx.audio.register("horn", Synth::square(415.0).length(0.5).volume(0.25).with(Synth::square(523.0).length(0.5).volume(0.2)));
35 ctx.audio.register("shift", Synth::noise().length(0.04).decay(90.0).volume(0.3));
36 ctx.audio.register("crash", Synth::noise().length(0.4).decay(10.0).volume(0.8).with(Synth::sine(80.0).sweep_to(30.0).length(0.3)));
37 ctx.audio.register("start", Synth::saw(40.0).sweep_to(55.0).length(0.6).volume(0.3));
38 ctx.audio.register("garage", Synth::sine(880.0).length(0.15).decay(10.0));
39
40 let level = ctx.physics.build_level(MAP, 6.0);
41 let sounds = |v: Vehicle| {
42 v.with_engine_sound("engine")
43 .with_horn_sound("horn")
44 .with_shift_sound("shift")
45 .with_crash_sound("crash")
46 .with_start_sound("start")
47 };
48 let car_start = level.point('P').unwrap_or(Vec3::ZERO);
49 let car = ctx.physics.add(Body::car(car_start).with_facing(90.0).with_vehicle(sounds(Vehicle::car().with_fuel(5.0, 8.0))));
50 let truck_start = level.point('T').unwrap_or(Vec3::ZERO);
51 let truck = ctx.physics.add(
52 Body::truck(truck_start).with_facing(90.0).with_vehicle(sounds(Vehicle::truck()).engine_off()),
53 );
54 let garage_at = level.point('G').unwrap_or(Vec3::ZERO);
55 let garage = ctx.physics.add(Body::sensor(garage_at).with_box(6.0, 6.0, 3.0).with_tag("garage"));
56 ctx.loop_on(garage, "garage");
57 ctx.follow(car);
58 Self { car, truck, driving: car, garage }
59 }Sourcepub fn with_vehicle(self, vehicle: Vehicle) -> Self
pub fn with_vehicle(self, vehicle: Vehicle) -> Self
Makes the body a vehicle (car, truck, bus, …) and kinematic. The weight is the
body’s mass plus the vehicle’s load.
Examples found in repository?
29 fn new(ctx: &mut Context) -> Self {
30 // Engine: a low buzz that loops without clicks (whole cycles, no fades).
31 let engine = Synth::saw(55.0).length(1.0).attack(0.0).release(0.0).volume(0.25)
32 .with(Synth::square(110.0).length(1.0).attack(0.0).release(0.0).volume(0.08));
33 ctx.audio.register("engine", engine);
34 ctx.audio.register("horn", Synth::square(415.0).length(0.5).volume(0.25).with(Synth::square(523.0).length(0.5).volume(0.2)));
35 ctx.audio.register("shift", Synth::noise().length(0.04).decay(90.0).volume(0.3));
36 ctx.audio.register("crash", Synth::noise().length(0.4).decay(10.0).volume(0.8).with(Synth::sine(80.0).sweep_to(30.0).length(0.3)));
37 ctx.audio.register("start", Synth::saw(40.0).sweep_to(55.0).length(0.6).volume(0.3));
38 ctx.audio.register("garage", Synth::sine(880.0).length(0.15).decay(10.0));
39
40 let level = ctx.physics.build_level(MAP, 6.0);
41 let sounds = |v: Vehicle| {
42 v.with_engine_sound("engine")
43 .with_horn_sound("horn")
44 .with_shift_sound("shift")
45 .with_crash_sound("crash")
46 .with_start_sound("start")
47 };
48 let car_start = level.point('P').unwrap_or(Vec3::ZERO);
49 let car = ctx.physics.add(Body::car(car_start).with_facing(90.0).with_vehicle(sounds(Vehicle::car().with_fuel(5.0, 8.0))));
50 let truck_start = level.point('T').unwrap_or(Vec3::ZERO);
51 let truck = ctx.physics.add(
52 Body::truck(truck_start).with_facing(90.0).with_vehicle(sounds(Vehicle::truck()).engine_off()),
53 );
54 let garage_at = level.point('G').unwrap_or(Vec3::ZERO);
55 let garage = ctx.physics.add(Body::sensor(garage_at).with_box(6.0, 6.0, 3.0).with_tag("garage"));
56 ctx.loop_on(garage, "garage");
57 ctx.follow(car);
58 Self { car, truck, driving: car, garage }
59 }Sourcepub fn with_box(self, width: f32, depth: f32, height: f32) -> Self
pub fn with_box(self, width: f32, depth: f32, height: f32) -> Self
Box shape with full width (x, east-west), depth (y, north-south) and height (z) in
meters. with_box(2.0, 2.0, 2.0) reaches 1 m from the center in every direction.
Examples found in repository?
31 fn new(ctx: &mut Context) -> Self {
32 ctx.audio.register("bird", Synth::sine(2200.0).sweep_to(3200.0).length(0.07).then(Synth::silence(0.05)).then(Synth::sine(2600.0).length(0.06)).then(Synth::silence(0.7)));
33 ctx.audio.register("hum", Synth::saw(70.0).length(1.0).volume(0.08));
34 ctx.audio.register("bump", Synth::sine(80.0).length(0.15).decay(25.0).volume(0.8));
35 ctx.audio.register("found", Synth::triangle(660.0).sweep_to(1320.0).length(0.4).decay(6.0).volume(0.3));
36
37 // A hall of 40 x 40 meters and 16 meters high: floor, roof and four walls.
38 // A box is given by its center and its full width (x), depth (y) and height (z).
39 let physics = &mut ctx.physics;
40 physics.add(Body::fixed(vec3(0.0, 0.0, -0.5)).with_box(40.0, 40.0, 1.0).with_tag("floor"));
41 physics.add(Body::fixed(vec3(0.0, 0.0, 16.5)).with_box(40.0, 40.0, 1.0).with_tag("roof"));
42 physics.add(Body::fixed(vec3(0.0, 20.5, 8.0)).with_box(40.0, 1.0, 16.0).with_tag("north wall"));
43 physics.add(Body::fixed(vec3(0.0, -20.5, 8.0)).with_box(40.0, 1.0, 16.0).with_tag("south wall"));
44 physics.add(Body::fixed(vec3(20.5, 0.0, 8.0)).with_box(1.0, 40.0, 16.0).with_tag("east wall"));
45 physics.add(Body::fixed(vec3(-20.5, 0.0, 8.0)).with_box(1.0, 40.0, 16.0).with_tag("west wall"));
46
47 // The drone starts in the middle, 2 meters above the floor. No gravity: it hovers.
48 let drone = ctx.physics.add(Body::kinematic(vec3(0.0, 0.0, 2.0)).with_sphere(0.5).with_tag("drone"));
49 ctx.follow(drone); // the ears use the drone's position, facing and pitch
50 ctx.audio.play_looped("hum");
51
52 for spot in BIRDS {
53 let bird = ctx.physics.add(Body::sensor(spot).with_sphere(1.0).with_tag("bird"));
54 ctx.loop_on(bird, "bird");
55 }
56 Self { drone, birds: BIRDS.len(), blocked: false }
57 }More examples
29 fn new(ctx: &mut Context) -> Self {
30 // Engine: a low buzz that loops without clicks (whole cycles, no fades).
31 let engine = Synth::saw(55.0).length(1.0).attack(0.0).release(0.0).volume(0.25)
32 .with(Synth::square(110.0).length(1.0).attack(0.0).release(0.0).volume(0.08));
33 ctx.audio.register("engine", engine);
34 ctx.audio.register("horn", Synth::square(415.0).length(0.5).volume(0.25).with(Synth::square(523.0).length(0.5).volume(0.2)));
35 ctx.audio.register("shift", Synth::noise().length(0.04).decay(90.0).volume(0.3));
36 ctx.audio.register("crash", Synth::noise().length(0.4).decay(10.0).volume(0.8).with(Synth::sine(80.0).sweep_to(30.0).length(0.3)));
37 ctx.audio.register("start", Synth::saw(40.0).sweep_to(55.0).length(0.6).volume(0.3));
38 ctx.audio.register("garage", Synth::sine(880.0).length(0.15).decay(10.0));
39
40 let level = ctx.physics.build_level(MAP, 6.0);
41 let sounds = |v: Vehicle| {
42 v.with_engine_sound("engine")
43 .with_horn_sound("horn")
44 .with_shift_sound("shift")
45 .with_crash_sound("crash")
46 .with_start_sound("start")
47 };
48 let car_start = level.point('P').unwrap_or(Vec3::ZERO);
49 let car = ctx.physics.add(Body::car(car_start).with_facing(90.0).with_vehicle(sounds(Vehicle::car().with_fuel(5.0, 8.0))));
50 let truck_start = level.point('T').unwrap_or(Vec3::ZERO);
51 let truck = ctx.physics.add(
52 Body::truck(truck_start).with_facing(90.0).with_vehicle(sounds(Vehicle::truck()).engine_off()),
53 );
54 let garage_at = level.point('G').unwrap_or(Vec3::ZERO);
55 let garage = ctx.physics.add(Body::sensor(garage_at).with_box(6.0, 6.0, 3.0).with_tag("garage"));
56 ctx.loop_on(garage, "garage");
57 ctx.follow(car);
58 Self { car, truck, driving: car, garage }
59 }19 fn new(ctx: &mut Context) -> Self {
20 let audio = &mut ctx.audio;
21 audio.register("jump", Synth::square(300.0).sweep_to(700.0).length(0.15).decay(10.0).volume(0.2));
22 audio.register("land", Synth::noise().length(0.1).decay(40.0).with(Synth::sine(90.0).length(0.1).decay(30.0)));
23 audio.register("coin", Synth::triangle(988.0).length(0.08).then(Synth::triangle(1319.0).length(0.17).decay(15.0)));
24 audio.register("run", Synth::noise().length(0.06).decay(60.0).volume(0.3).then(Synth::silence(0.09)));
25 audio.register("lift", Synth::saw(55.0).length(1.0).volume(0.1));
26 audio.register("push", Synth::noise().length(0.3).volume(0.15));
27
28 let physics = &mut ctx.physics;
29 physics.add(Body::fixed(vec3(0.0, 0.0, -0.5)).with_box(200.0, 4.0, 1.0).with_tag("ground"));
30 for (x, z) in [(8.0, 2.0), (14.0, 4.0), (20.0, 2.5)] {
31 physics.add(Body::fixed(vec3(x, 0.0, z)).with_box(4.0, 4.0, 0.5).with_tag("platform"));
32 }
33 // A lift going up and down at x = 40, and a heavy crate at x = 30.
34 let lift = physics.add(Body::kinematic(vec3(40.0, 0.0, 0.0)).with_box(3.0, 4.0, 0.5).with_tag("lift"));
35 physics.add(Body::dynamic(vec3(30.0, 0.0, 0.5)).with_box(1.0, 1.0, 1.0).with_mass(5.0).with_tag("crate"));
36 // Facing north, so x maps to left and right in the ears.
37 let player = physics
38 .add(Body::dynamic(vec3(0.0, 0.0, 1.0)).with_box(0.8, 0.8, 1.6).with_max_speed(25.0).with_tag("player"));
39
40 ctx.follow(player);
41 ctx.loop_on(lift, "lift");
42 // Coins are sensors with a looping sound, so you can hear where they are.
43 for (x, z) in [(5.0, 1.0), (14.0, 5.5), (25.0, 1.0), (40.0, 8.0)] {
44 let coin = ctx.physics.add(Body::sensor(vec3(x, 0.0, z)).with_sphere(0.6).with_tag("coin"));
45 ctx.loop_on(coin, "coin").set_volume(0.3);
46 }
47
48 let run_sound = ctx.audio.sound("run").looped().volume(0.0).play();
49 Self { player, lift, run_sound, score: 0 }
50 }Sourcepub fn with_sphere(self, radius: f32) -> Self
pub fn with_sphere(self, radius: f32) -> Self
Sphere shape with a radius in meters. 0.3–0.5 is a good player size.
Examples found in repository?
32 fn new(ctx: &mut Context) -> Self {
33 ctx.audio.register("step", Synth::noise().length(0.08).decay(60.0));
34 ctx.audio.register("wall", Synth::sine(90.0).length(0.15).decay(25.0).volume(0.8));
35 ctx.audio.register("beacon", Synth::sine(1320.0).length(0.08).then(Synth::silence(0.04)).then(Synth::sine(1320.0).length(0.08)).then(Synth::silence(0.8)));
36 ctx.audio.register("found", Synth::sine(440.0).sweep_to(1200.0).length(0.6).decay(4.0).volume(0.3));
37
38 // Every character is a 2 meter tile: walls, the player start and three beacons.
39 let level = ctx.physics.build_level(MAP, 2.0);
40 let player = ctx.physics.add(Body::kinematic(level.point('P').unwrap()).with_sphere(0.4).with_tag("player"));
41 ctx.follow(player); // the ears go wherever the player goes and face where it faces
42
43 let mut beacons = Vec::new();
44 for spot in level.points('B') {
45 let beacon = ctx.physics.add(Body::sensor(spot).with_sphere(0.8).with_tag("beacon"));
46 ctx.loop_on(beacon, "beacon"); // stops by itself when the beacon is removed
47 beacons.push(beacon);
48 }
49 Self { player, beacons, clock: Timer::new() }
50 }More examples
31 fn new(ctx: &mut Context) -> Self {
32 ctx.audio.register("bird", Synth::sine(2200.0).sweep_to(3200.0).length(0.07).then(Synth::silence(0.05)).then(Synth::sine(2600.0).length(0.06)).then(Synth::silence(0.7)));
33 ctx.audio.register("hum", Synth::saw(70.0).length(1.0).volume(0.08));
34 ctx.audio.register("bump", Synth::sine(80.0).length(0.15).decay(25.0).volume(0.8));
35 ctx.audio.register("found", Synth::triangle(660.0).sweep_to(1320.0).length(0.4).decay(6.0).volume(0.3));
36
37 // A hall of 40 x 40 meters and 16 meters high: floor, roof and four walls.
38 // A box is given by its center and its full width (x), depth (y) and height (z).
39 let physics = &mut ctx.physics;
40 physics.add(Body::fixed(vec3(0.0, 0.0, -0.5)).with_box(40.0, 40.0, 1.0).with_tag("floor"));
41 physics.add(Body::fixed(vec3(0.0, 0.0, 16.5)).with_box(40.0, 40.0, 1.0).with_tag("roof"));
42 physics.add(Body::fixed(vec3(0.0, 20.5, 8.0)).with_box(40.0, 1.0, 16.0).with_tag("north wall"));
43 physics.add(Body::fixed(vec3(0.0, -20.5, 8.0)).with_box(40.0, 1.0, 16.0).with_tag("south wall"));
44 physics.add(Body::fixed(vec3(20.5, 0.0, 8.0)).with_box(1.0, 40.0, 16.0).with_tag("east wall"));
45 physics.add(Body::fixed(vec3(-20.5, 0.0, 8.0)).with_box(1.0, 40.0, 16.0).with_tag("west wall"));
46
47 // The drone starts in the middle, 2 meters above the floor. No gravity: it hovers.
48 let drone = ctx.physics.add(Body::kinematic(vec3(0.0, 0.0, 2.0)).with_sphere(0.5).with_tag("drone"));
49 ctx.follow(drone); // the ears use the drone's position, facing and pitch
50 ctx.audio.play_looped("hum");
51
52 for spot in BIRDS {
53 let bird = ctx.physics.add(Body::sensor(spot).with_sphere(1.0).with_tag("bird"));
54 ctx.loop_on(bird, "bird");
55 }
56 Self { drone, birds: BIRDS.len(), blocked: false }
57 }19 fn new(ctx: &mut Context) -> Self {
20 let audio = &mut ctx.audio;
21 audio.register("jump", Synth::square(300.0).sweep_to(700.0).length(0.15).decay(10.0).volume(0.2));
22 audio.register("land", Synth::noise().length(0.1).decay(40.0).with(Synth::sine(90.0).length(0.1).decay(30.0)));
23 audio.register("coin", Synth::triangle(988.0).length(0.08).then(Synth::triangle(1319.0).length(0.17).decay(15.0)));
24 audio.register("run", Synth::noise().length(0.06).decay(60.0).volume(0.3).then(Synth::silence(0.09)));
25 audio.register("lift", Synth::saw(55.0).length(1.0).volume(0.1));
26 audio.register("push", Synth::noise().length(0.3).volume(0.15));
27
28 let physics = &mut ctx.physics;
29 physics.add(Body::fixed(vec3(0.0, 0.0, -0.5)).with_box(200.0, 4.0, 1.0).with_tag("ground"));
30 for (x, z) in [(8.0, 2.0), (14.0, 4.0), (20.0, 2.5)] {
31 physics.add(Body::fixed(vec3(x, 0.0, z)).with_box(4.0, 4.0, 0.5).with_tag("platform"));
32 }
33 // A lift going up and down at x = 40, and a heavy crate at x = 30.
34 let lift = physics.add(Body::kinematic(vec3(40.0, 0.0, 0.0)).with_box(3.0, 4.0, 0.5).with_tag("lift"));
35 physics.add(Body::dynamic(vec3(30.0, 0.0, 0.5)).with_box(1.0, 1.0, 1.0).with_mass(5.0).with_tag("crate"));
36 // Facing north, so x maps to left and right in the ears.
37 let player = physics
38 .add(Body::dynamic(vec3(0.0, 0.0, 1.0)).with_box(0.8, 0.8, 1.6).with_max_speed(25.0).with_tag("player"));
39
40 ctx.follow(player);
41 ctx.loop_on(lift, "lift");
42 // Coins are sensors with a looping sound, so you can hear where they are.
43 for (x, z) in [(5.0, 1.0), (14.0, 5.5), (25.0, 1.0), (40.0, 8.0)] {
44 let coin = ctx.physics.add(Body::sensor(vec3(x, 0.0, z)).with_sphere(0.6).with_tag("coin"));
45 ctx.loop_on(coin, "coin").set_volume(0.3);
46 }
47
48 let run_sound = ctx.audio.sound("run").looped().volume(0.0).play();
49 Self { player, lift, run_sound, score: 0 }
50 }Sourcepub fn with_tag(self, tag: impl Into<String>) -> Self
pub fn with_tag(self, tag: impl Into<String>) -> Self
Sets a tag, free text to recognize the body in events and queries
(e.g. "wall", "coin"). See World::tag and World::entered_tag.
Examples found in repository?
32 fn new(ctx: &mut Context) -> Self {
33 ctx.audio.register("step", Synth::noise().length(0.08).decay(60.0));
34 ctx.audio.register("wall", Synth::sine(90.0).length(0.15).decay(25.0).volume(0.8));
35 ctx.audio.register("beacon", Synth::sine(1320.0).length(0.08).then(Synth::silence(0.04)).then(Synth::sine(1320.0).length(0.08)).then(Synth::silence(0.8)));
36 ctx.audio.register("found", Synth::sine(440.0).sweep_to(1200.0).length(0.6).decay(4.0).volume(0.3));
37
38 // Every character is a 2 meter tile: walls, the player start and three beacons.
39 let level = ctx.physics.build_level(MAP, 2.0);
40 let player = ctx.physics.add(Body::kinematic(level.point('P').unwrap()).with_sphere(0.4).with_tag("player"));
41 ctx.follow(player); // the ears go wherever the player goes and face where it faces
42
43 let mut beacons = Vec::new();
44 for spot in level.points('B') {
45 let beacon = ctx.physics.add(Body::sensor(spot).with_sphere(0.8).with_tag("beacon"));
46 ctx.loop_on(beacon, "beacon"); // stops by itself when the beacon is removed
47 beacons.push(beacon);
48 }
49 Self { player, beacons, clock: Timer::new() }
50 }More examples
31 fn new(ctx: &mut Context) -> Self {
32 ctx.audio.register("bird", Synth::sine(2200.0).sweep_to(3200.0).length(0.07).then(Synth::silence(0.05)).then(Synth::sine(2600.0).length(0.06)).then(Synth::silence(0.7)));
33 ctx.audio.register("hum", Synth::saw(70.0).length(1.0).volume(0.08));
34 ctx.audio.register("bump", Synth::sine(80.0).length(0.15).decay(25.0).volume(0.8));
35 ctx.audio.register("found", Synth::triangle(660.0).sweep_to(1320.0).length(0.4).decay(6.0).volume(0.3));
36
37 // A hall of 40 x 40 meters and 16 meters high: floor, roof and four walls.
38 // A box is given by its center and its full width (x), depth (y) and height (z).
39 let physics = &mut ctx.physics;
40 physics.add(Body::fixed(vec3(0.0, 0.0, -0.5)).with_box(40.0, 40.0, 1.0).with_tag("floor"));
41 physics.add(Body::fixed(vec3(0.0, 0.0, 16.5)).with_box(40.0, 40.0, 1.0).with_tag("roof"));
42 physics.add(Body::fixed(vec3(0.0, 20.5, 8.0)).with_box(40.0, 1.0, 16.0).with_tag("north wall"));
43 physics.add(Body::fixed(vec3(0.0, -20.5, 8.0)).with_box(40.0, 1.0, 16.0).with_tag("south wall"));
44 physics.add(Body::fixed(vec3(20.5, 0.0, 8.0)).with_box(1.0, 40.0, 16.0).with_tag("east wall"));
45 physics.add(Body::fixed(vec3(-20.5, 0.0, 8.0)).with_box(1.0, 40.0, 16.0).with_tag("west wall"));
46
47 // The drone starts in the middle, 2 meters above the floor. No gravity: it hovers.
48 let drone = ctx.physics.add(Body::kinematic(vec3(0.0, 0.0, 2.0)).with_sphere(0.5).with_tag("drone"));
49 ctx.follow(drone); // the ears use the drone's position, facing and pitch
50 ctx.audio.play_looped("hum");
51
52 for spot in BIRDS {
53 let bird = ctx.physics.add(Body::sensor(spot).with_sphere(1.0).with_tag("bird"));
54 ctx.loop_on(bird, "bird");
55 }
56 Self { drone, birds: BIRDS.len(), blocked: false }
57 }29 fn new(ctx: &mut Context) -> Self {
30 // Engine: a low buzz that loops without clicks (whole cycles, no fades).
31 let engine = Synth::saw(55.0).length(1.0).attack(0.0).release(0.0).volume(0.25)
32 .with(Synth::square(110.0).length(1.0).attack(0.0).release(0.0).volume(0.08));
33 ctx.audio.register("engine", engine);
34 ctx.audio.register("horn", Synth::square(415.0).length(0.5).volume(0.25).with(Synth::square(523.0).length(0.5).volume(0.2)));
35 ctx.audio.register("shift", Synth::noise().length(0.04).decay(90.0).volume(0.3));
36 ctx.audio.register("crash", Synth::noise().length(0.4).decay(10.0).volume(0.8).with(Synth::sine(80.0).sweep_to(30.0).length(0.3)));
37 ctx.audio.register("start", Synth::saw(40.0).sweep_to(55.0).length(0.6).volume(0.3));
38 ctx.audio.register("garage", Synth::sine(880.0).length(0.15).decay(10.0));
39
40 let level = ctx.physics.build_level(MAP, 6.0);
41 let sounds = |v: Vehicle| {
42 v.with_engine_sound("engine")
43 .with_horn_sound("horn")
44 .with_shift_sound("shift")
45 .with_crash_sound("crash")
46 .with_start_sound("start")
47 };
48 let car_start = level.point('P').unwrap_or(Vec3::ZERO);
49 let car = ctx.physics.add(Body::car(car_start).with_facing(90.0).with_vehicle(sounds(Vehicle::car().with_fuel(5.0, 8.0))));
50 let truck_start = level.point('T').unwrap_or(Vec3::ZERO);
51 let truck = ctx.physics.add(
52 Body::truck(truck_start).with_facing(90.0).with_vehicle(sounds(Vehicle::truck()).engine_off()),
53 );
54 let garage_at = level.point('G').unwrap_or(Vec3::ZERO);
55 let garage = ctx.physics.add(Body::sensor(garage_at).with_box(6.0, 6.0, 3.0).with_tag("garage"));
56 ctx.loop_on(garage, "garage");
57 ctx.follow(car);
58 Self { car, truck, driving: car, garage }
59 }19 fn new(ctx: &mut Context) -> Self {
20 let audio = &mut ctx.audio;
21 audio.register("jump", Synth::square(300.0).sweep_to(700.0).length(0.15).decay(10.0).volume(0.2));
22 audio.register("land", Synth::noise().length(0.1).decay(40.0).with(Synth::sine(90.0).length(0.1).decay(30.0)));
23 audio.register("coin", Synth::triangle(988.0).length(0.08).then(Synth::triangle(1319.0).length(0.17).decay(15.0)));
24 audio.register("run", Synth::noise().length(0.06).decay(60.0).volume(0.3).then(Synth::silence(0.09)));
25 audio.register("lift", Synth::saw(55.0).length(1.0).volume(0.1));
26 audio.register("push", Synth::noise().length(0.3).volume(0.15));
27
28 let physics = &mut ctx.physics;
29 physics.add(Body::fixed(vec3(0.0, 0.0, -0.5)).with_box(200.0, 4.0, 1.0).with_tag("ground"));
30 for (x, z) in [(8.0, 2.0), (14.0, 4.0), (20.0, 2.5)] {
31 physics.add(Body::fixed(vec3(x, 0.0, z)).with_box(4.0, 4.0, 0.5).with_tag("platform"));
32 }
33 // A lift going up and down at x = 40, and a heavy crate at x = 30.
34 let lift = physics.add(Body::kinematic(vec3(40.0, 0.0, 0.0)).with_box(3.0, 4.0, 0.5).with_tag("lift"));
35 physics.add(Body::dynamic(vec3(30.0, 0.0, 0.5)).with_box(1.0, 1.0, 1.0).with_mass(5.0).with_tag("crate"));
36 // Facing north, so x maps to left and right in the ears.
37 let player = physics
38 .add(Body::dynamic(vec3(0.0, 0.0, 1.0)).with_box(0.8, 0.8, 1.6).with_max_speed(25.0).with_tag("player"));
39
40 ctx.follow(player);
41 ctx.loop_on(lift, "lift");
42 // Coins are sensors with a looping sound, so you can hear where they are.
43 for (x, z) in [(5.0, 1.0), (14.0, 5.5), (25.0, 1.0), (40.0, 8.0)] {
44 let coin = ctx.physics.add(Body::sensor(vec3(x, 0.0, z)).with_sphere(0.6).with_tag("coin"));
45 ctx.loop_on(coin, "coin").set_volume(0.3);
46 }
47
48 let run_sound = ctx.audio.sound("run").looped().volume(0.0).play();
49 Self { player, lift, run_sound, score: 0 }
50 }Sourcepub fn with_velocity(self, velocity: Vec3) -> Self
pub fn with_velocity(self, velocity: Vec3) -> Self
Sets the initial velocity in meters per second.
Sourcepub fn with_bounciness(self, bounciness: f32) -> Self
pub fn with_bounciness(self, bounciness: f32) -> Self
Sets bounciness: 0.0 stops dead (default), 1.0 bounces back at full speed. A ball
is about 0.6–0.9, a crate 0.1–0.3. See Body::bounciness.
Sourcepub fn with_friction(self, friction: f32) -> Self
pub fn with_friction(self, friction: f32) -> Self
Sets ground friction: the fraction of sideways speed removed per second while on the
ground. Default 8.0 (stops within about 0.3 s), 2.0 slides for about a second, 0.0 is
ice. See Body::friction.
Sourcepub fn with_damping(self, damping: f32) -> Self
pub fn with_damping(self, damping: f32) -> Self
Sets air damping: the fraction of speed removed per second, always and in every
direction. Default 0.0. See Body::damping.
Sourcepub fn with_gravity_scale(self, scale: f32) -> Self
pub fn with_gravity_scale(self, scale: f32) -> Self
Sets the gravity multiplier: 1.0 normal (default), 0.5 floats, 0.0 no gravity, negative values rise.
Sourcepub fn with_mass(self, mass: f32) -> Self
pub fn with_mass(self, mass: f32) -> Self
Sets the mass in kilograms (default 1.0).
Examples found in repository?
19 fn new(ctx: &mut Context) -> Self {
20 let audio = &mut ctx.audio;
21 audio.register("jump", Synth::square(300.0).sweep_to(700.0).length(0.15).decay(10.0).volume(0.2));
22 audio.register("land", Synth::noise().length(0.1).decay(40.0).with(Synth::sine(90.0).length(0.1).decay(30.0)));
23 audio.register("coin", Synth::triangle(988.0).length(0.08).then(Synth::triangle(1319.0).length(0.17).decay(15.0)));
24 audio.register("run", Synth::noise().length(0.06).decay(60.0).volume(0.3).then(Synth::silence(0.09)));
25 audio.register("lift", Synth::saw(55.0).length(1.0).volume(0.1));
26 audio.register("push", Synth::noise().length(0.3).volume(0.15));
27
28 let physics = &mut ctx.physics;
29 physics.add(Body::fixed(vec3(0.0, 0.0, -0.5)).with_box(200.0, 4.0, 1.0).with_tag("ground"));
30 for (x, z) in [(8.0, 2.0), (14.0, 4.0), (20.0, 2.5)] {
31 physics.add(Body::fixed(vec3(x, 0.0, z)).with_box(4.0, 4.0, 0.5).with_tag("platform"));
32 }
33 // A lift going up and down at x = 40, and a heavy crate at x = 30.
34 let lift = physics.add(Body::kinematic(vec3(40.0, 0.0, 0.0)).with_box(3.0, 4.0, 0.5).with_tag("lift"));
35 physics.add(Body::dynamic(vec3(30.0, 0.0, 0.5)).with_box(1.0, 1.0, 1.0).with_mass(5.0).with_tag("crate"));
36 // Facing north, so x maps to left and right in the ears.
37 let player = physics
38 .add(Body::dynamic(vec3(0.0, 0.0, 1.0)).with_box(0.8, 0.8, 1.6).with_max_speed(25.0).with_tag("player"));
39
40 ctx.follow(player);
41 ctx.loop_on(lift, "lift");
42 // Coins are sensors with a looping sound, so you can hear where they are.
43 for (x, z) in [(5.0, 1.0), (14.0, 5.5), (25.0, 1.0), (40.0, 8.0)] {
44 let coin = ctx.physics.add(Body::sensor(vec3(x, 0.0, z)).with_sphere(0.6).with_tag("coin"));
45 ctx.loop_on(coin, "coin").set_volume(0.3);
46 }
47
48 let run_sound = ctx.audio.sound("run").looped().volume(0.0).play();
49 Self { player, lift, run_sound, score: 0 }
50 }Sourcepub fn with_max_speed(self, max_speed: f32) -> Self
pub fn with_max_speed(self, max_speed: f32) -> Self
Sets a speed limit in meters per second (terminal velocity).
Examples found in repository?
19 fn new(ctx: &mut Context) -> Self {
20 let audio = &mut ctx.audio;
21 audio.register("jump", Synth::square(300.0).sweep_to(700.0).length(0.15).decay(10.0).volume(0.2));
22 audio.register("land", Synth::noise().length(0.1).decay(40.0).with(Synth::sine(90.0).length(0.1).decay(30.0)));
23 audio.register("coin", Synth::triangle(988.0).length(0.08).then(Synth::triangle(1319.0).length(0.17).decay(15.0)));
24 audio.register("run", Synth::noise().length(0.06).decay(60.0).volume(0.3).then(Synth::silence(0.09)));
25 audio.register("lift", Synth::saw(55.0).length(1.0).volume(0.1));
26 audio.register("push", Synth::noise().length(0.3).volume(0.15));
27
28 let physics = &mut ctx.physics;
29 physics.add(Body::fixed(vec3(0.0, 0.0, -0.5)).with_box(200.0, 4.0, 1.0).with_tag("ground"));
30 for (x, z) in [(8.0, 2.0), (14.0, 4.0), (20.0, 2.5)] {
31 physics.add(Body::fixed(vec3(x, 0.0, z)).with_box(4.0, 4.0, 0.5).with_tag("platform"));
32 }
33 // A lift going up and down at x = 40, and a heavy crate at x = 30.
34 let lift = physics.add(Body::kinematic(vec3(40.0, 0.0, 0.0)).with_box(3.0, 4.0, 0.5).with_tag("lift"));
35 physics.add(Body::dynamic(vec3(30.0, 0.0, 0.5)).with_box(1.0, 1.0, 1.0).with_mass(5.0).with_tag("crate"));
36 // Facing north, so x maps to left and right in the ears.
37 let player = physics
38 .add(Body::dynamic(vec3(0.0, 0.0, 1.0)).with_box(0.8, 0.8, 1.6).with_max_speed(25.0).with_tag("player"));
39
40 ctx.follow(player);
41 ctx.loop_on(lift, "lift");
42 // Coins are sensors with a looping sound, so you can hear where they are.
43 for (x, z) in [(5.0, 1.0), (14.0, 5.5), (25.0, 1.0), (40.0, 8.0)] {
44 let coin = ctx.physics.add(Body::sensor(vec3(x, 0.0, z)).with_sphere(0.6).with_tag("coin"));
45 ctx.loop_on(coin, "coin").set_volume(0.3);
46 }
47
48 let run_sound = ctx.audio.sound("run").looped().volume(0.0).play();
49 Self { player, lift, run_sound, score: 0 }
50 }Sourcepub fn with_facing(self, degrees: f32) -> Self
pub fn with_facing(self, degrees: f32) -> Self
Sets the compass direction the body faces in degrees (0 = north, 90 = east). The shape does not rotate.
Examples found in repository?
29 fn new(ctx: &mut Context) -> Self {
30 // Engine: a low buzz that loops without clicks (whole cycles, no fades).
31 let engine = Synth::saw(55.0).length(1.0).attack(0.0).release(0.0).volume(0.25)
32 .with(Synth::square(110.0).length(1.0).attack(0.0).release(0.0).volume(0.08));
33 ctx.audio.register("engine", engine);
34 ctx.audio.register("horn", Synth::square(415.0).length(0.5).volume(0.25).with(Synth::square(523.0).length(0.5).volume(0.2)));
35 ctx.audio.register("shift", Synth::noise().length(0.04).decay(90.0).volume(0.3));
36 ctx.audio.register("crash", Synth::noise().length(0.4).decay(10.0).volume(0.8).with(Synth::sine(80.0).sweep_to(30.0).length(0.3)));
37 ctx.audio.register("start", Synth::saw(40.0).sweep_to(55.0).length(0.6).volume(0.3));
38 ctx.audio.register("garage", Synth::sine(880.0).length(0.15).decay(10.0));
39
40 let level = ctx.physics.build_level(MAP, 6.0);
41 let sounds = |v: Vehicle| {
42 v.with_engine_sound("engine")
43 .with_horn_sound("horn")
44 .with_shift_sound("shift")
45 .with_crash_sound("crash")
46 .with_start_sound("start")
47 };
48 let car_start = level.point('P').unwrap_or(Vec3::ZERO);
49 let car = ctx.physics.add(Body::car(car_start).with_facing(90.0).with_vehicle(sounds(Vehicle::car().with_fuel(5.0, 8.0))));
50 let truck_start = level.point('T').unwrap_or(Vec3::ZERO);
51 let truck = ctx.physics.add(
52 Body::truck(truck_start).with_facing(90.0).with_vehicle(sounds(Vehicle::truck()).engine_off()),
53 );
54 let garage_at = level.point('G').unwrap_or(Vec3::ZERO);
55 let garage = ctx.physics.add(Body::sensor(garage_at).with_box(6.0, 6.0, 3.0).with_tag("garage"));
56 ctx.loop_on(garage, "garage");
57 ctx.follow(car);
58 Self { car, truck, driving: car, garage }
59 }Sourcepub fn with_pitch(self, degrees: f32) -> Self
pub fn with_pitch(self, degrees: f32) -> Self
Sets how far the body looks up (positive) or down (negative) in degrees, -90 to 90.
Sourcepub fn with_user_data(self, data: u64) -> Self
pub fn with_user_data(self, data: u64) -> Self
Sets a free number for your own data, e.g. an index into your enemy list.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for Body
impl RefUnwindSafe for Body
impl Send for Body
impl Sync for Body
impl Unpin for Body
impl UnsafeUnpin for Body
impl UnwindSafe for Body
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.