This page is a mirror of Tepples' nesdev forum mirror (URL TBD).
Last updated on Oct-18-2019 Download

Collision for all cases is hard... Tips?

Collision for all cases is hard... Tips?
by on (#38517)
Well, the hit detection is getting there, but I'm still finding myself able to go through walls and not be able to get into narrow gaps when falling and jumping...

Here's a basic synopsis of what I'm doing:

-A room is 16x12. There's an array that holds the various block types (0 for solid, 1 for blocking, 2 for spike)
-A player's hitbox is 16x16.
-I've got 4 variables: 2 for your X/Y coords and 2 more for an X/Y offset.
-The X/Y offset is setup so that 16 is center. When it either = 0 or 32, you've gone entirely into the next adjacent block and your X/Y coords will change.
-Whenever a player's offset is not 16, then you need to take into account some adjacent blocks.
-The order I check things in is walking, jumping, falling.

It doesn't check if you're INSIDE a solid block, but only if you tried to move into one. One example is if you walk out the right side and the next room has a solid block at the point of entry on the left, you can walk freely while inside that block, but if you walk off the block, you can't walk into it.

Does this approach sound reasonable or is there anything that stands out that should be looked at?

by on (#38520)
In my game I'll have a few different types of metatiles, but most metatiles are not solid at all, or solid 16x16 pixel squares. I have a bounding box around the character, and I check for collision only on the two sides that correspond with the two directions being moved in. So if I'm moving up and left at the same time, I'll check for collision on the top border and the left border of the bounding box.

Since each metatile is 16x16 pixels, I only have to check for collision every 16 pixels on the borders. But there'll always be a collision point on the very first and last pixels on each border of the bounding box (This may not be a multiple of 16). For when the character moves two directions at once, I have to check for collision by moving in each direction separately. So the character will move in one direction, and I'll check for collision on that border. Once I do that, I'll move the character in the other direction and check for collision there. I check for collision by moving, and correcting the position if there's a collision. It works differently for every direction and every tile type.

I keep track of the player's X and Y coords as 24-bit, since the room is multiple screens and there is lots of moving portions of pixels. I check for collision based on those coords.

I'd suggest trying to check if one is inside of a tile, and just correcting the position afterwards. And make sure that your bounding boxes have collision points everywhere they need to be.

by on (#38556)
Granted this is on GBA but this is the raw logic I use for hit detection. It will tell if you're in a solid block.

-Get the x,y coordinates of the midpoint of both hitboxes
(x0 + ( (x1-1)/2 ) ) where x0 is the left edge and x1 is the right edge

-Get the distance where the hitboxes would touch without overlapping. I call this ex,ey in code.
(width,height of box one)/2 + (width,height of box two)/2

-Get distance between the midpoints, called dx,dy, by subtracting the lower midpoint from the higher one.

-If dx<ex and/or dy<ey you have an overlap. To see if it's a vertical or horizontal collision, use the distance between e and d. If ey-dy > ex-dx it's a horizontal collision.

-There's also some overhead checking to make sure one hitbox is moving towards another, only check in the direction it's moving, etc.

You can pass the difference between e and d and you'll know how much to move the object out of the block. The problem is if you move too far into the block it might register as a side collision when you really moved from the top. That can be fixed with an additional test that adds the velocity to the current hitbox pos and reduces velocity if the next frame would be a hit*.

*This solution also fixed another problem that didn't show up with the player but did with other moving objects-they would move into a solid area then quickly move out.

For collision with level terrain I check the object against a surrounding 4x4 field of metatiles. Hope that doesn't kill performance on NES.