if(x>=3.0f && x<=5.0f && y>=3.5f && y<=4.0f)
{
bricks[2][4]=true;
g_bBlock[4].m_bActive_three=false;
}
if(bricks[2][4]==true)
{
glRasterPos2f(4.0f,2.0f);
printString("1");
ystep=-ystep;
}
let me know if you need more code.
right now my ball passes through the whole layers of bricks and turns them off and then bounces off the top of the screen, which I don't want. I want to thank spiro because she has been very helpful to me.
little more help
I'm not sure how your code flows, but when is the second if-statement supposed to be called? Right after the first?
Are you checking each element in your arrays individually? Or are you cycling through them with a for loop (or something else that would let you iterate through all of them without checking each one alone)?
I move the ball horizontally and vertically separately and for each movement I iterate through the bricks container and check if the ball collides with a brick. If there is a collision then the ball's direction is reversed and the brick is destroyed and set to a nullptr. After the brick container has been iterated all the way through, I then use erase/remove idiom to clear the nullptr bricks out. Thus, next time the ball gets to that location, there will be no brick there for the ball to hit as it's been erased.
You seem to have some serious organizational errors that are causing things to be more confusing than they really need to be. For instance, why is there OpenGL code (your call to glRasterPos) inside your collision detection code? Why is there reaction code (modifying the value of ystep) inside your collision detection code? Why are there tests against magic numbers (your if conditionals testing against 3.0, 5.0, etc...)?
Situations like this are where encapsulation of your objects/entities will make a HUGE difference on how confusing your code will be, and I know that people have recommended encapsulation to you before. You seem to have ignored them.
Consider a brick. A brick consists of the following data:
Position (X,Y)
Size (Width, Height)
Sprite (Image to draw)
So you can encapsulate that into a structure of some sort. Then you can write a collision routine that tests for collision between ball and brick (using simple rectangle test between the brick rectangle defined by (X,Y,X+Width,Y+Height) and the ball's own rectangle), a drawing routine that draws the brick (by drawing a quad at (X,Y) sized (Width,Height) using Sprite) and so forth. That way, drawing code is confined to the drawing routines, collision code is confined to the collision routines, physics code is confined to physics routines, and you don't have these nasty tendrils of spaghetti cluttering up your code. It will definitely save you debugging time (and save you from having to run to forums for help debugging your spaghetti) if you learn basic organizational principles and provide at least some type of encapsulation of your objects.
Here's something to get you started:
struct TBrick {
int XPosition;
int YPosition;
int XSize;
int YSize;
uint32_t Color;
uint32_t ActiveState; // 0 is deactive; If it takes multiple hits to kill a brick, it can start greater than 1
};
struct TBall {
int XPosition;
int YPosition;
int XSize;
int YSize;
int XSpeed;
int YSpeed;
};
#define BRICK_COLUMNS 20 // how many bricks in a column
#define BRICK_ROWS 10 // how many bricks ina row
#define BRICK_START_X 60 // Where the bricks start on the x-axis
#define BRICK_START_Y 40 // Where the bricks start on the y-axis
#define BRICK_WIDTH 30 // brick width in pixels
#define BRICK_HEIGHT 15 // brickheight in pixels
// make this a global array
TBrick BrickArray[BRICK_COLUMNS][BRICK_ROWS];
// Initialize the Brick Array somewhere at the start of your code
for (int x = 0; x < BRICK_COLUMNS; x++) {
for (int y = 0; y < BRICK_ROWS; y++) {
BrickArray[x][y].XSize = BRICK_WIDTH;
BrickArray[x][y].YSize = BRICK_HEIGHT;
BrickArray[x][y].XLocation = BRICK_START_X + x*BRICK_WIDTH;
BrickArray[x][y].YLocation = BRICK_START_Y + y*BRICK_HEIGHT;
BrickArray[x][y].Color = 0xFFFFFFFF; // white
BrickArray[x][y].ActiveState = 1; // 1 hit to turn off brick
// in main loop do this:
// move Ball in X direction, then check collision
Ball.XLocation += Ball.XSpeed;
if (CheckCollision(Ball)) {
// The ball hit something, move to original location and negate X speed
Ball.XLocation -= Ball.XSpeed;
Ball.XSpeed = -Ball.XSpeed;
}
// Do same for Y movement
Ball.YLocation += Ball.YSpeed;
if (CheckCollision(Ball)) {
// The ball hit something, move to original location and negate Y speed
Ball.YLocation -= Ball.YSpeed;
Ball.YSpeed = -Ball.YSpeed;
}
RenderBricks();
... // the rest of the main loop
// Here are those functions
bool CheckCollisions(TBall ball)
{
// loop through every brick and see if we've hit it
for (int x = 0; x < BRICK_COLUMNS; x++) {
for (int y = 0; y < BRICK_ROWS; y++) {
// Only check against bricks that are active
if (BrickArray[x][y].ActiveState > 0) {
if (ball.XLocation + ball.XSize < BrickArray[x][y].XLocation ||
ball.YLocation + ball.YSize < BrickArray[x][y].YLocation ||
ball.XLocation > BrickArray[x][y].XLocation + BrickArray[x][y].XSize ||
ball.YLocation < BrickArray[x][y].YLocation + BrickArray[x][y].YSize) {
// It's collided wit brick, decrment Active state of brick and return true
BrickArray[x][y].ActiveState--;
return true;
}
}
}
// Check if we've hit the paddle and
// Check if we've hit the wall (I'll leave this up to you)
}
// This Draws the bricks
void RenderBricks()
{
// loop through every brick and draw if active
for (int x = 0; x < BRICK_COLUMNS; x++) {
for (int y = 0; y < BRICK_ROWS; y++) {
if (BrickArray[x][y].ActiveState > 0) {
// Call you GL draw function, whatever it is. it would be simple to do in SFML however
GlDrawRect(BrickArray[x][y].XLocation, BrickArray[x][y].YLocation,
BrickArray[x][y].XSize, BrickArray[x][y].YSize, BrickArray[x][y].Color);
}
}
}
}
This is just some simple code that shows how you can handle the bricks. You might have a class for bricks which would make more sense, but this gets the point across.
What's missing is checking if the ball hits the paddle, or if the ball hit a wall. it also doesn't check if the ball has left the screen (i, the paddle missed it), and it doesn't check if all blocks are cleared (level is over).
Can you show that code? It would be a good step for you.
Good luck!