Hey everyone! We haven’t had a post in awhile, and I thought the folks interested in the physics aspect of the game would be interested in reading about how we solved the (probably age-old) problem of creating a dynamic, parabolic movement from a source position to a targeted position.
Problem Description
Normally, we specify an entity’s jump speed in our behavior tool that the code uses when creating an appealing jump or other movement. This is exactly what we want in most cases when an entity is jumping, hopping, or throwing a projectile – some kind of parabolic motion defined by a predetermined speed.
In some cases, however, we want an entity to move from its current position to a specified destination. So, at the moment the entity initiates this movement, how can we know what horizontal and vertical velocity to give it to make it land where we want?
First Attempt
Good for you if the Kinematic Equations immediately come to mind. (I’ll get to them in a second.) It took us until our second attempt at this problem before we found what we’d been carrying inside our rusty innards.
Our first attempt at the solution (over a year ago) was to solve a nasty-looking quadratic equation that defined a curve that passed through source and destination points, given the height of the peak. Ok, so that gave us the curve of the motion, but it still left us having to figure out how fast along that curve to move. After much finagling, I failed to get the jumps to look consistent using this method. Some jumps were way too fast, some too slow, and some just alright. So we needed another solution.
Kinematic Equations
Chris found a post that helped change our way thinking and ultimately brought us to remembering the previously mentioned Kinematic Equations. I thought, “oooooh yeah… I remember these equations from college and high school!” As I dove deeper into the solution, I remembered more and more truths about motion that helped solve the dynamic jump problem. In particular:
- Vertical velocity is 0 at the peak of a parabola, and this can be used to frame the steps of the problem in easier ways.
- Horizontal velocity, given no resistance (wind, bugs, etc.), remains the same for an object throughout its trajectory.
- Horizontal velocity has the same magnitude, but opposite direction when traveling back and forth along the same parabola. (Imagine two people throwing a baseball back and forth with exactly same velocity.)
Solution
Solving the dynamic jump problem came down to two cases for us (and ultimately, really one):
- The destination position is above the current position.
- The destination position is below the current position.
We’ll take a look at the first case. Suppose an enemy is jumping from one platform to a higher platform. What should its initial velocity be? Here’s what we know:
- dx: the horizontal distance from known start position to known destination position
- dy: the vertical distance from known start position to known destination position
- dyc: the amount of clearance we want – how high above the destination platform the peak should be
- Vertical acceleration is gravity and horizontal acceleration is 0.
Step 1 – Find the initial vertical velocity that will get us to the peak, where velocity is 0.
Given what we know and that we want to find the vertical vi, we can look at the Kinematic Equations and solve for vi like this, using dx as d:
vf2 = vi 2 + 2ad
0 = vi 2 + 2a(dy + dyc)
vi = sqrt(-2a(dy + dyc))
Step 2a – Find the time to reach the peak.
Finding the horizontal velocity took me a few steps. I knew I needed to calculate the total time for the projectile to traverse to from the start to the destination. I knew the distance, so if I had the time, I could easily calculate the velocity. (Remember that there is no horizontal acceleration.)
To find the total time, I had to first find the time to reach the peak, then the time from the peak to the destination. I calculated the time to the peak like this:
vf = vi + at
0 = vi + at
t = -vi /a
Step 2b – Find the time from the peak to the destination.
We can find the time from the peak to the destination by remembering again that velocity is 0 at the peak. In this step, that will be vi . Also, in this step, think of the distance from the peak down to the platform as negative:
d = vi t + 1/2at2
-dyc = 1/2at2
t = sqrt(-2dyc/a)
Now we can calculated the total traversal time by adding the time to get from the start to the peak, to the time to get from the peak to the destination.
Step 2c – Find the initial horizontal velocity that will get us to the destination.
At last we can find the horizontal velocity. Again remembering that horizontal acceleration is 0:
d = vi t + 1/2at2
dx= vi t
vi = dx/t
So now that we have the initial horizontal velocity and the vertical velocity from Step 1, we can put an entity in motion with the confidence that it will land where we want.
Case 2 – The destination position is below the current position.
The second case is much easier when you remember that the horizontal velocity when moving from one endpoint to the other is the same magnitude but opposite direction. So this means that finding the horizontal velocity in the second case is really the same as the first, only you flip the sign of the horizontal velocity. To find the vertical velocity, follow the same procedure as step 1 above, only use dyc (the amount of clearance we want on the jump) as the distance.
A Message for the Children
Because everything we do around here is for the children, I’d like to close the post with the following message: No matter how authoritarian your grade school physics teacher may be or how strong an accent your college professor has (and thus difficult to understand), the laws that govern mathematics and motion can be fun to learn and apply in practical settings, especially when gaming is on the line. It was a nostalgic exercise in problem-solving, and to my surprise, was something I enjoyed figuring out. I hope this post can help someone out there and was interesting to some of you. Until next time!!!
– Jeff
I dread to ask, but why no update all winter?
Hi andrewclunn, thanks for asking. Fear not, we’ve been hard at work on the game, and I agree, we are long overdue for an update.
😦