10
\$\begingroup\$

I am writing a breakout clone (my first game) and am totally stuck as to how I figure out which side of the brick was hit.

I have a collision detection method that looks like this:

DetectCollision(Object a, Object b)

   x = distance(a.x, b.x);
   y = distance(a.y, b.y);

   if (x is smaller than the combined width &  y is smaller is than combined height {
       return true;
   }
return false;  

This works totally fine, but I need to know the side of the collision, and location relative to the center in order to respond properly.

I've spent the past few days snooping around but am lost.

\$\endgroup\$
13
\$\begingroup\$

This can all be gleaned from the position of the ball relative to the position of the brick it collided with.

Once you have detected a collision:

if(ballPosition.y <= brickPosition.y - (brickHeight/2))
  //Hit was from below the brick

if(ballPosition.y >= brickPosition.y + (brickHeight/2))
  //Hit was from above the brick

if(ballPostion.x < brickPosition.x)
  //Hit was on left

if(ballPostion.x > brickPosition.x)
  //Hit was on right

The first two check to see if the ball is above or below the brick. If neither than it must be next to the brick, so check which side it's on. This will need to be tweeked to fit where you're taking the location from, i.e. brickPosition is the center of the brick or brickPosition is the top left corner.

\$\endgroup\$
  • \$\begingroup\$ But how would you use this to reposition the player, since it the player moves inside of a brick, multiple of those conditions will be met, and if you reset the desired x to the edge of the wall, for example if it hit the key of a brick set the desired x exactly next to the wall, then it wouldn't really work because when you check the theoretical position of the character to see which direction it's colliding from, multiple of these conditions will be met, so how would you use this to reset the player, do you need to add else's at the end of every if)? \$\endgroup\$ – bluejayke Jul 18 '18 at 6:52
  • \$\begingroup\$ As far as I know the "player" in a breakout type game is the paddle. The paddle is not moving inside of a brick, nor are you changing the position of the paddle based on the ball's interaction with bricks. If that's what you're doing, you don't need additional logic, just don't process the reposition until you'd done all the collision checks. Or return once one of the checks is true. \$\endgroup\$ – MichaelHouse Jul 25 '18 at 15:03
8
\$\begingroup\$

You could use Vector Math to discover the angles between them!

Here's a short answer:

ballToBrick = ballPosition - brickPosition;
ballToBrick.Normalize();
brickFacing = Vector2(0,1).Normalize();


float angle = acos( Dot(ballToBrick, brickFacing) );

The Brick facing is a tricky vector, it is the "start point" of the angle calculation. and if you want the vector to point up, make it (0, 1), point left (-1, 0), right (1, 0), point down(0, -1). Assuming you're in OpenGL axis, where up and right are positive.

If you dont know, here's the definitions of each function used:

Vector2.Normalize()
{
    float length = squareroot(x * x + y * y);
    x = x / length;
    y = y / length;
    return this;
}

Dot(Vector2 a, Vector2 b)
{
    return a.x * b.x + a.y * b.y;
}

(https://en.wikipedia.org/wiki/Dot_product)

Reference: http://blog.wolfire.com/2009/07/linear-algebra-for-game-developers-part-2/

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.