Sunday, December 29, 2013

Device Orientation (Game Programming)

In my last post, I reviewed a charming classic game called Orbland. It looked like this:


And my review of Orbland is at http://firefoxosgaming.blogspot.com/2013/12/orbland-labyrinth-game-review.html  Orbland simulated a rolling ball in a maze. This isn't a game you can play on a PC! You have to tilt the phone to roll the ball and if you try to run this type of game on a PC browser, it won't work. It also won't work on Firefox for Android (yet). You need a phone to do program this kind of interaction, but how?

And speaking of Firefox for Android, if you have an Android, be sure to get Firefox for Android, because a lot of the game I have reviewed here will run on Firefox for Android, so who needs Google Play for games!

Not only is it fun to play games (on Firefox OS), but it is fun to make games. Today's post will introduce the bizarre world of Device Orientation, that is, twisting and turning your phone. And by the way, don't confuse this with Screen Orientation, which has to do with playing games in Portrait or Landscape. If you want to see that article, go here: http://firefoxosgaming.blogspot.com/2013/11/screen-orientation-and-moz-prefixes.html.

So how does Device Orientation work? It uses a specific event, deviceorientation, to determine changes in orientation. Are you turning the phone from top to bottom? side to side? rotating around like a top? If this sounds confusing, check out this page on Mozilla Developer Network: https://developer.mozilla.org/en-US/docs/Web/Guide/Event/Orientation_and_motion_data_explained, which explains the three ways you can rotate your phone, and this page, which explains a bit about the API: https://developer.mozilla.org/en-US/docs/WebAPI/Detecting_device_orientation.

Here's the code I use to do some simple ball-rolling. Load it into your phone and have a good time. Not as skillful as Orbland, but it does have a ball rolling around.

<!DOCTYPE HTML>
<html>
 
  <head>
    <meta charset="UTF-8">
    <title>
      Device Orientation
    </title>
 
    <style>
        
      #ball
      {
        width: 20px;
        height: 20px;
        position: absolute;
        top: 230px;
        left: 150px;
        background-image: url(ball.png);
      }
      
    </style>
   
       <div id="ball"></div>

    <script type="text/javascript">

        // Load event listener
      window.addEventListener("load", getLoaded, false);
     
      // deviceorientation event listener
      window.addEventListener("deviceorientation",
        handleOrientation, false);

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

            // Output to console.
        console.log("The page is loaded.");
      }
     
      function handleOrientation(evt) {
     
        // Beta is top/bottom rotation.
        myBeta = ~~evt.beta;
       
        // Gamma is left/right rotation.
        myGamma = ~~evt.gamma;
     
        // Test to see if tilt is in range.
        if ((myBeta < 29) && (myBeta > -29)
               && (myGamma < 29) && (myGamma > -29)) {
     
          // Calculate ball position for beta.
          myBString = 230 - (myBeta * 7) + "px";
         
          // Display ball position for beta.
          tilt.textContent = "beta " + myBString;
         
          // Move ball to new beta position.
          myBall.style.top = myBString;
       
          // Calculate ball position for gamma.
          myGString = 160 - (myGamma * 5) + "px";
         
          // Display ball position for gamma.
          tilt.textContent = tilt.textContent +
            " gamma " + myGString;
           
          // Move ball to new gamma position. 
          myBall.style.left = myGString;             
        }     
      }
     
    </script>
  </head>
 
  <body>
  <p id="tilt">Tilt!</p>
  </body>

</html>


Here's what the screen looks like if your phone is held flat (tangent to the earth's surface).


At the top I've printed the beta and gamma positions of the ball. Since the screen is 320 x 460 pixels, the beta will be the vertical position (216 pixels from the top edge, roughly half of the screen height) and the gamma will be the horizontal (160 pixels from the left edge, roughly half of the screen width). For more about width and height, see my post at http://firefoxosgaming.blogspot.com/2013/10/how-big-am-i-game-programming.html.

What is beta and gamma? As the MDN article https://developer.mozilla.org/en-US/docs/Web/Guide/Events/Orientation_and_motion_data_explained explains, beta is the rotation from top to bottom, and gamma is the rotation from left to right. Or if you've ever ridden in a small boat, beta is rocking the boat from bow to stern, and gamma is rocking from port to starboard. There's a third Greek letter, alpha, that is like turning the boat around in circles (but because we don't want to get you seasick, alpha won't be covered here). Look at the excellent pictures on MDN for further explanation.

Essentially the code follows the same format as the CSS bouncing ball code example I wrote at http://firefoxosgaming.blogspot.com/2013/10/bouncing-ball-in-css-game-programming.html. You have a picture of a ball, you define it in CSS, and move it around. The movement is defined by changes in the deviceorientation event.

When the deviceorientation event is triggered, a check is made to see if the changes in device orientation are between -29 and +29. Device orientation runs from -180 to 180 (making a complete 360 degree circle) for beta and gamma, but it you don't want to know if the phone is tilting more than 30 degrees in any direction.

Here's my equation:

        // Test to see if tilt is in range.
        if ((myBeta < 29) && (myBeta > -29)
               && (myGamma < 29) && (myGamma > -29)) {


This uses the && to make sure that all four conditions are met. This evaluates to true only if all four conditions mean that the screen isn't tilting too much.

Also, before this equation, I did conversions that you may not have seen before:

        // Beta is top/bottom rotation.
        myBeta = ~~evt.beta;
       
        // Gamma is left/right rotation.
        myGamma = ~~evt.gamma;


These take the original value of the beta and gamma values and convert them from floating point to integer (whole number) values. There are JavaScript functions that will remove all the numbers to the right of the decimal point, but if you don't know whether the number is positive or negative, you can't use floor or ceil. But if you use a double ~~ (tilde), you can convert floaters to the correct values (-3.14 = -3, +3.14 = 3). Essentially ~ (tilde) is a bitwise NOT operator and it changes a number to a 32-bit integer and flips all the bits. And a second ~ (tilde) flips all the bits back, but now it's just an integer. This is cool because JavaScript doesn't have data typing for different kinds of numbers, but you can fool it with this obscure bit of magic. You can read more about it here: http://www.frontendjunkie.com/2012/06/deep-dive-into-javascript-not-bitwise.html

So here is how it works in practice:

Tilt the phone so the top is pointing down and read the beta and gamma values.


The beta is smaller but the gamma is still pretty much the same. Here's what happens if you tilt it so the bottom is tilted down.



And likewise, if you tilt it so the left side is down, you get:


And finally, if you tilt it toward the right side, you get:


Pretty cool, huh? The ball goes where you want, no tapping, no touching. A phone-only way of controlling your game. Simple in my sample, but cool in Orbland. If anyone sees other games that use this technique, let me know.

Friday, December 27, 2013

Orbland Labyrinth (Game Review)

Who could forget Dana Andrews in Laura, especially the way that he kept playing a little puzzle game, trying to get a little ball to roll around in a little box? I had the same kind of game when I was a kid, and now you can too!

Orbland Labyrinth lets you play the same kind of game on your Firefox OS phone.


Here's a game that doesn't really need directions. You just tilt your phone and roll the silver ball through the maze until it falls in the hole. Simple, maybe too simple. Of course there is more than one screen.

When you go through the first hole, you'll get this screen.


You get the choice of quitting, playing again, and going on to the next level. And even a little bit of help in case you didn't realize that you're not just rolling a ball, you're saving the Orb! All that on one screen.

And on to the next screen.


From easy to hard, in one step! But that makes it fun. The first level was very easy, but this one now requires you to roll the ball past several holes that will make you lose the level. Only the silver hole (at the middle right edge) is an exit. All the others will stop the level right there.

And the next level is even harder.


This game will keep you on your fingertips and will provide lots of twisting and turning. I like this game for its simplicity and ease of play. It replicates a common puzzle that has been around since the 40's and probably a lot earlier. Maybe a game historian can come forth and tell me what this kind of game is called and when it originated!

But it is fun nevertheless.

And interesting in another way. All the games I've been downloading from the Firefox OS Marketplace were free. So was this one, when I downloaded it a few weeks ago. But then last week when I was downloading it again, I searched for Orbland and noticed that there were two versions of Orbland.



At first I couldn't figure out what was the difference, and then I noticed that one was free (Orbland Labyrinth Free) and one was $0.99! (Orbland Ball Labyrinth). Wow! Something is for sale in the Marketplace.

I'll be sure to buy it soon so I can write up the process. And when create a game, I'll put it in the Marketplace so you can see how that process works as well. Buying and selling is part of what Mozilla wants to happen, so rush right out and buy Orbland Ball Labryinth for only $0.99. Let me know if you can buy this game in other countries and what it costs there.

So, pretty cool, Prokapi (creators of Orbland)! The free version of the game has 30 levels and the paid has over 100 levels. That's very generous to give you 30 levels for free, and if you get to 30, you'll want the hundred for the paid version. Prokapi is from Nordrhein-Westfalen, Germany, and I'll be eager to see more games from them in the Marketplace.

Support the Marketplace, buy an app!

Cost: Free for 30 levels, $0.99 for over 100 levels.
Genre: Puzzle
Score: 5 (out of 5)
Tested on: ZTE Open (Firefox OS)
Get it at: Firefox Marketplace

Thursday, December 26, 2013

Quick and Dirty Guide to Making Apps for Firefox OS

This blog is focused on game programming (and game playing) but I don't cover non-gaming very often and I'm following my own slow winding path to creating games on Firefox OS.





The best place to start is (always) the Mozilla Developer Network (MDN) and the MDN page for Firefox OS is

     https://developer.mozilla.org/en-US/Firefox_OS

Every scrap of Firefox OS info is all there somewhere, and you'll learn about the three G's: Gaia (the User Interface), Gonk (the Linux kernel and friends), and Gecko (the layout engine that powers the Firefox browser). There's lots of information about building Firefox OS itself, but I'm assuming you want to make apps, not operating systems.

Creating Apps

MDN provides a rich and juicy App Center.

     https://developer.mozilla.org/en-US/Apps
 
You should go there once you have the big picture of how Firefox OS is constructed.

One of your first stops should be "Your First App" at

     https://developer.mozilla.org/en-US/Apps/Quickstart/Build/Your_first_app

and if you're a web developer (as many are), check out "App Development for Web Developers" at

     https://developer.mozilla.org/en-US/Apps/Quickstart/Build/For_Web_developers
 
There's also a nice set of reference apps you can study at

     https://developer.mozilla.org/en-US/Apps/Reference_apps

For the most part, Firefox OS app development is just HTML5. Mozilla will provide you with lots of guidelines and frameworks you can use. The App Center has it all and has recently been redesigned and is easy to navigate. Just remember you're creating apps for a phone, so there's no keyboard and the size of the screen is small.

Development Environment

The actual development environment is the easiest I've ever seen. All you need is Firefox (the browser) and one plugin (the Firefox OS Simulator).

Firefox is at

     http://www.mozilla.org/en-US/firefox/new/

but you might want to get the Beta at

     http://www.mozilla.org/en-US/firefox/channel/
 
or maybe even the Nightly at

     http://nightly.mozilla.org/
 
The Nightly build is quite stable and you'll want to be testing the latest foxy goodness!

And once you have installed Firefox, go to Add-ons and search in Get Add-ons for "Firefox OS Simulator".

Read all about the Simulator at

     https://developer.mozilla.org/en-US/docs/Tools/Firefox_OS_Simulator
 
and once installed, run it from Web Developer in the Tools menu.

One of the cool things about the simulator is that you can run your programs and see them run in a little window, or, you have a Firefox OS phone, you can load your program by using the Simulator and a USB cable. If you have Firefox OS 1.3 or higher, you can use an advanced program called the App Manager which will let you do cool debugging and installation. But the Simulator works and I use it almost every day.

Selling Your App

Once you create, build, and test your app, you can put it in Firefox OS Marketplace. There's lots of stuff about preparing your app, monitizing, and the rules for submission. Note that there are two kinds of apps: ones that you download from the Marketplace and run on your phone, or ones that run from a server and the Marketplace just supplies the means to get there.

Check out the Marketplace at

     https://developer.mozilla.org/en-US/Marketplace

Tutorials

There are several good tutorials and more coming all the time. Try some of these (and let me know if you find good ones).

Simple slide show - http://shafiul.github.io/slides/kickstart_fxos.html#/

Simple Hello World - http://freezinfo.com/firefox-os-basic-tutorial-hello-world-application/

Several tutorials - http://rominirani.com/category/mobile-2/firefox-os/

Excellent eBook - https://leanpub.com/quickguidefirefoxosdevelopment

Other Resources

Mozilla Hacks - https://hacks.mozilla.org/category/firefox-os/

Google Group - https://groups.google.com/forum/#!forum/mozilla.dev.b2g

Some Posts I Wrote that Might be Useful

Using the Simulator - http://firefoxosgaming.blogspot.com/2013/10/firefox-os-easier-than-before.html

Putting Apps on the Phone - http://firefoxosgaming.blogspot.com/2013/10/pushing-your-game-to-your-phone.html

The rest of my posts are split evenly between reviews of games from the Firefox OS Marketplace and game programming articles on writing code in HTML5 for the Firefox OS phone using HTML, JavaScript, CSS, Canvas, and SVG. I also have covered unique-to-the-phone APIs such as Vibration, Device Orientation, Audio, Screen Orientation, Touch, and Screen Sizes. Check out the Firefox OS games and code at http://firefoxosgaming.blogspot.com/.

If I've missed anything, let me know. Twitter is fastest, Gmail is pretty good, and Google+ is not too bad, and I'm on Facebook but don't do much with it except to launch my blog Twitter announcements.

PS: Thanks to Joe Sanders on Google+ who asked me "Do you have any links to good Firefox tutorials for developing apps for it?" I realized that I should devote a post to Firefox OS resources and this is it. I'll archive this post at

     http://firefoxosgaming.blogspot.com/p/firefox-os.html

and make it a Blogger Page on the side. Thanks, Joe.

Tuesday, December 24, 2013

Vibration (Game Programming)

A few posts ago, I lamented the loss of the classic BEEP command (ASCII 07), and now it turns out that Firefox OS has the equivalent for phones. It's called Vibrate!



It's not music, but sometimes you want to alert the user and the music and sound is turned off. Or sometimes you might want to add a vibration as an extra cue that an explosion is taking place. Or sometimes you want to give the user a clue that they actually touched the screen in the right place by giving them a little buzz.

Regular web browsers don't do this and today's code won't work in desktop Firefox. But it works in Firefox OS!

Here's a little stand-alone code sample that shows exactly how to add vibrate to your games.

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

    #myButton2
    {
      position:absolute;
      top: 70px;
      left: 120px;
    }
   
    #myButton3
    {
      position:absolute;
      top: 70px;
      left: 230px;
    } 
     
  </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);
       
        // Initial message.
        myPara.innerHTML = "Tap on a button.";
       
        // Background color
        document.body.style.backgroundColor = "GreenYellow";
      }
             
      function myClick1() {    
        window.navigator.vibrate(200);
      }
     
      function myClick2() {    
        window.navigator.vibrate([200,100,200]);
      } 

      function myClick3() {    
        window.navigator.vibrate(500);
      }  
 
    </script>
  </head>
   
  <body>  


    <p id="myPara">Text goes here.</p>

    <button id="myButton1">Short</button>
    <button id="myButton2">Short Short</button>
    <button id="myButton3">Long</button>

</body>

</html>


You can read about the Vibrate API on MDN here: https://developer.mozilla.org/en-US/docs/Web/Guide/API/Vibration. It's simple. It vibrates!

The vibrate method takes one parameter. It can be either a single number, or an array of numbers. For example, if you add window.navigator.vibrate(200) to your code, your phone will buzz for 200 milliseconds (or 2/10 of a second).

If you use an array of numbers, the first number will set the length of vibration, the second number will set the length of silence (non-vibration), and the third will vibrate again. For example,

        window.navigator.vibrate([200,100,200]);

will vibrate for 200 milliseconds, then pause for 100 milliseconds, and then vibrate for another 20 milliseconds. Beep! Beep! You can have as many elements in the array as you want, just alternate between vibration and non-vibration. I could see a Morse code training device here, if anyone uses Morse code any longer.

The rest of the sample just sets up three buttons, positions them absolutely with CSS, and attaches events to each button with event listeners. By the way, you don't want to use the onclick or onmousedown  inline event triggers you may be used to. Firefox OS doesn't allow them in certain situations and you don't need them. And the mousedown event is faster than click as well, because click is waiting for you to let go. And remember, there's no mice here, this is just translated on the phone to touch events.

One other thing to note is that I decided that this sample should have a background color since the white buttons might not show up well on a white screen. Since I like to do as much as I can in JavaScript, I set the background color here:

        document.body.style.backgroundColor = "GreenYellow";

You may be used to using background-color in CSS, but when you do the JavaScript thing, a lot of CSS properties change their name slightly when they move to the JavaScript country. And bgcolor has been deprecated a long time. Here's a nice list of CSS to JavaScript translations: http://noobflash.com/set-style-dynamically-with-javascript/

Here's what the screen looks like, in all its GreenYellow color. And here's the place to find these weird color names https://developer.mozilla.org/en-US/docs/Web/CSS/color_value. Upper and lower case don't matter so you can also type greenyellow. And the exact red/green/blue values are rgb(173,255,47).




All this was tested and run on my trusty ZTE Open Firefox OS phone.

Add some vibration to your game today!

Monday, December 23, 2013

Puxxle (Game Review)

Puxxle is a difficult name to type (my fingers want to type puzzle) but a cool game. The developer (Cat Wee Corner) is also difficult because my fingers want to type Wee Cat Corner. But in Twitter picture, the developer explains that he shares his office with a cat litter box.



Litter box on the right, Mac Mini on the left. Cozy game studio in Northumberland, UK. @CatWeeCorner. http://www.catweecorner.com.

From tiny acorns grow mighty oaks. And a very cool puzzle game. When you start it up, you get this:


Very professional, very clean. I like the How To Play. I like it even more when I get there, because it is a movie that shows you exactly how it works.


You have your main board at the top and three smaller boards at the bottom that you move pieces from. Touch and drag. For example, the top has an upside-down "L" shape and when I drag the piece on the left, I get this:


And so on. When you add them together so that at least four squares of the same color are touching, those squares disappear. The How to Play shows you this. Cool. We like instructions.

We also like Options. Here's the options for this game:


The Music and SFX (sound effects) are obvious and the music has a nice beat. I give it a 7, Dick. The About is interesting, giving credit where credit is due:


I'm not sure how Entypo pictograms works, but I'd like to know more. Nice credits for the GEO font and the music from http://www.freesfx.co.uk. I'll have to check them out!

Playing this is fun and relaxing. Kind of like Tetris but without the time stress. Start with a blank board at the top.


Here are two tips that might have been useful in the How to Play.

Tip 1: You can rotate the pieces in the bottom three boards by tapping on them.

Tip 2: When you're ready to move, tap and hold underneath the piece you want to move.

For example, I tapped on the middle piece once to rotate it clockwise, and then tap-and-hold under the middle piece to move it to the main board.



 Another piece takes its place. Now I  tap the left piece three times so that I can have two yellow next to the two yellows on the main board. The result is looks like this.


 Then I tap the piece on the left once and move it onto the board. Nothing disappears because I need four or more of one color touching.


 I then move the right piece without rotating onto the board to connect five purple, leaving two red and one yellow behind.



You'll notice that my score is now 63. If I hit the Menu button at the top, I get this:


Back To Game takes you back to the game, Options takes you to the Options screen, Restart Game takes you back to the beginning, and Quit ... quits!

If you quit, and then go back to the game, you can see your score in the High Scores from the opening screen.


This game is just about perfect. It has everything working well and has a soothing puzzle quality that lets you keep your brain active without pumping your adrenalin. Well done, Cat Wee! I can't wait to see what they will do next.

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

Friday, December 20, 2013

Adding Music to Your Game (Game Programming)

The last several posts have been all about audio in Firefox OS. I've learned a lot about what works, and what doesn't work, on my trusty little ZTE Open. Go back and read: HTML5 Audio, HTML5 Audio Followup, Son of HTML5 Audio Followup, and HTML5 Audio Triumphant. Whew! There were surprises for me and technical blind alleys, but now no one has any excuse for not adding music and sound effects to their HTML5 Firefox OS game! And this post will show you how!


What I did is to add two sound effects and one background song to the SVG Collision Detection example.  That example had an innocent ball, a hungry box, and impending doom for the ball. But the ball can jump out of the way, and the point there was to show you how SVG has built-in collision detection, but there's just enough of a game in it to justify adding music and SFX (sound effects).

Here's the game screen:


Here's the code (and you can go to the SVG Collision Detection post for details on how the non-audio code works. You may also want to refer to my previous audio posts for reasons why I chose the way I do audio in this post.

<!DOCTYPE HTML>
<html>  
  <head>
      <meta charset="utf-8"> 
    <title>
    Game Sounds
    </title>

    <script>
       
          // Global variables
      var boardWidth = 320;
      var boardHeight = 460;
      var bwPixels = boardWidth + "px";
      var bhPixels = boardHeight + "px";
        var redBallHor = 60;
      var redBallVer = 160;
      var redBallRad = 10;
      var howFast = 3;
        var blueBoxHor = 270;
      var blueBoxVer = 150;
      var audMove;
      var audJump;
      var audEnd;
      var flagJump = 0;
      var flagEnd = 0;
   
          // Namespace for SVG.
          svgNS = "http://www.w3.org/2000/svg";
     
      // Covers all bases for various browser support.
        var requestAnimationFrame =
          window.requestAnimationFrame ||
          window.mozRequestAnimationFrame ||
          window.webkitRequestAnimationFrame ||
          window.msRequestAnimationFrame; 

      // Event listeners
      // Page load event listener
      window.addEventListener("load", getLoaded, false);
      // Mouse down event listener
      window.addEventListener(
          "mousedown", redBallJump, false);
         
      // Run this when the page loads.
      function getLoaded(){

        // Make sure we are loaded.
        console.log("Page loaded!");    
       
        // Load audio.
        audMove = new Audio("move.ogg");
        audJump = new Audio("jump.ogg");
        audEnd = new Audio("end.ogg");
       
        // Set up audio event listeners.
        audMove.addEventListener("canplaythrough",
          moveAudioOK, false);
        audJump.addEventListener("canplaythrough",
          jumpAudioOK, false); 
        audEnd.addEventListener("canplaythrough",
          endAudioOK, false);        
    
        // Create SVG parent element.
        myBoard = document.createElementNS(svgNS, "svg");
        myBoard.style.setProperty("width",bwPixels);
        myBoard.style.setProperty("height",bhPixels);
        myBoard.style.setProperty("top","0px");
        myBoard.style.setProperty("left","0px");
        myBoard.style.setProperty("position","absolute");
        
        // You must append the board to the body.
        document.getElementById("pageBody").
             appendChild(myBoard);
            
        // Create blue box.
        blueBox =
          document.createElementNS(svgNS, "rect");
         
        // Width,  height, radius, and color of box.
        blueBox.x.baseVal.valueAsString =
          blueBoxHor + "px";
        blueBox.y.baseVal.valueAsString =
          blueBoxVer + "px";
        blueBox.width.baseVal.valueAsString =
          "20px";
        blueBox.height.baseVal.valueAsString =
          "20px";       
        blueBox.style.
          setProperty("fill","blue","");
         
        // Attach the box to the game board.
        myBoard.appendChild(blueBox);

        // Create red ball.
        redBall =
          document.createElementNS(svgNS, "circle");
         
        // Width,  height, radius, and color of ball.
        redBall.cx.baseVal.valueAsString =
          redBallHor + "px";
        redBall.cy.baseVal.valueAsString =
          redBallVer + "px";
        redBall.r.baseVal.valueAsString =
          redBallRad + "px";
        redBall.style.
          setProperty("fill","red","");
         
        // Attach the ball to the game board.
        myBoard.appendChild(redBall);
       
        // Create ground.
        myGround =
          document.createElementNS(svgNS, "rect");
         
        // Width,  height, radius, and color of box.
        myGround.x.baseVal.valueAsString =
          "0px";
        myGround.y.baseVal.valueAsString =
          "170px";
        myGround.width.baseVal.valueAsString =
          "320px";
        myGround.height.baseVal.valueAsString =
          "230px";       
        myGround.style.
          setProperty("fill","chocolate","");
         
        // Attach the box to the game board.
        myBoard.appendChild(myGround);

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

      // Game loop
      function doMainLoop() {
               
        // Loop within the loop.
        // Outer loop
        // Runs every second.
            loopTimer = setTimeout(function() {
       
          // Inner loop
          // Runs as fast as it can.
          animTimer = requestAnimationFrame(doMainLoop);         
      
          // Drawing code goes here
              console.log("Moving the box.");
         
              // Move the box
              moveBlueBox();
         
        }, 1000 / howFast); // Delay / how fast     
      }
           
      // Move the blue box here.
      function moveBlueBox() {
     
          // Subtract 10 from box horizontal value.
          blueBoxHor = blueBoxHor - 10;
     
      // Draw the new blue box.
      blueBox.x.baseVal.valueAsString =
          blueBoxHor + "px";
             
          // If the blue box hits the left edge, restart.
          if (blueBoxHor < 10) blueBoxHor = 270;   

          // Get bounding box of box.
      bbBox = blueBox.getBBox();
      console.log(bbBox.x);

      // Get bounding box of ball.
      bbBall = redBall.getBBox();
      console.log(bbBall.x);

      // Is there an x collision?
      if (bbBall.x + 20 == bbBox.x) {
     
        // Is there a y collision?
        if (bbBall.y == bbBox.y) {
       
          // Collision!
          blueBoxHor = 270;
         
          // Make the end sound.
          if(flagEnd == 1) {
       
            // Play the end sound.
            audEnd.play();    
          }

          alert("Bang");
        }
      }  
      }

    // Make the red ball jump up.
    function redBallJump() {

      // Calculate red ball jump and move it.
      redBallVer = redBallVer - 50;  

      // Draw the new red ball.
      redBall.cy.baseVal.valueAsString =
          redBallVer + "px"; 

      // Make the jump sound.
      if(flagJump == 1) {
       
        // Play the jump sound.
        audJump.play();    
      }
 
      console.log("Ball up.");
   
      // Make the red ball fall after one second.
      redBallTimer = setTimeout(redBallFall, 1000);     
    } 

    // Make the red ball fall down.
    function redBallFall() {
   
      // Calculate the redBox fall and move it.
      redBallVer = redBallVer + 50; 
     
      // Draw the new red box.
      redBall.cy.baseVal.valueAsString =
          redBallVer + "px";    
      console.log("Ball down.");  
    }
   
    // Process the move audio loaded event.
    function moveAudioOK() {
   
      console.log("Move sound loaded.");
     
      // Loop and play the audio.
      audMove.loop = true;
      audMove.play(); 
    }
   
    // Process the jump audio loaded event.
    function jumpAudioOK() {
   
      console.log("Jump sound loaded.");
     
      // Set the jump audio flag.
      flagJump = 1;    
    }

    // Process the end audio loaded event.
    function endAudioOK() {
   
      console.log("End sound loaded.");
     
      // Set the end audio flag.
      flagEnd = 1;      
    }

    </script>
  </head>
   
  <body id="pageBody">
  </body>

</html>


I use three OGG audio files for this example:

     move.ogg - plays a song in the background

     jump.ogg - plays a sound effect when the ball jumps

     end.ogg - plays an explosion when the box and ball collide

If you want to play along at home, you can get these song files from my page on SoundCloud.

     move.ogg - https://soundcloud.com/thulfram/move

     jump.ogg -  https://soundcloud.com/thulfram/jump

     end.ogg - https://soundcloud.com/thulfram/end

SoundCloud is simply wonderful for musicians (and me).

Adding the Music and Sound Effects to your Game Code

I've evolved a fairly simple and fool-proof way to work with HTML5 Audio in Firefox OS. Here's what I have found works.

  1. Create a global name for every different sound. This makes sure that the sound will be available in every function. (But don't tell Douglas Crockford. He hates globals). Just put in placeholders. You will attach them later.
  2. After you make sure the page is loaded (with an event listener for the page load event), create a unique audio object for every sound you want to use. Use the new Audio() command and specify the name of the song when you do so. This will load the audio file. All your audio files should be in the OGG file format.
  3. Create an event listener for every audio object and use the canplaythrough event (not the canplay event). Audio files may take a while to load. With JavaScript, you can never assume that anything will load instantly, and sometimes code will run faster than things that you load. This applies to audio files for music and image files for canvas. Remember: trust no one! Especially not things you load into a web page.
  4. The event listener you created for each audio object should point to a unique function. In that function, you can do different things. One might be to kick off a song that plays in the background constantly. But another use would be for a specific sound effect that you don't want to play right away, but play later when something happens. If this is the case, use the unique function for that audio object to set a flag. Flags also should be global (so they can be used in any function anywhere) and are initially set to 0 (zero). When the audio object is loaded in its unique function, set the flag to 1.
     
  5. Then, when you want a sound to play, for example, when the red ball jumps, you first check to see if the flag is set (equal to 1). If it is, you play the song. But maybe the song is still loading, so if the flag is not set, don't try to play it. Sometimes code runs faster than loading (memorize this: code is faster than load).
     
  6. You can mute sounds using the flag. First kill the onplaythrough event, then call the pause() method of that sound, and finally,  set the flag to 0 (zero).
A little complicated, but following these steps will make sure you can play music and sound when you want to. And you want to, because music and sound can make a good game great!

Here's the lines that were added to the original code of the SVG Collision Detection file.

Setting the Global Audio Object Placeholders

These were put in the Globals section.

      var audMove;
      var audJump;
      var audEnd;


Creating the Audio Objects

These were put in the function that is called when the page loads.

        audMove = new Audio("move.ogg");
        audJump = new Audio("jump.ogg");
        audEnd = new Audio("end.ogg");


These create a new audio element with a specific name and use a specific audio file. OGG is your friend.

Setting Up Event Listeners for Each Audio Object

Just creating an audio object doesn't guarantee it will happen instantly, or at all. You don't want your game to crash, trying to call a non-existent file you forgot to load. Here are the event listeners.

        audMove.addEventListener("canplaythrough",
          moveAudioOK, false);
        audJump.addEventListener("canplaythrough",
          jumpAudioOK, false); 
        audEnd.addEventListener("canplaythrough",
          endAudioOK, false);   
     

They create an event listener for each audio object and use the canplaythrough event. A unique function is created that will be called when the canplaythrough event is triggered.

Filling in the Functions that will be Called by the Audio Events

If you use flags, specify them first in the Globals section. Here are the two flags I used for jumping and ending the game.

      var flagJump = 0;
      var flagEnd = 0;


Here is the function that is called when the canplaythrough event is triggered on the jump audio object.

   function jumpAudioOK() {
   
      console.log("Jump sound loaded.");
     
      // Set the jump audio flag.
      flagJump = 1;    
    }


It's always a good idea to have a console.log for loading. Then you can look in the console and see if your audio actually loaded. Beats an alert every time! Next, for this sound, you only set the jump flag to 1. That's it. The end audio object is the same, with only the names changed to protect the guilty.

For the background music move audio object, you don't need no stinkin' flags, you just want to play the music. So the function looks like this:

    function moveAudioOK() {
   
      console.log("Move sound loaded.");
     
      // Loop and play the audio.
      audMove.loop = true;
      audMove.play(); 
    }


You first set the audio move object so that it loops, and then you play it! How cool is that?

Playing Sound Effects

If it's not background music, you only want to play a sound effect when some event happens, like the ball jumping or the game ending.

For the ball jumping, I just inserted these lines in the code where the ball actually jumps, right after the ball is drawn.

      // Make the jump sound.
      if(flagJump == 1) {
       
        // Play the jump sound.
        audJump.play();    
      }


Here's where the flag earns its dinner. You want to test to see if the flag has been set. If the flag is 1, you know that it is fully loaded and can play. Once you've determined this, you just ... play it!

For the explosion sound when the box and ball collide, I just added these lines right after the code determines that the ball and box have collided and the box has moved out of the way.

          if(flagEnd == 1) {
       
            // Play the end sound.
            audEnd.play();    
          }


Again, I make sure that the sound is loaded and can play, and then I play it. Boom!

That's all there is to it:
  1. Global placeholders.
  2. Create the Audio after the page is loaded.
  3. Make sure the Audio is loaded by using the canplaythrough event.
  4. Process the Audio when loaded by playing (if background music).
  5. Use flags to make sure you can play Audio at a particular time.
  6. Use OGG.
  7. Have fun!
How did I Make this Music?

If you're a programmer or artist, making music can be hard. But there are lots of people who can make music and are eager to put it in your game. Ask around on Twitter or go to a Game Jam!

Speaking of Game Jams, as I've been learning about gaming in Firefox OS, I've been seeing a lot of talk about Game Jams. There are lots of them and people take part to ee if they can make a game in 48 hours. It reminds me of science fiction conventions, small groups of people, high energy, no sleep!

So I went to Kindle and read two books:

Game Jam Survival Guide by Christer Kaitila 
 Global Game Jam - 48 hours of Persistence, Programming, and Pizza at Scottish Game Jam by Jon Brady.
Both books were fascinating and I recommend them, for different reasons.

The first is a good guide to what goes on and how to survive one. If you're going to one and wonder how they work and what you need to think about before you go, get it!

The second was a long but entertaining ramble on how a game jam feels from the inside. Definitely gives the flavor of a game jam, and reminds me of Hunter S. Thompson (minus the drugs and sex).

But tbe Game Jam Survival Guide, as well as being entertaining, had some resources that were very helpful to this post.

Christer mentioned something called SFXR that was used in game jams a lot. I looked it up and it is a cool tool for making quick sound effects. Here's what it looks like:


You click on the buttons on the left until you get a sound you like (for example, a Jump sound). You can click on the button in the middle to modify the sounds, and there are even two buttons on the bottom left to mutate and randomize.  When you get something you like, click on Export .WAV and you've got a WAV file. Then use Audacity (or some other audio software) to convert it to OGG and use it in your game. Get it at http://www.drpetter.se/project_sfxr.html.

Kotaku also had a great article about using a tracker called Pulseboy that makes it easy to create chiptune music like the old 8-bit computers. Read the article here http://kotaku.com/5949117/make-chiptunes-in-your-browser-with-this-awesome-simple-sequencer. And get Pulseboy here: http://www.pulseboy.com/. Trackers are an old-school way to make music that have been replaced by Digital Audio Workstations (Sonar, Acid, Reason, Cubase, Logic Pro, FL Studio, etc.) which are big and expensive. I use FL Studio (formerly known as Fruity Loops until the cereal company made them stop) and Acid. The only tracker I used was Octamed and I don't like trackers because they are more complicated. If you want to know more about trackers, start here: http://woolyss.com/tracking-trackers.php.

Pulseboy is cool because it recreates the sounds of the Gameboy and looks like one too!


Pulseboy consists of 16 tracks, running vertically. You click on a square on the track and supply note information. When Pulseboy runs, it plays all 16 tracks and music comes out. Primitive, but at the same time simple. If you want chip music, use Pulseboy. Get it at: http://www.pulseboy.com/. It's pretty easy to learn and simple.

Between Pulseboy and SFXR, you can make your own music. Chip tunes belong with pixel art and both are very cool, so you don't have to be an artist or musician to make great game art and music.

As usual, all of this was tested and run on a Firefox OS ZTE Open phone.

Now back to games!


Thursday, December 19, 2013

Chrono & Cash (Game Review)

The people at Orange Pixel are definitely maniacs. They've created a handful of insane games that are challenging but ultimately crazy fun! I'm a big fan of pixel art and they do it really well. And the worst part is that they have catchy tunes that stick in your head and then you can't remember where you heard it on the radio and then you realize that it's not on the radio, but in a demented game.

They also are clever at porting their games. At last count, they do games for iOS, Android, BlackBerry, Chrome, and ... now Firefox. All with creamy pixel goodness. I even remembered their company name (Orange Pixel) from a crazy game on iOS called Heroes of Loot. Not in the Firefox Marketplace yet, but I'm hoping. But today's game is pretty bizarre, too, and is called Chrono & Cash.



The story is about a thief who jumps around and grabs bags of cash before the guards can get him. The game is very fast-paced and will challenge you but will stick in your mind and make you want to come back for another go.

Before you start, check out Options.


First of all, you can change the pixel looks of the master thief, Chrono. But you have to unlock disguises by getting higher scores.


You can also mute the sound or just the music.

Also you can adjust the distance between the left and right buttons on the game screen, a feature I haven't seen before, but is very handy for letting you manipulate the direction of the character the way you want. By the way, I find it easier to keep the two direction controls close together so you can slide your left finger back and forth as you change direction.


And of course, you can find out who are the lunatics that made this game:


And here are the directions on how to play:



You need to rob things by grabbing bags of cash, but you need to avoid guards and do it very quickly. Here's a typical screen.


The two circles on the left move your character left or right, and the red circle on the right makes the thief jump. Simple, but hard. The guards are after you and you don't have much time! And the music is fast and catchy. This reminds me of an arcade game and if it was, I'd be putting quarters in all day!

For each screen, you start at the bottom and work your way to the top, grabbing as much loot as you can. But you'll get caught and when you lose enough lives (you start with three) you're done! You get a high-score screen and you can play again, without any of those annoying quarters.


This game is fast-paced and unforgiving, but if you keep at it, you'll keep getting better and then you'll find the next screen a little tougher. But that's part of the fun and this game works just great on the Firefox OS phone.

Orange Pixel is based in the Netherlands but makes games in a way that makes me want to play the rest of their work and I can't wait for more of them to be in the Firefox Marketplace. Oh, did I say their music won't leave my head, no matter how hard I try to think about something else? These are people to watch!

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

Tuesday, December 17, 2013

HTML5 Audio Triumphant (Game Programming)

I've been a little dismayed when I found out that some of the HTML5 Audio properties (duration, currentTime, some control CSS properties) don't work as they do in other browsers. Part of that distress was that I made an assumption. Not a good idea. I had been hearing for a long time about the need for audio sprites because iPhone (and others) couldn't play two sounds at once. Remy Sharp's article made a big impression on a lot of people (http://remysharp.com/2010/12/23/audio-sprites/) and many people decided that audio for HTML5 wasn't going to work. And I notice that a lot of the games I'm playing don't have any audio.

But you need currentTime to work with audio sprites because you need to load one file and then run your audio from whatever position you want to start the playing from. Sounds like that doesn't work. But you don't need it! Then I realized I hadn't tested it, so I wrote a simple test and guess what?

Two audio files can dance with each other!


So now your jump sounds can take place without cutting off your music and your collision sounds can ignore the capture of coins. Dance!

My test program sets up two audio players and lets you listen to both songs, and start and stop each whenever you want. The songs repeat, and you can play with this all day, enjoying the combination of two different songs. I remember doing some singing like this, and I think it was a song called Frère Jacques, where some people would start singing and others would start singing a few measures later. I wonder if this song has been sung in other languages?

Anyway, here's what the program looks like in Firefox OS on my ZTE Open.



The top set of controls are playing oggsong.ogg and the bottom set of controls are playing a different song, oggsong_2.ogg. Start and stop each one by clicking on the | | symbol in each control. So these controls are useful for testing, even though you can't do much more than position them so they don't overlap.

And here's the code, very similar to the code in my first post on Audio Programming (http://firefoxosgaming.blogspot.com/2013/12/html5-audio-game-programming_10.html).

<!DOCTYPE HTML>
<html>
  <head>
    <meta charset="utf-8">
    <title>
      Audio x 2
    </title>
  
      <script>

      // Global variables
      var myAudio;
      var myAudio2;

      // Load the page.
      window.addEventListener("load",
        runFirst, false);

      // Runs when the page is loaded.
      function runFirst() {

        console.log("page loaded");

        // Create two audio objects.
        // We like OGG.
        myAudio = new Audio("oggsong.ogg");
        myAudio2 = new Audio("oggsong_2.ogg");
       
        // Need this to see the controls.
        document.getElementById("myBody").
            appendChild(myAudio);          
        document.getElementById("myBody").
            appendChild(myAudio2);

        // Loop both songs.
        myAudio.loop = true;
        myAudio2.loop = true;

        // Make both controls visible.
        myAudio.controls = true;
        myAudio2.controls = true;
       
        // Position 1st audio control.
        myAudio.id = "player1";
        player1.style.position = "absolute";
        player1.style.top = "70px";
        player1.style.left = "10px";
      
        // Position 2nd audio control.
        myAudio2.id = "player2";
        player2.style.position = "absolute";
        player2.style.top = "200px";
        player2.style.left = "10px";
       
        // Listen for fully loaded audios.
        myAudio.addEventListener("canplaythrough",
          processMyAudio, false);         
        myAudio2.addEventListener("canplaythrough",
          processMyAudio2, false);       
      }

      // The first audio is ready to play.
      function processMyAudio() {
     
        console.log("audio one loaded");
       
        // Event no longer needed.
        myAudio.removeEventListener("canplaythrough",
            processMyAudio, false);
           
         // Play the first audio.
        myAudio.play();     
      }

      // The second audio is ready to play.
      function processMyAudio2() {
     
        console.log("audio two loaded");
       
        // Event no longer needed.
        myAudio2.removeEventListener("canplaythrough",
            processMyAudio2, false);
           
        // Play the second audio.
        myAudio2.play();     
      }
     
       </script>
    </head>

    <body id="myBody">
      <p>Audio Controls</p>
    </body>

</html>


The trick here is very, very simple. For every audio track you want to create, create a new Audio object, give them different names, and process them separately.

For example:

        myAudio = new Audio("oggsong.ogg");
        myAudio2 = new Audio("oggsong_2.ogg");


This makes two Audio objects, each with a different name and each with a different song file (but both of them are OGG, yay OGG).

Add them both to the page, make them both loop and have controls. I then positioned each control so they don't fit on the screen.

        // Position 1st audio control.
        myAudio.id = "player1";
        player1.style.position = "absolute";
        player1.style.top = "70px";
        player1.style.left = "10px";
      
        // Position 2nd audio control.
        myAudio2.id = "player2";
        player2.style.position = "absolute";
        player2.style.top = "200px";
        player2.style.left = "10px";


I'm still working out what happens. I think the controls are centered on the phone page and maybe that's a bug someone should file, or maybe they want it that way? At least the top, left styles (absolute) let me have them not overlap.

Next I set up event listeners to make sure that each audio loads. 

        // Listen for fully loaded audios.
        myAudio.addEventListener("canplaythrough",
          processMyAudio, false);         
        myAudio2.addEventListener("canplaythrough",
          processMyAudio2, false);       


Then, finally, I have a separate function that is called when the audio is ready to play (canplaythrough). Here's the function for the first audio and the second is similar, except for the change in object names.

      // The first audio is ready to play.
      function processMyAudio() {
     
        console.log("audio one loaded");
       
        // Event no longer needed.
        myAudio.removeEventListener("canplaythrough",
            processMyAudio, false);
           
         // Play the first audio.
        myAudio.play();     
      }


And that's it! Start and stop the two tracks and see that they can both play at the same time. So who needs Remy Sharp?

Mangling Mozart
In case you want to listen to the two actual songs, you can download them for free (and you don't need to register there either, just click the Download button). Here are the links.

https://soundcloud.com/thulfram/oggsong
https://soundcloud.com/thulfram/oggsong_2

SoundCloud is a cool service for people who want to share their music and it is very easy to use. Put the songs in the same root folder as your index.html file and they will magically be loaded into the simulator and your phone.

The two songs are both about 9 seconds long. The two songs are mangled versions of a Mozart piece called Palindrome (which means running back and forth). I mangled them by putting the tune into FL Studio (http://www.image-line.com/documents/flstudio.html), loading in a synthesizer (H.G. Fortune's Swamp XT at http://www.hgf-synthesizer.com/), and then using FL Studio's Riff Machine to mangle the original music in two different ways (two different sounds, tempos, everything different).

What I find interesting is that even if you combine the two songs starting at different times, the human mind makes them sound like one song. Weird. But you can stop and start each song independently and see that they really are playing simultaneously.

But the important thing is that you can have two songs playing at the same time, so there's no excuse for not adding music and sound effects to your games. I have one or two more audio posts to do and then we can get back to making games. As I've learned, HTML5 Audio is a little tricky, but worth it.