   2D Breakout collision problem
  Yo,Since I consider 2d collision detection one of my weak spots, I decided to code a Breakout game but I''ve run into problems.I''ve been following this tutorial, for a simple rectangle overlap collision (1st bit of code)I''ve intergrated it with my code successfully. However, the ball''s current behaviour is that it bounces off the bat correctly, but about 1.5 units (roughly the height of the bat) above the bat. After seeing several other examples, I was wondering, should I take into account the ball speed?Here''s some useful code. Note that I check for collision after I update the ball, and that both are called every frame.   bool BatBallCollide(BBALL *ball,BBAT* bat){ float left1,left2; float right1,right2; float top1,top2; float bottom1,bottom2;  left1=ball->GetX(); right1=left1+ball->GetWidth(); top1=ball->GetY(); bottom1=top1+ball->GetHeight();  left2=bat->GetX(); right2=left2+bat->GetWidth(); top2=bat->GetY(); bottom2=top2+bat->GetHeight();  if (bottom1<top2) return false; if (top1>bottom2) return false;  if (right1<left2) return false; if (left1>right2) return false;  return true;}And my current updating/rendering function:   void RenderScene(){ball.Update();bat.Update(); if (BatBallCollide(&ball,&bat)){ ball.SetYDir(-ball.GetYDir());}glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glLoadIdentity();DrawBlocks();ball.Draw();bat.Draw();}Cheers for any help CloudNine 
  I''ve thought some time now about making a Breakout clone myself, and have figured out a way of doing col detection (I''m not sure if it would work, but it seems ok to me). I would have a bool array with all of the pixels of the playscreen, with either 1 for a pixel that contains a wall/brick/bat, or 0 for empty. Every time the ball moves, a function checks if any of the pixels in the ball overlap the mentioned array. If they do, I move the ball back again, find the average coordinate of those pixels that overlapped...whatever it was..., find the angle between the middle of the ball and that coordinate (which would then be the angle between the ball and the wall/brick/bat), and through this equation:newAngle = wallAngle + (wallAngle - oldAngle) + 180I find the new direction of the ball. For example, I have a ball that is 16x16 pixels. I find that pixels (7, 0) and (8, 0) collide with something. The direction of the ball is 60 degrees (0 degrees is to the right), or straight upwards. The average coordinate will be (7.5, 0), and the angle between this and the middle (7.5, 7.5) is 90.newAngle = 90 + (90 - 60) + 180 = 300.I hope I made myself clear, any questions are welcome. ;  This is how I detect collisions in my old version of breakout import java.awt.*;public class collisions{  make_layout mk_layout;  drawStick   my_stick;  drawBall    my_ball;  breakout    ping;  drawMapmap_it;  booleaninit,check_hit;  int[] priority = {0,2,4,6,1,3,5,7};  /**********************************/  /*  priority  */  /*4 */  /*  3  __  5  */  /*    /  \    */  /* 2 |ball| 6 */  /*    \__/    */  /*  1 7  */  /*0 */  /**********************************/  int xRange,yRange, e,count_tiles, right_b,y_limit;  collisions(breakout ping){    this.ping   = ping;  }  public void manage_coll(){    if(!init){ mk_layout   = ping.layout; my_stick    = ping.my_stick; my_ball= ping.my_ball; map_it = ping.map_it; right_b= ping.getSize().width -ping.radius; y_limit= ping.yLimit-ping.radius; count_tiles =0; init   = true;    }    check_hit = false;    switch((xRange=(my_ball.xCoords[6]-2)/(map_it.width +2))){ case  0: xRange =  1; break; case 13: xRange = 12;break;    }    for(int a =0; a<map_it.rows; a++) for(int i=xRange-1; i<xRange+1; i++){   if(map_it.exist<A href=''http://!=0)<br></font><br><font color=blue>for</font>(<font color=blue>int</font> s =0; s&lt;8; s++){<br>  e = priority[<font color=purple>s</font>];<br>  <font color=blue>if</font>(my_ball.xCoords[<font color=purple>e</font>] &gt;= map_it.xTiles[<font color=purple>a</font>][<font color=purple>i</font>])<br>  <font color=blue>if</font>(my_ball.xCoords[<font color=purple>e</font>] &lt;= map_it.xTiles[<font color=purple>a</font>][<font color=purple>i</font>] + map_it.width)<br>  <font color=blue>if</font>(my_ball.yCoords[<font color=purple>e</font>] &gt;= map_it.yTiles[<font color=purple>a</font>][<font color=purple>i</font>])<br>  <font color=blue>if</font>(my_ball.yCoords[<font color=purple>e</font>] &lt;= map_it.yTiles[<font color=purple>a</font>][<font color=purple>i</font>] + map_it.height){<br><br>  <font color=blue>switch</font>(e){<br>    <font color=blue>case</font> 0:  my_ball.ball_ySpeed = -abs(my_ball.ball_ySpeed); <font color=blue>break</font>;<br>    <font color=blue>case</font> 1:  my_ball.ball_ySpeed = -abs(my_ball.ball_ySpeed);<br>   my_ball.ball_xSpeed =  abs(my_ball.ball_xSpeed); <font color=blue>break</font>;<br>    <font color=blue>case</font> 2:  my_ball.ball_xSpeed =  abs(my_ball.ball_xSpeed); <font color=blue>break</font>;<br>    <font color=blue>case</font> 3:  my_ball.ball_ySpeed =  abs(my_ball.ball_ySpeed);<br>   my_ball.ball_xSpeed =  abs(my_ball.ball_xSpeed); <font color=blue>break</font>;<br>    <font color=blue>case</font> 4:  my_ball.ball_ySpeed =  abs(my_ball.ball_ySpeed); <font color=blue>break</font>;<br>    <font color=blue>case</font> 5:  my_ball.ball_ySpeed =  abs(my_ball.ball_ySpeed);<br>   my_ball.ball_xSpeed = -abs(my_ball.ball_xSpeed); <font color=blue>break</font>;<br>    <font color=blue>case</font> 6:  my_ball.ball_xSpeed = -abs(my_ball.ball_xSpeed); <font color=blue>break</font>;<br>    <font color=blue>case</font> 7:  my_ball.ball_ySpeed = -abs(my_ball.ball_ySpeed);<br>   my_ball.ball_xSpeed = -abs(my_ball.ball_xSpeed); <font color=blue>break</font>;<br>  }<br><br>  map_it.exist[<font color=purple>a</font>][<font color=purple>i</font>]-= 1;<br>  <font color=blue>if</font>(map_it.exist[<font color=purple>a</font>][<font color=purple>i</font>] &lt;=0){<br>    mk_layout.my_score  +=10;<br>    count_tiles++;<br>    ping.clip[<font color=purple>0</font>].play();<br>  }<br>  <font color=blue>else</font><br>    ping.clip[<font color=purple>1</font>].play();<br><br>  i  = xRange+1;<br>  a  = map_it.rows;<br>  s  = 8;<br>}<br>   }<br> }<br><br>    <font color=blue>if</font>(my_ball.xBall &lt;= ping.radius){<br> my_ball.ball_xSpeed = abs(my_ball.ball_xSpeed);<br>  ping.clip[<font color=purple>1</font>].play();<br>    }<br><br>    <font color=blue>if</font>(my_ball.xBall &gt;= right_b){<br> my_ball.ball_xSpeed = -abs(my_ball.ball_xSpeed);<br> ping.clip[<font color=purple>1</font>].play();<br>    }<br><br>    <font color=blue>if</font>(my_ball.yBall &lt;= ping.radius){<br> my_ball.ball_ySpeed = abs(my_ball.ball_ySpeed);<br> ping.clip[<font color=purple>1</font>].play();<br>    }<br><br>    <font color=blue>if</font>(my_ball.yBall &gt;=y_limit){<br> my_ball.ball_ySpeed = -abs(my_ball.ball_ySpeed);<br><br> <font color=blue>if</font>(my_ball.num_of_balls&gt;0){<br>   my_ball.num_of_balls–;<br>   lose_scene();<br>   <font color=blue>if</font>(my_ball.num_of_balls!=0)<br>ping.clip[<font color=purple>2</font>].play();<br> }<br> <font color=blue>if</font>(my_ball.num_of_balls==0)<br>   ping.clip[<font color=purple>3</font>].play();<br>    }<br><br>    <font color=blue>if</font>(my_ball.xBall &gt;= my_stick.stick_xLocation)<br> <font color=blue>if</font>(my_ball.xBall &lt;= my_stick.stick_xLocation +my_stick.stick_width)<br>   <font color=blue>if</font>(my_ball.yCoords[<font color=purple>0</font>]&gt;= my_stick.stick_yLocation )<br><font color=blue>if</font>(my_ball.yCoords[<font color=purple>0</font>]   &lt;= my_stick.stick_yLocation + (ping.radius&gt;&gt;1)){<br>  my_ball.ball_ySpeed    = -(<font color=blue>int</font>)(2 + 2*Math.random());<br><br>  <font color=blue>if</font>(my_ball.ball_xSpeed&lt;0)<br>    my_ball.ball_xSpeed  = -abs((<font color=blue>int</font>)(2 + 2*Math.random()));<br>  <font color=blue>else</font><br>    my_ball.ball_xSpeed  =  abs((<font color=blue>int</font>)(2 + 2*Math.random()));<br>  ping.clip[<font color=purple>1</font>].play();<br>}<br><br>    <font color=blue>if</font>(count_tiles == map_it.score_limit)<br> ping.load_new_map();<br><br>    my_ball.yBall+= my_ball.ball_ySpeed;<br>    my_ball.xBall+= my_ball.ball_xSpeed;<br>  }<br><br>  <font color=blue>public</font> <font color=blue>int</font> abs(<font color=blue>int</font> a){<br>    <font color=blue>return</font> (a&gt;0) ? a : -a;<br>  }<br><br>  <font color=blue>public</font> <font color=blue>void</font> lose_scene(){<br>    my_stick.stick_xLocation = my_stick.stick_xLocation_init;<br>    my_ball.xBall  = my_ball.xBall_init;<br>    my_ball.yBall  = my_ball.yBall_init;<br>    ping.start= <font color=blue>false</font>;<br>    mk_layout.start.enable();<br>    mk_layout.pause.disable();<br>  }<br>}</pre><!–ENDSCRIPT–> <br><br><br>http://www.realityflux.com/abba/Breakout.html<br><br>Keep in mind that this was my very early attempt to clone the said game, now I can substitue all that cheating with real physics;  It looks like I''ll have to start storing the angle of the ball.I''m using OpenGL, without an orthonogal matrix, so I''m not sure if I can check for pixels on a screen, without using glCopyTex2D and going through all the pixels on that texture.It''s turning out to be harder than it looks.CloudNine ;quote:Original post by CloudNine   It looks like I'll have to start storing the angle of the ball.I'm using OpenGL, without an orthonogal matrix, so I'm not sure if I can check for pixels on a screen, without using glCopyTex2D and going through all the pixels on that texture.It's turning out to be harder than it looks.CloudNine   I don't know OpenGL much (I'll be using SDL), but I don't think it would be necessary to do that. Instead, you can make the array while you are loading the level, and just remove the block and bar/bat's pixels as you destroy blocks and move the bat. I think that would be fast enough.The reason why I didn't want just the 45, 135, 225 and 315 angles for my ball is that my bar/bat/whatever you call it will have rounded edges, like this:/^^^^^^\\________/So if the ball hits the edge, it will get a more steep or gentle angle.I'll store the x and y coordinates of the ball in a float and use cos/sin angle to calculate the new position each time it moves.    [edited by - Goldfish on August 17, 2003 6:48:49 AM];  Well, my bat and ball will be even, since both are just blocks. ;  In that case, my way of doing it will just be more complicated and CPU-demanding. Consider having such a feature, though, ''cos I think it''ll look much cooler Check out Arkanoid 2, it''s a really cool Breakout clone. ;  I'll check it out sometime I don't really understand why it works like that. Is there anything really wrong with the code?It might be that I'll have to get the absolute value of both collision positions. I'll try that and see if it works  No such luck I notice when I move the bat far away from the ball, the ball gets to the height of the bat, does a little jiggle  and carries on in roughly the same direction.   [edited by - CloudNine on August 17, 2003 12:42:14 PM];  It just looks like your''re up for some old-fashioned debugging. Go through the code yourself and find out what''s causing the bug. ;  Now it''s just stuttering on the same Y position. Things just get wierder every day. 