Plan
Collisions is how we will detect interaction between enemies and obstacles with our player. We plan to do this by using axis-aligned bounding boxes (AABBs). It’s a mathematical way of detecting collisions between multiple objects. It’s typically used for rectanglular and square hitboxes, perfect for what we are trying to accomplish. While our sprites aren’t rectangular, as you’ll know from the hitbox blog, they use rectangles for collision detection.
Logic behind AABB
In order to understand collision detection (AABB), let’s take a look at the code below (this is part of the code we used for own game).
//Checks for collision between the player & enemy
function checkCollisions(playerObj, enemyObj) {
if (
playerObj.hitbox.x < enemyObj.hitbox.x + enemyObj.hitbox.width &&
playerObj.hitbox.x + playerObj.hitbox.width > enemyObj.hitbox.x &&
playerObj.hitbox.y < enemyObj.hitbox.y + enemyObj.hitbox.height &&
playerObj.hitbox.y + playerObj.hitbox.height > enemyObj.hitbox.y
) {
//If there is collision, log "Collision"
console.log("Collision");
}
}
The first thing to note is how the function checkCollisions takes into two parameters. The player object and the enemy object. Now, we compare the x and y values of the player and enemy hitboxes to see if there is any overlap between. If all 4 conditions are meant, then there is an overlap between the two objects. If in fact there is collision between the two sprites, then log Collision in the console. This can be replaced with ore meaningful code, such as deploying a Game Over screen or causing the player to lose health.
However, how as mentioned above, the code checks the x and y values of the player of the enemy to check for overlap. How exactly this works is a bit more complex. In a nutshell, each hitbox (playerObj.hitbox.x, enemyObj.hitbox, etc.) represents a part of the hitbox.
- playerObj.hitbox.x = left side of player hitbox
- playerObj.hitbox.x + playerObj.hitbox.width = right side of player hitbox
- playerObj.hitbox.y = top side of player hitbox
- playerObj.hitbox.y + playerObj.hitbox.height = bottom side of playerhitbox
Let’s take a look at this code partially written in English.
if (
left side of player < rigt side of enemy &&
right side of player > left side of enemy &&
top side of player < bottom side of enemy &&
bottom side of enemy > top side of player
)
With each side defined, we can compare the two shape’s sides to see if there are colliding. Further information into this can be found here.
But heading back to the code, all we would have to do at this point is loop checkCollisions continously, so the game would constantly be checking if there are collisions.
function gameLoop() {
//Checks for collisions between the player and enemy
checkCollisions(playerObj, enemyObj);
}
Holistic View
Now, at the time of writing this, we have a strong understanding on how hitboxes and collisions work and have implemeneted such into our game. Two key components in having interaction between multiple objects. Now that we have this foundation for interation, we just have to implement what we have planned for it. Spikes, enemies, etc. Perhaps when colliding with enemies, decrease the health of player or just make them instantly die and make a Game Over Screen pop up. These are all much more feasible ideas thanks to the additional code that we have now.
Collisions is just one small, but critical part of having a good game. But taking an even more restropective view of the situation is how one’s experience with coding collisions tests many different parts of their knowledge, making them in the end, much better than before. That is the most holistic way to approach this, and perhaps the most accurate way as well.