Rectangular to trapezoid coordinates:
The first problem I ran into, is the way the court is drawn. I wanted to keep the coordinates in a rectangle and yet have the court be displayed to the player at an angle so the hoop and sidelines are more visible. The view to the player would look something like this:
In order to keep the coordinates rectangular, I had to change the position that the player was drawn on the screen so that it did not display rectangular, but displayed on a trapezoid. I had to come up with a function to convert the coordinates. My first idea was to use the barycentric coordinates relative to the two vectors that make up the trapezoid, which would convert the display nicely to a parallelogram, but it would not work here because opposite ends of the court angle in toward each other, instead of the same direction.
View mapping
I decided that the angle would change based on how close you are to the center. If the angle at the top left edge of the shape is 10°, then the player a quarter of the way down the court would move at a 5° angle, the center would move at a 0° angle, 3 quarters of the way would be -5° , and the entire other end of the court would be -10°.
An equation to describe the current angle based on player position would be:
angle = 10° * ( DIST_FROM_CENTER / (COURT_WIDTH / 2) )
with DIST_FROM_CENTER being a signed value.
We can then use this angle to find the two vectors describing the shape.
The first will always be along the positive x axis: (1,0)
The second will be: (cos(angle), sin(angle))
And then we can find our draw coordinates. With rectangular coordinates (x,y) we will have new coordinates:
new_x = x + ( y * cos(angle) )
new_y = y
Note: the new_y value is not affected by the vectors because we want the movement to look like the player is always moving parallel to the sideline (not realistic.) I made the error in adding y*sin(angle) to the new y value at first which made the player move along an arc, but since the view is warped to make it easier to see the game, this does not look correct.
Basic 3d Physics:
One of the main tasks in basketball, from what I've learned, is to shoot the ball in the hoop. However, we did not want this to be the main focus of the game, so we wanted to do an automatic aiming system that is based on a percentage chance that it goes in (rather than manually aiming the player's arms.)
He's like the Michael Jordan of basketball.
So we need to find the velocity at which the player needs to throw the ball from any position in the court in order to make it in the hoop. Since the game takes place in a full 3d world, we will have to use 3d kinematics (which is the exact same thing as 2d with an extra d somewhere (it doesn't change things too much.))
We can define a specific velocity in the z (up) direction that we want to throw the ball (as long as it is strong enough to reach the hoop) and we know the height of the ball at start. We must find the amount of time the ball will remain in the air until it reaches the height of the hoop on the way back down. We can use the kinematic equation:
(z_target – z_initial) = velocity_z*t + 0.5 * GRAVITY * t^2
solving for t we get:
GRAVITY * t^2 + 2*velocity_z*t – 2*(z_target – z_initial) = 0
using the quadratic equation:
a = GRAVITY
b = 2*velocity_z
c = 2*(z_target – z_initial)
t = max( (-b ± sqrt(b^2 – 4*a*c)) / (2*a) )
We want to use the max value of t because we want to know the time it takes to collide with the hoop on the way back down, otherwise we would have the player chucking the ball directly at the hoop instead of arcing it in.
So we now have the time the ball will be in the air, we now need to find the velocity in the x and y directions the player needs to throw the ball so that it will make it in the hoop.
We will use the same equation as before, but this time we are trying to find the initial velocity and we know the time. Solving for velocity we get:
velocity_x = ( (target_x – initial_x) – (acceleration*t^2/2)) / t
velocity_y = ( (target_y – initial_y) – (acceleration*t^2/2)) / t
I don't have any acceleration or deceleration while the ball is in the air (acceleration = 0) so I simplified the equations to:
velocity_x = ( (target_x – initial_x)) / t
velocity_y = ( (target_y – initial_y)) / t
And with that, we get a perfect shot every time.