little more help

Started by
5 comments, last by phil67rpg 11 years, 3 months ago
well I have figured out to get the ball in my breakout game to turn off the appropriate brick. However I want the ball to bounce off the brick and turn it off and then pass through it the next time it comes into to contact with it again. Here is a small amount of code I am using for collision detection.

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.
Advertisement
Why don't you include your reverse ystep (is this the ball's y-velocity?) in the if-condition that terminates the block?
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)?

Inspiration from my tea:

"Never wish life were easier. Wish that you were better" -Jim Rohn

soundcloud.com/herwrathmustbedragons

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.

??????3??????????! wwwwwww
void hurrrrrrrr() {__asm sub [ebp+4],5;}

There are ten kinds of people in this world: those who understand binary and those who don't.

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!

My Gamedev Journal: 2D Game Making, the Easy Way

---(Old Blog, still has good info): 2dGameMaking
-----
"No one ever posts on that message board; it's too crowded." - Yoga Berra (sorta)

wow that is a lot of code

This topic is closed to new replies.

Advertisement