Monday, August 15, 2022

Flame: Forces, impulses & linear velocity

We know that Forge2D has forces that, when applied to the bodies, they will move and create a realistic simulation.

For this article, we are going to create a Ball class that will receive the position on the X-axis, then we are going to place three balls on the floor and apply different kinds of forces.

class Ball extends BodyComponent {
  final double positionX;

  Ball(this.positionX);

  
  Body createBody() {
    final bodyDef = BodyDef(
      position: Vector2(positionX, worldSize.y - 1),
      type: BodyType.dynamic,
    );

    final shape = CircleShape()..radius = .35;
    final fixtureDef = FixtureDef(shape)
      ..density = 5
      ..friction = .5
      ..restitution = .5;
    return world.createBody(bodyDef)..createFixture(fixtureDef);
  }
}

Let’s add the balls to the game, but because we want to keep track of the balls so we can apply a force each time the screen is clicked, we will store the ball objects in a list:

class GameLesson04 extends MyGame with TapDetector {
  final balls = [Ball(2), Ball(6), Ball(10)];
  final speed = Vector2(0, -9);

  
  Future<void> onLoad() async {
    super.onLoad();

    add(Floor());
    addAll(balls);
  }

  
  void onTapDown(TapDownInfo info) {
    super.onTapDown(info);
    balls[0].body.applyForce(speed);
    balls[1].body.applyLinearImpulse(speed);
    balls[2].body.linearVelocity = speed;
  }
}

The list balls contains the three balls placed horizontally on the x positions 2, 6, and 10.

The speed vector is the value we will use to apply a force to the body. In this case, the body will only move vertically because the Y-axis value is not zero, and the value on the X-axis is zero, so the body will not move horizontally.

We are using TapDetector and overriding the function onTapDown(), so every time there is a click on the screen, we will interact with the bodies.

After running the code, it will look like this:

Applying forces

To interact with the balls, we tap or click the screen, and then the following code will be executed:

balls[0].body.applyForce(speed);
balls[1].body.applyLinearImpulse(speed);
balls[2].body.linearVelocity = speed;

And the result will look like this:

As you have noticed, the movement of the ball is different. Each ball is calling a different function. Let’s check what each of them is doing:

applyForce: To the ball on the left, we are applying a force. Forces change the velocity of a body gradually over time. For example, an accelerating car will start moving slowly, and over time it will reach the desired velocity.

applyLinearImpulse: To the ball in the middle, we apply a linear impulse. Impulses make immediate changes to the body’s velocity. For example, kicking a soccer ball will immediately change the ball’s velocity and make it move far away, but what if you kick a big rock? Probably it will not move very far.

linearVelocity: To the ball on the right, we set the velocity, so no matter the body’s size and mass, we just “magically” set the desired velocity.

Note: By default, these forces are applied in the center of the bodies, so they will move up and not rotate.

The source code of all tutorials is available on Github, and you can try all the examples in your browser:

0 comments:

Post a Comment

Entradas populares