Collision between station bricks and a moving ball...

Started by
12 comments, last by Codejoy 20 years, 11 months ago
Okay so I have this game where there are bricks that act as walls (verticle or horizontal) or if they are a single brick, then just an obsticle.. the bricks are a sqaure of 32x32 pixels, the ball is 8x8 pixels. I can check for the collision between a brick and a ball, no sweat...but I need to know how to see WHAT SIDE of the brick the ball collided with so I can properly reflect the velocity in the x or y direction. The variables of concern are: float Ballx < - balls x position float Bally <- Balls y position float Ballvx <- balls velocity in x float Ballyv <- balls velocity in y brick[current_brick].x <-- bricks x position brick[current_brick].y <-- bricks y position brick[current_brick].width <--width of brick brick[current_brick].height <--height of brick The skeleton of the code looks like:
    
for (int current_brick=0; current_brick<numBricks; current_brick++)
{
   if(Collision(theBall, theBrick[current_brick])==TRUE)
   {
      //we collided check which side and set

      //the proper vx or vy ala Ballvx=-Ballvx etc..

   }
}
    
I thought this was trivial, but that above part wher u see the comments are wehre I have tried everything i could think of, on paper most my algo's seemed right, in practice the ball would either go through the brick, or reflect back both velocities) I think the underlying problem here is that I use many bricks to make a wall or a barrier to speak. Say like 15 bricks across side by side is a barrier, and 15 bricks down and up is a wall...I think thats why some of my algorithms for reflecting the ball properly havent worked since it was colliding with another brick near the main brick it should of collided with. i.e. |---|---|---| | 1 | 2 | 3 | bricks... |---|---|---| / \ -- where exactly was the collision brick 1 or 2? / [] <-- ball It looks like it hits a corner, but then some case in some part of the algo should just reflect the ball, but i guess its missing that and going right through. I have also used two different kinds of collision algorithms, one to test if the two collided using CollisionBOBs for those who are familiar with Tricks of the Windows Programming Gurus and i tried a different test which says: if(theBall.x+theBall.width > theBrick.x) && (theBall.x < theBrick.x+theBrick.width) && so &#111;n and so &#111;n.. Now I thought maybe the collision was getting mis fired because the velocity of the ball in &#111;ne frame failsto be caught by a case in my collision detectoin, but since the bricks are 32x32 there is no way the ball is travling more than that to exceed a test. I am willing to go with normals here…but how the hell do i do that? I know i could read a lot of articles, but honestly this has taken so much time and im soo behind &#111;n this silly game that I dont think id get much out of them in an applicable way… I have had tried to hack some code that LaMothe uses in his Tricks of the Windows Game Programming gurus (more specifically demo13_7.cpp) but that was geared more twards the ball bouncing around inside an irregular shaped polygon, when applied to the regular shaped rectangles here it seems to not work quite as well.. so im at wits end, i need this, I need this bad, and im to the point where I dont care how it works i just want it to work. So if ineed to go with computing normals etc.. how if my object a brick is just defined as, x, y, width, height (an 32x32 bitmap) would i get a normal for each side of it, and how would i compute the normal of my ball (which is essentialy an 8x8 bitmap) If anyone can help, id soo greatly appreciate this its not even funny. This is the &#111;nly thing holding my whole game up, I thought it was trivial, after posting here a while back and getting no responses that worked (Was in beginners section) and asking some friends to help, still today it isnt working. Thanks for any help as im really at my wits end bout this, Shane </i> <SPAN CLASS=editedby>[edited by - Codejoy &#111;n May 8, 2003 9:44:11 AM]</SPAN>
Advertisement
use ode
3D Side-Scroller game demo Project-X2 "playable"Lashkar: A 3D Game & Simulation Project demo @ lashkar.berlios.de
Ok, I''m a n00b programmer too, so don''t expect some great GURU insight from me, but here''s my two cents...maybe I''ll spark a thought

Just out of curiosity, how are you testing for collisions?

Questions asked because if you are testing for example to see if there is a collision to the LEFT of the ball, then it would of course be the RIGHT side of the block in which you would reverse the X velocity...and so on.

if each block is 32 pixels wide, really no need for the variable block.width/height...they would always be 32
(unless of course you have smaller blocks stored in a 32x32 pixel bitmap)

(x,y) (x+32, y)
|---------|
| | __
| |(__)
| |
|---------|
(x,y+32) (x+32,y+32)

also depending on how you detect collision...
(assuming ball.x/y and block.x/y are on the same relative plane)

...if ball.x = 32 + block.x, it''s on the right side of the brick
...if ball.x + 8 = block.x, left side of brick,
...if ball.y = 32 + block.y, it''s on the bottom of brick,
...if ball.y + 8 = block.y, it''s on the top of brick.

(the + 8 is there to accomodate for the ball size).

That''s all my insight for now, good luck gettin it to work and sorry if my thoughts didn''t help
Bad drawing on that picture...allow me to compensate...

(x,y) (x+32, y)
|--------||
| .| __
| .|(__)
| .|
|---------|
(x,y+32) (x+32,y+32)
I apoligize once more...man, this forum needs a preview button

(x,y) (x+32, y)..|---------|..|.........| __..|.........|(__) ..|.........|..|---------|(x,y+32) (x+32,y+32) 


(ignore the dots)


EDIT: Wrapped it in tags for you. No amount of dots will get around the proportional font issue. <img src="smile.gif" width=15 height=15 align=middle> -- Kylotan.<br><br><SPAN CLASS=editedby>[edited by - Kylotan &#111;n May 8, 2003 5:18:20 AM]</SPAN>
Screw it, you get the point
I also had trouble with the ball going through the bricks, and it was because I was updating the ball''s position twice instead of one time in my code.

Another thing, in the code you posted, you were incrementing i, but shouldn''t you increment current_brick so you test each brick? It looks to me like you''re just testing the first brick.

-noix-

In this world gone mad, we won''t spank the monkey; the monkey will spank us.
In this world gone mad, we won't spank the monkey; the monkey will spank us.
I had a similar problem (if I understand correctly) when I made my first ever platform game. I was happily checking collisions against generic blocks every loop but was unsure how to determine the side they had collided with.

I solved it in the end by determining where the player was before the collision. So, once I detected a collision I checked to see if they were previously to the left of the block, or the right, the top and finally the bottom.

In the case of your game it should be something like this.

    if ((ball.locx - ball.velx) < block.leftside){   // the ball was approaching from the left side   // and we will assume that is the side it hit.}// and so on for the other sides    



Not sure if that makes sense, or if it helps, but I hope you get the idea.

[edited by - m_wherrett on May 8, 2003 4:08:20 AM]

[edited by - m_wherrett on May 8, 2003 4:08:54 AM]
I''ve done this many time when I was still programming games on the Amiga. I hope this is what you want?

/* Update ball movement */
Ballx += Ballvx;
Bally += Ballvy;

/* Check all bricks for collision */
for (int current_brick=0; i{

/* Check current brick for collision */
if(Ballx > brick[current_brick].x &&
Bally > brick[current_brick].x &&
Ballx < brick[current_brick].x + brick[current_brick].width &&
Bally < brick[current_brick].y + brick[current_brick].height)
{
/* Optionally: Do action on brick */

/* Example of test which side the ball entered the brick */
if((Bally + Ballvy) > brick[current_brick].y + brick[current_brick].height)
BallCollideBottom();

/* Bounce ball, independent of which side collided */
Ballvx = -Ballvx;
Ballvy = -Ballvy;

/* Optionally: reposition ball using velocity */
}

}

RenderFrame();
Mike Machuidel
Thanks for the responses guys, I have to say its getting there but yet the corners are giving me problems, i think since the blocks are 32x32 and i string them togteher to make a horizontal or verticle wallt hat sometimes the collision goofs up on what brick its hitting, because sometimes the balls x and y vectors are returned, and i think that sbecause its thinking its hitting the bottom of one brick while somehow simultanously (close to simultanously) hitting the right side of the brick next to the one it hit the bottom of.. i have no clue how to allevate this.

And its still going through the bricks and i double checked and im only updating the xy positions once from their velocities... hmmmm
Whats working better is the code:

  for(i=0; i<numbricks; i++){  if(collision(ball, brick[i]) //ala if ball is inside brick.   {      if((Ballx-Ballvx) <brick[i].x)            Ballvx=-Ballvx;      else if((Ballx-Ballvx) > brick[i].x+brick[i].width)            Ballvx=-Ballvx;      else if((Bally-Ballvy) < brick[i].y)            Ballvy=-Ballvy;      else if((Bally-Ballvy) > brick[i].y+brick[i].height)            Ballvy=-Ballvy;   }}  

any other suggestions and quick fixes?

-Shane

This topic is closed to new replies.

Advertisement