Advertisement

AABB collision

Started by March 29, 2024 09:20 PM
50 comments, last by JoeJ 6 months ago

This creates two instances, each at its own unique memory address.

But both using the same definition of data layout and order,

and both being initialized to the same 5,10 values.

So likely you want to change the data manually for at least one of the two rects.

I have to sleep now, but i feel you are close to the missing realization, which did hold you back for all those years… ; )

so how do I make the boxes using rect1.x and rect2.x and so forth in the main function?

Advertisement

pbivens67 said:
so how do I make the boxes using rect1.x and rect2.x and so forth in the main function?

That's easy. You already did it previously with SDLs rectangles.

class Rect
{
public:
	float x = 0;
	float y = 0;
	float w = 0;
	float h = 0;
};

bool intersectRect(const Rect1& rect1, const Rect2& rect2)
{
	return rect1.x < rect2.x + rect2.w && rect1.x + rect1.w > rect2.x &&
		rect1.y < rect2.y + rect2.h && rect1.y + rect1.h > rect2.y;
}

int main(int argc, char* args[])
{
	Rect rect1;
	rect1.x = 5;
	rect1.y = 5;
	rect1.w = 100;
	rect1.h = 100;
	
	Rect rect2;
	rect2.x = 25;
	rect2.y = 25;
	rect2.w = 100;
	rect2.h = 100;
	
	Rect3;
	//...
	
	bool i1_2 = intersectRect(rect1, rect2);
	bool i1_3 = intersectRect(rect1, rect3);
	bool i2_3 = intersectRect(rect2, rect3);
}

But to realize the real advantage, you should do something like:

Make a grid of 5 x 4 rects and render them all on screen.
E.g. to make Space Invaders.

This would look something like:

int main(int argc, char* args[])
{
	Rect r[5*4];
	
	 for (int y=0; y<4; y++)  
	 {
	 	for (int x=0; x<5; x++)  
	 	{
	 		int index = y*5 + x;
	 		r[index].x = x * 30;
	 		r[index].y = y * 20;
	 		r[index].w = 20;
	 		r[index].h = 10;
	 	}
	 }
	 
	 while (true) // gameloop pseudocode
	 {
	 	for (int index=0; index<5*4; index++)
	 	{
	 		sdl_rect renderRect;
	 		renderRect.left = r[index].x;
	 		//...
	 		
	 		SDL_RenderImage(renderRect);
	 	}
	 }
}

That's the whole point.
You can handle many objects, but requiring not much code than for only one object.

I get the following errors.

Severity Code Description Project File Line Suppression State

Error (active) E0020 identifier "Rect1" is undefined Project95 C:\Users\Owner\source\repos\Project95\Project95\struct.cpp 16

Error (active) E0020 identifier "Rect2" is undefined Project95 C:\Users\Owner\source\repos\Project95\Project95\struct.cpp 16

Error (active) E0135 class "SDL_Rect" has no member "left" Project95 C:\Users\Owner\source\repos\Project95\Project95\struct.cpp 43

Error (active) E0020 identifier "SDL_RenderImage" is undefined Project95 C:\Users\Owner\source\repos\Project95\Project95\struct.cpp 46

Error C4430 missing type specifier - int assumed. Note: C++ does not support default-int Project95 c:\users\owner\source\repos\project95\project95\struct.cpp 16

Error C2143 syntax error: missing ',' before '&' Project95 c:\users\owner\source\repos\project95\project95\struct.cpp 16

Error C2065 'rect1': undeclared identifier Project95 c:\users\owner\source\repos\project95\project95\struct.cpp 18

Error C2065 'rect2': undeclared identifier Project95 c:\users\owner\source\repos\project95\project95\struct.cpp 18

Error C2065 'rect1': undeclared identifier Project95 c:\users\owner\source\repos\project95\project95\struct.cpp 19

Error C2065 'rect2': undeclared identifier Project95 c:\users\owner\source\repos\project95\project95\struct.cpp 19

here is my code I really like what jjoe has presented, it should work well with breakout bricks.

#include <iostream>
#include <SDL.h>

using namespace std;

class Rect
{
public:
	float x = 0;
	float y = 0;
	float w = 0;
	float h = 0;
};


bool intersectRect(const Rect1& rect1, const Rect2& rect2)
{
	return rect1.x < rect2.x + rect2.w && rect1.x + rect1.w > rect2.x &&
		rect1.y < rect2.y + rect2.h && rect1.y + rect1.h > rect2.y;
}

int main(int argc, char* args[])
{
	Rect r[5 * 4];

	for (int y = 0; y < 4; y++)
	{
		for (int x = 0; x < 5; x++)
		{
			int index = y * 5 + x;
			r[index].x = x * 30;
			r[index].y = y * 20;
			r[index].w = 20;
			r[index].h = 10;
		}
	}

	while (true) // gameloop pseudocode
	{
		for (int index = 0; index < 5 * 4; index++)
		{
			SDL_Rect renderRect;
			renderRect.left = r[index].x;
			//...

			SDL_RenderImage(renderRect);
		}
	}

	return 0;
}

pbivens67 said:
I get the following errors. Severity Code Description Project File Line Suppression State Error (active) E0020 identifier

They always put some bugs in typos into their pseudo code.
To ensure the people who copy it have to do some work, so they do not only copy, but also understand. ; )

(I did not do it on purpose, but i still expect you can fix the typos yourself.)

pbivens67 said:
identifier "Rect1" is undefined Project95

Quite telling, those messages…

Advertisement

ok good to know I will work on it

here is my code for collision detection with breakout bricks using AABB techniques. let me know what you think of it.

#include <iostream>
#include <SDL.h>

using namespace std;

class Rect
{
public:
	float x = 0;
	float y = 0;
	float w = 0;
	float h = 0;
};

int main(int argc, char* args[])
{
	Rect r[3 * 6];

	for (int y = 0; y < 6; y++)
	{
		for (int x = 0; x < 3; x++)
		{
			int index = y * 3 + x;
			r[index].x = x * 40 + 260;
			r[index].y = y * 80;
			r[index].w = 40;
			r[index].h = 80;
		}
	}

	return 0;
}

Looks good so far.

I remember you want to make Pong, Space Invaders, and Breakout games.
I recommend you do it in this order. Breakout is by far the hardest game.

But you could use the Rect class and the rect intersection test in all 3 of those games.
Thus it would make sense to put the Rect in it's own files, likely Rect.h and Rect.cpp.
For now just Rect.h would be enough. Since it's not so much code, a cpp file isn't needed.

Then you can include it into all 3 games. That's how you build up a code base over time.

In Pong you can use the Rect for the paddles and the ball.

In Space Invaders for the player and the aliens. (I would skip the shields at first, since they are partially destructible, which is complicated.)

In Breakout it would be ideal to have some tile map for the bricks, so you can find them quickly and don't have to iterate over all those many bricks to find collisions. Such tile map can then also be used for static levels in other games.

Maybe Space Invaders is simpler than Pong, because it does not matter where the bullet hits the alien.
In Pong it matters, deciding if the ball velocity should reflect horizontally or vertically.

But does not really matter, pick what you like. Just not yet Breakout ; )

I am making a pong-breakout game I have two paddles and a ball and bricks lining up and down the center of the screen. The bricks are in a 3x6 rectangles.

This topic is closed to new replies.

Advertisement