![]() |
|
Find angle for pong game |
IroNuckles
Member #1,988
March 2002
![]() |
Okay, I'm trying to modify my simple pong game to have realistic ball-bouncing action. How would I find the angle that the ball is making with the wall or paddle? Right now I'm just reversing the direction when a collision is detected. |
DanTheKat
Member #1,990
March 2002
![]() |
Actually i've been trying to find this out for ages.
--- |
gnudutch
Member #951
February 2001
![]() |
IroNuckles, did it hurt when you got your neck pierced? Simple solution: At collision, determine whether you hit a vertical wall (left and right side of playfield) or a horizontal wall (ceiling or your paddle). Then: if (hit_vert_wall) x_speed = -x_speed; Basically just invert one axis only and it will give you a perfect reflection. Next thing I would add is variable angles provided by the paddle. |
Derezo
Member #1,666
April 2001
![]() |
Quote: IroNuckles, did it hurt when you got your neck pierced?
heh, I was wondering what you were refering to for a moment Well, in pong.. the ball really only goes 4 directions, right? In a very simple, and boring, pong game that I made quite some time ago I didn't use angles at all. I used 2 variables - horizontal direction, vertical direction.. updating post after rereading the original If you want to use angles, I think you could add or subtract 90 (or 65 in allegdegress) to the angle whenever it hits the paddles or the borders... "He who controls the stuffing controls the Universe" |
IroNuckles
Member #1,988
March 2002
![]() |
If you're referring to my mug shot, that's actually a ceiling fan in the background. |
Derezo
Member #1,666
April 2001
![]() |
Giving the ball a velocity which affects the direction it bounces in would give a bit more unpredictability, but... uhh.. I dunno how you could add an increasing/decreasing velocity in a game of pong.. "He who controls the stuffing controls the Universe" |
superstar4410
Member #926
January 2001
![]() |
heres something that does work I made a pong game earler back in my days of early programming. for the angle problem, I didn't use advance math the ball had to varaibles Ball_x = the x value the ball gets incremented Ball_y = the y value the ball gets incremented so if you like have a way that you like can hit like turbo hit, basically depending on what angle the ball is coming from, increment like for sharp angles you will have so it would travel like
/ And for lesser angles you would have the Ball_x incremented value high and the Ball_y value low
Don't take yourself too seriously, but do take your responsibilities very seriously. |
Derezo
Member #1,666
April 2001
![]() |
Sorta combines the velocity with the 'angle', nice The only problem is, in a 'simple' game of pong, it's hard to make the ball "boost" forward without adding some sort of creative feature.. and who wants to do THAT?
"He who controls the stuffing controls the Universe" |
Johan Halmén
Member #1,550
September 2001
|
Use variables d for direction, v for velocity. When the ball gets its direction and velocity (depending on how it hits the pad) you use the sin and cos only once, to compute vx and vy. Then when the ball hits the walls, do vx = -vx or vy = -vy. If the velocity changes, say if a turbo boost ends, just do vx = k * vx and vy = k * vy. k > 1 speeds up while k < 1 slows down. If your new direction depends on the old direction when you hit the pad (or other objects) you may have to recompute the direction out of vx and vy. But actually, after any number of hits, your direction will be any of four possible directions. So when you determine vx and vy, determine also all 4 possible values for d. Johan Halmén ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Years of thorough research have revealed that what people find beautiful about the Mandelbrot set is not the set itself, but all the rest. |
Mariusz
Member #1,634
November 2001
|
What I do is calculate where ball hits the pad |
Thomas Harte
Member #33
April 2000
![]() |
If you mean you want angled walls, i.e. the simple 'reflecting just x or just y' approach that about 16,000 people have already explained on this thread isn't good enough, then as you speculate, you need to do a little vector maths. And Allegro won't help. But I will! If the ball has velocity (vx, vy) and hits a wall which has the vector (wx, wy) - e.g. you draw the wall with line(bmp, x, y, x+wx, y+wy, col), then you can do this : float r, l; l = wx*wx + wy*wy; r = (-wy*vx + wx*vy) / l; vx += r*wy; vy -= r*wx; And if you're smart, you could observe that this is the same thing : float r, l; l = sqrt(wx*wx + wy*wy); wx /= l; wy /= l; r = -wy*vx + wx*vy; vx += r*wy; vy -= r*wx; And do the divides by l in your startup section rather than at every collision, saving a few calculations. [My site] [Tetrominoes] |
sicgamemaker
Member #1,365
June 2001
![]() |
heres my shot at it... this is a entire article i got from some website (a long time ago, i forgot where) but here it is...its got good math for fast detection of collision, angled bounces, and mass/momentum transfer 1[CODE]
2Calculating a ricochet turns out to be a lot trickier problem than it
3first appears. For those of us who are a decade or more away from our
4last practice with algebra and trigonometry it requires some patience
5and perseverance.
6
7First we're going to concentrate on the collision of two balls. Later
8we'll expand that to the collision of a ball against a wall. Our
9discussion will include mass and elasticity. At the end we'll discuss
10some of our ideas on how we might handle simultaneous collisions
11between multiple objects.
12
13First, two balls.
14
15There are six parts to the calculation, with a couple of subparts.
16
17 1) Gross collision detection
18 2) Calculate accurate positions at time of collision
19 3) Calculate the angle of collision vs the velocity vector
20 4) Calculate portion of velocity vector that applies to collision
21 5) Calculate final velocities along collision vector
22 6) Apply final velocities back to the object
23
24---------------------------------------------------------------------
25 1) Gross collision detection.
26
27The purpose of this step is to determine in as few instructions as
28possible whether the objects are close enough together to warrant more
29expensive calculations. There are many ways to accomplish this. The
30one we chose was the simple bounding box (See figures 1a through 1c).
31
32The quickest way to find out if two bounding boxes overlap is to test
33to see if the bounding boxes DON'T overlap. It only takes four tests
34to show that box A is to the right of, left of, above, or below box B.
35
36// Use this macro in an if statement. Ex.
37// if (bounding_box_test(ibx, ibx1, iby, iby1, jbx, jbx1, jby, jby1))
38// DoSomething();
39// else
40// DoSomethingElse();
41#define bounding_box_test(ibx, ibx1, iby, iby1, jbx, jbx1, jby, jby1) \
42 (!((ibx > jbx1) || (ibx1 < jbx) || (iby > jby1) || (iby1 < jby)))
43
44You'll need to extend the bounding boxes to include both the beginning
45and ending positions of each object. Otherwise, the objects could
46become overlapped before you detect a collision.
47
48---------------------------------------------------------------------
49 2) Calculate accurate positions at time of collision.
50
51The central trick for this step is the Quadratic equation.
52
53Let's take a moment to define our terms. (See figure 2a)
54
55 Stuff we know:
56 x1,y1 and x2,y2 - The initial positions of the centers of the two objects
57 dx1,dy1 and dx2,dy2 - The distances the objects moved this frame
58 r1, r2 - radii of the two objects
59
60 Stuff we calculate:
61 t - Time of collision
62 cx1,cy1 and cx2,cy2 - The centers at time of impact
63
64What we're trying to find is when the centers of the two objects are
65the same distance apart as the sum of their radii. The distance
66formula is sqrt([cx1-cx2]^2 + [cy1-cy2]^2). Therefore, we're looking
67for the time (t) when
68 (r1+r2)=sqrt([cx1-cx2]^2 + [cy1-cy2]^2).
69
70How do we know where will a ball be at any given time (t)? Here are
71functions which describe the paths of the centers of the balls over
72time:
73
74 cx1 = x1 + tdx1 cx2 = x2 + tdx2
75 cy1 = y1 + tdy1 cy2 = y2 + tdy2
76
77The t's relate all the forumlas to each other. Replacing the cx's and
78cy's in the distance forumla with these equations and we end up with:
79
80 r1+r2 = sqrt(((x2 + tdx2)-(x1 + tdx1))^2 + ((y2 + tdy2)-(y1 + tdy1))^2)
81
82Multiply everything out then rearrange and simplify and you end up
83with:
84
85 0 = [(dx2-dx1)^2 + (dy2-dy1)^2] t^2
86 + [2(x2-x1)(dx2-dx1) + 2(y2-y1)(dy2-dy1)] t
87 + [(x2-x1)^2 + (y2-y1)^2 - (r1+r2)^2]
88
89This is a polynomial in the form 0=ax^2+bx+c. We can use the Quadratic
90equation (-b(+|-)sqrt(b^2-4ac))/2a to solve for the variable. The a, b
91and c are all spelled out above. You could plug a, b and c into that
92monster equation, but it turns out you want to calculate it in pieces.
93
94The Quadratic equation will give two answers, call them t1 and t2. One
95for each the plus and minus of the square root portion. There are some
96special cases to check before solving the equation, and some special
97cases that result from the equation. (See figure 2, cases 1-6)
98
99 1) If a=0 the equation goes infinite. Notice that "a" consists of the
100 square of the difference between the direction vectors.
101 Therefore, a=0 if and only if the balls are moving the same
102 direction and the same speed.
103
104 2) If 4ac > b^2 then you end up trying to take the square root of a
105 negative number. In other words, there's no solution. It turns
106 out that this happens if and only if the balls never pass within
107 r1+r2 of each other. Even though the paths may cross, the balls
108 are far enough apart in time that they don't approach close
109 enough to each other to ever actually touch.
110
111 3) If both t's are negative then the balls are receding from each
112 other.
113
114 4) If one t is negative and the other t is positive then the balls
115 began the frame already overlapped.
116
117 5) If both t's are positive then the smaller of the two is when they
118 first reach r1+r2 from each other.
119
120 6) If both t's are greater than 1.0 then the balls do not collide
121 this frame.
122
123Condition 5 is the only valid collision and you continue with the rest
124of the calculations.
125
126Conditions 1, 2, 3 and 6 indicate that there is not a valid collision
127this frame and you therefore can abort before performing the rest of
128the calculations. In effect, you discard this pair of objects since a
129collision didn't take place.
130
131Ideally, condition 4 should not occur. Whether or not it does occur
132depends on whether or not you handle multiple collisions in one frame.
133If you don't test for condition 4 then the rest of the math works out
134that the balls will remain locked together "arm-in-arm" so to speak.
135
136---------------------------------------------------------------------
137 3) Calculate the angle of collision vs the velocity vector
138
139In order to calculate the momentum transfer later on we need to perform
140the remainder of these steps on both objects.
141
142At first glance it appears that you simply take the angle between the
143paths of the balls. That doesn't work. Let's take the example of two
144balls headed in the same direction and one ball is catching up on the
145other. If their centers lie on the same line then it's a simple 1D
146collision. But if the center of one ball is offset a little to one
147side then the momentum transfer occurs at an angle even though the
148motion paths are parallel. (See figures 3a and 3b)
149
150What we need to find is the angle formed by the velocity vector and the
151line connecting the centers. We need this angle in order to calculate
152how much of the velocity vector to apply to the collision. In other
153words, if the balls hit head-on, as in figure 3a, then the entire
154velocity vector is applied to the collision. If the balls just nick
155each other, as in figure 3b, then less momentum is transfered between
156the balls.
157
158The mathmatical tool for this problem is the Law of Cosines.
159 a^2 = b^2 + c^2 - 2bc cos(A).
160As written, it's intended for finding the length of a side when an
161angle is known, but we can flip it around:
162 cos(A) = ( a^2 - b^2 - c^2 ) / (-2bc)
163
164 Thus the angle is: A = acos( ( a^2 - b^2 - c^2 ) / (-2bc) )
165
166Note that we can't use "simple" trig since we're not guaranteed of
167having a right angle. (See figure 3c and 3d) This way you won't have
168to transform coords to some artificial origin.
169
170(-2bc) approaches 0 if and only if the radii of both objects approach
1710. That's a pretty obvious should-not-occur situation.
172
173---------------------------------------------------------------------
174 4) Calculate portion of velocity vector that applies to collision
175
176Once we have angle A this part turns out to be trivial. The piece of
177the total velocity vector that points toward Ball 2 is:
178 vi=cos(A)*sqrt(dx1^2+dy1^2)
179
180One obvious optimization is to save and use cos(A) above, rather than
181find A only to immediately take its cos() again.
182
183---------------------------------------------------------------------
184 5) Calculate final velocities along collision vector
185
186At this point we can treat the this as a 1D collision along the line
187connecting the centers. You can find the momentum transfer equations
188in most first-year college physics texts.
189
190 vf1=(((m1-m2)*vi1)+(((1.0+(e1*e2))*m2)*vi2))/(m1+m2);
191 vf2=((((1.0+(e1*e2))*m1)*vi1)+((m2-m1)*vi2))/(m1+m2);
192
193Where: vf1, vf2 - final velocities along collision vector
194 vi1, vi2 - initial velocities along collision vector
195 m1, m2 - mass of each ball
196 e1, e2 - elasticity of each ball
197
198---------------------------------------------------------------------
199 6) Apply final velocities back to the object
200
201Now we need to subtract the off old velocity vector and add on the new
202one. That will leave us with an object that's moving at the new,
203adjusted speed after ricochet.
204
205 angle=atan2(dcy,dcx); // angle of the line connecting the centers
206 sina=sin(angle); cosa=cos(angle);
207 odx=cosa*vi; // subtract off old velocity vector
208 ody=sina*vi;
209 ndx=cosa*vf1; // add on new velocity vector
210 ndy=sina*vf1;
211 dx+=odx-ndx; // signs look reversed but are correct
212 dy+=ody-ndy;
213
214---------------------------------------------------------------------
215 So, that's a ricochet
216
217So, that's how you ricochet two balls. Whew! It seems like a lot of
218work, but there's no magic involved. Just break the problem into
219pieces and use the appropriate tool for each piece.
220
221We haven't discussed optimizations, yet. It turns out, collisions
222happen rarely enough that even using floating point and transcendental
223functions like sin and cos don't slow things down noticable. For
224example, an Asteroids clone with 30-40 rocks bouncing around spends
225almost all its time blting the sprites to the screen. The time to
226calculate ricochets is completely swamped. Still, for maximum speed
227you'll want to use a fixed-point representation and lookup tables for
228the transcendentals.
229
230But my advice is to live with floats while you build your prototype.
231The first rule of optimization: Make it right before you make it faster.
232
233Our implementation uses a dx, dy method to move the balls. An
234angle/norm implementation would perform the same work, it's just
235arranged a little different. See CBENCH.ZIP for a dx/dy implementation
236by David Bollinger and CAROM.ZIP for an angle/norm implementation by
237Csaba Markus.
238
239---------------------------------------------------------------------
240 Wall collisions
241
242At the time of this writing, we haven't completed the implementation of
243wall collisions.
244
245Our first pass implies that the trick to finding the collision point is
246to calculate a "shadow wall" one radius distance to each side of the
247wall. Then, simply find the intersection of the path of the center of
248the ball with each shadow wall (see figure 4a). Find which is closer to
249the original location of the ball.
250
251That gives you a possible collision. Next, you need to decide if the
252ball actually hit the wall face, or if it passed beyond the end of the
253wall and possibly hit the endpoint.
254
255To find if the ball hit a wall face, find the distance from the center
256of the ball to each endpoint of the shadow wall. If either distance is
257greater that the distance from one endpoint to the other then the
258center missed the wall face.
259
260To find if the ball hit the endpoint of a wall, treat the wall endpoint
261as an infinitely massive ball of zero size and go through the ball
262collision above (see figure 4b).
263
264---------------------------------------------------------------------
265 Simultaneous collisions
266
267Again, we haven't implemented this yet. There are two likely
268candidates for this.
269
270First, go through each pair of objects and find the pair lowest time of
271collision. Perform that collision and then find the next lowest time,
272taking into account the new velocities of the objects.
273
274Or, sort the times and step through them in that order. Resort all
275objects that are close enough to be affected by each collision as they
276happen.
277
278---------------------------------------------------------------------
279 Wrapping it up
280
281I hope you found this description useful. I realize it's ended up a bit
282on the terse side. Hopefully the PCX files will help you visualize what
283I'm trying to describe. If anyone has questions, feedback, suggestions or
284critique please feel free to contact me, Drake Christensen 71251,433.
285
286This file owes its existence to David Bollinger 72510,3623. He and I
287spent over a month brainstorming this surprizingly obscure problem in the
288GAMDEV forum on Compuserve. His CBENCH example is available in GAMDEV.
289Obviously, any mistakes or obfuscation in this text are entirely my fault.
290
291Another who provided needed assistance is Csaba Markus (E-mail:
292ethcms@duna.ericsson.se). We found his CAROM simulator at just the right
293time to convince ourselves that we were heading down (one of) the right
294path.
295
296I can't give a specific bibliography, but if you want to research this in
297texts, my suggestion is to visit a local college library and look for
298mechanics and physics texts circa 1910 or so. I was unable to find
299anything more recent than those. Apparently, the academic community
300doesn't consider this an interesting subject anymore. :-)
301
302Related files:
303 CBENCH.ZIP - Collision test bench by David Bollinger 72510,3623
304 CAROM.ZIP - Carom simulator by Csaba Markus ethcms@duna.ericsson.se
305 CLDTHD.ZIP - Thread on collision physics by (mostly) David Bollinger
306 and Drake Christensen
[/CODE] _______________________ |
Mark Venture
Member #1,272
April 2001
![]() |
The following code calculates a smooth path towards a target :
so the problem becomes finding a good target_x, target_y : angle is in radians (from 0 to 2*PI). Radius can be any number; it is just needed to calculate target_x, target_y for a breakout-style game you need to calculate the angle from the distance of ball_x to pad's center. The more to the side the ball hits the pad, the highest angle the ball should take. You can also use this algorithm for bullets in a shoot-em-up to target the player's sprite. (if it does not work it means I don't remember the algorithm exactly, but I 've done it in my breakout game) "as long as there is hope, we will fight" (quote by Captain Avatar, Star Blazers, Season 1) |
almeidaj
Member #1,951
February 2002
|
Aren't we all forgetting the padle influence on the ball angle and velocity, when the ball colides with a padle in movement... |
Thomas Harte
Member #33
April 2000
![]() |
You mean the fact that at the point of collision there is actually a force perpendicular to the collision and you assume the bat's surface has a non-zero friction coefficient? Indeed, under those circumstances, even if you are doing the most common thing and modelling your collisions as instantaneous, when the ball hits the bat, the bat will excert a force as you describe. The trick is to remember that the law of conservation of momentum works 'in both directions' (i.e. parallel and perpendicular, or for a simple game, x & y). [My site] [Tetrominoes] |
|