< Day Day Up > |
ProjectilesOne of the easiest types of motion to spot in a game is projectile motion. Any object that has been thrown, kicked, or shot and that is flying through the air is considered a projectile. Think about the last time you threw a baseball or kicked a soccer ball. What type of path did the ball follow? That's rightit followed a parabolic path! You might want to flip back to Chapter 2, "Geometry Snippets," for a quick review of the parabola. Check out the parabola that opens downward. Doesn't it look like the trajectory of a missile that's just been shot at an angle? Any first-person or third-person shooter will have tons of projectiles, so how do we model them mathematically? The easiest way to approach a 2D projectile is to break all the vector quantities into components, as you did in the preceding section, and then separate the horizontal components from the vertical ones. The components are completely independent of each other, so mathematically you can treat them separately. If you don't believe me, try this simple experiment. Get two identical balls or pencils, and find a table with a nice smooth surface. Roll one ball off the edge of the table, and watch it fall to the floor in a parabolic path. Now repeat the process, but this time drop the other ball from the same height as the table at the exact same time that the first ball reaches the edge of the table. Do they both hit the floor at the same time? They should. This tells you that the horizontal motion of the first ball does not affect its vertical motion. Both balls fall vertically in the same way. Figure 10.5 shows what happens from the side view. Figure 10.5. Ball experiment side view.If you watch the experiment from the front view, where you have no depth perception, the motion of both balls appears identical, as shown in Figure 10.6. Figure 10.6. Ball experiment front view.Now that we have established that vertical motion is completely independent of horizontal motion, let's address them separately. The best part of separating them is that we're back to 1D motion, which means just dealing with positive and negative numbers. Let's look at vertical motion first. If we look at just the vertical components of the displacement, velocity, and acceleration vectors, we're really back to vertical 1D motion, which was discussed in Chapter 8. Looking at the displacement, the object goes up to a maximum height and then falls back down. The velocity starts out positive, decreases to 0 at the maximum height, and then speeds up in the negative direction as it falls down. This, of course, is caused by negative acceleration due to gravity (9.8m/s2). Because we're back to 1D motion with constant acceleration, we can use the five equations of motion discussed in Chapter 8.
Example 10.6: Vertical Components of a ProjectileSuppose you're coding a game like Spyro the Dragon where the player climbs onto a cannon, and it launches cannon balls at a speed of 20m/s at a 30° angle. How much time will it take a cannon ball to come back down to the ground? Solution
Now let's turn our attention to the horizontal components of the projectile's vector quantities. The horizontal components are even easier to work with, because as soon as a projectile is airborne, it does not speed up or slow down in the horizontal direction (if we ignore air resistance). This means that the horizontal component of the acceleration is always 0. In other words, the horizontal velocity does not change; it stays constant. And that constant velocity is equal to the horizontal displacement divided by time. Again, we're back to 1D motion with constant velocity, so we can use the five equations of motion just like we did in Chapter 8. What's even nicer about the projectile is that the horizontal acceleration is 0, and if you plug that into the equations of motion, they all reduce to one equation: vx = Dx/t. That's the only equation you need to worry about for the horizontal components.
Example 10.7: Horizontal Components of a ProjectileOnce again, you're coding a game like Spyro the Dragon where he's climbed onto a cannon, and it launches water balloons at a speed of 20m/s at a 30° angle. If the edge of the screen is 30 meters away from the launch, how much time will it take the cannon ball to fly out of view? Solution
The cannon ball will go off the edge of the screen 1.73 seconds after it has been launched. Now let's put the two pieces together. Earlier I said that all the projectile's vector quantities can be broken into components and then separated. You've been working with one more quantity that's not a vector. Time is a scalar quantity, so it has no direction. This means that time is the one element that can bridge the horizontal and vertical parts of projectile motion. For example, the water balloon you looked at in the last two examples had both horizontal and vertical components to its motion. You found in Example 10.6 that it took 2.04 seconds for the water balloon to go up and back down to the ground. That's the same amount of time it takes the water balloon to travel horizontally before it hits the ground. You can use the same 2.04 seconds to calculate how far away the balloon will hit the ground. That takes you to the horizontal information, so make a list:
Because the acceleration is 0, you can use the equation v = Dx/t to find the horizontal displacement: v = Dx/t 17.32m/s = Dx/2.04s Dx = 35.33m The trick here is that it takes 2.04 seconds to go up and back down, so it also takes 2.04 seconds to travel 35.33 meters horizontally before hitting the ground. Let's look at a few examples where this comes in handy. In these examples, you'll see that I place the horizontal and vertical components on opposite sides of the page. You also might want to consider sketching the motion to help organize all the numbers. Example 10.8: Falling from a Known HeightSuppose you're making a 2D game like Joust with platforms at various heights. One platform is 8 meters above the ground. If the player (on his ostrich) runs off the ledge at 10m/s without jumping, how far away from the edge will he land on the ground? Solution
The player lands 12.8 meters from the edge of the platform. In this example, the player's initial velocity is completely horizontal. Let's look at the same situation but with an initial velocity at an angle. Generally in a game, we don't calculate where a player is going to land or strike another object unless it is vital to some form of prediction code we're implementing. In the scenario previously described, once the player leaves the platform, in every frame we would apply gravity to his motion while also adjusting his position accordingly until we detected a collision with either the ground or another platform. Let's take a look at how this works. The player's position and his current direction of movement could be stored in arrays of two floats. Let's assume a screen coordinate of (200, 200) for the player and a velocity at 10 pixels/second: float player_pos[2] = { 200, 200 }; float player_motion[2] = { 10, 0 }; In every frame, we would call a function to update the player's position, as follows: // purpose: to update the player's position // input: none // output: the updated position void updatePlayerPos() { for(int i = 0; i < 2; ++i) player_pos[i] += player_motion[i]; } We would also need to call a function to update the player's motion. In the game of Joust, horizontal motion would be affected by things like player input and collisions with objects, but in this instance, we're concerned more with the vertical motion, which is affected by gravity until it is affected by a collision. So in every frame, we would need to check to see if there was something underneath the player, and if not, we would need to allow gravity to affect his motion: // purpose: to update the player's motion if there is nothing under him // input: accel - the amount of constant vertical acceleration per second // fps - our frames per second, in other words our time interval // output: update player_motion[1] (vertical velocity) void updatePlayerVertMotion(float accel, float fps) { if(/*check to see if there is nothing underneath the player*/) { player_motion[1] = player_motion[1] + accel * fps; } } This same code could be used to solve the following problem as well, the only difference being that the player would begin the scenario with a negative initial velocity in the Y direction. You may be confused by this statement, because generally in this book a negative y-component for velocity represents downward motion, but keep in mind that in a game the Y axis decrements in the upward direction, so negative velocity in the vertical would indicate upwards travel. Example 10.9: Jumping from a Known HeightSuppose you're making the same Joust-like game with platforms at various heights. One platform is 8 meters above the ground. If the player (on his ostrich) stands at the ledge and jumps off with an initial speed of 10m/s at a 30° angle, how far from the edge will he land on the ground? Solution
This time, the player lands 16.33 meters from the edge of the platform. In Examples 10.8 and 10.9, you were ultimately looking for the horizontal displacement. That won't always be the case. Let's look at one more example where you try to find the vertical displacement. Example 10.10: Shooting PaintballsSuppose the character in your game is shooting paintballs at the side of a building 20 meters from where he's lying on the ground. If the pellets leave the gun with an initial speed of 25m/s, and the character is aiming at a 40° angle, how high above the ground will the splattered paint appear on the wall? Solution
NOTE All these examples began with all metric units. Be careful if you estimate initial values in different units. Always convert all values to the same units before plugging anything into an equation. All the examples we've looked at have been flat on a 2D screen. You might be wondering how this translates to 3D. Well, it works the same way. A parabola is a 2D shape, so ultimately any projectile moves in a flat 2D planeit just might not be the xy plane. The math still works. Just think of the components as horizontal and vertical, not necessarily parallel to the x- and y-axes. In the end, any horizontal component you find might need to be rotated in the xz plane, but the vertical components will always stay the same. Self-Assessment
|
< Day Day Up > |