Skip to main content

Body

Struct Body 

Source
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: Vec3

Center of the body in meters (+x east, +y north, +z up).

§velocity: Vec3

Velocity in meters per second. Ignored for fixed bodies and sensors.

§shape: Shape

Collision shape.

§kind: BodyKind

How the body is simulated.

§gravity_scale: f32

Multiplier for world gravity (dynamic bodies only). Default 1.0; 0.0 ignores gravity, 0.5 floats, negative values rise.

§bounciness: f32

How 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: f32

Fraction 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: f32

Fraction 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: String

Free text to recognize bodies in events, e.g. "wall" or "coin".

§user_data: u64

Free number for your own data, e.g. an index into your entity list.

§facing: f32

Compass 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: f32

How 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: f32

Mass (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: f32

Speed limit in meters per second, e.g. a terminal velocity when falling. f32::INFINITY (the default) means no limit.

§on_ground: bool

Whether 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

Source

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?
examples/platformer.rs (line 35)
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    }
Source

pub fn fixed(position: Vec3) -> Self

An immovable body such as a wall or floor.

Examples found in repository?
examples/flight.rs (line 40)
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
Hide additional examples
examples/platformer.rs (line 29)
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    }
Source

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?
examples/beacon.rs (line 40)
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
Hide additional examples
examples/flight.rs (line 48)
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    }
examples/platformer.rs (line 34)
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    }
Source

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?
examples/beacon.rs (line 45)
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
Hide additional examples
examples/flight.rs (line 53)
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    }
examples/driving.rs (line 55)
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    }
examples/platformer.rs (line 44)
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    }
Source

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?
examples/driving.rs (line 49)
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    }
Source

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?
examples/driving.rs (line 52)
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    }
Source

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?
examples/driving.rs (line 49)
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    }
Source

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?
examples/flight.rs (line 40)
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
Hide additional examples
examples/driving.rs (line 55)
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    }
examples/platformer.rs (line 29)
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    }
Source

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?
examples/beacon.rs (line 40)
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
Hide additional examples
examples/flight.rs (line 48)
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    }
examples/platformer.rs (line 44)
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    }
Source

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?
examples/beacon.rs (line 40)
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
Hide additional examples
examples/flight.rs (line 40)
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    }
examples/driving.rs (line 55)
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    }
examples/platformer.rs (line 29)
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    }
Source

pub fn with_velocity(self, velocity: Vec3) -> Self

Sets the initial velocity in meters per second.

Source

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.

Source

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.

Source

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.

Source

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.

Source

pub fn with_mass(self, mass: f32) -> Self

Sets the mass in kilograms (default 1.0).

Examples found in repository?
examples/platformer.rs (line 35)
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    }
Source

pub fn with_max_speed(self, max_speed: f32) -> Self

Sets a speed limit in meters per second (terminal velocity).

Examples found in repository?
examples/platformer.rs (line 38)
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    }
Source

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?
examples/driving.rs (line 49)
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    }
Source

pub fn with_pitch(self, degrees: f32) -> Self

Sets how far the body looks up (positive) or down (negative) in degrees, -90 to 90.

Source

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.

Source

pub fn contains(&self, point: Vec3) -> bool

Whether this body overlaps a point.

Trait Implementations§

Source§

impl Clone for Body

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Body

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

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> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert 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>

Convert 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)

Convert &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)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync> ⓘ

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<S> FromSample<S> for S

Source§

fn from_sample_(s: S) -> S

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<F, T> IntoSample<T> for F
where T: FromSample<F>,

Source§

fn into_sample(self) -> T

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> ToSample<U> for T
where U: FromSample<T>,

Source§

fn to_sample_(self) -> U

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more