HTML and CSS Reference
In-Depth Information
The three following methods— each , eachInvoke , and detect —are the same as the ones described in
Chapter 2. They exist as helper methods to make it easier to perform operations on the items list. The difference
between each and eachInvoke is that the former takes an actual callback method, whereas the latter calls
a method stored as a property on the object. You'll notice each of these methods calls the Function.call
method with exactly two parameters instead of Function.apply , which could support any number of para-
meters passed as an array. The reason for this is that to call Function.apply a new array object needs to be
created, which is something that any good HTML5 Engine should try to avoid wherever possible for methods
that are called frequently to limit the stutters caused by the garbage collector.
NOTE As an HTML5 game programmer, you have only one real enemy: the garbage collector. JavaScript is
a garbage-collected language, which means that the developer doesn't need to worry about allocating and
freeing memory. The downside to this, however, is that at certain intervals JavaScript needs to clean up no-
longer-used pieces of memory itself by running a garbage collector. The collector can take some time to run,
sometimes more than 100ms, leading to a noticeable stutter in gameplay. The goal of any JavaScript engine
should be to create as few objects as possible over the course of a normal frame and save the creation of ob-
jects for situations where real game objects like sprites need to be created.
The functionality for adding and removing objects also works the same as in Chapter 2, with the add ,
remove , and forceRemove methods performing the same tasks as before with only the addition of a
call to the object's destroy method and some triggered events. There is also an additional index on the
id of the object. If you remember the Q.GameObject code from Chapter 10, the destroy method also
calls remove , which could lead to an infinite recursive loop. This is the reason you added the GameOb-
ject.destroyed property, which allows you to remove an object by calling GameObject.destroy()
or Stage.remove(object) and have the engine behave correctly either way.
To make it easier to look up objects on the stage by their id , the stage object keeps both the sorted items'
array as well as an object that is used as a hash to key objects to their id s.
The collision methods are also similar to what you saw in Chapter 2. The overlap method has been pulled
out and is placed as a method directly on Q primarily to make it easier to reach for scoping reasons. The primary
method for doing bounding box collisions— Stage.collide —calls a helper method called _hitTest that
uses the Q.collide method. The definition for _hitTest could have been embedded as an anonymous
function directly inside of Q.collide , but this would have led to the function definition being parsed on every
call, slowing down the engine slightly and adding to the garbage that needs to be collected.
Finally, the step and draw methods loop over each of the objects in the list and call the appropriate method
on each as well as trigger events before and after. The draw method also calls the optional sort function to
make sure objects are drawn in the correct z order.
Rounding Out the Scene Functionality
The last bit of code needed for scenes are some helper methods for staging, clearing, pausing, unpausing, and
looping the game. These utility methods are added directly onto the Q object instance.
Add the code in Listing 11-9 to the bottom of the Quintus.Scenes module before the final closing curly
brace.
Listing 11-9: Scene and stage utility methods
 
 
 
Search WWH ::




Custom Search