Pages

Tuesday, November 26, 2013

Jumping Marcelo (Game Review)

This is a cool game done by cool people. There, my review is done, you can go home now.

Actually this game really is flawless and beyond what I would expect. But it's not exactly a surprise, because this game is from Double Duck, who already has done something cool with Age of Barbarians. Marcello is a jumping monkey, but he jumps in a fascinating way. And the graphics and all the navigation is just flawless and fun.

Even the opening is fun. When you start out, the first thing you see is the Double Duck logo, very nice:


Having a classy logo helps, and what could be better than a rubber duck riding on a real duck?

Next you see a banana!


A monkey is holding a banana. But the camera pulls back and ...


There is the moon, in the shape of the banana. What is the monkey thinking?


He's looking up a the moon and thinking bananas. This sets a feeling like a movie. You now have some identification with the monkey and you are wondering what the monkey is going to do. The screen says Tap to Play.



The next screen gives you several choices. You can mute the sound, get Help with the game, or go to the store. Or Play!

Here's what the Help screen looks like:


It tells you everything you need to know. Climb up by tapping.  And there's that moon again. I think the monkey wants to go there. Maybe he thinks it is a banana! My last post made a sly reference to the bunny in the moon, and now we have banana in the moon (or rather, the banana is the moon).'

Let's play!


The play is very simple, but works. You tap on the screen and the monkey jumps to the other side of the screen. The screen is constantly scrolling down, forcing the monkey to keep climbing. As he climbs, he can grab bananas.

And those bananas aren't just good to eat. You can spend them in the store. The store lets you buy things with .... bananas. You'll gather them as you climb up. Here's what you can buy:



You can buy a helmet, which give you extra protection. You can buy the ability to get double the bananas. The lightning bolt gives you extra speed, and the jet pack gives you the ability to start the game at a higher elevation (1000 meters). The point of the game is to see how high you can climb, and the higher you climb, the more you'll see.

So you can jump from side to side, but watch out for snakes, tree limbs, and who knows what!


The monkey is about to hit a bee hive. If he hits anything, he'll fall down and you start over again. But of course, no monkeys were hurt during the making of this game, because Marcelo grabs a limb on the way down and saves himself. He's back at the start screen and can play again.


By the way, if you look at the screen while you're climbing, you'll see a Pause button at the lower right. Tap that and you go to this screen:


This shows you your current score, the best score, and the number of bananas you've gotten this round. You can resume the game where you left it, retry the climb again, or quit the game.

Everything is neatly laid out, very clear, and let's you focus on the game. I really like the play of jumping from side to side, trying to catch bananas, avoiding snakes, bees, tree limbs, etc., on the way up, in Marcelo's mad climb to get the big banana of the moon. There's even some cool stuff on the way, where you can grab a helmet and temporarily be allowed to smash into an enemy instead of dying.

Way to go, Double Duck. This is a fun game, and original game (as far as I can tell), and lots of fun. It plays very well on the Firefox OS ZTE Open and I love it.

Cost: Free
Genre: Endless Climber
Score: 6 (out of 5)
Tested on: ZTE Open (Firefox OS)
Get it at: Firefox Marketplace

Monday, November 25, 2013

Color Canvas Collisions (Game Programming)

No, this is not a post about crazed artists whacking each other with wet canvases. I'm talking about Canvas, the strangely popular technique for drawing game graphics on an HTML5 web page. When it comes to collisions, Canvas is interesting. You can (and most people do) keep track of where your objects are flying, and you can calculate any possible collisions (as detailed in my post on CSS Collisions). Decide where you want to go, calculate if anyone or anything is in the way, make a decision and draw.

But what if you are battling 100 red space rabbits at once? You don't want to calculate the position of every rabbit, especially if they hop around (don't ask how rabbits hop around in space).


There's a technique that is unique to Canvas that can help you with collision detecting. When you copy an image to a canvas, the canvas doesn't remember what you put there. It only knows that it has pixels and it doesn't know where they came from. But they do have pixels. If you have red rabbits hopping around, you must erase the old rabbit, move to a new position, and draw the new rabbit. Clearing the canvas takes care of the erasing (unless you want to do exact erasing, as detailed in this blog post) in the example today, but you have to keep track of all the rabbits and make sure you hit one.

Well, there's something else notable about those rabbits. They are red! There is a Canvas method called getImageData that can go to a specific region of the canvas and capture what is there. Read all about it on MDN at https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D#getImageData. This cool method returns an ImageData object, which is documented at https://developer.mozilla.org/en-US/docs/Web/API/ImageData. (Isn't Mozilla wonderful, documenting all these things for us!) This method and object might seem complicated, but it isn't really. You just call getImageData with the top, left, width, and height of the area of the canvas you want to grab. The ImageData object is a bit more unusual, but really is easy to explain. If you look at the data property of the object, it an array of red, green, blue, and alpha that defines the actual color of that one pixel.

So, if I want to find out whether part of a canvas is red, I just have to use getImageData and see if the first part of the array is solid red. Of course, to be careful, you want to make sure that none of the rest of your objects are 100% red in the RGBA breakdown of the color spot you are looking at. And you also want to be careful if your pixel is on the edge of an area where there are other different-colored pixels because sometimes Canvas smears (I'm not kidding).  But if you want to kill 100 rabbits, you have to be efficient about it.

Here is some sample code, written in the same style as the CSS Collision code. Instead of a box and a ball, I change the code to two squares, an angry blue square and a scared red square (sorry, bunnies). The blue square marches across the screen from right to left, attempting to collide with the red square.

It looks like this:


The red square can jump out of the way (with a tap on the screen).


If the red square doesn't jump out of the way in time, a collision takes place and a message is displayed showing this:



So here is the code, modeled after the CSS Collision example, but using Canvas and color detection. Tested, run, and screenshots on Firefox OS on ZTE Open.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>
      Canvas Collision
    </title>
 
    <script>
      // Global variables
      var canvas;
      var ctx;
      var boardWidth = 320;
      var boardHeight = 460;
      var redBoxHor = 50;
      var redBoxVer = 150;
      var howFast = 3;
      var blueBoxHor = 270;
      var blueBoxVer = 150;
   
      // Covers all bases for various browser support.
      var requestAnimationFrame =
          window.requestAnimationFrame ||
          window.mozRequestAnimationFrame ||
          window.webkitRequestAnimationFrame ||
          window.msRequestAnimationFrame; 

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

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

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

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

    // Game loop
    function doMainLoop(){

      // Outer loop
      // Runs every 1/3 second.
          loopTimer = setTimeout(function() {
       
        // Inner loop
        // Runs as fast as it can.
        animTimer = requestAnimationFrame(doMainLoop);
         
        // Drawing code goes here
       
          // Clear the canvas.
        ctx.clearRect(0,0,320,460);   
         
        // Draw the ground.
        ctx.fillStyle="chocolate";
        ctx.fillRect(0,170,320,230);
        ctx.fill();

        // Draw the red box
        ctx.fillStyle="#FF0000";
        ctx.fillRect(redBoxHor,redBoxVer,20,20);
        ctx.fill(); 

        // Move the blue box
            moveBlueBox();
         
        }, 1000 / howFast); // Delay timing
      }
  
      // Move the blue box here.
      function moveBlueBox() {
     
          // Subtract 10 from box horizontal value.
          blueBoxHor = blueBoxHor - 10;
     
          // Draw the blue box with new coordinates.
          ctx.fillStyle="#0000FF";
          ctx.fillRect(blueBoxHor,blueBoxVer,20,20);
          ctx.fill(); 
   
          // If the blue box hits the left edge, restart.
          if (blueBoxHor < 10) blueBoxHor = 270;   

          // Report position of blue box.
          console.log(blueBoxHor);

          // See what is to the left of the box.
          // We're looking for the red box!
          p = ctx.getImageData(blueBoxHor - 5,
             blueBoxVer + 10, 1, 1).data;
     
          // Get first value of array (red value).
          p =  p[0];
     
          // If the first part of the color is red,
          // then the color was hit.
          if (p == 255) {
     
             blueBoxHor = 270;
             alert ("Bang");  
          }    
      }
      
      // Make the redBox jump up.
      function redBoxJump() {
   
      // Calculate redBox jump and move it.
      redBoxVer = redBoxVer - 50;   
   
      console.log("Ball up.");
   
      // Make the redBox fall after one second.
      redBoxTimer = setTimeout(redBoxFall, 1000);     
    }
   
    // Make the redBox fall down.
    function redBoxFall() {
   
      // Calculate the redBox fall and move it.
      redBoxVer = redBoxVer + 50; 
   
      console.log("Ball down.");  
    }

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

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

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

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

</script>

</head>
<body>

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

</body>
</html>


This is simple Canvas code. In this example I didn't import the bitmaps, but just created squares of red, blue, and chocolate using the fillRect method. When you use fillRect, you need to also define the fillStyle as a color before you call fillRect, and then you need to use fill afterward.
  1. Define your style.
  2. Define your fill object.
  3. Do the actual fill.
This example uses the same double loop as the CSS Collision example: a slow outer loop that runs every 1/3 second and a faster inner loop (using requestAnimationFrame) that moves the blue box and draws it. The red box moves with its own loop, which is triggered by a mousedown event (which becomes a simple tap on the screen).  Move, jump, and ... collide (or not).

The actual collision test is done every time the blue box moves. Here is the code:

      // See what is to the left of the box.
      // We're looking for the red box!
      p = ctx.getImageData(blueBoxHor - 5,
             blueBoxVer + 10, 1, 1).data;
     
      // Get first value of array (red value).
      p =  p[0];
     
      // If the first part of the color is red,
      // then the color was hit.
      if (p == 255) {
     
        blueBoxHor = 270;
        alert ("Bang");  
      }     


getImageData looks 5 pixels to the left and 10 pixels down, so it is looking inside any potential red box that is sitting around. If the red box jumps up, there won't be any red pixels there. If the red box is too slow, red will be detected and ... "Bang".

The value of the data property (p) is an array of length 4. I only tested for the first array value (p[0]) and all I was looking for was the value of 255. The value of red is, in RBG values, 100% red, 0% green, 0% blue. Or in the actual array: [255, 0, 0]. Ignore the 4th part of the array, which has to do with transparency/opacity. For more about colors than you ever want to know, see https://developer.mozilla.org/en-US/docs/Web/CSS/color_value. Essentially I grabbed the pixel, tore it apart into its three color values, and wanted to see if red was 100% red. Other colors might also have this, so I made sure I only had an 100% red square to look for.

In some cases, using getImageData is considered to be a slow method to call on Canvas, but if you use it for just looking at one pixel and define your pixels carefully, it can be a lot faster than calculating the position of every other object on the screen.

But there's one other method of collision that is very cool, and you may not be surprised to learn that it involves the mysterious (but not really that hard) world of SVG. Next time, unless something else gets in the way, and of course, not before I do another game review.

Stay tuned, but not iTuned!

Saturday, November 23, 2013

Bubble Meadow (Game Review)

Every once in a while, a game comes along that is both familiar and pleasant. It may not break new ground, but it can provide a few minutes of fun when you are distracted or impatient. One such game is Bubble Meadow, created by Logicking, based in Kiev, Ukraine. The art is pleasing and the game play is familar, but well tuned and works well on the Firefox OS ZTE Open.

Bubble Meadow is a simple bubble shooter, but I like it better than other bubble shooters I've played (with maybe the exception of a variant called bubble spinner), and I like bubble shooters very much. In fact, I reviewed one earlier called Planet Defense that I liked because of its space theme. But Bubble Meadow survives and succeeds for a few important reasons. But first a little about the game.

Here is the title screen. Cute, fun, bright on rainy day!


The star of the game is a cat who has a cart full of bubbles. And the meadow he is driving through has bubbles also. There are three buttons on the screen.One is for sound, and the sound doesn't work. This is the only flaw in the game, but I understand that sound is tricky in HTML5 games and I will definitely be writing about it soon.

The other two buttons are Play and ?. If you press ?, you get the credits of the team in Kiev:
 

If you press Play and choose the first level (which is all you can choose the first time through), you get some great help and tips. This is great, even though there a lot of bubble shooters out there. Here is what the first screen tells you:


Shoot at the bubbles and match three. Notice that the art uses a finger so you know you are playing a game on a phone or tablet. You throw the bubble in your hand at the bubbles at the top of the screen. But you need to match the color, and match three to get the bubbles to burst.

Next is a useful tip. You can bounce the bubbles off the side to get the bubbles you want. Nice!


Finally, you are told something that makes this game more fun.


You can swap the ball in your hand for one in your cart. This helps you from getting stuck. Way cool, Logicking! Having some options makes a game cooler, more fun, and telling me about it in this simple way is better still. Firefox OS is clearly aimed at a world market, and so the rules for your game should be told in some kind of pictures. Text should be optional. I was really charmed by the rules and story for Steel Story and I can't recommend enough that it is always great if you can give the rules and tell your story in pictures, making your game easy to play in any country in the world.

So now you know how to play the game. When you press Play on the title screen, you get this:


You get a set of meadows to play in, each with a different challenge of bubbles to burst. There are 16 levels here but that is a good start. I'm looking forward to Bubble Meadow II. This screen also gives you a choice to go a main menu, which looks like this:


You can use this as a pause, and then you can resume your current level, restart it, or go to the Levels screen, or also turn off the sound if you had any (boo hoo). 

And here is the first of actual play:


The cat is holding a purple ball and he must shoot it at other purple balls. Shoot straight up, cat!

But what makes this game cool is that you can switch the balls by touching the cart:


Now he has a green ball, which he could shoot in either directions since there are two green groups.

Here's a later screen, for comparison:


As you can see, the layout of the balls is more complicated. I really like two things about this game:

  1. The balls are larger which makes it actually easier to aim but at the same time make it harder to bounce around balls you don't want.

  2. I like the option to switch balls.

And the art is really bright and colorful. This will have a permanent place on my ZTE Open! 

Even without the sound, this rates a definite 5. I look forward to more games from Logicking.

Cost: Free
Genre: Bubble Shooter (match 3)
Score: 5 (out of 5)
Tested on: ZTE Open (Firefox OS)
Get it at: Firefox Marketplace

PS: I just noticed that Logicking is the creator of Ultimate JS, an HTML5 game engine. I'll have to check it out! There are so many HTML5 game engines out there but right now I'm focusing on making everything from pure HTML5, CSS, and JavaScript (oh, and SVG, which is a good friend of HTML5. I'm also starting to look at CSS3, but I'm not sure how widely adopted it is.

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!

Tuesday, November 19, 2013

Battery+ (App Review)

Okay, so I said I was only reviewing games. But I saw a Google+ post about the revised version of a battery app by Gerard Coll. Gerard's icon by the way is really cool. Hello Kitty + Star Wars.


Gerard's company name is Webserveis and you can get this in the Marketplace at https://marketplace.firefox.com/app/battery-2. There was an earlier version that was okay, but the new version (Battery+) is really useful.

Why do I care so much about batteries. Well, on a phone it matters a lot. All my phones have some kind of battery app, because I really want to know (and quick) how much battery I have left.

Once you load the app, here is what it looks like:


I like the big colored bar with the percent (%) remaining. 93% looks good. There's lots of statistics that change as the app sits longer on your phone. If you scroll down, there's more information:


 
If you hit Direct access, it takes you to the device's battery information. But what I like is that I can get an instant battery percent with one click. The little battery icon at the top of my screen is nice, but not exact enough for me. 

This is a perfect app for me, especially for the Firefox OS ZTE Open. After having this phone a month or so, I can tell you that the ZTE Open seems to have a better battery life than my other recent phones. My Samsung Galaxy Note II will get a day of use before a recharge (a real power hog), but the ZTE Open seems to last at least 3 days. 

So this isn't a game, but it is one of the few apps I consider essential (Facebook, Twitter, Blogger, Google+ are the others right now). 

Cost: Free
Genre: App
Score: 5 (out of 5)
Tested on: ZTE Open (Firefox OS)
Get it at: Firefox Marketplace




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>


Saturday, November 16, 2013

Rooftops (Game Review)

Rooftops is very similar to a game called Canabalt which appeared in 2009 and was open-sourced in 2010. Originally a Flash game, I remember playing it and getting bored fast.

Unlike games that were inspired by Canabalt (like Temple Run), Rooftops isn't much different than the original Canabalt, and actually, seems to have a controls problem with Firefox OS.

Here's the basic idea. You run and jump. You start out running from left to right and you can't stop. Ever. You just run. The fun is that if you tap on the screen, your character jumps.


Simple enough, except that there seems to be too much delay from when I tap and when I jump. I've tried this several times, and it just isn't smooth. Maybe it would be different for you.

I would run for a few seconds and I'm supposed to jump to the next building, but I don't jump soon enough and I fall to a horrible death. When I do fall, I am asked to put in a nickname and submit my score. If I don't want to, I have no option except press the home button.


If I submit my score, I get this:






Not very good, but there isn't much incentive to try again. When I hit OK, I get the start screen again:




My stats after a few games aren't good:




Maybe if I had more patience, I might keep trying, but there isn't even any known incentive. The art is dull (so was the art in 2009) and the statistics mentions items, but I don't know what they are.

It would have been nice if the first minute or so was easier and you could get used to the controls. The other games I've played on the ZTE Open with Firefox OS didn't seem to have control problems, but I can't be sure. 

The game is by RĂ©mi Vansteelandt and maybe I'll just leave it by saying the game didn't work for me but 883,636 people did better than me, so maybe it is just me! But when there are better "endless runner" games like Jetpack Joyride or Robot Unicorn Attack, not to mention a new Rayman runner, I would have been more encouraging if there was something original here. It looks just like Canabalt!

I'm bummed out when a game isn't good on Firefox OS, but due to the lack of originality, no learning mode, and possible control failure, I have to rank this 2 out of 5. It does work and you may enjoy it, but I didn't.

Cost: Free
Genre: Arcade
Score: 2 (out of 5)
Tested on: ZTE Open (Firefox OS)
Get it at: Firefox Marketplace

Thursday, November 14, 2013

Screen Orientation and moz Prefixes (Game Programming)

I was planning to write a post comparing the game graphics capabilities of CSS, Canvas, and SVG, but I realized it would be smarter to compare all the game issues, so I'll wait until I write about some other programming stuff first. Collision detection is also important, and so are special effects!

So today I'd like to cover the subject of Screen Orientation. This concept is often confused with Device Orientation but the two are different. Screen Orientation is only about portrait and landscape. How does the screen orient itself to the device? Device Orientation is about how does the device orient itself to the world. Sometimes there's overlap, sometimes not.

Screen Orientation isn't something you need to worry about on a laptop or desktop. You usually don't turn your screen sideways (although I once had a monitor that would do that so you could read documents to match paper size orientation). But with a phone, playing games in landscape is very common. And if a game needs a long left-to-right playing field, landscape is good. Similarly, if the playing field needs to be more up and down, portrait is the way to go. Personally, I like portrait-style games; I like the way they feel in my hand.

Firefox OS provides ways to detect, change, and lock orientation. I've written a little app that has three buttons, a line for a message, and picture so you can see the orientation. Here's a screenshot of the app when it starts up:


Before you do anything else, tilt the phone sideways and see what happens. If you rotate the device counter-clockwise, it should look like this:




The image rotates to match. The message at the top should say "landscape-primary". Firefox OS uses the convention that primary is the standard way to view an app. So landscape-primary means that the phone has been normal up and down by going 90 degrees in a counter-clockwise manner. If you rotate the device 90 degrees clockwise (back to the starting position), the screen will look like this:



And surprise! The screen is now in "portrait-primary" orientation. But it doesn't stop there. You can rotate the screen 90 clockwise from the main portrait position and get this:


This is called "landscape-secondary" and might feel odd because most games use the landscape-primary setting if they use landscape at all. But the oddest of all would be last, which is if you rotate the screen 180 degrees from the original portrait position.


It looks the same as portrait-primary, but the phone itself is upside down. While this is fun, the purpose of this in gaming is that you might want to require a particular screen orientation. The buttons in my app will lock the orientation.

If you touch the Portrait button, the screen will be locked in portrait-primary position. Now if you rotate the phone, the screen orientation will be locked to the orientation of the phone. So if you turn the phone upside down, the screen will be upside down also.

Similarly, if you touch the Landscape button, the screen will lock into landscape-primary and will flip sideways even if you are in portrait position.

Finally, the Float button will release the locks and let the screen orientation match however you are holding the phone. Pretty cool, huh. Playing with this is so much fun I should put it in the Firefox OS Marketplace ... not!

The code for this is pretty straight-forward:

<!DOCTYPE HTML>
<html>  
  <head>
  <title>orientation</title>
  <meta charset="UTF-8">
 
  <style>
  
    #myPara
    {
      position:absolute;
      top: 10px;
      left: 50px;
    }
   
    #myButton1
    {
      position:absolute;
      top: 70px;
      left: 50px;
    }

    #myButton2
    {
      position:absolute;
      top: 70px;
      left: 120px;
    }
   
    #myButton3
    {
      position:absolute;
      top: 70px;
      left: 215px;
    } 
   
    #myFox
    {
      position:absolute;
      top: 120px;
      left: 40px;
    }
   
  </style>

    <script type="text/javascript">
       
      // Add load event listener to run first function.
      window.addEventListener("load", runFirst, false);
                  
      // This function runs when the document loads.
      function runFirst() {
        
        myButton1.addEventListener(
          "mousedown", myClick1,false);

        myButton2.addEventListener(
          "mousedown", myClick2,false);

        myButton3.addEventListener(
          "mousedown", myClick3,false);
         
        window.screen.addEventListener(
          "mozorientationchange", screenChange, false);
       
        // Initial message.
        myPara.innerHTML = "Tilt the device.";
      }
             
      function myClick1(evt){    
        window.screen.mozLockOrientation("portrait");
        myPara.textContent = window.screen.mozOrientation;     
      }
     
      function myClick2(evt){    
        window.screen.mozLockOrientation("landscape");
        myPara.textContent = window.screen.mozOrientation;    
      } 

      function myClick3(evt){    
        screen.mozUnlockOrientation();
        myPara.textContent = window.screen.mozOrientation;    
      }  

      function screenChange(){
        myPara.textContent = window.screen.mozOrientation;
      }       
     
    </script>
  </head>
   
  <body> 
    <p id="myPara">Text goes here.</p>

    <button id="myButton1">Portrait</button>
    <button id="myButton2">Landscape</button>
    <button id="myButton3">Float</button>
   
    <img id="myFox" src="fox.png" />

</body>

</html>


This is a straight HTML5 page. It starts out with some simple CSS definitions for the text caption, the three buttons, and the picture of a fiery fox.


The code then has a function that runs when the page loads. This function sets up event listeners for the three buttons and then a fourth event listener that listens for a change in screen orientation. This will be called when you rotate the screen enough to be considered landscape or portrait, depending on where you are. The event is called mozorientationchange.

At one point in history, this was called onmozorientationchange, but is now mozorientationchange. It should probably become orientationchange at some point, but I don't know whether it will or not or when. However, there is an MDN page for orientationchange at https://developer.mozilla.org/en-US/docs/Web/Reference/Events/orientationchange, but it doesn't mention mozorientationchange and doesn't work today.

It would be nice to see a table of mozXXX methods and events, what's in and what's not, but the developers have plenty of more important things to do. You can do something similar to what I did for requestAnimationFrame (see here) but I'm waiting to see if this will change again soon.

Then I have three functions that will be called, one for each button. The first two use the mozLockOrientation method and display the new status. Here's the one for portrait:

     function myClick1(evt){    
        window.screen.mozLockOrientation("portrait");
        myPara.textContent = window.screen.mozOrientation;     
      }


Note that the prefix moz is used for mozLockOrientation and that mozLockOrientation takes the parameter value of portrait, locking the screen into portrait-primary position. The position is displayed by using mozOrientation. Lots of moz around here in the land of moz.

The second button is the same as the first, but locks the screen using secondary. You can read about lockOrientation at  https://developer.mozilla.org/en-US/docs/Web/API/Screen.lockOrientation and it does say This API is currently in draft form. It is only implemented as a prefixed method (mozLockOrientation) in B2G and Firefox for Android. The page has a link to onorientationchange but not orientationchange. It does have a link to unlockOrientation, which is used in the third button.

If you want to unlock the orientation and let the screen follow the way the phone is oriented, use mozUnlockOrientation (and maybe someday unlockOrientation). Read about it here: https://developer.mozilla.org/en-US/docs/Web/API/Screen.lockOrientation.

mozOrientation just returns the value of the current orientation. Read about it at https://developer.mozilla.org/en-US/docs/Web/API/Screen.orientation.

There's also a good overview page about screen orientation at https://developer.mozilla.org/en-US/docs/WebAPI/Managing_screen_orientation

The prefixes are documented inconsistently, but once you know that, you can code away and the code above works fine on my Firefox OS ZTE Open.

Prefixes are a pain in the industry and Mozilla has recently said that they won't be using them any longer. When a new API is introduced, it will only be available by setting a flag in the about:config section. Read about that here: https://wiki.mozilla.org/WebAPI/ExposureGuidelines

Fun stuff!

Next I'd like to investigate Device Orientation, which is a bit more complicated, but is very important for game programming. If you don't want to touch the screen, you have an alternative in Device Orientation. You can tilt the device to move something. Like this old wooden game:



 But on your phone!