🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

breakout in opengl and c++

Started by
55 comments, last by pbivens67 2 years, 11 months ago

pbivens67 said:
I want the ball to hit the brick and then redraw a black brick but not redraw a blue brick.

This would be easier if you would use glColor instead having a texture of assumingly painted bricks.

Anyway, there is a lot permutations which seems not necessary:

drawTopBricks();
drawMiddleBricks();
drawBottomBricks();
eraseBottomBrick(); // also a drawing function

Likely you want to handle all this with just one function to draw the board and eventually another to draw a brick. E.g. like this:

void CalcBrickCoords (	float &br_x, float &br_y, float &br_w, float &br_h, 
						const int boardX, const int boardY )
{
	br_x = float(boardX) * scaleX + offsetX; 
	br_y = float(boardY) * scaleY + offsetY;
	br_w = brickWidth;
	br_h = brickHeight;
	
	// those scale and size constants vould be defines / global variables at first, or variables of some level definitions class, etc.
}

void DrawBoard()
{
	for (int y=0; y<boardHeight; y++)
	for (int x=0; x<boardWidth; x++)
	{
		int brickType = board[x + y * boardWidth];
		if (brickType == 0) // skip if no brick in tht grid cell
			continue;
			
		float br_x, br_y, br_w, br_h;
		CalcBrickCoords (br_x, br_y, br_w, br_h, x, y);
		
		DrawBrick (br_x, br_y, br_w, br_h, brickType);
	}
}

You can reuse the transformation math and DrawBrick() function then to visualize a collision, ensuring coordinates and scaling etc. matches up:

float br_x, br_y, br_w, br_h;
CalcBrickCoords (br_x, br_y, br_w, br_h, 
	test_coll_brick_x, test_coll_brick_y);
	
if (coll.collision(b_x, b_y, b_w, b_h, br_x, br_y, br_w, br_h) == 1)
{
	DrawBrick (br_x, br_y, br_w, br_h, blackBrickType);
}

Advertisement

can you explain scaleX and offsetX.

pbivens67 said:
can you explain scaleX and offsetX.

Those are meant to transform integer grid coordinates (blue) to world coordinates (red):

In this example the numbers would be:

scaleX = 2.0
scaleY = 1.0
offsetX = -4.0
offsetY = -2.0

brickWidth could be something like 1.75, and brickHeight 0.75, or just 2 and 1 to have no gap between bricks as usual.

If your bricks are arranged in a grid like pattern as usual, there is no need to store world coordinates with each brick. We can calculate them on the fly from x and y coords we use to look up the grid array/vector containing them (array index = x + y * boardWidth).

To have top/mid/borrom bricks you could just use 3 horizontal rows of the grid, or insert empty rows between them so the ball can zig zag between two rows, etc. You want to define the shape of the level with ‘data’, not with a unique function per row. And the data you generate usually with a level editor, or procedural generation code as proposed from finalSpace.

For the start i would write a tool function to convert a string to your board array/vector:

char *testLevelString = 
“11111”
“22222”
“33333”;
MakeLevel (5, 3, testLevelString);

Here board width and height would be dynamic per level, but ofc. you can use constant for that.
Then you write the display function and tweak scale, offset, brick width and height values manually until looks good, later you may calculate them from given board dimensions when a new level is generated.

FYI, transforming from index space to world space (and the other way around) can also be done with a matrix, like OpenGL uses. That's often more convenient, but not yet for a beginner.

can you explain

JoeJ said:
test_coll_brick_x, test_coll_brick_y

Those test coordinates were just meant as example to debug collision against a single brick at given grid coordinates.

well I stubbed out your code joe. I am stuck on how to implement the test_coll… and the drawBrick function and how they work.

here is my code so far

#include <iostream>

using namespace std;

void CalcBrickCoords(float &br_x, float &br_y, float &br_w, float &br_h, const int boardX, const int boardY);

float brickWidth = 35.0f, brickHeight = 15.0f;

float scaleX = 35.0f, scaleY = 15.0f;
float offsetX = -135.0f, offsetY = 100.0f;
int boardHeight = 3, boardWidth = 8;

class Bricks
{
public:
	float ball_x;
	float ball_y;
	float ball_width;
	float ball_height;
	float brick_x;
	float brick_y;
	float brick_width;
	float brick_height;
	bool collision(float, float, float, float, float, float, float, float);
};

bool Bricks::collision(float ball_x, float ball_y, float ball_width, float ball_height, float brick_x, float brick_y, float brick_width, float brick_height)
{
	if (ball_x<brick_x + brick_width && ball_x + ball_width>brick_x&&ball_y<brick_y + brick_height && ball_y + ball_height>brick_y)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

int main()
{
	Bricks coll;

	float b_x, b_y, b_w, b_h;
	float br_x, br_y, br_w, br_h;

	CalcBrickCoords(br_x, br_y, br_w, br_h, test_coll_brick_x, test_coll_brick_y);

	if (coll.collision(b_x, b_y, b_w, b_h, br_x, br_y, br_w, br_h) == 1)
	{
		DrawBrick(br_x, br_y, br_w, br_h, blackBrickType);
	}
	return 0;
}

void CalcBrickCoords(float &br_x, float &br_y, float &br_w, float &br_h, const int boardX, const int boardY)
{
	br_x = float(boardX) * scaleX + offsetX;
	br_y = float(boardY) * scaleY + offsetY;
	br_w = brickWidth;
	br_h = brickHeight;
}

void DrawBoard()
{
	int board[24] = {};
	for (int y = 0; y < boardHeight; y++)
		for (int x = 0; x < boardWidth; x++)
		{
			int brickType = board[x + y * boardWidth];
			if (brickType == 0) // skip if no brick in that grid cell
				continue;

			float br_x, br_y, br_w, br_h;
			CalcBrickCoords(br_x, br_y, br_w, br_h, x, y);

			DrawBrick(br_x, br_y, br_w, br_h, brickType);
		}
}

pbivens67 said:
I am stuck on how to implement the test_coll… and the drawBrick function and how they work.

The drawBrick function can just draw a rectangle or 4 lines.
But i have forgotten OpenGL details so can't make a proper example. Easiest way is using glVertex(), which is slow and deprecated but can be changed later.

Likely you also need to work on projection matrix if you don't have yet. Using glOrtho would do fine for 2D.

Then after you can display a level properly it makes sense to test collision stuff.

void DrawBoard()
{
	int board[24] = {}; // <- empty level
	for (int y = 0; y < boardHeight; y++)

Here you create an empty level inside the drawing function.

Ofc. you want to create that just once at startup and give it as parameter:

int board[24] = {
0,0,1,1,1,1,0,0,
0,1,2,2,2,2,1,0,
1,2,2,3,3,2,2,1,
};

void DrawBoard(int *board)
{
	for (int y = 0; y < boardHeight; y++)

The board can be a global variable, but later you might want to put it into some level class eventually, together with scale / height / width etc. variables which define the level.

I am sorry for all the handholding but I am making progress here is my code that I have after putting in the board array.

int main()
{
	Bricks coll;

	float b_x, b_y, b_w, b_h;
	float br_x, br_y, br_w, br_h;

	CalcBrickCoords(br_x, br_y, br_w, br_h, test_coll_brick_x, test_coll_brick_y);

	if (coll.collision(b_x, b_y, b_w, b_h, br_x, br_y, br_w, br_h) == 1)
	{
		DrawBrick(br_x, br_y, br_w, br_h, blackBrickType);
	}
	return 0;
}

void CalcBrickCoords(float &br_x, float &br_y, float &br_w, float &br_h, const int boardX, const int boardY)
{
	br_x = float(boardX) * scaleX + offsetX;
	br_y = float(boardY) * scaleY + offsetY;
	br_w = brickWidth;
	br_h = brickHeight;
}

void DrawBoard(int *board)
{
	int board[24] = {0,0,1,1,1,1,0,0,
					 0,1,2,2,2,2,1,0,
	                 1,2,2,3,3,2,2,1};
	for (int y = 0; y < boardHeight; y++)
		for (int x = 0; x < boardWidth; x++)
		{
			int brickType = board[x + y * boardWidth];
			if (brickType == 0) // skip if no brick in that grid cell
				continue;

			float br_x, br_y, br_w, br_h;
			CalcBrickCoords(br_x, br_y, br_w, br_h, x, y);

			DrawBrick(br_x, br_y, br_w, br_h, brickType);
		}
}

pbivens67 said:
I am making progress here is my code that I have after putting in the board array.

There's no question, Phil. Should the thread be closed now? Happy to close it if you're good now… If you just want to share code, maybe you should write a blog.

-- Tom Sloper -- sloperama.com

how do I initialize the drawBrick function?

This topic is closed to new replies.

Advertisement