Tutorial & Videos

Posts tagged ‘about html’

HTML5 for Games

Using HTML5 for Games

Many features from the HTML5 specification have applications in game development, but one of the first features to gain widespread popularity was the canvas element. The visual nature of this element without a doubt helped it spread quickly when the first interactive animations and graphics effects started appearing. More advanced projects soon followed, giving the new standard a dose of good publicity and promising a future with a more dynamic and visually interesting web.

 Canvas

Hobbyist game developers were also among the first to embrace HTML5, and for good reason. The canvas element provides web game developers with the ability to create dynamic graphics, giving them a welcome alternative to static images and animated GIFs. Sure, people have created more or less ingenious (and/or crazy) solutions in lieu of better tools for creating dynamic graphics. Entire drawing libraries rely on nothing more than coloured divelements — that may be clever, but it’s not very efficient for doing anything more than drawing a few simple shapes. Uniform Resource Identifier (URI) schemes exist that let you assign source files to img elements, for example, using a base64-encoded data string, either directly in the HTML or by setting the src or href property with JavaScript. One of the clever uses of this data: URI scheme has been to generate images on the fly and thus provide a dynamically animated image, which is not a great solution for anything but small and simple images. Wolf 5K, the winner of the 2002 contest The 5K, which challenged developers to create a web site in just 5 kilobytes, used a somewhat similar technique. The game, a small 3D maze game, generated black and white images at runtime and fed them continuously to the image src property, relying on the fact that img elements can also take a JavaScript expression in place of an actual URL.

 Graphics drawn on a canvas surface cannot be declared with HTML markup but rather must be drawn with JavaScript using a simple Application Programming Interface (API). Listing 1.1 shows a basic example of how to draw a few simple shapes. Note that the full API provides much more functionality than the small portion shown in this example.
Listing 1.1 Drawing Shapes with the Canvas API
<canvas id=”mycanvas”></canvas>
<script>
var canvas = document.getElementById(“mycanvas”),
ctx = canvas.getContext(“2d”);

canvas.width = canvas.height = 200;

// draw two blue circles

ctx.fillStyle = “blue”;

ctx.beginPath();

ctx.arc(50, 50, 25, 0, Math.PI * 2, true);

ctx.arc(150, 50, 25, 0, Math.PI * 2, true);

ctx.fill();

// draw a red triangle

ctx.fillStyle = “red”;

ctx.beginPath();

ctx.moveTo(100, 75);

ctx.lineTo(75, 125);

ctx.lineTo(125, 125);

ctx.fill();

// draw a green semi-circle

ctx.strokeStyle = “green”;

ctx.beginPath();

ctx.scale(1, 0.5);

ctx.arc(100, 300, 75, Math.PI, 0, true);

ctx.closePath();

ctx.stroke();

</script>

 

Audio

Just as welcome to the toolbox of the web game developer as the canvas element is the new audio element. Finally, we have native audio capabilities in the browser without resorting to plug-ins. A few years ago, you could be almost certain that if a web site had audio, some form of Flash would be involved. Libraries like the SoundManager 2 project (www.schillmania.com/projects/soundmanager2/) provide full JavaScript access to most of the audio features of Flash. But even if such a bridge allows your own code to stay on the JavaScript side, your users still need the plug-in installed. The HTML5 audio element solves this problem, making access to audio available in browsers out of the box using only plain old HTML and JavaScript.

The audio element has a few issues still to be resolved, however. The major browser vendors all seem to agree on the importance of the element and have all adopted the specification, but they have so far failed to agree on which audio codecs should be supported. So, while the theory of the audio element is all good, reality has left developers with no other option than to provide audio files in multiple formats to appease all the browsers.

The audio element can be defined both in the mark-up and created dynamically with JavaScript. (The latter option is of more interest to us as application and game developers.) Listing 1.2 shows a basic music player with multiple source files, native user interface (UI) controls, and a few keyboard hotkeys that use the JavaScript API.

Listing 1.2 A Simple Music Player with HTML5 Audio

<audio controls id=”myaudio”>

<source src=”Prelude In E Minor, Op. 28.ogg”/>

<source src=”Prelude In E Minor, Op. 28.mp3”/>

</audio>

<script>

var audio = document.getElementById(“myaudio”);

document.onkeydown = function(e) {

if (e.keyCode == 83) {

audio.pause(); // Key pressed was S

} else if (e.keyCode == 80) {

audio.play(); // Key pressed was P

}

}

</script>

Audio data APIs that will eventually allow dynamically generated sound effects and audio filters are in the works at both the Mozilla and WebKit camps. Because these APIs are still very early in their development, I won’t be using them for the games in this book, although I briefly examine the possibilities they present in Chapter 10 when I dive into HTML5 audio.

WebSockets

Ajax and the XMLHttpRequest object that is at its heart brought new life to the web with the Web 2.0 explosion of the early 2000s. Despite the many great things it has enabled, however, it is still painfully limited. Being restricted to the HTTP protocol, the action is rather one-sided, as the client must actively ask the server for information. The web server has no way of telling the browser that something has changed unless the browser performs a new request. The typical solution has been to repeatedly poll the server, asking for updates, or alternatively to keep the request open until there is something to report. The umbrella term Comet (en.wikipedia.org/wiki/Comet_(programming)) is sometimes used to refer to these techniques. In many cases, that is good enough, but these solutions are rather simple and often lack the flexibility and performance necessary for multiplayer games.

Enter WebSockets. With WebSockets, we are a big step closer to the level of control necessary for efficient game development. Although it is not a completely raw socket connection, a WebSocket connection does allow us to create and maintain a connection with two-way communication, making implementation of especially real time multiplayer games much easier. In Listing 1.3, you can see that the interface for connecting to the server and exchanging messages is quite simple.

Listing 1.3 Interacting with the Server with WebSockets

// Create a new WebSocket object

var socket = new WebSocket(“ws://mygameserver.com:4200/”);

 

// Send an initial message to the server

socket.onopen = function () {

socket.send(“Hello server!”);

};

 

// Listen for any data sent to us by the server

socket.onmessage = function(msg) {

alert(“Server says: “ + msg);

}

Of course, using WebSockets requires that we also implement a server application that is compatible with the WebSockets protocol and capable of responding to the messages we send to it. This doesn’t have to be a complex task, however, as I show you in Chapter 13 when I implement multiplayer functionality using Node.js on the server side.

Web Storage

Cookies are the usual choice when web applications need to store data on the client. Their bad reputation as spyware tracking devices aside, cookies have also given developers a much-needed place to store user settings and web servers a means of recognizing returning clients, which is a necessary feature for many web applications due to the stateless nature of the HTTP protocol.

Originally a part of HTML5 but later promoted to its own specification, Web Storage can be seen as an improvement on cookies and can, in many cases, directly replace cookies as a larger storage device for key-value type data. There is more to Web Storage than that, however. Whereas cookies are tied only to the domain, Web Storage has both a local storage that is similar to cookies and a session storage that is tied to the active window and page, allowing multiple instances of the same application in different tabs or windows. Unlike cookies, Web Storage only lives on the client and is not transmitted with each HTTP request, allowing for storage space measured in megabytes instead of kilobytes.

Having access to persistent storage capable of holding at least a few megabytes of data comes in handy as soon as you want store to any sort of complex data. Web Storage can only store strings, but if you couple it with a JavaScript Object Notation (JSON) encoder/decoder, which is natively available in most browsers today, you can easily work around this limitation to hold structures that are more complex. In the game I develop during the course of the book, I use local Web Storage to implement a “Save Game” feature as well as to store local high score data.

Listing 1.4 shows the very simple and intuitive interface to the storage.

Listing 1.4 Saving Local Data with Web Storage

// save highscore data

localStorage.setItem(“highscore”, “152400”);

 

// data can later be retrieved, even on other pages

var highscore = localStorage.getItem(“highscore”);

 

alert(highscore); // alerts 154200

WebGL

WebGL is OpenGL for the web. The most widely used graphics API is now available for web developers to create online 3D graphics content. Of course, this has major implications for the kind of web games that are now possible. As a testament to this significance, Google developers released a WebGL port of the legendary first-person shooter, Quake II, on April 1, 2010, to general disbelief due to both the carefully chosen release date and the achievement itself.

remember.eps

Creating a full 3D game is a rather complex task and does not fit within the scope of this book. Using WebGL also requires developers to be very aware of the platforms they plan to target because Internet Explorer, for example, has no support whatsoever and the problem can’t be worked around with polyfills. WebGL is not used much in this book because it is not yet supported on mobile platforms such as iOS or Android, although it will be one day. I do however use a bit of WebGL to create an interesting intro screen for those with WebGL-enabled browsers.

HTML5 is (not) a Flash killer

Ever since the arrival of the canvas element and the improved JavaScript engines, the Internet has seen discussions and good old flame wars over whether the new standards would replace Flash as the dominant delivery method for multimedia applications on the web. Flash has long been the favorite choice when it comes to online video, music, and game development. Although competing technologies such as Microsoft’s Silverlight have tried to beat it, they have only made a small dent in the Flash market share. HTML5 and its related open technologies now finally look like a serious contender for that top spot.

It appears that Adobe, too, has acknowledged the power of HTML5 because they are currently preparing the launch of Adobe Edge (http://labs.adobe.com/technologies/edge/), a development environment very similar to Flash but based fully on HTML5, CSS3, and JavaScript. Adobe’s position seems to be that HTML5 and Flash can coexist for the time being but perhaps this is a sign that Flash will be phased out in the long term in favor of HTML5 and the open web.

remember.eps

That is not to say that HTML5 is a drop-in replacement for Flash. You must know where the new standards fall short and where alternative solutions like Flash might be more appropriate. One area where Flash is still very handy is to ensure backward compatibility with older browsers, which I talk about next.

Creating Backward Compatibility

As with most other new technologies, issues with backward compatibility inevitably show up when working with HTML5. HTML5 is not one big, monolithic thing: Browsers support features, not entire specifications. No browsers today can claim 100 percent support for all of the HTML5 feature set and Internet Explorer, still the most widely used browser, has only begun HTML5 support with its newest version, 9. Some features like WebGL are not implemented at all, and Microsoft has so far not shown any interest in doing so. However, even if the current crop of browsers fully supported HTML5 and the related standards, you still have to think about legacy browsers. With browsers like Internet Explorer 6 still seeing significant use today, a decade after its release in 2001, you can’t safely assume that the users of your applications and games can take advantage of all the features of HTML5 for many years to come.

Feature detection

No one says that the applications and games we build today must support all browsers ever released — doing so would only lead to misery and hair-pulling. We shouldn’t just forget about those users, though. The least we can do is try to tell whether the user is able to play the game or use a certain feature and then handle whatever problems we detect. Browser sniffing — that is, detecting what browser the user is using by examining its user agent string — has almost gone out of style. Today, the concept of feature detection has taken its place. Testing for available properties, objects, and functions is a much saner strategy than simply relying on a user changeable string and assuming a set of supported features.

Using the Modernizr Library

With so many discrepancies in the various implementations and features that can be tricky to detect, doing adequate feature detection is no simple task. Fortunately, you don’t usually need to reinvent the wheel because many clever tricks for detecting feature support have already been developed and aggregated in various libraries. One collection of these detectors is available in the Modernizr library (www.modernizr.com/). Modernizr provides an easy-to-use method of testing whether a certain feature is available or not. You can detect everything from the canvas element and WebGL to web fonts and a whole slew of CSS features, allowing you to provide fallback solutions where features aren’t supported and to degrade your application gracefully.

Using the Modernizr library is dead simple. Simply include a small JavaScript file and you can start testing for features by evaluating properties on the Modernizr object, as seen in Listing 1.5.

Listing 1.5 Detecting Features with Modernizr

if (Modernizr.localstorage){

// local storage is supported, carry on.

} else {

// no local storage support, use a fallback solution.

}

Modernizr also adds CSS classes to the html element, indicating which features are supported and which are not. Because all other elements are children of the html element, this allows you to easily style your markup appropriately according to the supported features. For example, if you want to use rgba() colors to make a semi-transparent background and fall back to an opaque background if rgba() colors are not supported, you could create styles as shown in Listing 1.6.

Listing 1.6 Applying CSS Based on Supported Features

/* rgba() colors are supported */

.rgba .some_element {

background-color : rgba(255,255,255,0.75);

}

 

/* rgba() colors are not supported */

.no-rgba .some_element {

background-color : rgb(220,220,220);

}

remember.eps

Modernizr can only tell you whether something is supported; it is up to you, the developer, to make sure that the appropriate action is taken if the desired feature is unavailable. In the next section, I examine some of the options for dealing with missing features.

Filling the gaps with polyfills

Beginning in the early 2000s, a popular trend has been to favor so-called progressive enhancement when adding new features to web sites. This strategy calls for web sites to target the lowest common denominator in terms of supported features. Any technology that is not supported across the board should be used only to add enhancements to the site, never critical functionality. This ensures that everyone can access and use the web site. If the user has a modern browser, they simply get a better experience.

Progressive enhancement is a sound strategy in many cases, but sometimes you simply need to use a certain feature. If some browsers have no native support for that feature, that hole must be plugged even if it means using less than ideal or even hackish fallback solutions. These fallbacks are sometimes called polyfills, named after the spackling paste Polyfilla, as their function is somewhat similar. They fill out the cracks in the supported feature sets when running your code in actual browsers, bridging the gap between specifications and the reality of dealing with non-perfect browsers.

As an example, Internet Explorer had no support for canvas until IE9, but several polyfills exist that provide various amounts of canvas functionality for legacy browsers. One of the earliest of these polyfills is the ExplorerCanvas project from Google (http://code.google.com/p/explorercanvas/). It uses Vector Markup Language (VML), an old Microsoft developed XML-based language, to simulate a canvas element. It provides enough 2D drawing functionality that it has been used successfully in many projects. Some features are missing, however, because VML does not perfectly overlap the canvas specification and lacks support for, for example, patterns and clipping paths. Other polyfills use Flash or Silverlight to get even closer to the full canvas API, letting you use advanced features like image data access and compositing effects. With all these different options, picking the right fallback solutions is no easy task. Depending on the target platforms, sometimes even the polyfills need fallbacks.

To make things easier, you can turn to Modernizr’s built-in script loader. The script loader is based on a small library called yepnope.js (http://yepnopejs.com/) that combines dynamic script loading techniques with a feature tester like Modernizr. This combination allows you to perform automatic, conditional script loading based on available features. Listing 1.7 shows how different scripts can be loaded depending on the support of a feature.

Listing 1.7 Loading scripts conditionally with Modernizr

Modernizr.load([

{

test : Modernizr.localstorage,

yep : “localstorage-data.js”,

nope : “cookiebased-hack-data.js”

}

]);

The Modernizr.load() function takes a list of objects, each describing a feature test that determines which script(s) should load. The script specified by the yep property loads if the feature is supported; the nope script loads if it is not. The yepnope.js functionality includes many other cool features that can help you streamline the loading stage, letting you load both JavaScript and CSS files based on feature support, browser make and version, or even something completely different.

Building a Game

Starting with Chapter 2 and throughout the rest of the book, I take you through the process of developing an HTML5 web game from scratch. I show you how to create a match-three gem-swapping game in the style of Bejeweled or Puzzle Quest, casual games that have been very popular on many platforms over the past decade. This type of game has tried-and-tested game mechanics, allowing us to focus our attention on the use of web technologies in the context of game development. Additionally, these games play well in desktop browsers as well as on mobile devices such as smart phones and tablets, giving us opportunity to explore multiplatform web game development.

The game takes advantage of several features from the HTML5 specification, but also uses related technologies such as web fonts and CSS3 for building the UI. Although the game itself might not be revolutionary, it allows me to cover many of the newest advances in open web technology. Among other things, I use the canvas element to generate some of the game graphics and I show you how to add sound effects using HTML5 audio. The finished game will be playable in a regular browser but I show you how to ensure that it plays just as well on mobile devices and even offline. I show you how to use Web Storage to save high score data and to allow players to pick up where they left.

The canvas element lets us create interesting dynamic graphics, but it’s not always suitable for creating user interfaces. You don’t really need any new tools for that part, however, because traditional HTML and CSS gives us all you need to build great UI. With the latest additions to the CSS specification, you can add animations, transforms, and other features that bring life to the UI experience. In Chapters 6 and 7, I show you how to build the display module with the canvas element. Later on, in Chapter 11, I take you a bit further as I show you how to use WebGL to add 3D graphics to the game.

In Chapter 13, I show you how to create a simple chat application using WebSockets. For this purpose, I also show you how to develop a small server application using the Node.js framework (http://nodejs.org/). However, you should note that WebSockets are only supported in a few browsers and it might be a while before it is ready for prime time use.

Summary

It’s been a bumpy road but it finally looks like HTML and the web in general is on the right track again. The WHATWG brought in some fresh perspective on the standards process, and web developers are now beginning to enjoy the fruits of this undertaking in the form of a plethora of new tools and a HTML standard that is more in line with how the web is used today. As always, using new features requires dealing with older browsers but many polyfills are already available that you can use to ensure cross-browser compatibility. Using a helper like Modernizr eases the burden of this task even further.

Many of the new additions are of special interest to game developers because real alternatives to Flash-based web games are now available. Canvas and WebGL bring dynamic and hardware accelerated graphics to the table, theaudio element has finally enabled native sound, and with WebSockets, it is now possible to create multiplayer experiences that are much closer that of desktop games than what was possible just a few years ago. Advances in other, related areas like CSS and the increasing support for web fonts let us create richer UI experiences using open, standardized tools.

Gaming on the Web

• Figuring out what HTML5 is and where it came from

 • Seeing HTML5 in the context of games
 • Looking at important new features
 • Enabling feature detection and dealing with legacy browsers
Before I dive into code, I want to establish the context of the technology we use. In this first chapter, I discuss what HTML5 is as well as some of the history that led to the HTML5 specification.
One of the most interesting aspects of HTML5 is how game developers can profit from many of the new features. In this chapter, I introduce some of these features and give a few quick examples of how they are used. I talk about the canvas element and WebGL and the huge improvements these additions make in terms of our ability to create dynamic graphics. I also cover the audio element and the added multiplayer possibilities created by the WebSockets specification.
Everybody likes new toys, but we mustn’t forget that in the real world, old and outdated browsers keep many users from using these bleeding-edge features. In this chapter, I show a few helpful tools for detecting which features you can safely use as well as how you can use these feature tests to load appropriate fallback solutions when necessary.
Finally, I briefly introduce the puzzle game that I use throughout the rest of the book to take you through the creation of a complete HTML5 game.

HTML5 and Using Google Flash Player

And using Google’s Flash Player and the embed element looks like this:
<audio controls>
<source src=”sayHello.ogg” type=”audio/ogg”>
<source src=”sayHello.mp3” type=”audio/mp3”>
<embed type=”application/x-shockwave-flash”
wmode=”transparent”
src=”http://www.google.com/reader/ui/3523697345-audiop
player.swf?audioUrl=sayHello.mp3&autoPlay=true”
height=”27”
width=”320”>
</audio>

All of the preceding examples will work in browsers that support HTML5 audio
And the examples will all work in Internet Explorer 8 using a Flash player

You can take advantage of the fact that Flash can play MP3 files, so you don’t
have to serve up yet another audio file format. Of course, users must have the Flash
player installed on their system. But what if they don’t?
Well, you can go one step further with the fallbacks presented and offer a simple
link to the file for the user to download:

<audio controls>
<source src=”sayHello.ogg” type=”audio/ogg”>
<source src=”sayHello.mp3” type=”audio/mp3”>
<object type=”application/x-shockwave-flash”
data=”player.swf?audioUrl=sayHello.mp3&autoPlay=true”
height=”27” width=”320”>
<param name=”movie”
value=”player.swf?audioUrl=sayHello.mp3&autoPlay=true”>
</object>
<a href=”sayHello.mp3”>Download the audio file</a>
</audio>

 

HTML5 Programming perspective

We use the Ball class again for these examples, and for interaction, let’s get fancy and use the mouse and keyboard. The mouse controls the ball’s x and y position, and the up and down keys on the keyboard move the ball forward and back on the z-axis. The variables xpos, ypos, and zpos are used to represent the 3D position. Here’s the code for example 01-perspective-1.html:

<!doctype html>
<html>
<head>
<meta charset=”utf-8″>
<title>Perspective 1</title>
<link rel=”stylesheet” href=”style.css”>
</head>
<body>
<canvas id=”canvas” width=”400″ height=”400″></canvas>
<script src=”utils.js”></script>
<script src=”ball.js”></script>
<script>
window.onload = function () {
var canvas = document.getElementById(‘canvas’),
context = canvas.getContext(‘2d’),
mouse = utils.captureMouse(canvas),
ball = new Ball(),
xpos = 0,
ypos = 0,
zpos = 0,
fl = 250,
vpX = canvas.width / 2,
vpY = canvas.height / 2;
window.addEventListener(‘keydown’, function (event) {
if (event.keyCode === 38) { //up
zpos += 5;
} else if (event.keyCode === 40) { //down
zpos -= 5;
}
}, false);
(function drawFrame () {
window.requestAnimationFrame(drawFrame, canvas);
context.clearRect(0, 0, canvas.width, canvas.height);
var scale = fl / (fl + zpos);
xpos = mouse.x – vpX;
ypos = mouse.y – vpY;
ball.scaleX = ball.scaleY = scale;
ball.x = vpX + xpos * scale;
ball.y = vpY + ypos * scale;
ball.draw(context);
}());
};
</script>
</body>
</html>

First, you create variables for xpos, ypos, and zpos, as well as fl. Then you create a vanishing point,
vpX, vpY. Remember, as objects move off in the distance, they converge on 0, 0. If you don’t offset this
somehow, everything converges at the top-left corner of the screen, which is not what you want. You use
vpX, vpY to make the center of the canvas element the vanishing point.
Next, add a listener for the keydown event that changes the zpos variable. If the up key is pressed, zpos
increases, and pressing the down key decreases it. This makes the ball move farther from, or closer to, the
viewer.
In the drawFrame animation loop, set xpos and ypos to the mouse position, as offset by the vanishing
point. In other words, if the mouse is 200 pixels right of center, xpos is 200. If it’s 200 pixels left of center,
xpos is –200.

The perspective formula

The idea is that as something moves farther away (z increases), its scale approaches 0 and its x, y position converges on the 0, 0 of the vanishing point. Because the ratio of distance to scale is the same as the ratio of distance to convergence, you need to figure out what that ratio is for a given distance and use it in both places. The diagram in Figure 15-3 helps to explain this concept.

Figure 15-3. Perspective seen from the sideHere, you have an object off in the distance, a viewpoint we look from (the camera), and a picture plane, which we look through to see the scene. You have the distance of the object to the picture plane, which is the z value, and, you have the distance from the viewpoint to the picture plane. This last one is similar to the focal length of a camera lens, so we use the variable fl to represent it. A long focal length can be compared to a telephoto lens on a camera, with a narrow view that compresses the distance between objects. A short focal length is like a wide-angle lens, where you see a lot of the scene, but with a lot of distortion. A medium focal length approximates what the human eye sees, and uses a value for fl that’s between 200 and 300. Here’s the perspective formula:

scale = fl / (fl + z)
This usually yields a number between 0.0 and 1.0, which is your ratio for scaling and converging on the vanishing point. However, as z approaches -fl, (fl + z) approaches 0 and scale approaches infinity. This is the coding equivalent to being poked in the eye. What do you do with this scale value? Well, you can adjust the scale of the canvas context before drawing the object. For example, in the Ball class we’ve used throughout the book, there are scaleX and scaleY properties that are referenced in its draw method, like so:
context.scale(this.scaleX, this.scaleY);
Once the scale as been determined, you multiply the object’s x and y position by this factor to find its screen x and y position. Let’s look at an example where we use 250 as the focal length. If z is zero—in other words, the object is exactly on the picture plane—then the scale will be 250 / (250 + 0). This comes out to exactly 1.0. That’s your scaleX and scaleY (remember that for scale, 1.0 means 100%). Multiplying 1.0 by the object’s x and y positions gives the same numbers back as a result, so the object’s screen position is exactly equal to its x and y. Now move it out so that z is 250. That makes the scale equal to 250 / (250 + 250), or 0.5 for scaleX and
scaleY. It also moves the object’s screen position. If the object were at 200, 300 on the x and y axis, its screen position would now be 100, 150—it has moved halfway to the vanishing point. (Actually, the screen position would be in relation to the vanishing point, which you see shortly.) Move z out to 9750. This makes the scale equal to 250/10000, or 0.025 for scaleX and scaleY. The object becomes just a speck that is close to the vanishing point. Now we see how to write all of this in code.

The third dimension and perspective

The main concept behind 3D is the existence of another dimension beyond the x and y axes. This is the dimension of depth, and it is usually labeled z. The canvas element does not have a built-in z dimension, but it isn’t too difficult to create one with JavaScript. And it’s actually less complex than a lot of the stuff you did in the previous chapters! The z axis To begin with, you must decide which direction the z-axis will go: in or out. If you recall back to the description of the canvas coordinate system in Chapter 3, it is in some ways opposite to most other commonly used coordinate systems. The y axis goes down instead of up, and angles are measured clockwise instead of counterclockwise. If an object’s z position increases, is it going away from you or toward you on the z-axis? Neither way is necessarily more correct than the other. In fact, this subject has been addressed enough times that there are even names to describe the two methods: left-hand system and right-hand system. Take either hand, and point the fingers in the direction of the positive x-axis and curl them toward the positive y-axis. The direction your thumb points, either toward you or away from you, is the direction that the positive z-axis points for that coordinate system. So, if you take your right-hand, point it away from you following the positive x-axis, and then curl the fingers to the ground, toward the positive y-axis, your thumb will point in front of you—the positive z-axis for the right-handed coordinate system. So in code, this means the z-axis increases as it goes away from the viewer, and decreases as it goes toward the viewer, as shown in Figure 15-1.

Figure 15-1. Right-hand coordinate system
If you try it with your left hand, you get the opposite result—your thumb is pointing behind you. Figure 15-2
shows the left-hand coordinate system.

Figure 15-2. Left-hand coordinate system
We use the right-hand coordinate system (refer to Figure 15-1) for the examples here, so as an object’s z position increases, it moves further in front of us. But that is just the preference of this book, there’s no reason that you couldn’t make a left-hand system.
The next step in creating a third (z) dimension is to figure out how to simulate perspective.

HTML5 3D Basics

What we’ll cover in this chapter:

  • The third dimension and perspective
  • Velocity and acceleration
  • Bouncing
  • Gravity
  • Wrapping
  • Easing and springing
  • Coordinate rotation
  • Collision detection

Up to now, everything in this book has been in just two (and sometimes only one) dimensions, and you’ve created some pretty interesting animations. Now, let’s take it to the next level. Creating graphics in 3D is exciting because the extra dimension seems to make things really come to life. We move through the basics of programming 3D fairly quickly, and after that, we’ll see how the motion
effects discussed in the previous chapters can be done with a third dimension. Specifically, this chapter covers velocity, acceleration, friction, gravity, bouncing, wrapping, easing, springing, coordinate rotation, and collision detection. For now, you are primarily concerned with taking an object and moving it around in 3D space, using perspective to calculate its size and position on the screen. The object we draw is flat, of course. It won’t have a back, side, top, or bottom that you can see. Over the next couple of chapters, you do some modeling of points, lines, shapes, and solids in 3D. It’s worth mentioning there is currently, at the time of writing, a 3D specification in development for the canvas element, called WebGL. However, it is not considered part of the HTML5 specification, and is not supported across all the major web browsers at this time (and it is not known if it ever will be). WebGL is, by design, a low-level means to execute code on the computer’s graphics card. Although WebGL is a powerful way to run hardware-accelerated graphics in the browser, it’s rather advanced and uses JavaScript more as a way to tie together other programs, called shaders, which are written in a separate shader language and are compiled when the browser loads the document. But WebGL could provide the foundation for the next generation of web-based graphics, on which other, easier to use, libraries and 3Dengines are built. There are still a number of issues facing its broad adoption by all browsers, but it does offer a glimpse into the future of graphics and games on the web.

A basic HTML5 document

One of the best parts of web development is how easy it is to create and view a document—all you need is a text editor and a web browser. This simple snippet provides the setup for all of the examples contained in this book. After you walk through the structure of these elements, we’ll add a couple of minor additions for clarity, but this is the basic HTML5 file you will use:
<!doctype html>
<html>
<head>
<meta charset=”utf-8″>
<title></title>
<link rel=”stylesheet” href=”style.css”>
</head>
<body>
<canvas id=”canvas” width=”400″ height=”400″></canvas>
<script>
window.onload = function () {
//Our code here…
};
</script>
</body>
</html>
Save this file as 01-skeleton.html and load it in your web browser. You won’t actually see anything
because it’s a blank document, but the page did load and is a completely valid HTML5 document. (You
can always view the source in your browser to confirm that something is there.)
Now let’s go through the elements step by step. The first line simply declares that this is an HTML5
document type. If you have any familiarity with all the various HTML4 document types, you’ll see that this
declaration is quite simple:
<!doctype html>
Next, we declare the root html element and the header:
<html>
<head>
<meta charset=”utf-8″>
<title></title>
<link rel=”stylesheet” href=”style.css”>
</head>
At the top of the head element, set the document character encoding to utf-8. UTF-8 is an encoding for Unicode, which is a universal character set that defines the characters used in most of the world’s languages. The browser uses this encoding to read the characters from a file and display them as properly formatted text. These documents are stored in a sequence of bytes contained in a file on a server somewhere, transmitted across the network, then reassembled on the client’s computer and displayed in a web browser. The character encoding tells the browser how to convert this sequence of bytes into a sequence of characters, which is then processed and displayed as a web page. If you don’t include the encoding declaration, the browser might attempt to guess the character encoding of the file (wrongly), or use a default setting (wrongly), causing the page to display incorrectly. It’s best to explicitly set the character encoding here and avoid the potential confusion. All valid HTML5 documents contain a title element, which is also placed in the header. Because we use a CSS stylesheet, create a link element that points to an external file. This contains the style definitions for our document; we’ll look at the style.css file in a moment. With the header set, let’s look at the rest of the document:

<body>
<canvas id=”canvas” width=”400″ height=”400″></canvas>
<script>
window.onload = function () {
//Our code here…
};
</script>
</body>
</html>
In the body element, we place a canvas element. This is what we draw to and reference from our scripts. Give the canvas an id name and a height and width value so you can see it, and use its id to access the element with the DOM interface. After the canvas element, add a script tag that includes the JavaScript code for each example. We’ve placed the script after the other elements, right before the closing body tag, so that the browser loads the rest of the document before executing the script. Also, if the script is loaded from a file—possibly from a different server—it won’t hold up the rest of the document while waiting to download. This makes loading
faster and the document more responsive. The skeleton script is simple and effectively does nothing. The window object is the top of the Document Object Model and how we access the DOM. When the document has finished loading, the window object executes the function assigned to its onload property:
<script>
window.onload = function () {
//Our code here…
};
</script>
The example code in this book is placed within the window.onload callback function. Because this method is executed after all the document elements have been loaded, we can be assured that the canvas element is ready to go by the time the code is called. Consequently, if your document contains a lot of data embedded in it, such as large images, you can wait a long time for window.onload to execute. In this situation, it might be better to load the assets using JavaScript, which I show you how to do in Chapter 4. Finally, we close out our script, body, and html tags. We’re finished creating a basic but perfectly valid HTML5 document.

Canvas Support

The good news, at least for this book, is that all the major browser vendors have implemented support for
the canvas element. This means that you can be relatively confident that your user can see the animation
you create, provided she has upgraded to a recent version of her browser. Games and animations provide
an excellent way to push users into upgrading their browsers, because, after decades of video games,
most people understand that cutting-edge graphics require the latest hardware and software. At least it’s
easier to convince someone to upgrade her browser rather than buy a brand new gaming console.
In case the canvas element is not supported in a web browser, in your HTML document, you can provide
backup content by including it within the canvas tags:
<canvas width=”400″ height=”400″>
<p>This browser does not support the<code>canvas</code> element.</p>
</canvas>
The warning message appears only if the browser does not recognize the canvas tag. If the browser does
support it, then it renders the canvas element and ignores the nested <p> element.
To programmatically test whether the browser supports the canvas element, you can add the following
JavaScript to your document:

if (document.createElement(‘canvas’).getContext) {
console.log(“Success! The canvas element is supported.”);
}
This code creates a new canvas element and tests for the existence of its getContext property, which the
object has if it’s a valid HTML5 canvas element. If the browser does have support, it prints a message to
the debugging console letting you know.

Chapter 1 Flash Professional Basics

Flash Professional is a popular tool used to author a wide variety of creative and interactivecontent that can be deployed to the Web and mobile devices. It can even be usedto create desktop applications. There are many aspects to the application itself, but its most notable characteristic is a timeline and asset-centric interface that makes it ideal for creating animations. Until recently, Flash-created content was only viewable by devices with support for Flash. Now, when combined with Wallaby, Flash Professional can be used to create HTML5-based animations as well. At this point, you might be wondering why we would bother using an application
intended to create Flash content to instead create HTML5 animations. After all, aren’t we talking apples and elephants here? The answer is both yes and no. Sure, Flash and HTML5 are different technologies with different implementations for powering content
on the Web. However, if we look at creating animations from an artistic perspective, the workflow is really one and the same. Flash Professional provides an advanced visual interface to create animated content that really accelerates this workflow. This remains true regardless of whether that content is ultimately powered by Flash or by HTML5. In fact, Flash Professional is one of the first tools, if not the first tool, on the market that allows you to take a visual approach to creating HTML5 animations versus a fully programmatic approach. As an animation tool, Flash Professional is well seasoned. The first incantation of the Flash software actually debuted in 1996 as an application called FutureSplash Animator. It was then given the name Flash after being purcased by Macromedia not long after its release. At the time, the visual capabilities of Flash went far beyond the capabilities of HTML; that led to widespread use of Flash on the Web. Today Flash Professionalis part of the Adobe Creative Suite of products and has evolved into a very powerful and feature-rich tool responsible for much of the content on the Web. Before we go any further, it bears mentioning that Flash Professional is just one tooln within the family of the Flash Platform. In fact, because of the versatility of Flash Player itself, there are several tools, each of which takes a different approach to creating content. The common thread among these tools is that they all produce content that is powered by the Flash Player runtime. There is, however, one new exception to this, in that Flash Professional animation projects can now be exported to HTML5. This means that animations created with Flash can run on the standard Web without the need for a plug-in.