HTML5 2D game development: Setting the stage

Implementing the game object, pausing, freezing, thawing, and keyboard input

In this series, HTML5 maven David Geary shows you how to implement an HTML5 2D video game one step at a time. In this installment, you'll learn how to encapsulate game code in an object, how to implement pause and unpause, and how to use CSS3 transitions to implement a game-restart countdown.

David Geary, Author and speaker, Clarity Training, Inc.

David GearyThe author of Core HTML5 Canvas, David Geary is also the co-founder of the HTML5 Denver User's Group and the author of eight Java books, including the best-selling books on Swing and JavaServer Faces. David is a frequent speaker at conferences, including JavaOne, Devoxx, Strange Loop, NDC, and OSCON, and he is a three-time JavaOne Rock Star. He wrote the JSF 2 fu and GWT fu article series for developerWorks. You can follow David on Twitter at @davidgeary.



30 October 2012

Also available in Chinese Russian Japanese Vietnamese

Many aspects of game development have nothing to do with gameplay. Displaying instructions, pausing the game, transitioning between levels, and rolling game credits are just some of the features that game developers must implement besides the game itself.

When inspiration for a game strikes, it usually doesn't include ingenious ways to display high scores or transition between levels, so it's natural to dive into implementing game mechanics without much thought about the game's infrastructure. But as in most projects, bolting on that functionality as an afterthought is more work than if you incorporate it from the beginning.

In the last article in this series, I discussed graphics and animation, which are fundamental to Snail Bait's gameplay. In this article, I take a temporary detour to implement some of the game's infrastructure. I start by encapsulating Snail Bait's code in a Game object. When I originally implemented the game, I started with that step, but for the articles I didn't want to obfuscate the discussions of graphics and animation by implementing them in an object, so I've postponed the Game object until now.

I'll also show you how to pause and freeze Snail Bait and subsequently how to thaw and restart the game with an animated countdown. At the end of the article, I return to gameplay mechanics by showing you how to handle keyboard events to control the runner's vertical position.

In this article, you'll learn how to:

  • Encapsulate game functions in an object.
  • Pause and unpause the game.
  • Automatically pause the game when the window loses focus.
  • Resume the game with an animated countdown when the window regains focus.
  • Temporarily display messages (known as toasts) to the user.
  • Handle keyboard input.

Along the way, you'll learn how to define and instantiate JavaScript objects, how to use CSS3 transitions, and how to combine setTimeout() with those transitions to implement stepwise animations.

The game object

Up to now in this series, I've implemented all Snail Bait functions, along with several of its variables, as global variables. That, of course, will never do. If you're not already well-versed in the evils of global variables, see Resources for supporting arguments from JavaScript luminaries such as Douglas Crockford and Nicholas Zakas.

Instead of using globals, from now on I will encapsulate all Snail Bait functions and variables in an object. That object is composed of two parts, as you can see in Listings 1 and 2. (See Download to get the complete sample code for this article.)

Listing 1 is the game's constructor function, which defines the object's attributes:

Listing 1. The game's constructor (partial listing)
var SnailBait = function (canvasId) {
   this.canvas  = document.getElementById(canvasId);
   this.context = this.canvas.getContext('2d');

   // HTML elements 

   this.toast = document.getElementById('toast'),
   this.fpsElement = document.getElementById('fps');

   // Constants

   this.LEFT = 1;
   this.RIGHT = 2;
   ...

   // Many more attributes are defined in the rest of this function
};

Listing 2 is the game's prototype, which defines the object's methods:

Listing 2. The game's prototype (partial listing)
SnailBait.prototype = {
   // The draw() and drawRunner() methods were
   // discussed in the second article in this series.


   draw function (now) {
      this.setPlatformVelocity(); 
      this.setOffsets();
   
      this.drawBackground();
   
      this.drawRunner();
      this.drawPlatforms();
   },
   
   drawRunner: function () {
      this.context.drawImage(this.runnerImage,
         this.STARTING_RUNNER_LEFT,
         this.calculatePlatformTop(this.runnerTrack) - this.RUNNER_HEIGHT);
   },
   ...

   // Many more methods are defined in the rest of this object
};

As I incorporate new features throughout this series, I will add and remove methods and also modify some method implementations. Table 1 lists Snail Bait methods as they exist as of the end of this article:

Table 1. Snail Bait methods at this stage of development (listed in invocation order)
MethodDescription
initializeImages()Initializes the game's images. The onload event handler for the background image invokes start().
start()Starts the game by invoking requestAnimationFrame(), which calls the animate() method when it's time to draw the first animation frame.
splashToast() [1]Displays a temporary message to the player.
animate() [2]If the game is not paused, this method draws the next animation frame and invokes requestNextAnimationFrame() to schedule another call to animate(). If the game is paused, animate() waits 200ms before invoking requestNextAnimationFrame().
calculateFps()Calculates the frame rate based on the elapsed time since the last animation frame.
draw()Draws the next animation frame.
setTranslationOffsets()Sets translation offsets for the background and platforms.
setBackgroundTranslationOffset().Sets the background translation offset, depending on the current time.
setPlatformTranslationOffset()Sets the platform translation offset, depending on the current time.
setPlatformVelocity()Sets platform velocity as a multiple of the background velocity to produce a mild parallax effect.
drawBackground()Translates the Canvas coordinate system, draws the background twice, and translates the coordinate system back to its original position.
drawRunner() [3]Draws the runner with drawImage().
drawPlatforms() [3]Draws the rectangular platforms with the 2D context's strokeRect() and fillRect().
calculatePlatformTop()Calculates the Y coordinate of the top of a platform, given a track (platforms move on one of three horizontal tracks).
turnLeft()Scroll the background and platforms to the right.
turnRight()Scroll the background and platforms to the left.
togglePaused() [1]Toggle the paused state of the game.

[1] Introduced in this article
[2] Called by the browser
[3] Will be replaced in the next installment of this series

Functions vs. methods

JavaScript functions that are members of an object are referred to as methods, whereas standalone functions are simply called functions.

I introduced most of the methods — which at the time were mere functions — listed in Table 1 in the two preceding articles in this series. In this article, I discuss two new methods: togglePaused() and splashToast(), in addition to modifications to other methods such as animate().

The JavaScript in Listing 1 and Listing 2 defines a function and a prototype but does not instantiate a SnailBait object. I do that in the next section.


Starting the game

SnailBait's global objects

As Listing 1 and Listing 3 illustrate, Snail Bait has only two global objects: the SnailBait function and the snailBait object.

Listing 3 shows the JavaScript that starts the game. The beginning of the listing shows the implementation of three SnailBait methods: animate(), start(), and initializeImages().

Listing 3. Starting
SnailBait.prototype = {
   ...

   // The 'this' variable in the animate() method is
   // the window object, so the method uses snailBait instead

   animate: function (now) { 
      snailBait.fps = snailBait.calculateFps(now); 
      snailBait.draw(now);

      requestNextAnimationFrame(snailBait.animate);
   },

   start: function () {
      this.turnRight();                     // Sets everything in motion
      this.splashToast('Good Luck!', 2000); // "Good Luck" is displayed for 2 seconds

      requestNextAnimationFrame(this.animate);
   },

   initializeImages: function () {
      this.background.src = 'images/background_level_one_dark_red.png';
      this.runnerImage.src = 'images/runner.png';
   
      this.background.onload = function (e) {

         // ...the 'this' variable is the window object,
         // so this function uses snailBait instead.
     
         snailBait.start();
      };
   },
}; // End of SnailBait.prototype


// Launch game

var snailBait = new SnailBait(); // Note: By convention, the object
                                     // reference starts with lowercase, but
                                     // the function name starts with uppercase

snailBait.initializeImages();

JavaScript's persnickety this object

If you've used a classic object-oriented language such as Java, you expect an object's this variable always to point to the method's associated object.

One of JavaScript's sharpest edges is the fact that the this variable can change. In Listing 2, the this variables in the animate() method and the background image's onload event handler refer to the window object, not the snailBait object, so those methods access the snailBait object directly.

The JavaScript in Listing 3 instantiates a SnailBait object and invokes its initializeImages() method, which sets the background image's onload event handler. When the image loads, that event handler invokes the start() method.

The start() method calls turnRight(), which sets the background and platforms in motion. It also calls splashToast(), which displays Good Luck! for two seconds. Finally, start() calls the requestNextAnimationFrame() polyfill — discussed in the second article in this series (see that article's A requestAnimationFrame() polyfill section) — which ultimately calls the game's animate() method.

The animate() method draws the current frame and then calls requestNextAnimationFrame()— specifying itself as the callback function — to sustain the animation.

That's how the game begins. Next I'll show you how to pause it after it's under way.


Pausing the game

HTML5 games — especially video games — must be able to pause. In Listing 4, I've modified Snail Bait's game loop to pause and unpause the game:

Listing 4. Pause and unpause
var SnailBait = function (canvasId) {
   ...
   this.paused = false,
   this.PAUSED_CHECK_INTERVAL = 200; // milliseconds
   ...
};

SnailBait.prototype = {
   animate: function (now) { 
      if (snailBait.paused) {

         // Check again in snailBait.PAUSED_CHECK_INTERVAL milliseconds

         setTimeout( function () {

            requestNextAnimationFrame(snailBait.animate);

         }, snailBait.PAUSED_CHECK_INTERVAL);
      }
      else {

         // The game loop from Listing 1

         snailBait.fps = snailBait.calculateFps(now); 
         snailBait.draw(now);
         requestNextAnimationFrame(snailBait.animate);
      }
   },

   togglePaused: function () {
      this.paused = !this.paused;
   },
};

The togglePaused() method simply toggles the game's paused variable. When that variable is true — meaning the game is paused — the animate() method does not execute the game loop.

It's not necessary — nor is it efficient — to check 60 times per second (assuming a frame rate of 60fps) to see if it's time to resume a paused game; therefore, the animate() method in Listing 4 waits 200ms before invoking the requestNextAnimationFrame() polyfill, which schedules another call to animate() when it's time to draw the next animation frame.

Automatically pausing when the window loses focus

The W3C's Timing control for script-based animations specification says the following about animations implemented with requestAnimationFrame():

If the page is not currently visible, animations on that page can be throttled heavily so that they do not update often and thus consume little CPU power.

The term throttled heavily means that the browser invokes your animation callback at an abysmal frame rate, usually somewhere between 1 and 10fps, as illustrated by Figure 1, which shows a frame rate of 6fps immediately after the window has regained focus:

Figure 1. Snail Bait after losing and regaining focus
Screen shot of Snail Bait after regaining focus

Heavily throttled frame rates can wreak havoc on collision-detection algorithms, which usually determine if collisions have occurred (or will occur), based on frame rate. You can avoid collision-detection meltdowns resulting from heavily throttled frame rates by pausing the game when the game's window loses focus, and restarting it when the window regains focus. You can see how to do that in Listing 5:

Listing 5. Autopause
window.onblur = function () { // window looses focus
   if (!snailBait.paused) {
      snailBait.togglePaused();
   }
};

window.onfocus = function () { // window regains focus
   if (snailBait.paused) {
      snailBait.togglePaused();
   }
};

Not only should you pause the game when your window loses focus, but you should also freeze the game while it's paused.


Freezing the game

Pausing a game involves more than simply halting its animation. Games should resume exactly where they left off. Listing 4 appears to fill that requirement; after all, while the game is paused, nothing happens, so it seems as though the game should resume exactly as it was before it was paused. However, that's not the case, because the primary currency for all animations — Snail Bait's included — is time.

As I discussed in the second article (see its requestAnimationFrame() section), requestAnimationFrame() passes the time to a callback function you specify; in Snail Bait's case, that callback is the animate() method, which in turn passes the time to the draw() method.

Even though the animation does not run when the game is paused, time still marches on unabated. And because Snail Bait's draw() method draws the next animation frame based on the time it receives from animate(), the implementation of togglePaused() in Listing 4 causes the game to lurch ahead in time when the paused game resumes.

Listing 6 shows how Snail Bait avoids an abrupt time shift when a paused game resumes:

Listing 6. Freezing the game
var SnailBait = function (canvasId) {
   ...
   this.paused = false,
   this.pauseStartTime = 0,
   this.totalTimePaused = 0,
   this.lastAnimationFrameTime = 0,
   ...
};

SnailBait.prototype = {
   ...
   calculateFps: function (now) {
      var fps = 1000 / (now - this.lastAnimationFrameTime);
      this.lastAnimationFrameTime = now;
   
      if (now - this.lastFpsUpdateTime > 1000) {
         this.lastFpsUpdateTime = now;
         this.fpsElement.innerHTML = fps.toFixed(0) + 'fps';

      }

      return fps; 
   },

   togglePaused: function () {
      var now = +new Date();

      this.paused = !this.paused;
   
      if (this.paused) {
         this.pauseStartTime = now;
      }
      else {
         this.lastAnimationFrameTime += (now - this.pauseStartTime);
      }
   },
};

In Listing 6, I have modified Snail Bait's togglePaused() and calculateFps() methods to account for the amount of time the game was paused, if any.

To calculate the frame rate for the previous animation frame, I subtract the time when I drew the last frame from the current time and divide 1,000 by that value, which gives me the frame rate in seconds instead of milliseconds. (See the second article's Calculating animation rate in fps section for more about calculating frame rates.)

When the game resumes, I add the amount of time the game was paused to the time of the last animation frame. That addition effectively erases the pause, and the game resumes exactly where it left off when the pause began.


Thawing the game when the window receives focus

When a game resumes, players appreciate a smooth transition back to the action, giving them time to regain the controls. During that time, it's a good idea to provide feedback concerning the amount of time remaining before the game resumes. Snail Bait implements that feedback with a countdown shown in a toast, so I begin this discussion with an overview of toasts.

Toasts

A toast is something that a game temporarily displays to a player, like the Good Luck! toast in Figure 2:

Figure 2. Toasts
Screen shot of the Good Luck! toast in Snail Bait

Like Snail Bait itself, Snail Bait toasts are implemented with a combination of HTML, CSS, and JavaScript, as you can see in the next three listings.

Listing 7 shows the HTML for a toast:

Listing 7. Toasts: HTML
<!DOCTYPE html>
<html>
   <head>
      ...
   </head>

   <body>
      <div id='wrapper'>
         <!-- Toast...................................................-->

         <div id='toast'></div>
         ...
   
      </div>
      ...
  </body>
</html>

The CSS for implementing Snail Bait's Good Luck! toast is in Listing 8:

Listing 8. Toasts: CSS
#toast {
   position: absolute;
   ...

   -webkit-transition: opacity 0.5s;
   -moz-transition: opacity 0.5s;
   -o-transition: opacity 0.5s;
   transition: opacity 0.5s;

   opacity: 0;
   z-index: 1;
   display: none;
}

Listing 9 shows the JavaScript for the Good Luck! toast:

Listing 9. Toasts: JavaScript
var SnailBait =  function () {
   ...
   this.toast = document.getElementById('toast'),
   this.DEFAULT_TOAST_TIME = 3000, // 3 seconds
   ...
};

SnailBait.prototype = {
   ...
   start: function () {
      ...
      snailBait.splashToast('Good Luck!');
   },

   splashToast: function (text, howLong) {
      howLong = howLong || this.DEFAULT_TOAST_TIME;

      toast.style.display = 'block';
      toast.innerHTML = text;

      setTimeout( function (e) {
         toast.style.opacity = 1.0; // After toast is displayed
      }, 50);

      setTimeout( function (e) {
         toast.style.opacity = 0; // Starts CSS3 transition

         setTimeout( function (e) {
            toast.style.display = 'none'; // Just before CSS3 animation concludes
         }, 480);
      }, howLong);
   },
   ...
}

As implemented in the preceding three listings, toasts are just DIVs, as you can see in Listing 7. Things get more interesting in Listing 8, which lists the DIV's CSS. The DIV's position is absolute, meaning it can appear over or under other DIVs instead of before or after them. The toastDIV also has a z-index of 1, which means that it's always displayed above the game's canvas, whose z-index is 0 by default. Finally, the CSS for the toast element defines a 0.5 second transition tied to the opacity property; when that property changes, CSS smoothly animates the DIV from its previous opacity to the new value for 0.5 seconds.

Things get even more interesting in the splashToast() method in Listing 9, which displays a toast for a specified amount of time. When Snail Bait invokes splashToast() with the default display time of 3 seconds, the toast fades in for 0.5 seconds, briefly displays for 2.5 seconds, and then fades out for 0.5 seconds. Here's how it works:

The splashToast() method begins by setting the toastDIV's display attribute to block, which normally would make the DIV visible; however, because its opacity attribute is initially 0, the toastDIV remains invisible. Then splashToast() sets the inner HTML of the toastDIV to the text you pass to the method, but the opacity setting remains, so setting the text doesn't make the DIV visible either.

To make the toastDIV visible, I set its opacity to 1.0. That setting triggers the CSS3 animation resulting from the transition I specified in Listing 8, but only if the opacity setting is made later on (in this case 50ms) as a result of the odd-looking setTimeout() in which it is enclosed. Here's why:

CSS3 transitions can only be specified for properties of elements that have intermediate states. For example, if you change opacity from 0.2 to 0.3 (to pick two random numbers), there are intermediate opacities at 0.21, 0.22, and so on.

It makes sense that transitions require intermediate states; without them, there is no distinct way to specify a transition's animation. That's why you cannot, for example, specify a transition for the display property, which has no intermediate states. Not only that, but if you change the display property, CSS3 will not honor any transitions that you have specified for any other properties. That too makes sense, because you are telling CSS3 to do two things that conflict: make the element immediately visible by changing the display property, but also, for example, slowly fade it into view with a transition on the opacity property. CSS3 can't do both, so it chooses to change the display property.

Translucent DIVs and events

After the preceding discussion about splashToast(), you might wonder why the method bothers to manipulate the toastDIV's display property at all. Why not just manipulate the DIV's opacity to make it visible or invisible? The answer is that unless you explicitly mean to do so, it's not a good idea to have invisible DIVs hanging around, because they are likely to make their presence known in other, surprising ways, such as intercepting events.

Because CSS3 ignores the opacity transition if splashToast() sets the toastDIV's display and opacity properties simultaneously, the method sets the opacity to 1.0 after it sets the display property — more specifically, approximately 50ms later.

Finally, after the required display time has elapsed, splashToast() resets the toastDIV's opacity property to 0, which again triggers a CSS3 animation for 0.5 seconds. Two seconds after initiating the CSS3 animation, the splashToast() method resets the display property to 0.

Thawing Snail Bait

When Snail Bait resumes play after being paused, it gives players time to get ready with a three-second countdown, as shown in Figure 3:

Figure 3. Countdown during thaw
Screen shot of the Snail Bait countdown during thaw

Listing 10 shows the JavaScript for the countdown:

Listing 10. Countdown: JavaScript
var SnailBait = function (canvasId) {
   ...
   this.toast = document.getElementById('toast'),
};


window.onblur = function (e) {  // Pause if unpaused
   if (!snailBait.paused) {
      snailBait.togglePaused();
   }
};

window.onfocus = function (e) {  // unpause if paused
   var originalFont = snailBait.toast.style.fontSize;

   if (snailBait.paused) {
      snailBait.toast.style.font = '128px fantasy';

      snailBait.splashToast('3', 500); // Display 3 for one half second

      setTimeout(function (e) {
         snailBait.splashToast('2', 500); // Display 2 for one half second

         setTimeout(function (e) {
            snailBait.splashToast('1', 500); // Display 1 for one half second

            setTimeout(function (e) {
               snailBait.togglePaused();

               setTimeout(function (e) { // Wait for '1' to disappear
                  snailBait.toast.style.fontSize = originalFont;
               }, 2000);
            }, 1000);
         }, 1000);
      }, 1000);
   }
};

When the Snail Bait window regains focus, it starts the countdown using the splashToast() method. Each numeral fades in for 0.5 seconds and then fades out for 0.5 seconds. Once the countdown reaches zero, the onfocus handler restarts the game.

The code in Listing 10 does not work properly, however, if a player activates another window or tab during the countdown, because the game will restart at the end of the countdown whether the window has focus or not. That's easy enough to fix with a windowHasFocus flag, as shown in Listing 11:

Listing 11. Accounting for lost focus during the countdown
var SnailBait = function (canvasId) {
   ...
   this.windowHasFocus = true,
   ...
};
...

SnailBait.prototype = {
   ...

   splashToast: function (text, howLong) {
      howLong = howLong || this.DEFAULT_TOAST_TIME;

      toast.style.display = 'block';
      toast.innerHTML = text;

      setTimeout( function (e) {
         if (snailBait.windowHasFocus) {
            toast.style.opacity = 1.0; // After toast is displayed
         }
      }, 50);

      setTimeout( function (e) {
         if (snailBait.windowHasFocus) {
            toast.style.opacity = 0; // Starts CSS3 transition
         }

         setTimeout( function (e) { 
            if (snailBait.windowHasFocus) {
               toast.style.display = 'none'; 
            }
         }, 480);
      }, howLong);
   },
   ...
};
...

window.onblur = function (e) {  // pause if unpaused
   snailBait.windowHasFocus = false;
   
   if (!snailBait.paused) {
      snailBait.togglePaused();
   }
};

window.onfocus = function (e) {  // unpause if paused
   var originalFont = snailBait.toast.style.fontSize;

   snailBait.windowHasFocus = true;

   if (snailBait.paused) {
      snailBait.toast.style.font = '128px fantasy';

      snailBait.splashToast('3', 500); // Display 3 for one half second

      setTimeout(function (e) {
         snailBait.splashToast('2', 500); // Display 2 for one half second

         setTimeout(function (e) {
            snailBait.splashToast('1', 500); // Display 1 for one half second

            setTimeout(function (e) {
               if ( snailBait.windowHasFocus) {
                  snailBait.togglePaused();
               }

               setTimeout(function (e) { // Wait for '1' to disappear
                  snailBait.toast.style.fontSize = originalFont;
               }, 2000);
            }, 1000);
         }, 1000);
      }, 1000);
   }
};

Keyboard input

Players use the keyboard to control the runner in Snail Bait, so I'll wrap up this article with a brief discussion of how the game handles keyboard input. The d and k keys move the runner left and right, whereas j and f make her jump and fall, respectively. Figure 4 shows the runner after she's jumped onto the third platform track:

Figure 4. Running after jumping between tracks
Screen shot of the Snail Bait runner after jumping between tracks

You can only add keyboard event listeners to focusable HTML elements. The canvas element is not focusable, so Snail Bait adds an onkeydown event handler to the window object, as shown in Listing 12:

Listing 12. Reacting to keyboard input
var runnerTrack = 1,
    BACKGROUND_VELOCITY = 42;

function turnLeft() {
   bgVelocity = -BACKGROUND_VELOCITY;
}

function turnRight() {
   bgVelocity = BACKGROUND_VELOCITY;
}

window.onkeydown = function (e) {
   var key = e.keyCode;

   if (key === 80 || (paused && key !== 80)) {  // p
      togglePaused();
   }

   if (key === 68 || key === 37) { // d or left arrow
      turnLeft();
   }
   else if (key === 75 || key === 39) { // k or right arrow
      turnRight();
   }
   else if (key === 74) { // j
      if (runnerTrack === 3) {
         return;
      }
      runnerTrack++;
   }
   else if (key === 70) { // f
      if (runnerTrack === 1) {
         return;
      }
      runnerTrack--;
   }
};

It's important to realize that Snail Bait's game loop is constantly running. The animate() function is continuously called by the browser when the browser is ready to draw the next animation frame, and animate(), in turn, continuously calls draw() (listed in Listing 2).

Because the game loop is constantly running, the keyboard event handler simply sets the game's variables. For example, when you press k to move the runner to the right, the event handler sets bgVelocity to BACKGROUND_VELOCITY = 42 (pixels/second), and when you press d to move the runner to the left, the event handler sets bgVelocity to -42 pixels/second. It's not until later on, when the game draws the next animation frame, that those settings take effect.


Next time

In the next article in this series, I'll show you how to turn Snail Bait's inert graphics into animated objects known as sprites. You'll see how to paint sprites several different ways, including painting them from a spritesheet, and you'll see how to incorporate them into Snail Bait's existing code. See you next time.


Download

DescriptionNameSize
Sample codej-html5-game3.zip3.9MB

Resources

Learn

Get products and technologies

  • Replica Island: You can download the source for this popular open source platform video game for Android.

Discuss

  • Get involved in the developerWorks community. Connect with other developerWorks users while exploring the developer-driven blogs, forums, groups, and wikis.

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Java technology on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Java technology, Web development
ArticleID=842841
ArticleTitle=HTML5 2D game development: Setting the stage
publish-date=10302012