Creating a Dynamic Tile Sheet at Runtime

In Chapter 4, we briefly examined two
principles we can use to help eliminate the need to precreate rotations of
objects in tile sheets. Creating these types of tile sheets can be
cumbersome and use up valuable time that’s better spent elsewhere in the
project.

The idea will be to take a single image of a game object (e.g., the
first tile in the medium rock tile sheet), create a “dynamic tile sheet”
at runtime, and store it in an array rather than using the prerendered
image rotation tiles.

To accomplish this, we need to make use of a second canvas, as well
as the getImageData() and putImageData() Canvas functions. If you recall
from Chapter 4, getImageData() will throw a security error if
the HTML page using it is not on a web server.

Currently, only the Safari browser will not throw this error if the
file is used on a local filesystem. For this reason, we have separated
this functionality from the Geo Blaster Extended game
and will simply demonstrate how it could be used instead of replacing all
the tile sheets in the game with this type of prerendering.

We will use the mediumrocks.png
file (Figure 9-9) from the
Geo Blaster Extended game as our source for the
dynamic tile sheet. Don’t let this confuse you. We are not going to use
all five tiles on this tile sheet—only the first tile.

Figure 9-9. The mediumrocks.png tile sheet

In Geo Blaster Extended, we used all five tiles
to create a simulated rotation animation. Here, we will only use the first tile. We will draw
this first tile and rotate it on theCanvas2 by 10 degrees, and then copy the current imageData pixels from this canvas to an array of
imageData instances, called rotationImageArray.

We will then repeat this process by rotating theCanvas2 by 10 more degrees and in a loop until we have 36
individual frames of imageData
representing the rotation animation for our medium rock in an
array:

This loop first clears theCanvas2
with a white color, and then saves it to the stack. We then translate to
the center of our object and rotate the canvas by the current ctr value (an increment of 10). Next, we draw the first tile from mediumrocks.png and save the result into a new
local imageData instance using the
getImageData() function.

Note

This is the place where the security error will be thrown if the
domain of the image and the domain of the HTML file are not the same. On
a local machine (not running on a local web server, but from the
filesystem), this error will be thrown on all browsers but Safari
(currently).

Finally, the new imageData is
pushed into the rotationImageArray.
When the loop is complete, we set up an interval to run and call the
drawScreen() function every 100
milliseconds.

To display the animation on the first canvas, we use this timer loop
interval and call putImageData() to
draw each frame in succession, creating the simulation of animation. As
with the tile sheet, we didn’t have to use 36 frames of animation, we
could use just five. Naturally, the animation is much smoother with more
frames. But this process shows how easy it is to create simple
transformation animations “on the fly” rather than precreating them in
image files: