Let's build basic collision detection in JavaScript!

By Eric Lewis March 30, 2018

If you're building a game where one character bumps into other characters, you might find yourself asking "Hey self...how do I check if Pacman bumped into a ghost?"

The answer is 🔍💥 collision detection 💥🔍

There's plenty of ways to implement collision detection. I'll describe one method: grid-based collision detection.

In grid-based collision detection, the game board is divided into single tiles. My game board will be a 4×4 grid. Each character and object in the game occupies exactly one tile.

My grid will be a div element with position: relative applied. Items on the board will be absolutely positioned to fit into its tile's location. Here's what the grid will look like. I've overlayed each tile's x, y coordinates and grid lines just for show here, and won't include them in the game proper.

0, 0 1, 0 2, 0 3, 0 0, 1 1, 1 2, 1 3, 1 0, 2 1, 2 2, 2 3, 2 0, 3 1, 3 2, 3 3, 3

My game will be called Breakfast with Blerf. Let me tell you the rules.

You are Blerf. Blerf wakes up on Planet Chill every day around 11:30am and promptly eats plants for breakfast. Sounds late to wake up? Blerf is an astronomer by trade, and works late nights at the observatory. So cut Blerf some slack.

Blerf moves around Chill when you press the arrow keys.

On Planet Chill, quite like Planet Earth, there are rocks that are too big and craggly to climb over. If a tile contains a rock, Blerf cannot move into it.

These are Chill plants. Mmm, Blerf likes delicious Chill plants. When Blerf moves into a tile with a plant, the plant disappears into Blerf's belly.

I'm going to represent each thing's location on Planet Chill as an object with properties for its x and y coordinates.

Blerf starts out in the top left tile, so I'll initialize Blerf's location like this:

Since there are many rocks, I'll make an array of location objects to represent tile locations for a few rocks:

To render Blerf on the grid, I'm going to hard-code a <div class="character"> element as a child of the board div the HTML. Blerf will appear in the top left tile.

Blerf's picture and the likenesses of other items show up because I've set an image for each element's background-image.

To render the rocks on the grid, we'll write a function that loops over the rocks global variable, create DOM elements and set their position.

Cool! At this point we would see Blerf and the Chill rocks sitting there on the grid.

The player will press an arrow key in our game to move Blerf around. I'll set up an event listener to call separate move functions depending on which key is pressed.

When a user presses the right arrow key, Blerf should move right while there's still grid tiles to move to that aren't occupied by rocks. Here's where the "magic" happens.

I can check Blerf's location by accessing blerf.x and blerf.y. Before we let Blerf move, we'll find the location that Blerf will move to, if we say he can. If Blerf is at coordinate 0, 0 and Blerf is moving right, then Blerf wants to go to 1, 0.

Let's write a few functions to help us decide whether Blerf is allowed to move to 1, 0. First, a function that checks whether the coordinate to move to is on the grid. Blerf can't leave his planet, that would be literally not Chill.

Let's also write a function to check whether there's a rock at a coordinate, because Blerf doesn't want to scale craggly rocks that slice up his feet.

Now we can combine these in a function that checks whether Blerf can move to a given coordinate.

We can now implement the moveRight() function we call in the keydown event listener. It checks if Blerf can move to a hypothetical new location. If he can't, nothing happens. If he can, Blerf's location value is updated, and we call another function that updates the positioning of Blerf's DOM element to make the change visible to the player.

That is grid-based collision detection in a nutshell. Check if the character can move to a hypothetical location against any number of obstacles, and move them if so.

Here's the completed game, playable below. Oh wait, I didn't even mention how to implement Blerf eating the plants! Drats, I'm out of time. Check out the stand-alone version of the game that includes the source code to see how I did it :)

Exercises

Are you learning about collision detection? Awesome! Remix my source code on Glitch and try one of these exercises:

  1. Create a function resetGame() which changes the state of the game back to the beginning. resetGame() should be called two seconds after the player wins the game.

  2. Instead of hard-coding rock and plant locations, randomize their locations on the grid. Make sure items don't overlap each other!

  3. Make the grid bigger: try 5×5 or 6×6.

  4. Introduce a friend for Blerf. When Blerf moves next to the friend, display a message from the friend for two seconds like "Hi Blerf!" or "How's the stars, Blerf?" Check out the displayWinMessage() function for an example of how we display a message.