Friday, August 5, 2022

Flame: Body types: dynamic, static & kinematic

Box2D has three different types of bodies: dynamic, kinematic, and static.

Note: If you do not know how to create a body, please check the previous article.

Static bodies

A static body does not react to any force, impulse, or collision and does not move. Static bodies are perfect for ground, walls, and any object which does not need to move.

Let’s create the class FloorStatic that will hold a static body:

class FloorStatic extends BodyComponent {
  
  Body createBody() {
    final bodyDef = BodyDef(
      position: Vector2(0, worldSize.y - .75),
      type: BodyType.static,
    );

    final shape = EdgeShape()..set(Vector2.zero(), Vector2(worldSize.x, 0));
    final fixtureDef = FixtureDef(shape);
    return world.createBody(bodyDef)..createFixture(fixtureDef);
  }
}

As you can see, the body definition type is BodyType.static, and the shape is EdgeShape. The edge shape is just a line segment and is great for floors.

Let’s add the FloorStatic to the game:

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

After running the code, we can see there is only a static line crossing the screen horizontally:

Dynamic bodies

A dynamic body reacts to forces, impulses, collisions, and other world events.

Let’s create a class BallDynamic that will hold a dynamic body:

class BallDynamic 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);
  }
}

This time the body definition type is BodyType.dynamic, and the shape is CircleShape.. The ball is positioned vertically at the screen’s top and horizontally centered.

Let’s add the BallDynamic to the game:

class GameLesson02 extends MyGame {
  
  Future<void> onLoad() async {
    super.onLoad();
    add(FloorStatic());
    add(BallDynamic());
  }
}

When we run the code, we can see the ball is falling from top to bottom until reaching the floor:

Kinematic bodies

Kinematic bodies are very similar to static and dynamic bodies. How? Like static bodies, they do not react to forces, but like dynamic bodies, they can move. To move a kinematic body, we must set the velocity or position.

Let’s create a class BoxKinematic that will hold a dynamic body:

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

    final shape = PolygonShape()..setAsBoxXY(.15, 1.25);

    final fixtureDef = FixtureDef(shape);
    return world.createBody(bodyDef)
      ..createFixture(fixtureDef)
      ..angularVelocity = radians(180);
  }
}

The body definition type is BodyType.kinematic, and the shape is PolygonShape.. The body is positioned in the center of the screen. And the body has an angularVelocity, which means it will rotate on its axis.

Let’s add the BoxKinematic to the game:

class GameLesson02 extends MyGame {
  
  Future<void> onLoad() async {
    super.onLoad();
    add(FloorStatic());
    add(BallDynamic());
    add(BoxKinematic());
  }
}

When we run the code, we can see the ball is falling, colliding with the rotating box, and finally reaches the floor and moves out of the screen:

Note that the kinematic body is not affected by gravity, or the ball colliding into it, it will always stay in the same position.

Conclusion

One of the most important topics related to Box2D is the type of bodies. We saw how they react to the world forces (gravity) and how they react when they collide with each other.

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