#150359 - 3dfx - Sun Feb 03, 2008 2:20 am
Hey guys, I'm trying to make a 2d bball game. My problem is, how do I make the ball move properly. The ball has a moveX and moveY variable that is added to its x and y position once it is shot. The hoop has its own hoop.x, hoop.y position. How can I find the proper moveX and moveY values for it? -Many thanks.
#150364 - Dwedit - Sun Feb 03, 2008 3:11 am
Make it 3D instead.
Let's assume you have a Double Dribble or NBA Jam style view of the action. You have 3 axes: left to right (X), front view to back view (Z), and floor to ceiling (Y). Make the sprite's Y position a function of Z and Y.
Simple Newtonian physics says that the X and Z velocity of the ball will remain constant, and there is acceleration on the Y axis due to gravity.
If you choose to make it completely 2D, making the basketball court into a single straight line, throw out the Z axis.
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."
#150365 - tepples - Sun Feb 03, 2008 3:54 am
Sir Isaac Newton's first law of motion is that an object in motion will move at the same velocity unless acted upon by an outside force. This means that in each frame, you should add the velocity into the position of the ball:
Code: |
ball.x += ball.dx;
ball.y += ball.dy;
ball.z += ball.dz; |
Newton's law of gravity is that objects are attracted by a force proportional to each mass and inversely proportional to the square of the distance between their centers. For objects the size of a basketball on Earth's surface, this force is pretty much constant: 9.8 m/s^2 times the mass of the ball.
Newton's second law of motion is that the acceleration of an object is proportional to the force applied to it: F = m*a, or a = F/m. In the case of gravity, the mass cancels out, leaving a = 9.8 m/s^2. This means that in each frame, you should add a constant to the height coordinate of velocity:
Code: |
ball.dy += M_S2(9.8); |
By now, you are dealing with quantities smaller than 1 pixel/frame^2, so you should be using some sort of fixed-point arithmetic.
EDIT: clarification of which vector's height coordinate that gravity affects
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
Last edited by tepples on Sun Feb 03, 2008 11:53 pm; edited 1 time in total
#150404 - gauauu - Sun Feb 03, 2008 10:09 pm
tepples wrote: |
This means that in each frame, you should add a constant to the height coordinate:
Code: | ball.dy += M_S2(9.8); |
|
Just a nitpick, but to avoid confusion...the code is correct, but you're adding the constant to the y velocity, not to the height itself (as Tepple's explanation sounds like)
#150407 - 3dfx - Sun Feb 03, 2008 10:24 pm
Thanks guys, but I already know how to simulate gravity. My question is how do I make sure the ball has the proper arc to always hit the rim each time the player shoots?
Here's how I do gravity;
Code: |
//ball.x and ball.y are 16.16 fixed point
if(ball.released){
ball.vX = somevalue;
ball.dY = -anothervalue;
}
ball.x += ball.vX;
ball.dY += GRAVITY;
ball.y += ball.dY;
displaySprite(ball.id, (ball.x>>16), (ball.y>>16));
|
Right now, in order to get the right arc I'm just playing around with vX and the initial dY value depending on the player's location.
#150408 - Miked0801 - Sun Feb 03, 2008 10:41 pm
Ah, you get to use 1st year physics to solve that problem. I don't have a book in front of me at the moment, but you are basically giving a start and end x/z positions and probably a starting velocity and need to find the correct shoot angle(s) that will solve the problem.
#150409 - Dwedit - Sun Feb 03, 2008 10:41 pm
Given an initial position, a final position, constant acceleration, and a length of time, you can calculate the initial velocity.
Vinitial= ( Xfinal-Xinitial - .5 * a*t^2 ) / t
Vinitial, Xfinal, Xinitial, and a are 3d vectors. Because there is only acceleration in Y, .5*a*t^2 = 0 for the X and Z axes.
This probably won't give very good arcs though, since it takes in T as a parameter.
This also probably explains why the grenades in "Worms" have timed fuses.
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."
#150448 - Miked0801 - Mon Feb 04, 2008 7:05 pm
Derived from:
1/2 a*(t^2) + Vinit * t + Xfinal - Xinit = 0
The equation of the parabala is:
y = (tan ElevationAngle)x - (g / 2(Vinit * cos ElevationAngle) ^ 2) * x^2
Alas, my physics book has nothing on how to calculate angles when the starting elevation is different between positions. I believe google is your friend here.
#150484 - Cearn - Tue Feb 05, 2008 4:53 pm
The basic equations are:
x(t) = x0 + vx0*t
y(t) = y0 + vy0*t - ½g*t²
These can be rewritten to the parabola in the space-domain:
(1) y(x)= A*t² + B*t + C
With A, B, C having some relation to the initial velocities, vx0 and vy0. To solve this, you'd need three control points, (x0, y0), (x1, y2), and (x2, y2). (x0, y0) and (x2, y2) you have: those are the initial position and the position of the hoop. The other point you're free to choose. With eq (1), these form three new linear equations which corresponds to a matrix formula: M?(A, B C) = (y0, y1, y2), but solving this manually is somewhat unpleasant.
You can simplify things by switching to relative coordinates: x= x-x0 and y= y-y0. This reduces the system to 2 equations rather then 3:
⌈ x1² x1 ⌉ ? ⌈ A ⌉ = ⌈ y1 ⌉
⌊ x2² x2 ⌋ ⌊ B ⌋ ⌊ y2 ⌋
Inverting the equation gives
A = ( x2*y1 - x1*y2)/(x1*x2*(x1-x2))
B = (-x2²*y1 + x1²*y2)/(x1*x2*(x1-x2))
The initial velocities vx0 and vy0 then follow from the first couple of equations:
vx0 = sqrt(-g/(2A))
vy0 = vx0*B
Example excel sheet with solution.
#150520 - 3dfx - Wed Feb 06, 2008 2:07 am
Miked0801 wrote: |
Derived from:
1/2 a*(t^2) + Vinit * t + Xfinal - Xinit = 0
The equation of the parabala is:
y = (tan ElevationAngle)x - (g / 2(Vinit * cos ElevationAngle) ^ 2) * x^2
Alas, my physics book has nothing on how to calculate angles when the starting elevation is different between positions. I believe google is your friend here. |
That was somewhat my problem. At first, I was going to create a parabola but because of the high likelihood of elevation change, I couldn't do that.
Cearn wrote: |
Inverting the equation gives
A = ( x2*y1 - x1*y2)/(x1*x2*(x1-x2))
B = (-x2?*y1 + x1?*y2)/(x1*x2*(x1-x2))
The initial velocities vx0 and vy0 then follow from the first couple of equations:
vx0 = sqrt(-g/(2A))
vy0 = vx0*B
|
Thanks Cearn! I'll test this out. it looks right to me!