Spicy Yoghurt | Last updated: 10 April 2019 | HTML5 game tutorial

# Collision detection and physics

Perform collision detection and react with physics, using JavaScript. Check for overlap between shapes, apply hitboxes and calculate velocities. Make your game objects interact in a natural looking way. By the end of this tutorial you'll have a basic physics simulation running.

This tutorial requires the HTML5 file with the canvas and game loop, you have created in the previous tutorials. If you
skipped that step, you can download the HTML5 file with the canvas animation
here.

## Create some moving objects

*If you already know how to create moving objects and are just interested in detecting collisions or physics, scroll down to the next section.*

```
class Square extends GameObject
{
constructor (context, x, y, vx, vy){
super(context, x, y, vx, vy);
//Set default width and height
this.width = 50;
this.height = 50;
}
draw(){
//Draw a simple square
this.context.fillStyle = this.isColliding?'#ff8080':'#0099b0';
this.context.fillRect(this.x, this.y, this.width, this.height);
}
update(secondsPassed){
//Move with set velocity
this.x += this.vx * secondsPassed;
this.y += this.vy * secondsPassed;
}
}
```

This code might look a bit familiar.
There is a draw() and a update() function, just like in the previous tutorial.
Only this time it is baked into a separate square class.
This way you can create many instances of a square and they all use the same logic to draw and update.
You'll have the behavior and looks of the square in one, easy-to-manage, place.
The fillStyle in this new class is tweaked a bit. When this object is colliding, it will change color from blue to red. You'll see this in action when the first collisions are detected. For now, all squares will be blue.

All the squares inherit from the GameObject class. Every game object has a position and a speed. This enables you to easily create new types of game objects. They inherit the attributes and methods of the GameObject class. The square is just an example, but you could also make enemies for your game this way.

```
class GameObject
{
constructor (context, x, y, vx, vy){
this.context = context;
this.x = x;
this.y = y;
this.vx = vx;
this.vy = vy;
this.isColliding = false;
}
}
```

You can create a new instance of a class by using the new keyword.
Make some squares to fill up your game world using this createWorld() function.
```
var gameObjects;
function createWorld(){
gameObjects = [
new Square(context, 250, 50, 0, 50),
new Square(context, 250, 300, 0, -50),
new Square(context, 150, 0, 50, 50),
new Square(context, 250, 150, 50, 50),
new Square(context, 350, 75, -50, 50),
new Square(context, 300, 300, 50, -50)
];
}
```

In the function, a bunch of squares are created. They are passed a position and speed as arguments.
For now, this function is very static, but you could easily modify it to create more random squares or use some spawning algorithm.
Everything is in place to draw squares now. Update your game loop with the following code to loop over the newly created game objects and draw them on the screen.

```
function gameLoop(timeStamp) {
var secondsPassed = (timeStamp - oldTimeStamp) / 1000;
oldTimeStamp = timeStamp;
// Loop over all game objects
for (var i = 0; i < gameObjects.length; i++) {
gameObjects[i].update(secondsPassed);
}
clearCanvas();
// Do the same to draw
for (var i = 0; i < gameObjects.length; i++) {
gameObjects[i].draw();
}
window.requestAnimationFrame(gameLoop);
}
```

As you can see, update() and draw() are no longer just called once per iteration.
There are called once for every object on screen, every iteration.
This way the implementation of update() and draw() is object-specific. For the game loop it doesn't matter what kind of objects you are trying to draw, as long as they have an update() and draw() function.

For the square you are using, it will draw a simple square and move it in a straight line. But imagine other types of objects who have their own implementation of the two functions and have behavior and looks of their own. This game loop can handle it.

By the way, did you notice the "use strict" line missing in these new classes? That's because classes defined with the class keyword are strict by default. So, there is no need to specifically add "use strict" in these classes.

Take a look at the result: You can see a bunch of rectangles getting drawn now. They each have their own starting position and move in a different direction. Just as defined in the createWorld() function. You can tweak the variables to create new types of squares.

The squares may overlap in their movement, but that doesn't do much for now. It would be cool if the squares could interact and behave like actual solid objects. They would have to know they're colliding with one another. That's where collision detection comes in.

## Check for collisions between objects

The squares are moving on the screen, but there is no form of interaction jet. It's like they don't notice each other. Let's do something about that.You are going to check for collisions between the moving objects. That requires you to loop over all objects and check if any of them overlaps with another. You'll need a nested for loop for this. Take a look at the example:

```
function detectCollisions(){
var obj1;
var obj2;
// Reset collision state of all objects
for (var i = 0; i < this.gameObjects.length; i++) {
this.gameObjects[i].isColliding = false;
}
// Start checking for collisions
for (var i = 0; i < gameObjects.length; i++)
{
obj1 = gameObjects[i];
for (var j = i + 1; j < gameObjects.length; j++)
{
obj2 = gameObjects[j];
// Compare object1 with object2
if (rectIntersect(obj1.x, obj1.y, obj1.width, obj1.height, obj2.x, obj2.y, obj2.width, obj2.height)){
obj1.isColliding = true;
obj2.isColliding = true;
}
}
}
}
```

All objects are checked for intersection with each other.
The second for loop is a bit smarter and skips all previous checked items.
You don't have to check objects twice. If they overlap the first time, they will too the second time.
And of course, you don't have to check an object against itself, it would always overlap.
The function calls rectIntersect() for every combination of objects. When it finds a collision, it sets isColliding to true for both objects involved.

Remember the draw() function from the square? It will react to isColliding and draw the square in a different color. You can easily see when two objects overlap.

## When do you check for collisions?

Just as with the draw() method, you want to update the position of all your game objects first, before checking for collisions. This way you'll always check for overlapping objects in their most recent state. If you do it the other way around and check for collisions before updating, you'll be checking for overlap on the state of the previous frame. You'll always run behind the facts.Another option would be to do the collision check in the right order, but iterative. You would update object-a, check object-a for overlap with all other objects, update object-b, check object-b for overlap with all other objects, and so on. This is also an incorrect way of doing a collision check. Imagine object-a would be in collision with object-b after updating object-a's position. The system would detect a collision, even though it might not have been the case when object-b would have moved first too. That's why you'll always have to update

*all*objects, before doing a collision check.

The correct order for your game loop is, update, collision check, clear canvas, draw. So, place the detectCollisions() function right after the loop for updating all game objects. Your total game loop now looks like this:

## Collision detection between rectangles

The last piece of the puzzle is the rectIntersect() method. You can use it to check if two rectangles overlap. Checking for overlap between two axis-aligned (unrotated) rectangles is pretty simple and straight forward. You can probably come up with a method of checking for overlap on both axis by using the position and size of the rectangles. There are a lot of ways to do this, but the next method is very efficient:```
rectIntersect(x1, y1, w1, h1, x2, y2, w2, h2) {
// Check x and y for overlap
if (x2 > w1 + x1 || x1 > w2 + x2 || y2 > h1 + y1 || y1 > h2 + y2){
return false;
}
return true;
}
```

The code detects rectangles clearly overlapping halfway, but also works in the case of one small rectangle falling completely in a large one.
With this piece of code in place, you can finally check out the result. Here are the squares again, but this time they react upon each other. After detecting a collision, the isColliding attribute is set to true. This makes the squares draw in red. You can clearly see when two objects overlap now.

## Check if two circles overlap

You have a method now for checking collision between unrotated rectangles. But what if you want to do the same for circles? Well, that's not that hard either.Imagine you have two circles, each with their own radius. They are placed with a distance between them. The circles would overlap if the distance is smaller than the sum of the radius of both circles. Since circles are round, this would even work when rotating the objects, they don't have to be axis-aligned.

## Calculate distance between two points

You can calculate the distance between two points with the following formula:c = sqrt((x1 - x2)

^{2}+ (y1 - y2)

^{2})

If you think of Δx and Δy as two sides of a triangle, it basically applies the Pythagorean theorem to compute the size of the straight line between the points,

*c*, the distance.

```
circleIntersect(x1, y1, r1, x2, y2, r2) {
// Calculate the distance between the two circles
var squareDistance = (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2);
// When the distance is smaller or equal to the sum
// of the two radius, the circles touch or overlap
return squareDistance <= ((r1 + r2) * (r1 + r2))
}
```

As you can see, the formula is tweaked a bit.
Multiplication is much faster than getting the square root with Math.sqrt, so distance is calculated without getting the root and the sum of the radii is multiplied by itself.
The outcome stays the same, but the performance is better.
Here is the same example as before, but with circles this time:

## What about other shapes?

In this article, collision detection is only covered for two types of shapes. But what if your game objects consist of other, more complex, shapes or even images, and you want to perform collision checks between them?Well, for geometric shapes you can find other formulas to detect when two objects overlap. Here's a website who covers collision detection for a lot of different shapes. Overall, more complex shapes make collision detection more difficult. And for images you could apply pixel perfect collision detection. The downside of this, is that it's a super CPU-heavy operation.

That's why, to make things easier and put less stress on your system, developers often use hitboxes to detect collisions between complexly shaped game objects. It's a way to make collision detection easier and uses only basic geometric shapes, like the rectangles and circles covered in this tutorial. So, before you start building support for all kinds of complex shapes, try to think of a simple way to achieve the same effect, with basic shapes and hitboxes.

## What are hitboxes and how do you use them?

Hitboxes are imaginary geometric shapes around game objects that are used to determine collision detection. Imagine you have a player figure. You won't check its arms and legs for collision but instead just check a big imaginary rectangle that's placed around the player.You could simply use the function for rectangle collision detection, you've applied before, to check the hitboxes for collisions. It's far less CPU-intensive and makes supporting complex shapes in your game much easier. In some special cases, you could even use multiple hitboxes per game object. It would still outperform the pixel perfect solution. The image above demonstrates the different types of collision detection. They each have their own advantages and disadvantages:

- Pixel perfect - Super precise collision detection, but it requires some serious system resources. In most cases this is an overkill.
- Hitbox - Much better performance, but the collision detection can be pretty imprecise. In many game scenario's though, this doesn't really matter.
- Multiple hitboxes - Less efficient then a single hitbox but it still outperforms the pixel perfect variant. And you can support complex shapes. This is a nice option to use for important game objects that need some extra precision, like
*the player*for example. You could make a hitbox for the core and separates ones for arms, legs and the head.

## React to collisions with physics

Ok, let's continue. You now have game objects who can detect a collision and change color. But wouldn't it be much cooler if the objects bounce off on each other, like real life objects? It's time to apply some physics to your game.To change the velocity of the moving objects, you'll need to find out in what direction and with what speed the collision took place. You can then apply a change in velocity to the collided objects. The principles behind this work for both rectangles and circles.

## Find the direction and speed of the collision

Start by creating a vector for the collision that took place. The vector is nothing more than the difference in*x*and

*y*between the two colliding objects. You can see it as an arrow with length and direction. With vectors, the length is also called magnitude.

```
var vCollision = {x: obj2.x - obj1.x, y: obj2.y - obj1.y};
```

The magnitude, in this case, is equal to the distance between the two colliding objects.
It has nothing to do with speed yet. But we *can*use the direction of the vector. To use the direction, you need to take away the factor of the distance.

Let's first calculate the distance for the collision vector. You can use the same formula as you did before to calculate the distance between two colliding circles. So, the code becomes:

```
var distance = Math.sqrt((obj2.x-obj1.x)*(obj2.x-obj1.x) + (obj2.y-obj1.y)*(obj2.y-obj1.y));
```

Now use the distance to compute a normalized collision vector.
You basically remove the distance as a factor in the basic collision vector, so you are left with just a direction.
The collision norm is in the same direction as the collision vector, only with norm/magnitude/length 1.
You also call this an unit vector.
```
var vCollisionNorm = {x: vCollision.x / distance, y: vCollision.y / distance};
```

You now have a direction. This is the direction in which the collision took place. All you have to do is apply a speed to it, to actually use it.
You can calculate the speed of the collision like this:
```
var vRelativeVelocity = {x: obj1.vx - obj2.vx, y: obj1.vy - obj2.vy};
var speed = vRelativeVelocity.x * vCollisionNorm.x + vRelativeVelocity.y * vCollisionNorm.y;
```

First, another vector is created with the relative velocity of the objects. Together with the collision normal it is used to calculate the dot product of the two vectors.
The dot product is the length of the projection of relative velocity on the collision normal. Or in other words, the length of the velocity vector when it's in the direction of the collision.
Learn more about dot products here. Learn more about vector operations here.
The dot product is equal to the speed of the collision. So that's it, you've got a speed and direction of the collision between the two objects.

## Change velocity of the moving objects

The speed can be positive or negative. When it's positive, the objects are moving toward each other. When it's negative, they move away. When objects move away, there is no need to perform any further action. They will move out of collision on their own.```
if (speed < 0){
break;
}
```

For the other case, when objects are moving toward each other, apply the speed in the direction of the collision.
Both objects get the same change in velocity from the collision. Subtract or add the velocity to the velocity of the two collided objects.
```
obj1.vx -= (speed * vCollisionNorm.x);
obj1.vy -= (speed * vCollisionNorm.y);
obj2.vx += (speed * vCollisionNorm.x);
obj2.vy += (speed * vCollisionNorm.y);
```

That's it, by applying speed to direction, you calculate the collision velocity. And that velocity is now processed in the velocity of the objects involved.
Your game objects should bounce in a natural looking way.
Now take a look at the result:

## Add mass, impulse and momentum

If you like, you can take mass into the equation by calculating the collision impulse from the speed. Use the impulse to calculate momentum. Heavy objects will push light ones aside.```
var impulse = 2 * speed / (obj1.mass + obj2.mass);
obj1.vx -= (impulse * obj2.mass * vCollisionNorm.x);
obj1.vy -= (impulse * obj2.mass * vCollisionNorm.y);
obj2.vx += (impulse * obj1.mass * vCollisionNorm.x);
obj2.vy += (impulse * obj1.mass * vCollisionNorm.y);
```

If you have two objects with a mass of 1, the impulse is just equal to the speed.
In other cases, you basically split the speed into many small parts.
Heavy objects receive a few of those parts as momentum, light objects a lot.
This makes the lighter objects more effected by the collision.
Don't forget to add mass to your game objects. The GameObject class is a good place to store mass. Try to modify the createWorld() function to pass mass as an argument via the Circle and Rectangle classes.

Here's an example that's modified to create a lot of small circles and two larger ones. (The spawning algorithm isn't very smart so the objects might start in collision) In the example, the big circles have a very large mass compared to the smaller circles. They push everything out of their way. But when the two heavy objects hit each other, they too bounce off.

## More physics, like gravity

The examples shown here in this tutorial are just a basic implementation of physics. You could add more to your game. Things like restitution or friction aren't too hard to implement.As a final example, here's how to add gravity to your game objects. Simply adjust the

*y*-speed of your objects with the gravitational acceleration. This is done inside the update() function of your game objects. Every second,

*g*is added to the

*y*-speed, this will make the object fall, faster and faster.

```
//Set gravitational acceleration
var g = 9.81;
update(secondsPassed){
//Apply acceleration
this.vy += g * secondsPassed;
//Move with set velocity
this.x += this.vx * secondsPassed;
this.y += this.vy * secondsPassed;
}
```

Update the velocity before you update the position. This will give more accurate results, as explained in this article about integrating the equations of motion.
This type of integration is called Semi-implicit Euler.
## Ways of improving performance

You might not really notice it right now, but with many game objects on screen at once, or with more complex shapes, the collision detection and -reaction can put some serious stress on your system. Here are some tips that might help to improve performance. They might seem obvious, but when a game gets more complex it's easy to overlook some of these concepts.- Only compare objects that are close enough to have a possible collision. You could use a grid system or only detect collision when objects enter a certain radius. This is called splitting the collision detection into a broad phase and narrow phase. Learn more about broad phase collision detection here.
- Keep your object pool clean. Clean up objects when they are out of view or destroyed in-game.
- Exclude background/stationary objects. Some objects won't ever react to collisions, so don't include them in the iteration.
- Use hitboxes. As explained before, hitboxes are a great way of optimizing collision detection and simplify complex shapes.
- Adjust the implementation of collision detection and physics to fit your game. You don't need a full physics engine when all you want to do is to make tic-tac-toe. That's a bit of a drastic example, but you get the point. Strip your logic to only support what is needed.

## Handle fast moving objects

One final note about collision detection. The above example detects collisions by checking if two objects overlap. This is a good solution in many cases. But it won't work when your objects move at great speed. When the speed is higher than the size of your smallest object, objects have a chance of skipping the collision check. They pass through each other.Imagine you check for a collision between a bullet and an enemy in your game. The first frame the bullet is before the enemy. There is no overlap, so the objects didn't hit. The next frame the bullet moved so fast, it is now behind your enemy. There still is no overlap, so no collision. But the bullet did pass right through the enemy and there should've been a hit.

You need another approach for this kind of situation. The simplest way is to limit the speed of your game objects. In short, make sure the speed is never larger than the smallest game object, so it can't pass through. For many types of games this is a great solution and it requires minimal effort.

The other solution is to perform collision detection with the projected path instead of the current position of the two objects. Try to visualize the path of a bullet as a line. The length of the line is equal to the distance the bullet will travel. Now you can use a line-to-rectangle or line-to-circle collision check to find out if the bullet will hit another object. For large bullets, you could use a rectangle instead of a line.

This is a simplified solution. You will probably run into other problems along the way, like finding the point of impact or determining which object of a greater set is hit first. But the steps mentioned here might help to point you in the right direction. For now, this is all on fast moving objects for this tutorial.

## Final code

That's all for now on collisions and physics. Your collision check is in place and your game objects are now interacting with each other in a semi-natural way. You can download the final code here. Feel free to ask questions in the comments.In the next step of the tutorial, you'll learn how to use images in your game.

## Leave a comment