Game Development Reference
In-Depth Information
There's a lot going on here. The first thing to notice is that our definition of the
method immediately invokes an anonymous function that returns our actual method
definition. We do this to create some helper objects for efficiency. Most Three.js
math happens in place (as opposed to returning a new object with the result of each
operation), which means that to perform calculations with existing math objects
such as the
acceleration
vector, we either need to clone them or copy values to a
helper
object that we can manipulate without side effects. Cloning creates too much
garbage-collection churn, meaning that the browser will lag if it has to process all
the objects we would be rapidly creating and then discarding. Instead, we define
the
halfAccel
vector, for example, in a closure (so that it doesn't pollute the global
namespace) and do our vector math with that. This pattern is used frequently in the
Three.js library itself.
Almost everything else in the
update
method is addition and multiplication. To
look around, we aggregate how far the mouse has moved between each frame, then
add the corresponding amount of rotation when the player is updating. Also, the
acceleration and velocity part should look familiar—it's the same midpoint strategy
we just covered in the
Physical movement
section. We have to be sensitive to a few
issues though. First, we restrict
r.x
in order to constrain how far the player can look
up and down so that they don't get confused which way is up. Second, we want the
concept of
forward
to be relative to the world instead of where the camera is looking,
so that we can look up and walk forward without flying into the air in the direction
we're looking. To do this, we reset the pitch (making the player look straight ahead
instead of up or down) before adding the velocity to the position. Finally, we add
friction, which allows the player to slow down and stop after moving in a given
direction. In your actual game, you will probably want to use different levels of
friction depending on whether your player is in the air or not.
Player collision
There are several different approaches to detecting collision:
•
Voxels
: As discussed in
Chapter 2
,
Building a World
, one common way to
design worlds is to use a string or image to represent repeatable building
blocks, such as LEGOs. When using this method, the fastest way to check
for collision between an actor and the world is to simply check if the actor's
coordinates are inside the zone that the map designates for use by a building
block. This avoids the complexity of comparing 3D shapes.