Your First Flutter Flame Game

Mar 6 2024 · Dart 3, Flutter 3.10.1, Android Studio 2021.3.1 or higher, Visual Studo Code 1.7.4 or higher

Part 3: Collision Detection & Overlays

14. Understand Collision Between Components

Episode complete

Play next episode

Next
About this episode
Leave a rating/review
See forum comments
Cinema mode Mark complete Download course materials
Previous episode: 13. Play Sound Effects Next episode: 15. Attack Saucers

Get immediate access to this and 4,000+ other videos and books.

Take your career further with a Kodeco Personal Plan. With unlimited access to over 40+ books and 4,000+ professional videos in a single subscription, it's simply the best investment you can make in your development career.

Learn more Already a subscriber? Sign in.

Notes: 14. Understand Collision Between Components

Check out Flame’s documentation about collision detection.

Transcript: 14. Understand Collision Between Components

Collision detection is the detection of collisions between objects in the virtual environment of a game.

It is used to avoid components moving through each other and the environment.

They are in a lot of places:

  • character to character
  • character to terrain
  • character to item

Hitboxes are the cornerstone of collision detection. They are like a digital space around a component that tells the game when and where it collides with another component.

Example #1: Collision between A & B both with hitboxes.

Since both game elements have a hitbox. You can certainly determine when both of them collide.

Example #2: Collision between A & B, just A with hitbox.

But be careful, if you don’t add a hitbox to your component then it’ll be invisible to other components and there won’t be any collisions.

There are multiple types of hitboxes bundled within Flame. Here’s a few of them that you might find useful while developing your game.

ShapeHitbox is a hitbox that matches a specific shape. There’s pre-built shapes and hitboxes like: PollygonHitbox, RectangleHitbox, or CircleHitbox. You can add as many ShapeHitboxs as you want to your PositionComponent to make up more complex areas. For example a snowman with a hat could be represented by three CircleHitboxs and two RectangleHitboxs as its hat.

ScreenHitbox: If you add a ScreenHitbox to your game your other components with hitboxes’ll be notified when they collide with the edges.

CompositeHitbox can be used when you want to add multiple hitboxes so that they emulate being one joined hitbox.

GestureHitbox exists so that you can more accurately recognize gestures on top of your Components.

Demo

MeteormaniaGame

To enable collision detection you just have to add HasCollisionDetection as a mixin to MeteormaniaGame. It’ll help the game keep track of the components that can collide.

HasCollisionDetection 

Now, let’s also add a new class property that let you know if the Spaceship is getting hit by a Meteorite.

bool _hitByEnemy = false;

Let’s also add a new function for when Spaceship gets hit.

void spaceshipHit(bool isBigMeteorite) {
}

First, play the explosion sound effect when Spaceship gets hit.

FlameAudio.play('sfx/explosion.mp3');

Now, check that there aren’t any hits currently happening and if not, let’s update the class flag and also make sure to update the game’s state by calling playerHit on manager.

if (!_hitByEnemy) {
  _hitByEnemy = true;
  manager.playerHit();
}

Now, it’d be cool to have Spaceship flicker when an enemy hits it. You can do so by adding an OpacityEffect. Let’s use fadeOut to build the effect and use an EffectController that alternates the effect and has a repeatCount of five.

_spaceship?.add(
  OpacityEffect.fadeOut(
    EffectController(
      alternate: true,
      duration: 0.1,
      repeatCount: 5,
    ),
  ),
);

Lastly, when the opacity effect is done, set _hitByEnemy back to false to allow further hits on Spaceship.

..onComplete = () {
  _hitByEnemy = false;
},

Spaceship

Now, to enable collisions on Spaceship, you’ll need to add two different mixins: CollisionCallbacks that informs the component when it collides with other components; and HasGameRef which let’s your component access the parent MeteormaniaGame it belongs to.

with CollisionCallbacks, HasGameRef<MeteormaniaGame>

Now, override onLoad and add a RectangleHitbox to your component. This way you’ll allow it to collide with other components’ hitboxes.

@override
FutureOr<void> onLoad() {
  add(RectangleHitbox());
  return super.onLoad();
}

Finally, in Spaceship, you’ll have to override onCollision. This callback allows you to check the other component that Spaceship is colliding with.

@override
void onCollision(Set<Vector2> intersectionPoints, PositionComponent other) {
  super.onCollision(intersectionPoints, other);
}

The easiest way you can determine which type of component you are colliding with is by using is operator. Let’s check for collisions with Meteorite and call the newly created function spaceshipHit like so.

if (other is Meteorite) {
  game.spaceshipHit(other.isBig);
}

Meteorite

The only thing left to do is adding a hitbox for Meteorite. Again, find onLoad and add a RectangleHitbox to the component. This allows it to collide with other components that have collision detection enabled.

add(RectangleHitbox());

Build and run the game. Wait until any Meteorite hits the Spaceship and verify the changes you just added. You’ll see the Spaceship flicker and hear a sound effect when it happens.