Efficient 2d collision [SOLVED]

Whether you're a newbie or an experienced programmer, any questions, help, or just talk of any language will be welcomed here.

Moderator: Coders of Rage

Post Reply
Talder
Chaos Rift Newbie
Chaos Rift Newbie
Posts: 2
Joined: Sat Feb 13, 2010 4:31 pm

Efficient 2d collision [SOLVED]

Post 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! =)
Last edited by Talder on Sun Feb 14, 2010 6:50 am, edited 1 time in total.
User avatar
Bakkon
Chaos Rift Junior
Chaos Rift Junior
Posts: 384
Joined: Wed May 20, 2009 2:38 pm
Programming Language of Choice: C++
Location: Indiana

Re: Efficient 2d collision

Post 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.
User avatar
Ginto8
ES Beta Backer
ES Beta Backer
Posts: 1064
Joined: Tue Jan 06, 2009 4:12 pm
Programming Language of Choice: C/C++, Java

Re: Efficient 2d collision

Post 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.
Quit procrastinating and make something awesome.
Ducky wrote:Give a man some wood, he'll be warm for the night. Put him on fire and he'll be warm for the rest of his life.
Talder
Chaos Rift Newbie
Chaos Rift Newbie
Posts: 2
Joined: Sat Feb 13, 2010 4:31 pm

Re: Efficient 2d collision

Post 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.
Post Reply