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>