Handling collisions in a platformer

Hey guys!

I’m starting to make a simple 2D platformer and I’m not sure how to handle collisions. I get the basic idea: entities and tiles have bounding boxes and checking if two boxes overlap is basic math. But once I know entity A and tile B overlap, I can’t think of a way to move entity A to the edge of tile B so they don’t overlap without an if chain checking for each direction. And then there are special cases, such as tiles you can jump onto from below so I’d need another if statement to check against those and if the entity is moving up when that collision happens. How do you guys/gals go about doing this cleanly, without a dozen if statements and state checking? What is generally done to resolve collisions in a basic platformer? I tried searching the forums and googling solutions but all the articles I found focused more simply detecting if two bounding boxes overlap rather than what to do after that.

I feel like there should be a simple solution but I’m thinking about this too much and can’t think of a way to handle this without messy code that couples a dozen objects together.

If an entity is colliding with a tile/entity, that’s as easy as calling the intersects method of your favourite Rectangle class (or just use if statements). You said you wanted platforms that can be accessible through the bottom face (or only be solid on the top face). You can generally find what face you collided with with some resolution.

This is definitely not the most efficient way, but it is one of the easiest ways to implement working collision detection. It works fine for small levels, not so much for huge open world games (although I’ll explain how to optimize this method enough for bigger worlds and more entities).

For entity to static tile collisions, you don’t have to check constantly because you know the tile boundary always lines up every X pixels (or whatever units you’re measuring the world in). If my tile size is 32x32, I only have to check every 32 pixels. The way to check that is position % tile_size == 0. If I’m lined up on one of the axes, I have to iterate through the tiles that I may be colliding with on one face. If any one of the tiles is solid on that face, I must stop my velocity in that direction. Unfortunately this is the crappy part about this method. Instead of moving your position by the velocity and then checking for a collision, you have to step your position every pixel (I am so sorry) and constantly check for a collision. The collision only checks every tile width so it’s still pretty bad. However this method has extremely high accuracy when moving at extremely fast velocities (in my previous game this was an absolute must). Another upside is that your tiles can have faces in which they are solid or not. This way you could have a platform that’s only solid on its top face so you could jump “under” it to land on top of it.

Entity to entity collisions are similar. Unfortunately this means checking against every single entity each time. This gets really slow really quickly(O(n^2) I think) so this is only good for small games, not huge open world games.

Optimizations for reducing the frequency of checks can involve checking less often and visually interpolating the position to make it appear smooth.

Optimizations for the entity-entity collision involve reducing the number of entities it must check against. To do this you can use a quad tree. Quad trees divide the world into 4 quadrants. Entities can fit in that quadrant (or not but that’s a different case). Entities in a quadrant only have to check against the other entities in its same quadrant. This reduces the number of entities to check against. If there are too many entities in a quadrant, the quadrant itself splits into 4 more littler quadrants. The number of entities to check reduces again. This is an absolute must for open world games because the high number of entities will cripple performance rapidly if you’re checking some monster on the opposite side of the world with the player.

I hope that helps. This is definitely not an efficient way to handle collision but it’s easy to implement and understand and has high accuracy. This should be enough for a small platforming game.

Your entity to tile collision method should work fine for my purposes. To avoid stepping the position every pixel, I’m thinking of storing the previous tile position of an entity and comparing it to the new tile position when it moves to check if an entity crossed a tile boundary. Then I wouldn’t have to use a modulo and can step the position with the velocity.

I’ll look into implementing quad trees. I found something similar called a Spatial Hash Grid, which divides the world into a simple grid of cells, but it has the drawback that one cell can contain many entities. I might still use it though since it’s easier to implement (and who designs a level with thousands of entities in a platformer?).

Thanks for the help!

Edit: With a quad tree, wouldn’t you have to rebuild the tree every time an entity moves? This would make it very slow, no?

You rebuild the tree every logic tick AFTER all the movement and collision has been handled. It’s a tiny bit slow but way faster than updating it every time one entity moves.

I see, that makes sense.