Page 1 of 1

Efficient 2d collision [SOLVED]

Posted: Sat Feb 13, 2010 4:50 pm
by Talder
Heya!
To start off, I'm very new to game development so this might be an incredibly dumb question and if it is very annoying to answer, you don't have to bother =P

Okay, so I'm making a 2d game with C++/SDL and I've just started making movement and collision checking for my character. My game screen is basically built up of a 10x10 grid. I have an array called "objects[10][10]" to hold this information and there's an collision check for these 100 objects that works great, but it seems very ineffective.

Every frame i call a function named "move()" uses my velocities to move the character and checks for collision. The collision checking is simply a loop that goes through my "object[10][10]"-array and if there is an object on some location in the array I put values into an temporary rectangle that I'll then use for collision detecting. So I call another function named "collision(SDL_Rect, SDL_Rect)" and use my characters offsets and the temporary rectangle as the paremeters.

This means that I check if there is an object on every location of my array every frame. If there would be like 30 objects on the map I would also check for collision 30 times every frame and this seems like a very slow way to do this. So my question is basically if someone could explain a more efficient way to do this or give me an URL to a guide or something of that kind.

Thanks for your help! =)

Re: Efficient 2d collision

Posted: Sat Feb 13, 2010 6:51 pm
by Bakkon
When your character moves, assuming it's position is held by a floating point X and Y, do some simple math to figure out which tile it's currently in and which tile it'll be in once moved. Then check only the tiles it passes through for collision.

Re: Efficient 2d collision

Posted: Sat Feb 13, 2010 7:36 pm
by Ginto8
Presuming that you use a rect class similar to this:

Code: Select all

class Rect {
public:
    float x,y,w,h; // x and y are
};
you can use this function:

Code: Select all

inline bool colliding(Rect A, Rect B) { return (A.x < B.x + B.w) && (A.y < B.y + B.h) && (A.y + A.h > B.y) && (A.x + A.w > B.x); }
But it will only serve you if all you need is collision detection. If you need something more complex, check out the Separating Axis Theorem, here.

Re: Efficient 2d collision

Posted: Sun Feb 14, 2010 6:49 am
by Talder
Thanks, it really helped!

EDIT:
In case anyone would have this problem in the future, here's how my move function looks now:
Offsets is a square that represents my character.
Object[10][10] is my array holding objects.

Code: Select all

//Move along the x-axiz
offsets.x = offsets.x + xSpeed ;
//If the character is moving to the right
if (xSpeed > 0)
{
	//These are the objects that would be to his/her right:
	//object [(offsets.x/32)+1] [(offsets.y/32)-1]
	//object [(offsets.x/32)+1] [(offsets.y/32)]
	//object [(offsets.x/32)+1] [(offsets.y/32)+1]

	for (int i = -1; i<2; i++) //Loops through those 3 objects
	{
		//If there is an object at that location
		if (object [(offsets.x/32)+1] [(offsets.y/32)+i] > 0 )
		{
			//Create a temporary rectangle representing that object
			temp_rect.x = ( (offsets.x/32)+1 ) * 32 ;
			temp_rect.y = ( (offsets.y/32)+i ) * 32 ;
			//Check for collision
			if (collision (offsets, temp_rect) == true)
				offsets.x = offsets.x - xSpeed ;
		}
	}
}
Please note that there is a lot of better ways to this, just wanted to give some kind of help if anyone would have the same problem.