You are previewing HTML5 Canvas.

HTML5 Canvas

Cover of HTML5 Canvas by Steve Fulton... Published by O'Reilly Media, Inc.
  1. HTML5 Canvas
    1. SPECIAL OFFER: Upgrade this ebook with O’Reilly
    2. A Note Regarding Supplemental Files
    3. Preface
      1. Running the Examples in the Book
      2. What You Need to Know
      3. How This Book Is Organized
      4. Conventions Used in This Book
      5. Using Code Examples
      6. We’d Like to Hear from You
      7. Safari® Books Online
      8. Acknowledgments
    4. 1. Introduction to HTML5 Canvas
      1. The Basic HTML Page
      2. Basic HTML We Will Use in This Book
      3. The Document Object Model (DOM) and Canvas
      4. JavaScript and Canvas
      5. HTML5 Canvas “Hello World!”
      6. Debugging with Console.log
      7. The 2D Context and the Current State
      8. The HTML5 Canvas Object
      9. Another Example: Guess The Letter
      10. What’s Next
    5. 2. Drawing on the Canvas
      1. The Basic File Setup for This Chapter
      2. The Basic Rectangle Shape
      3. The Canvas State
      4. Using Paths to Create Lines
      5. Advanced Path Methods
      6. Compositing on the Canvas
      7. Simple Canvas Transformations
      8. Filling Objects with Colors and Gradients
      9. Filling Shapes with Patterns
      10. Creating Shadows on Canvas Shapes
      11. What’s Next
    6. 3. The HTML5 Canvas Text API
      1. Displaying Basic Text
      2. Setting the Text Font
      3. Text and the Canvas Context
      4. Text with Gradients and Patterns
      5. Width, Height, Scale, and toDataURL() Revisited
      6. Final Version of Text Arranger
      7. What’s Next
    7. 4. Images on the Canvas
      1. The Basic File Setup for This Chapter
      2. Image Basics
      3. Simple Cell-Based Sprite Animation
      4. Advanced Cell-Based Animation
      5. Applying Rotation Transformations to an Image
      6. Creating a Grid of Tiles
      7. Zooming and Panning an Image
      8. Pixel Manipulation
      9. Copying from One Canvas to Another
      10. What’s Next
    8. 5. Math, Physics, and Animation
      1. Moving in a Straight Line
      2. Bouncing Off Walls
      3. Curve and Circular Movement
      4. Simple Gravity, Elasticity, and Friction
      5. Easing
      6. What’s Next?
    9. 6. Mixing HTML5 Video and Canvas
      1. HTML5 Video Support
      2. Converting Video Formats
      3. Basic HTML5 Video Implementation
      4. Preloading Video in JavaScript
      5. Video and the Canvas
      6. Video on the Canvas Examples
      7. Animation Revisited: Moving Videos
      8. What’s Next?
    10. 7. Working with Audio
      1. The Basic <audio> Tag
      2. Audio Formats
      3. Audio Tag Properties, Functions, and Events
      4. Playing a Sound with No Audio Tag
      5. Creating a Canvas Audio Player
      6. Case Study in Audio: Space Raiders Game
      7. What’s Next
    11. 8. Canvas Game Essentials
      1. Why Games in HTML5?
      2. Our Basic Game HTML5 File
      3. Our Game’s Design
      4. Game Graphics: Drawing with Paths
      5. Animating on the Canvas
      6. Applying Transformations to Game Graphics
      7. Game Graphic Transformations
      8. Game Object Physics and Animation
      9. A Basic Game Framework
      10. Putting It All Together
      11. The player Object
      12. Geo Blaster Game Algorithms
      13. The Geo Blaster Basic Full Source
      14. Rock Object Prototype
      15. What’s Next
    12. 9. Combining Bitmaps and Sound
      1. Geo Blaster Extended
      2. Creating a Dynamic Tile Sheet at Runtime
      3. A Simple Tile-Based Game
      4. What’s Next
    13. 10. Mobilizing Games with PhoneGap
      1. Going Mobile!
      2. Creating the iOS Application with PhoneGap
      3. Beyond the Canvas
      4. What’s Next
    14. 11. Further Explorations
      1. 3D with WebGL
      2. Multiplayer Applications with ElectroServer 5
      3. Conclusion
    15. Index
    16. About the Authors
    17. Colophon
    18. SPECIAL OFFER: Upgrade this ebook with O’Reilly

Game Object Physics and Animation

All of our game objects will move on a two-dimensional plane. We will use basic directional movement vectors to calculate the change in the x and y coordinates for each game object. At its very basic level, we will be updating the delta x (dx) and delta y (dy) of each of our game objects on each frame to simulate movement. These dx and dy values will be based on the angle and direction in which we want the object to move. All of our logical display objects will add their respective dx and dy values to their x and y values on each frame of animation. The player ship will not use strict dx and dy because it needs to be able to float and turn independently. Let’s take a closer look at the player movement now.

How Our Player Ship Will Move

Our player ship will change its angle of center axis rotation when the game player presses the left and right arrow keys. When the game player presses the up arrow key, the player ship will accelerate (thrust) in the angle it is facing. Because there is no friction applied to the ship, it will continue to float in the current accelerated angle until a different angle of acceleration is applied. This happens when the game player rotates to a new angle and presses the up (thrust) key once again.

The difference between facing and moving

Our player ship can rotate to the direction it is facing while it is moving in a different direction. For this reason, we cannot simply use classic dx and dy values to represent the movement vector on the x and y axes. We must keep both sets of values for the ship at all times. When the player rotates the ship but does not thrust it, we need to draw the ship in the new rotated angle. All missile projectiles the ship fires must also move in the direction the ship is facing. On the x-axis, we will name this value facingX; on the y-axis, it’s facingY. movingX and movingY values will handle moving the ship in the direction it was pointed in when the thrust was applied. All four values are needed to thrust the ship in a new direction. Let’s take a look at this next.

Thrusting in the rotated direction

Once the ship is rotated to the desired direction, the player can thrust it forward by pressing the up arrow key. This thrust will accelerate the player ship only while the key is pressed. Since we know the rotation of the ship, we can easily calculate the angle of the rotation. We will then add new movingX and movingY values to the ship’s x and y attributes to move it forward.

First, we must change the rotation value from degrees to radians:

var angleInRadians = rotation * Math.PI / 180;

You have seen this before—it’s identical to how we calculated the rotation transformation before it was applied to the player ship.

Once we have the angle of the ship’s rotation, we must calculate the facingX and facingY values for this current direction. We only do this when we are going to thrust because it is an expensive calculation, processor-wise. We could calculate these each time the player changes the ship’s rotation, but doing so would add unnecessary processor overhead:

facingX = Math.cos(angleInRadians);
facingY = Math.sin(angleInRadians);

Once we have values on the x and y axes that represent the direction the player ship is currently facing, we can calculate the new movingX and movingY values for the player:

movingX = movingX+thrustAcceleration*facingX;
movingY = movingY+thrustAcceleration*facingY;

To apply these new values to the player ship’s current position, we need to add them to its current x and y positions. This does not occur only when the player presses the up key. If it did, the player ship would not float; it would only move when the key was pressed. We must modify the x and y values on each frame with the movingX and movingY values:

x = x+movingX;
y = y+movingY;

Redrawing the player ship to start at angle 0

As you may recall, when we first drew the image for our player ship, we had the point end (the top) of the ship pointing up. We did this for ease of drawing, but it’s not really the best direction in which to draw our ship when we intend to apply calculations for rotational thrust. The pointing-up direction is actually the -90 (or 270) degree angle. If we want to leave everything the way it currently is, we will need to modify the angleInRadians calculation to look like this:

var angleInRadians = (Math.PI * (player.rotation -90 ))/ 180;

This is some ugly code, but it works fine if we want our player ship to be pointing up before we apply rotation transformations. A better method is to keep the current angleInRadians calculation but draw the ship pointing in the actual angle 0 direction (to the right). Figure 8-5 shows how we would draw this.

The player ship drawn at the 0 degree rotation

Figure 8-5. The player ship drawn at the 0 degree rotation

The drawing code for this direction would be modified to look like this:

//facing right

Controlling the Player Ship with the Keyboard

We will add in two keyboard events and an array object to hold the state of each key press. This will allow the player to hold down a key and have it repeat without a pause. Arcade games require this type of key-press response.

The array to hold our key presses

An array will hold the true or false value for each keyCode associated with key events. The keyCode will be the index of the array that will receive the true or false value:

var keyPressList = [];

The key events

We will use separate events for both key down and key up. The key down event will put a true value in the keyPressList array at the index associated with the event’s keyCode. Conversely, the key up event will place a false in that array index:

document.onkeydown = function(e){

      //ConsoleLog.log(e.keyCode + "down");
      keyPressList[e.keyCode] = true;

   document.onkeyup = function(e){
      e = e?e:window.event;
      //ConsoleLog.log(e.keyCode + "up");
      keyPressList[e.keyCode] = false;

Evaluating key presses

Our game will need to include code to look for true (or false) values in the keyPressList array, and use those values to apply game logic:

if (keyPressList[38]==true){
   var angleInRadians = player.rotation * Math.PI / 180;
   facingX = Math.cos(angleInRadians);
   facingY = Math.sin(angleInRadians);

   movingX = movingX+thurstAcceleration*facingX;
   movingY = movingY+thurstAcceleration*facingY;

if (keyPressList[37]==true) {
   //rotate counterclockwise

if (keyPressList[39]==true) {
   //rotate clockwise

Let’s add this code to our current set of rotation examples and test it out. We have made some major changes, so Example 8-8 presents the entire HTML file once again.

Example 8-8. Controlling the player ship

<!doctype html>
<html lang="en">
<meta charset="UTF-8">
<title>CH8EX8: Ship Turn With Keys</title>
<script type="text/javascript">
window.addEventListener('load', eventWindowLoaded, false);
function eventWindowLoaded() {



function canvasApp(){

   var theCanvas = document.getElementById("canvas");
   if (!theCanvas || !theCanvas.getContext) {

   var context = theCanvas.getContext("2d");

   if (!context) {

   //canvasApp level variables

   var rotation = 0;
   var x = 50;
   var y = 50;
   var facingX = 0;
   var facingY = 0;
   var movingX = 0;
   var movingY = 0;
   var width = 20;
   var height = 20;
   var rotationalVelocity = 5; //how many degrees to turn the ship
   var thrustAcceleration = .03;
   var keyPressList = [];
   function drawScreen() {

   //check keys

   if (keyPressList[38]==true){
       var angleInRadians = rotation * Math.PI / 180;
       facingX = Math.cos(angleInRadians);
       facingY = Math.sin(angleInRadians);

       movingX = movingX+thrustAcceleration*facingX;
       movingY = movingY+thrustAcceleration*facingY;


   if (keyPressList[37]==true) {
       //rotate counterclockwise
       rotation −= rotationalVelocity;

   if (keyPressList[39]==true) {
       //rotate clockwise
       rotation += rotationalVelocity;;

   x = x+movingX;
   y = y+movingY;

   // draw background and text
   context.fillStyle = '#000000';
   context.fillRect(0, 0, 200, 200);
   context.fillStyle = '#ffffff';
   context.font = '20px _sans';
   context.textBaseline = 'top';
   context.fillText  ("Player Ship - key turn", 0, 180);

   var angleInRadians = rotation * Math.PI / 180;; //save current state in stack
   context.setTransform(1,0,0,1,0,0); // reset to identity

   //translate the canvas origin to the center of the player


   context.strokeStyle = '#ffffff';

   //hardcoding in locations
   //facing right


   //restore context
   context.restore(); //pop old state on to screen

   const FRAME_RATE = 40;
   var intervalTime = 1000/FRAME_RATE;
   setInterval(drawScreen, intervalTime );

   document.onkeydown = function(e){
      e = e?e:window.event;
      //ConsoleLog.log(e.keyCode + "down");
      keyPressList[e.keyCode] = true;

   document.onkeyup = function(e){
      //document.body.onkeyup = function(e){
      e = e?e:window.event;
      //ConsoleLog.log(e.keyCode + "up");
      keyPressList[e.keyCode] = false;


<div style="position: absolute; top: 50px; left: 50px;">
<canvas id="canvas" width="200" height="200">
 Your browser does not support HTML5 Canvas.

Once this file is run in a browser, you should be able to press the left and right keys to rotate the ship on its center axis. If you press the up key, the ship will move in the direction it is facing.

Giving the Player Ship a Maximum Velocity

If you play with the code in Example 8-8, you will notice two problems:

  1. The ship can go off the sides of the screen and get lost.

  2. The ship has no maximum speed.

We’ll resolve the first issue when we start to code the complete game, but for now, let’s look at how to apply a maximum velocity to our current movement code. Suppose we give our player ship a maximum acceleration of 2 pixels per frame. It’s easy to calculate the current velocity if we are only moving in the four primary directions: up, down, right, left. When we are moving left or right, the movingY value will always be 0. If we are moving up or down, the movingX value will always be 0. The current velocity we are moving on one axis would be easy to compare to the maximum velocity.

But in our game, we are almost always moving in the x and y directions at the same time. To calculate the current velocity and compare it to a maximum velocity, we must use a bit more math.

First, let’s assume that we will add a maximum velocity variable to our game:

var maxVelocity = 2;

Next, we must make sure to calculate and compare the maxVelocity to the current velocity before we calculate the new movingX and movingY values. We will do this with local variables used to store the new values for movingX and movingY before they are applied:

var movingXNew = movingX+thrustAcceleration*facingX;
var movingYNew = movingY+thrustAcceleration*facingY;

The current velocity of our ship is the square root of movingXNew^2 + movingYNew^2:

var currentVelocity = Math.sqrt ((movingXNew*movingXNew) + (movingXNew*movingXNew));

If the currentVelocity is less than the maxVelocity, we set the movingX and movingY values:

if (currentVelocity < maxVelocity) {
   movingX = movingXNew;
   movingY = movingYNew;

The best content for your career. Discover unlimited learning on demand for around $1/day.