Archived

This topic is now archived and is closed to further replies.

xg0blin

reflection based on position in breakout

Recommended Posts

I made a clone of the popular game breakout. The problem with it right now is that the ball only reflects at forty-five degree angles, and I wish for it to reflect differently depending on where you hit the ball on the paddle. My idea was as follows: First of all, I want to constrain the paddle from -PI to PI in length, and as the paddle has varying lengths, I''ve decided that this would work x1/length_of_half_paddle = x2/PI X1 = ball_collision_x_coordinate - paddle_center I then simplify to this for x2 x2 = (x1 * PI)/length_of_half_paddle if x1 is negative you''ll recieve somewhere in this range [-PI, 0] if x1 is positive you''ll recieve somewhere in this range [0, PI] All of this is in the first and second quadrant, so this should work. It is not though, I''ve erred somewhere. I plug this into my function that calculates reflections based on the normal you wish to reflect from. I take the cos of the calculated x2 for my x-coordinate of my normal and the sin of the calculated x2 for my y-coordinate of my normal to reflect from. I am using this algorithm for reflection:
  
void ball::reflect(double normal_x, double normal_y)               
{                                                                  
	ball_vector temp_vect, temp_vect2;                             
	double temp1;                                                  
                                                                   
	temp1 = (current_direction.x * normal_x +                      
		 current_direction.y * normal_y)*2;                    
                                                                   
	temp_vect.x = temp1 * normal_x;                                
	temp_vect.y = temp1 * normal_y;                                
																   //

	temp_vect2.x = current_direction.x - temp_vect.x;              
	temp_vect2.y = current_direction.y - temp_vect.y;              
                                                                   
	current_direction.x = temp_vect2.x;                            
	current_direction.y = temp_vect2.y;
	
	move_ball();
}             
  
Here is the way I am calling it. Notice that x is actually the paddle center, Modifier is half of the paddle length.
  
void ball::collided_paddle(double x, double Modifier,              
			   double top, double bottom)              
{																   //

	if(current_position_y - radius - current_direction.y <= top && 
	   current_position_y + radius - current_direction.y >= top && 
	   current_position_x + radius >= x - Modifier &&              
	   current_position_x - radius <= x + Modifier &&
	   in_motion == true)                
	{	
		reflect(cos((3.14159 * (current_position_x - x))/Modifier), 
                        sin((3.14159 * (current_position_x - x))/Modifier)); 
		sounds.play_sound(0);									   
	}		
}	
  
The ball reflects correctly part of the time, but other times it goes downwards into the third or the fourth quadrant, and I have yet to figure out why.

Share this post


Link to post
Share on other sites
Not exactly what I''m looking for. I always want to keep a normalized vector and multiply it by some speed to effect a speed I can control. If I kept adding to the ball vector, after hitting the paddle a few times, the ball''s speed would be out of control. Not to mention that the only possibilities for the paddle vector would be

c = speed of paddle
c[1, 0] or c[-1, 0] or c[0, 0]

None of which would change the ball''s reflection angle by a small gradient depending on where you hit the paddle

Share this post


Link to post
Share on other sites
True if you base your movement vector on pixels. Also, it would be possible to slow the ball down using the method mentioned.

In light of this, what I would do is create an arc that represents the paddle''s collision characteristics. When the ball hits the paddle, you can do an additional collision detection on this invisible arc that determines the reflection vector. Of course the arc is composed of line segments so you can make as many as you want and adjust the ''center'' to whatever width you would like.

Happy coding.

Share this post


Link to post
Share on other sites
That may be a little much for what I''m trying to achieve. If the ball hits dead center, I want it to reflect going straight up or [1, 0] (which is [cos(PI/2), sin(PI/2)]. If it hits the left edge, I want it to reflect at [0, -1] (which is [cos(-PI), sin(-PI)]. If it reflects exactly 1/4 the way between the center of the paddle and the right edge, I want it to reflect at
[sqrt(2)/2, sqrt(2)/2] which is [cos(PI/4), sin(PI/4)]. There is a simple solution to this, and in writing this post, I''ve just figured out that 0 isn''t going to work for PI/2. Time to fix one thing at least.

Share this post


Link to post
Share on other sites
the best thing to do is write a general collision lib between balls and lines, points and cirles. then you can attach a collision object to your paddle consisting of two circles at the endpoints and a linesegment in the middle.

Share this post


Link to post
Share on other sites