Showing posts with label requestAnimationFrame. Show all posts
Showing posts with label requestAnimationFrame. Show all posts

Thursday, November 21, 2013

CSS Detecting Collisions (Game Programming)

One of the foundations for any kind of action game is the ability to detect collisions. Did your spaceship crash into the asteroid or not? How about your fancy race car?



There are three ways that I know of to do this, depending on the technology you are using (CSS, Canvas, or SVG).

The first and definitely the most popular is to calculate if one object's boundaries overlap with another object's boundaries. This is called bounding boxes and is simple, but involves some minor calculation. In the example below, I'm making it simple and only comparing the top left corner of two same-sized square objects. Do they match or not?

Maybe not that exciting, but the example also shows how to move a character automatically and also uses three different timing loops. The stars of this show are:

1. A ball. You've seen it before.



2. A box. He's new. And wants to kill the ball. Don't ask why. Boxes just do that.





3. The ground. This isn't a space game, so we need a patch of ground for the battle to take place:


Maybe not the most exciting, but my philosophy about understanding game programming concepts is to keep it as simple as it can be and still show something. So we've got a ball and a box and they're sitting on the ground.

Here's what the game looks like:


The square tries to kill the poor little ball. But the ball has a secret power. Well, probably not too secret if you read earlier posts. The ball can bounce!


Touch the screen anywhere and the ball will jump up in the air for one second. This makes it a game. You must make the ball jump up just before the box would collide with you. If you fall back down again and the box collides with you, you're dead.

If you don't make it and the box collides with you, an alert is displayed that says "Boom".

So here's the code. It has been tested and run on the ZTE Open with 1.0 Firefox OS.

<!DOCTYPE HTML>
<html>
 
  <head>
    <meta charset="UTF-8">
    <title>
      CSS Collision
    </title>
 
    <style>
        
      #ball
      {
        width: 20px;
        height: 20px;
        position: absolute;
        top: 150px;
        left: 50px;
        background-image: url(ball.png);
      }
      
        #box
      {
        width: 20px;
        height: 20px;
        position: absolute;
        top: 150px;
        left: 270px;
        background-image: url(box.png);
            border-style: solid;
            border-color: black;
            border-width: 1px;
      }

        #ground
      {
        width: 320px;
        height: 230px;
        position: absolute;
        top: 170px;
        left: 0px;
        background-color: chocolate;
      }

    </style>
   
       <div id="ball"></div>
    <div id="box"></div>
      <div id="ground"></div>

    <script type="text/javascript">

      // Global variables    
      var boardWidth = 320;
      var boardHeight = 460;    
      var ballHor = 50;
      var ballVer = 150;     
      var howFast = 3;
        var boxHor = 270;
      var boxVer = 150;
      var loopID;
     
        // requestAnimationFrame browser variations
        var requestAnimationFrame =
          window.requestAnimationFrame ||
          window.mozRequestAnimationFrame ||
          window.webkitRequestAnimationFrame ||
          window.msRequestAnimationFrame; 
       
      var cancelAnimationFrame =
        window.cancelAnimationFrame ||
        window.mozCancelAnimationFrame;
     
        // Load event listener
      window.addEventListener("load", getLoaded, false);
      window.addEventListener(
          "mousedown", ballJump, false);

        // Get box and ball information.
        var myBall = document.querySelector("#ball");
        var myBox = document.querySelector("#box");
        var myGround = document.querySelector("#ground");
     
      // Function called on page load.
      function getLoaded() { 

            // Output to console.
        console.log("The page is loaded.");
       
          // Start game loop.
            gameLoop();              
      }
     
        // Game loop
        function gameLoop() {
       
            // Loop within the loop.
            setTimeout(function() {
       
          loopID = requestAnimationFrame(gameLoop);
         
          // Drawing code goes here
              console.log("Moving the box.");
         
              // Move the box
              moveBox();
         
        }, 1000 / howFast); // Delay / how fast
          }

      // Move the box here.
      function moveBox() {
     
          // Subtract 10 from box horizontal value.
          boxHor = boxHor - 10;
     
          // Move the box 10 pixels left.
          myBox.style.left = boxHor + "px";
       
          // If the box hits the left edge, restart.
          if (boxHor < 10) boxHor = 270;   

          // Report position of box.
          console.log(boxHor);
     
      // Check for collision.
      if ((boxHor == ballHor) && (boxVer == ballVer)) {
         
        // Collision took place!
        alert("Bang");
            
        window.cancelAnimationFrame(loopID);
      }
      }

        // Make the ball jump up.
    function ballJump() {
   
      // Calculate ball jump and move it.
      ballVer = ballVer - 50;
      myBall.style.top = ballVer + "px";
   
      console.log("Ball up.");
   
      // Make the ball fall after one second.
      ballTimer = setTimeout(ballFall, 1000);     
    }
   
    // Make the ball fall down.
    function ballFall() {
   
      // Calculate the ball fall and move it.
      ballVer = ballVer + 50;
      myBall.style.top = ballVer + "px";
   
      console.log("Ball down.");  
    }

    </script>
  </head>
 
  <body>
  </body>

</html>


I'm using the CSS shell that I wrote in this post: http://firefoxosgaming.blogspot.com/2013/11/css-shell-game-programming.html. The shell just provides the basic HTML5 structure, has a initial function that runs when the page loads, has a game loop, and then other functions that do specific things.

Style

Because this is CSS, I have an inline style that defines the properties of a ball, a box, and the ground. The ball is the same as what you've seen before. The box is just a square of color. I didn't like the way the box looked with just color, so I modified it in the style to have a black outline one pixel thick. The ball and the box were created in an art editor (Paint Shop Pro) and saved as PNG files. For the background, I decided to save room and just had it be a separate div with a background color (chocolate). This shows that there are three ways to make a graphic: import, import with modification, and fill a div with color.

To make these styles work, I had to create a separate div for each one, assign it a style, and then use querySelector to grab it and assign it a variable name. After that, I have three objects I can play with. The ground is just decoration and doesn't serve any programming purpose.

Game Loop

The game loop is called by the page load function. The game loop is interesting and uses two different timers to make sure that the box moves in regular steps as it marches across the screen.

The outer loop uses setTimeout to do something at regular intervals. In this case the interval is 1000 milliseconds (one second) divided by the howFast variable. In this case, howFast is 3, but you could use different values to make a game easier or harder. In this example, the "something" you do every 1/3 of a second is to move the box.

So, every 1/3 of a second, requestAnimationFrame is used to start the main loop over again, but also makes a call to actually draw the box (in a separate function, moveBox). Using requestAnimationFrame here makes sure that the drawing is done right away and helps with battery life. Whenever possible, use this for animations, especially repetitive ones like moving the box one step at a time.

Moving the Box

The box moves every 1/3 of a second. As it moves, it checks for two things:

1. Did I hit the left wall? If I did, move back to my initial position and try again.

2. Did I collide with the ball? If I did, then display an alert.

Step 2 is a bit tricky. You want to test for matching the top left corner of each object, and see if they both match. If they do, you've got a collision. The test is for this:

          ((boxHor == ballHor) && (boxVer == ballVer))

This line tests for three things:

  1. Does the horizontal (left) point of both box and ball match?
  2. Does the vertical (top) point of both box and ball match?
  3. Are both of these true?
The && is a symbol that means both of these things are true, and the placement of parentheses is important so you know what you're comparing and that they fit into the if statement.

Collision Test

If the top left of both match, we have a collision. Where things are moving in different directions or are of different sizes, you might figure out what the bounding box would be of each object and then compare them. A bounding box is an imaginary square that encloses the part of the object you want to test for. Maybe you only care about the center of your spaceship and so you have a small bounding box. The point is that you care and then by subtraction, you see if the two boxes overlap. Here because I kept the movement and size simple, you're only caring about the top left corner of each object, and the moving object is moving at a regular pace that will always match the position of the ball in its steady march of 10 pixels left every 1/3 of a second.

Bouncing Balls

You knew we had to have a bouncing ball somewhere. What makes a game is the choice the player makes to avoid or capture or destroy the enemy. Because this is a phone game, you make the ball jump up by tapping the screen anywhere. The easy way to do this is by using the mousedown event, which gets translated to a touch by Firefox OS. Don't use click, which requires the mouse to go down and then up.

If you touch the screen and fire the mousedown event, the ballJump function is called. This will draw the ball 50 pixels above where it was (don't forget that you're measuring pixels from the top left corner of the screen, so up is smaller numbers and down is larger numbers).

setTimeout (a different timer than the setTimeout one in the game loop) is called that will run for one second (1000 milliseconds). After the second has passed, the ballFall function is called. This simply changes the ball position 50 pixels below where it was (by adding 50 to it -- up is down, down is up).

Timers

This example uses three timers:

1. The first is the 1/3 second delay every time the game loop is processed. Slow.

2. The second is the call using requestAnimationFrame, which draws the box as fast as the browser can, but is more efficient than setTimeout. Fast.

3. The third is the one-second delay that the ball spends hanging in air before it falls back down. Slow.

The first and third use setTimeout, which is okay because you don't need precision timing or power efficiency. The second uses requestAnimationFrame because anything that uses repetitive drawing (like marching across the screen) will do well here. Of course this example is pretty simple, but as you move on to more complex animations, this kind of looping will be very useful. Slow timing is fine for setTimeout, but requestAnimationFrame is better for fast and efficient motion.

There is a great article about using both of these timing methods (and more) at http://creativejs.com/resources/requestanimationframe/
 
requestAnimationFrame and close

I thought it would be nice to stop the game when the collision took place. But I found that there is some kind of problem with using cancelAnimationFrame. I coujldn't get it to work. This function is supposed to stop the animation frame loop (which is used to reset the game loop). It works just fine in Firefox browser, but does NOT work on the ZTE.

The above code that I used for this was straight from the MDN https://developer.mozilla.org/en-US/docs/Web/API/window.cancelAnimationFrame page.  I might be doing something wrong or I left out a semicolon. All I can say is that I copy and pasted this from this page, which should allow either cancelAnimationFrame or mozCancelAnimationFrame, and does work in the big browser (go Aurora!) but doesn't work on my poor old ZTE Open stuck at Firefox OS 1.0. If someone wants to tell me what is supposed to work when, I'll be happy to post the changes needed to make this work.

I also thought that well, if I can't kill the animation timer, maybe I can just close the window. It turns out that Firefox doesn't support window.close() unless you opened that window yourself. Probably a good idea. But I would like to find a way to shut down an app. Where's that task manager when you need it?

But the principles of the rest of the code are just fine and having the marching repeat endlessly can be considered a feature, not a bug. (Ha ha!)

You can apply this type of collision testing to any of the three technologies (CSS, Canvas, and SVG). Decide on your bounding box coordinates and test for boundary overlaps.

But there is ... another. In fact, two others. One for Canvas and the other for SVG. I'll do the Canvas thing next and then SVG.

WebGL

Note: when I started this series, the three technologies of CSS, Canvas, and SVG were all that seemed currently useful. It now looks like some serious WebGL technologies are ready for prime time. In the last few days there have been two cool advances in WebGL.

WebGL is a technology that takes the core of OpenGL and applies it to web programming to create cool visual effects. OpenGL is used by most 3D game programmers but was claimed by Microsoft to be evil (because DirectX was better). Then, in a move that surprised a lot of folks, Microsoft included WebGL in Internet Explorer 11. Maybe not as good as Firefox's WebGL, but at least they're not saying it is evil any longer.  So, like SVG, once Microsoft says it is okay, the rest of the world can jump in and play.

The first news about WebGL is that Firefox now has a cool way to debug and edit WebGL in the browser itself. Check out this post: https://hacks.mozilla.org/2013/11/live-editing-webgl-shaders-with-firefox-developer-tools/. WebGL (or any 3D graphics) isn't easy to understand, but I'll be curious to see people using it on Firefox OS.

The second bit of news about WebGL is that Sony is using WebGL for their user interface for the Playstation 4 for the store, music player, and other junk. See this post by one of the developers (a very smart guy) https://plus.google.com/+DonOlmstead/posts/Mzy6VEAwHaa. I can't wait to see it (oh, wait, I don't have a Playstation 4. But I'm too busy playing Firefox OS games to care).

WebGL sits on top of Canvas, so maybe when I finish writing about all the useful aspects of 2D games written in CSS, Canvas, or SVG, I'll start tackling WebGL. I have done some programming in DirectX and OpenGL (and even a little WebGL), but I like 2D programming better.

Stay tuned, but not iTuned!

Monday, November 18, 2013

CSS Shell (Game Programming)

I went back and revised the shell that I am going to use for Firefox OS CSS programming. Some of it is the same, but I added the following:

requestAnimationFrame

Instead of using this timer:

        gameLoop = setInterval(ballMove, 16);

I'm using requestAnimationFrame with a shim:

      // requestAnimationFrame browser variations
      var requestAnimationFrame =
      window.requestAnimationFrame ||
      window.mozRequestAnimationFrame ||
      window.webkitRequestAnimationFrame ||
      window.msRequestAnimationFrame; 


This makes for smoother animation and better battery life. Basically you're letting Firefox OS decide how fast the loop will repeat. And if you're running this in webkit or IE9, it will also work.

To use requestAnimationFrame, simply put it in the endless loop you want to use for your game loop. This will allow the loop to repeat, making things happen on a timely basis. Just put this in your loop and call the loop once:

      requestAnimationFrame(gameLoop);

The other major change is to create an event handler for page loading. The onXXX functions still work, but using event handlers is easier to use, debug, and cancel. So instead of:

      <body onload="playBall()">

Use this:

      window.addEventListener("load", getLoaded, false);

I like to have a standardized starting set of code which I call a shell. I'll be posting them as I go through a series of coding for collision testing for CSS, Canvas, and SVG.

Below is the code for the whole page. By the way, this was fun to run in Firefox OS and watch the Inspector display the coordinates of the ball in the DOM. Even though no code seems to run in the body, when the code runs, the Inspector shows you the rapidly changing:

      <div id="ball" style="left: 150px; top: 400px;"></div>

Find that in Web Developer -> Inspector. Also cool is that when in the Inspector mode, a little caption follows the ball around telling you that this is div#ball.


I'm starting to explore the new Firefox tools and how they work for debugging. Lots to learn.

So here's the code for my CSS Shell, as usual, tested and run in the little-but-loud ZTE Open, running Firefox OS 1.01.

<!DOCTYPE HTML>
<html>
 
  <head>
    <meta charset="UTF-8">
    <title>
      CSS Collision
    </title>
 
    <style>
        
      #ball
      {
        width: 20px;
        height: 20px;
        position: absolute;
        top: 200px;
        left: 100px;
        background-image: url(ball.png);
       }

    </style>
   
       <div id="ball"></div>    

    <script type="text/javascript">

    // Global variables    
      var boardWidth = 320;
      var boardHeight = 460;    
      var ballHor = boardWidth / 2;
      var ballVer = boardHeight /2;     
      var changeHor = 10;
      var changeVer = 10;
     
      // requestAnimationFrame browser variations
      var requestAnimationFrame =
      window.requestAnimationFrame ||
      window.mozRequestAnimationFrame ||
      window.webkitRequestAnimationFrame ||
      window.msRequestAnimationFrame; 
     
      // Load event listener
      window.addEventListener("load", getLoaded, false);

      // Get ball information.
      var myBall = document.querySelector("#ball");
     
      // Function called on page load.
      function getLoaded() { 

        // requestAnimationFrame for game loop
        requestAnimationFrame(gameLoop);
       
        // Output to debugger.
        console.log("The page is loaded.");
        }
     
      // Game loop
      function gameLoop() {
     
        // Repeat game loop infinitely.
        requestAnimationFrame(gameLoop);
     
        // Move the ball once.
        ballMove();       
        }
     

      // Calculate and move the ball.  
      function ballMove() {
     
        // Changes are calculated but do not
        // take effect until next time through loop.      
        myBall.style.left = ballHor + "px";
        myBall.style.top = ballVer + "px";
         
        // Calculate new vertical component.
        ballVer = ballVer + changeVer;

        // Top hit, reverse direction.
        if (ballVer + changeVer < -10)
          changeVer = -changeVer;
       
        // Bottom hit, reverse direction.
        if (ballVer + changeVer > boardHeight - 10)
          changeVer = -changeVer;

        // Calculate new horizontal component.
        ballHor = ballHor + changeHor;

        // Left edge hit, reverse direction.
        if (ballHor + changeHor < -10)
          changeHor = -changeHor;
       
        // Right edge hit, reverse direction.
        if (ballHor + changeHor > boardWidth - 10)
          changeHor = -changeHor;
        }

    </script>
  </head>
 
  <body>
  </body>

</html>


Monday, November 4, 2013

Canvas, Bitmaps, and requestAnimationFrame (Game Programming)

After two recent posts showing how to use canvas arc drawing to create a ball and bounce it (here and here) I'm ready to talk about the more popular technique of copying bitmaps to the canvas. I hope you're not getting sick of bouncing balls!


 
Using Canvas shapes is somewhat difficult because there aren't yet powerful editors that can let you create Canvas shapes and paths. There are some intermediate plugins that will converts an Illustrator drawing to Canvas, but I'm not sure how good they are.

But there are a zillion editors that can create a bitmap that can be copied to a canvas. Instead of drawing a ball with something like the arc method, I'll copy a bitmap drawing of a ball to the canvas and then bounce it around.

By some coincidence, I happen to have a bitmap drawing of a ball left over from my post on using CSS to bounce a ball. In case you've forgotten, here is the bitmap of the ball:

Impressive! This is a 20x20pixel bitmap of a ball with transparent bits around it. You're really looking at a square, but you see only the round part.

Here's the code:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>
      Canvas Bounce BitMap w/requestAnimationFrame
    </title>
 
    <script>

    // Global variables
    var canvas;
    var ctx;
    var myImage = new Image();
    var boardWidth = 320;
    var boardHeight = 460;
      var ballHor = boardWidth / 2;
    var ballVer = boardHeight /2;
    var changeHor = 10;
    var changeVer = 10;
   
      // Covers all bases for various browser support.
      var requestAnimationFrame =
      window.requestAnimationFrame ||
      window.mozRequestAnimationFrame ||
      window.webkitRequestAnimationFrame ||
      window.msRequestAnimationFrame; 

    // Event listener
    window.addEventListener("load", getLoaded, false);

    // Run this when the page loads.
    function getLoaded(){

      // Make sure we are loaded.
      console.log("Page loaded!");
 
      // Load the image and the canvas.
      loadMyImage();

      // Start the main loop.
      doMainLoop();
    }

    // Runs to the beat of requestAnimationFrame.
    function doMainLoop(){

      // Loop the loop for the canvas.
      requestAnimationFrame(doMainLoop);
 
      // Clear the canvas.
      ctx.clearRect(0,0,320,460);
 
      ballMove(); 
    }

    // Calculate new ball position.
    function ballMove() {
     
      // Changes are calculated but do not
      // take effect until next time through loop.
         
      // Calculate new vertical component.
      ballVer = ballVer + changeVer;

      // If top is hit, change direction.
      if (ballVer + changeVer < -10)
        changeVer = -changeVer;
       
      // If bottom is hit, reverse direction.
      if (ballVer + changeVer > boardHeight - 10)
        changeVer = -changeVer;

      // Calculate new horizontal component.
      ballHor = ballHor + changeHor;

      // If left edge hit, reverse direction.
      if (ballHor + changeHor < -10)
        changeHor = -changeHor;
       
      // If right edge is hit, do something.
      if (ballHor + changeHor > boardWidth - 10)
        changeHor = -changeHor;
       
      // Draw the ball with new coordinates.
      ctx.drawImage(myImage, 0, 0, 20, 20,
          ballHor, ballVer, 20, 20);             
    }

    // Load the image and the canvas.
    function loadMyImage() {

      // Get the canvas element.
      canvas = document.getElementById("myCanvas");

      // Make sure you got it.
      if (canvas.getContext) {

        // Specify 2d canvas type.
        ctx = canvas.getContext("2d");

        // When the image is loaded, draw it.
        myImage.onload = function() {

          // Did the image get loaded?
          console.log("The image was loaded.");
        }

        // Define the source of the image.
        myImage.src = "ball.png";
      }
    }

</script>

</head>
<body>

  <canvas id="myCanvas" width="320" height="460">
  </canvas>

</body>
</html>


Most of the code is the same as CSS and Canvas code I've already written about. Here are the main differences:
  1. Using requestAnimationFrame instead of setInterval.
  2. Using drawImage instead of arc.
  3. Using the HTML DOM Image object.
requestAnimationFrame

You may be asking yourself, why use this when you have good old setInterval? Well, the short answer is that instead of you setting the timing of the animation with setInterval, you can let the browser decide. This is especially important because the browser can make sure that the animation is making the most efficient use of the battery, and Firefox OS phones use batteries (so does everything else, practically).

This is a more recent addition to web programming, and is mostly adopted. While the details were being figured out in the W3C committee, browser manufactures started to adopt requestAnimationFrame, but they would prefix it. So Firefox had moxRequestAnimationFrame instead of requestAnimationFrame.  Robert Helmer pointed out t me that I should use requestAnimationFrame and Panagiotis Astithas explained to me why Firefox OS 1.0 and 1.1 don't work with requestAnimationFrame:
Firefox 18, which only supported the moz-prefixed version. Firefox OS 1.2 is based off Firefox 26 and will support the unprefixed version.
And here is how to handle this in your code. First, create a new definition for requestAnimationFrame (I'm basing this on the Mozilla documentation for requestAnimationFrame).

var requestAnimationFrame =
      window.requestAnimationFrame ||
      window.mozRequestAnimationFrame ||
      window.webkitRequestAnimationFrame ||
      window.msRequestAnimationFrame; 
This covers webkit, Mozilla, and old IE browsers before IE9.

Next, instead of using setInterval, put this line in your game loop:

     requestAnimationFrame(doMainLoop);

This will call the main loop as quickly as the browser decides is correct. Typically this will be 60 frames per second, but it may vary. The point is that it will do the best thing for your animation and your battery life.

drawImage

This is a handy method on the canvas context (ctx). It might seem complicated (with 9 parameters), but it's really easy. Here's the code:

      ctx.drawImage(myImage, 0, 0, 20, 20,
          ballHor, ballVer, 20, 20);


I'll talk about myImage in a minute, but it hold the image you want to copy to the canvas. After the image, the next four numbers define the portion of the bitmap you want to copy from. The first two numbers are 0,0 and they represent the upper left-hand corner of the bitmap. The next two are 20,20 and they represent the lower right-hand corner of the image. One cool feature of this method is that you can take part of a bitmap and copy it, letting you have all your images in one big bitmap (saving loading time).

Next comes the place on canvas you want to copy the image to. ballHor and ballVer represent the upper left-hand corner of the current position of the ball, and 20,20 are lower right-hand corner. Again, you don't need to have the save size or ratio when you copy, allowing cool effects.

The drawing takes place every time through the loop, but in this example, the canvas is erased before each drawing. You could also erase where the ball was by copying a blank bitmap, and you don't need to worry about aliasing (which was a problem in the second canvas arc example if you didn't erase the whole canvas, but just the part you wanted to remove), because the edges are straight.

Using the HTML DOM Image object

I find it convenient to do all my image loading at the same time, and I like to make sure that both my image and my canvas context loaded properly, so you'll see that in the code for loadMyImage. There may be other ways to do this, but I find it works best when I define an HTML DOM image object and copy the bitmap into that.

Here's how you do it:

    var myImage = new Image();

As you may know, one of the important concept in web programming is the DOM (Document Object Model). That defines a set of objects that can be modified by JavaScript. Image is an object that you can use. One of the things that is fun about web programming is the different way things are named. When you create an <img> tag, you are creating an Image object. And to write effective HTML5 games, you need to understand HTML5, JavaScript, CSS, and the DOM.

Sometimes the DOM is documented in ways that are a little confusing. For example, MDN has a very useful page on using the Image object, but it is called the HTMLImageElement. The difference between elements and objects are fun. They are really the same thing, but they change their names depending on what country (HTML or DOM) they are in. HTMLImageElement is the Image object is the <img> tag. Note that I could have created a new empty image with

    document.createElement('img');

Sorting out when to use an element and when to use an object is definitely mind-boggling, but when you start using JavaScript in really cool ways, objects will be your best friends forever.

So there's a 4-step process for images:
  1. Define a blank object with the new Image() method.
  2. Make sure that blank image was created (using myImage.onload).
  3. Define the source of the image (myImage.src).
  4. Use the image in drawImage.
Follow these steps and your canvas images will always work. The reason you need to check is that sometimes bits of the browser load before other bits, so you always want to make sure:
  1. The page is loaded.
  2. The canvas context is loaded.
  3. The image container is loaded.
Whew!

So I've covered a few ways to use Canvas to draw a bouncing ball. There are advanced techniques that I'll be covering later, such as flipping two canvas back and forth, and using different canvases for layers. But this post covers the bread and butter of mangling canvases.

And don't forget to use requestAnimationFrame. You'll want to use the code that permits use of requestAnimationFrame or mozRequestAnimationFrame because early Firefox OS phones may not be upgraded to Firefox OS 1.2. Mine isn't, and won't be until I hear widespread reports that it is safe to upgrade my ZTE Open phone. I'll probably buy a different Firefox OS phone before then. That LG model looks nice, but maybe Asus will make a phone soon!

So far I am liking CSS bouncing balls more than Canvas bouncing balls. Canvas requires cleanup and CSS doesn't. Now it's possible that Canvas has better hardware acceleration on the Firefox OS phone, but no one has told me that, and all browsers have gotten pretty good at making CSS efficient.

But why stop with CSS and Canvas for creating games? There's a third, mysterious graphics technology called SVG (Scalable Vector Graphics) that is really cool and well-supported in Firefox and all other browsers. Next time I write about game programming, I'll explain the mystery and how to make SVG fly. Not only that, but I'll show you three different ways (in three posts) to use SVG and introduce you to an even more shadowy figure, the SVG DOM!

But first some game reviews and then on to ... touch! And lots more. There's so much to write about, and Firefox OS is the place to be for games and game programming.