Collision Detection in Games

Collision Detection in Games

Collision detection is one of the most important systems in game development. Almost every game uses collisions in some way. When a player touches an enemy jumps on a platform hits a wall collects a coin or fires a bullet collision detection makes those interactions possible.

Without collision systems game objects would simply pass through each other without interaction. The game would feel broken and unrealistic.

In Flutter web games using Flame Engine collision detection helps objects understand when they touch or overlap. Once a collision happens the game can react by reducing health ending the game collecting rewards or playing effects.

Collision systems are used in almost every game genre:

In this chapter you will learn how collision detection works how Flame handles collisions how to build collision systems manually using Dart code and how collisions work inside a Traffic Rush style game.

What is Collision Detection

Collision detection is the process of checking whether two objects touch each other inside a game world.

For example:

The game constantly checks positions of objects every frame. If two objects overlap a collision happens.

Most games run at around sixty frames every second. This means collision checks happen very quickly and continuously.

Collision systems normally use invisible shapes around objects. These invisible shapes are easier to calculate than checking image pixels directly.

Common collision shapes include:

Rectangle collisions are the easiest and most common type for beginner games.

Imagine a car in a Traffic Rush game. Even though the car image has mirrors and a spoiler the collision system may simply use a rectangular box around it.

If another rectangle overlaps this box the game treats it as a collision.

Collision systems usually answer one important question:

Are these two objects touching right now

If the answer is yes the game reacts immediately.

The reaction depends on gameplay logic. The player may lose health gain points bounce away or trigger an explosion.

Understanding collision systems is important because collisions connect all gameplay systems together.

Normal Collision Detection Using Dart Code

Before learning Flame collision systems it is important to understand how collision detection works manually using normal Dart code.

The most common beginner method is rectangle collision detection. This is also called box collision detection.

Every object has:

The collision system checks whether two rectangles overlap.

Imagine two boxes on the screen. If the boxes overlap even slightly the collision becomes true.

This method is fast and simple which makes it perfect for web games.

Here is a simple collision detection function:

bool checkCollision(
  double x1,
  double y1,
  double w1,
  double h1,
  double x2,
  double y2,
  double w2,
  double h2,
) {

  return x1 < x2 + w2 &&
         x1 + w1 > x2 &&
         y1 < y2 + h2 &&
         y1 + h1 > y2
}

This function checks if two rectangles overlap.

Let us understand what happens here.

The code checks:

If all conditions match correctly the rectangles overlap.

Now let us create a player and enemy example.

class Player {
  double x = 100
  double y = 300

  double width = 60
  double height = 60
}

class Enemy {
  double x = 400
  double y = 300

  double width = 50
  double height = 50
}

During every frame update the game checks collision.

Player player = Player()
Enemy enemy = Enemy()

void update() {

  bool collided = checkCollision(
    player.x,
    player.y,
    player.width,
    player.height,
    enemy.x,
    enemy.y,
    enemy.width,
    enemy.height,
  )

  if (collided) {
    print("Game Over")
  }
}

This is the basic foundation of collision systems in many games.

Manual collision systems are useful because they help developers understand what the engine is doing internally.

Even advanced engines still use mathematical collision checks underneath.

Collision Detection in Traffic Rush Games

Traffic Rush games are one of the best examples for understanding collision systems. The gameplay is simple which makes it easier to focus on collision logic.

In a Traffic Rush game the player controls a car while obstacles move toward the player.

The main gameplay loop is:

The player car usually stays near the bottom of the screen. Obstacles continuously move toward it.

Every frame the collision system checks whether the car box overlaps the obstacle box.

Let us create a simple player car class.

class PlayerCar {
  double x = 100
  double y = 300

  double width = 70
  double height = 70
}

Now create a road cone obstacle.

class RoadCone {
  double x = 800
  double y = 320

  double width = 40
  double height = 60

  double speed = 8

  void update() {
    x -= speed
  }
}

During every frame the obstacle moves closer to the player car.

The collision system continuously checks overlap.

PlayerCar car = PlayerCar()
RoadCone cone = RoadCone()

void updateGame() {

  cone.update()

  bool hit = checkCollision(
    car.x,
    car.y,
    car.width,
    car.height,
    cone.x,
    cone.y,
    cone.width,
    cone.height,
  )

  if (hit) {
    print("Car Crashed")
  }
}

This creates the main challenge in the game.

If the player moves or switches lanes at the correct time the car avoids collision.

If the player fails to react the boxes overlap and the game ends.

Traffic Rush collisions are simple but powerful because timing becomes the core gameplay mechanic.

More advanced Traffic Rush games may include:

Collision systems become the heart of gameplay because every challenge depends on accurate detection.

Flame Collision Detection System

Flame Engine provides a built in collision detection system that makes game development much easier.

Instead of manually checking rectangles every frame Flame can automatically detect overlaps between game components.

Flame uses hitboxes for collision detection.

A hitbox is an invisible collision shape attached to a game object.

Flame supports multiple hitbox types:

To use Flame collisions the game component normally mixes in collision features.

First import Flame collision packages.

import 'package:flame/collisions.dart'
import 'package:flame/components.dart'

Now create a player with collision support.

class PlayerCar extends SpriteComponent
    with CollisionCallbacks {

  @override
  Future<void> onLoad() async {

    add(RectangleHitbox())

    super.onLoad()
  }
}

The RectangleHitbox creates an invisible collision box around the player.

Now create an enemy obstacle.

class EnemyObstacle extends SpriteComponent
    with CollisionCallbacks {

  @override
  Future<void> onLoad() async {

    add(RectangleHitbox())

    super.onLoad()
  }
}

Flame automatically checks collisions between hitboxes during the game loop.

When two hitboxes touch Flame calls collision callback methods.

Here is an example collision response.

@override
void onCollision(
  Set<Vector2> intersectionPoints,
  PositionComponent other,
) {

  if (other is EnemyObstacle) {
    print("Game Over")
  }

  super.onCollision(intersectionPoints, other)
}

This method activates automatically whenever the player touches the enemy.

Flame collision systems are easier because developers do not need to manually calculate overlap every frame.

Flame also supports advanced collision systems such as:

The built in system is very useful for larger games with many objects.

Understanding Hitboxes

Hitboxes are one of the most important parts of collision systems.

A hitbox is an invisible area that represents where collisions can happen.

The hitbox does not always match the image perfectly.

For example a car image may have empty transparent space around it. If the hitbox covers the entire image collisions may feel unfair.

Developers often make hitboxes slightly smaller than the visible sprite.

This creates smoother gameplay and makes collisions feel more accurate.

Flame allows hitboxes to be resized and repositioned.

add(
  RectangleHitbox(
    size: Vector2(40, 50),
    position: Vector2(10, 10),
  ),
)

This creates a smaller hitbox inside the sprite.

Good hitbox design is extremely important in games. Bad hitboxes make games feel frustrating and unfair.

Fighting games shooting games and platform games often spend a lot of time tuning hitboxes carefully.

Even simple games benefit from proper collision shape design.

Collision Responses

Detecting a collision is only the beginning. After the collision happens the game must respond correctly.

Different games use different collision responses.

Common collision reactions include:

In a Traffic Rush game the response is usually game over.

In a shooting game bullets may destroy enemies.

In a platform game landing on the ground stops falling.

Collision response logic creates interaction between game systems.

Here is a simple health example.

int playerHealth = 3

void onPlayerHit() {

  playerHealth--

  if (playerHealth <= 0) {
    print("Game Over")
  }
}

Collision systems become much more exciting when combined with sound effects animations and particles.

Small visual reactions make collisions feel powerful and satisfying.

Image vs Object Collision Detection

There are two main ways to detect collisions in games: image pixel detection and object hitbox detection.

Image collision detection checks the actual visible pixels of a sprite. Object collision detection uses invisible geometric shapes like rectangles or circles.

Pixel perfect collision is very accurate because it checks exactly what the player sees on screen. If a character has a strange shape the collision matches the shape perfectly.

However pixel perfect collision has major disadvantages for web games.

First it is very slow. Checking thousands of pixels every frame requires heavy processing power. This can cause lag especially on mobile browsers.

Second pixel perfect collision can make gameplay feel frustrating. Sometimes a player might hit a single stray pixel on an enemy and lose the game which feels unfair.

Object collision detection using hitboxes is the industry standard for most 2D games including Flame Engine games.

The advantages of object collision are:

For almost all Flutter web games you should use object hitbox detection instead of image pixel detection. It provides the best balance between performance and fun gameplay.

Conclusion

Collision detection is one of the foundations of game development. It allows objects to interact with each other and creates the core gameplay experience.

In Flutter web games collisions can be created manually using Dart code or automatically using Flame hitbox systems.

Traffic Rush style games are excellent examples because the gameplay depends completely on avoiding collisions with obstacles.

Flame makes collision systems easier by providing hitboxes callbacks and automatic overlap detection.

Once you understand collision systems you can build much more advanced gameplay mechanics such as combat systems pickups enemies bullets physics interactions and puzzle mechanics.

In the next chapter you will learn more deeply about hitboxes in Flame and how different collision shapes improve gameplay accuracy.

← Previous Chapter Next Chapter 14 →