Skip to main content

gravity_simulation/
gravity_simulation.rs

1//! This example is a show off about applied gravity.
2//! The Gravity component will be affect all entities with the Velocity and RigidBody components.
3//! Making use of the velocity and collision components, one sprite is coliding with a shape.
4//! After the collision, the sprite bounce until its stops based on its restitution value.
5
6use lotus_engine::*;
7
8your_game!(
9    WindowConfiguration::default(),
10    setup,
11    update
12);
13
14fn setup(context: &mut Context) {
15    let table: Shape = Shape::new(Orientation::Horizontal, GeometryType::Rectangle, Color::by_option(ColorOption::Black));
16    let object: Shape = Shape::new(Orientation::Horizontal, GeometryType::Circle(Circle::default()), Color::by_option(ColorOption::Blue));
17
18    context.commands.spawn(vec![
19        Box::new(table),
20        Box::new(Transform::new(
21            Position::new(Vector2::new(0.0, -0.70), Strategy::Normalized),
22            0.0,
23            Vector2::new(0.90, 0.10)
24        )),
25        Box::new(Collision::new(Collider::new_simple(GeometryType::Rectangle)))
26    ]);
27
28    context.commands.spawn(vec![
29        Box::new(object),
30        Box::new(Transform::new(
31            Position::new(Vector2::new(400.0, 100.0), Strategy::Pixelated),
32            0.0,
33            Vector2::new(0.50, 0.50)
34        )),
35        Box::new(Collision::new(Collider::new_simple(GeometryType::Square))),
36        Box::new(Gravity::new(0.0)),
37        Box::new(Velocity::new(Vector2::new(0.2, 0.2))),
38        Box::new(RigidBody::new(BodyType::Dynamic, 1.0, 0.9, 1.0))
39    ]);
40}
41
42fn update(context: &mut Context) {
43    let keyboard_input: KeyboardInput = context.world.get_resource_cloned::<KeyboardInput>().unwrap();
44
45    let mut query: Query = Query::new(&context.world).with::<Gravity>();
46    let entity: Entity = query.entities_with_components().unwrap().first().unwrap().clone();
47
48    if keyboard_input.is_some_released() {
49        let mut gravity: ComponentRefMut<'_, Gravity> = context.world.get_entity_component_mut::<Gravity>(&entity).unwrap();
50        gravity.value = 9.8;
51    }
52    check_table_object_collision(context);
53}
54
55fn check_table_object_collision(context: &mut Context) {
56    let mut table_query: Query = Query::new(&context.world).with::<RigidBody>();
57    let mut object_query: Query = Query::new(&context.world).with::<RigidBody>();
58
59    let table: Entity = table_query.entities_without_components().unwrap().first().unwrap().clone();
60    let object: Entity = object_query.entities_with_components().unwrap().first().unwrap().clone();
61
62    let table_collision: ComponentRef<'_, Collision> = context.world.get_entity_component::<Collision>(&table).unwrap();
63
64    let (object_collision, mut object_transform, mut object_velocity, mut object_rigid_body) = (
65        context.world.get_entity_component::<Collision>(&object).unwrap(),
66        context.world.get_entity_component_mut::<Transform>(&object).unwrap(),
67        context.world.get_entity_component_mut::<Velocity>(&object).unwrap(),
68        context.world.get_entity_component_mut::<RigidBody>(&object).unwrap()
69    );
70
71    if Collision::check(CollisionAlgorithm::Aabb, &table_collision, &object_collision) {
72        if object_velocity.y < -0.001 {
73            object_velocity.y = -object_velocity.y * object_rigid_body.restitution;
74            let y: f32 = object_transform.position.y + object_velocity.y * context.delta;
75            object_transform.set_position_y(&context.render_state, y);
76        } else {
77            object_velocity.y = 0.0;
78            object_rigid_body.rest = true;
79        }
80    }
81}