Monday, August 15, 2022

Flame: The world, bodies, shapes, and fixtures

The world

Every game using Forge2D needs a world. The world object is what holds all your physics objects/bodies and simulates the reactions between them.

We did not notice it, but in the previous article, we already created a world.

1- In Flame, to create a world, we must extend the class Forge2DGame, and internally it will create the world.

class MyGame extends Forge2DGame {

}

2- We must define the gravity of our world:

MyGame() : super(gravity: Vector2(0, 15)); 

Gravity affects every dynamic body in the world. x=0 means there is no horizontal gravity and y=15 means objects will be pulled downwards like in real life. These values can be anything you like, but remember to stick to a constant scale. In Forge2D 1 unit = 1 meter

If you want a world without gravity, then the code will look like this:

MyGame() : super(gravity: Vector2(0, 0)); 

Bodies

In Forge2D, our objects are called bodies and they are the fundamental objects in the world. Anything you can move or interact with is a body.

There are different body types: static, dynamic, and kinematic.

Bodies can have different shapes: circular, rectangular, or any kind of polygon.

Also, bodies can have different attributes: density, friction, restitution, velocity, position, etc.

In Flame, to create a Body, we need to create a class and extend from BodyComponent.

class Ball extends BodyComponent {  
    
  Body createBody() {  
     
  }  
}

Inside the function createBody(), we create a BodyDef that will hold the data needed to create the body:

final bodyDef = BodyDef(  
  position: Vector2(worldSize.x / 2, 0),  
  type: BodyType.dynamic,  
);

We can see that this will be a dynamic body, positioned vertically at the screen’s top and horizontally centered.

Shapes

In Forge2D, bodies must have a shape; it can be circular, rectangular, or any kind of polygon.

Let’s create a circular shape for our body:

final shape = CircleShape()..radius = .35;

We created a CircleShape and set a radius of .35

Fixtures

A fixture has a shape, density, friction, and restitution attached to it.

  • Density is the mass per square meter
  • Friction is the amount of opposing force when the object rubs/slides along something
  • Restitution is how bouncy the body is

Let’s create the fixture of our body:

final fixtureDef = FixtureDef(shape);

We created the fixture and attached the circular shape to it. This time we did not add any other attribute to it.

Adding the body to the World

Now we must add the body to the world, so we will use the bodyDef and fixtureDef that we created previously:

world.createBody(bodyDef)..createFixture(fixtureDef);

Putting all the code together, the Ball class will look like this:

class Ball extends BodyComponent {
  
  Body createBody() {
    final bodyDef = BodyDef(
      position: Vector2(worldSize.x / 2, 0),
      type: BodyType.dynamic,
    );

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

Adding the Ball to the Game

Finally, we have to add the Ball to the game. So let’s create a new class, GameLesson01.

class GameLesson01 extends MyGame {
  
  Future<void> onLoad() async {
    super.onLoad();
    add(Ball());
  }
}

Now we can run this code, and we will see a ball falling from the top to the bottom of the screen:

You can do some experimentation, try changing the gravity values, the radius of the ball, etc.

Conclusion

This article taught us about the Forge2D world and how to add bodies to it. We also learned that a body could have different shapes and attributes.

Remember 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