Writing apps for Firefox OS phones
The Package
Another thing you want to do (otherwise, you won't be able to run your app on the simulator or handset) is write the manifest. The manifest is a JSON summary that contains all the details needed for Firefox OS to run the app correctly.
The manifest.webapp
file must be in the root of the app. The example in Listing 1 gives you an idea of what the file should contain.
Listing 1
Manifest.webapp for Life
Most of the fields in the listing are pretty self-explanatory; however, note in the icons
section that you will have a 60x60-pixel icon and another 128x128 pixels. The handset uses the 60-pixel icon in its list of apps (Figure 2); the 128-pixel icon comes into play if you want to distribute your app through the Firefox OS marketplace, which I talk about a bit later. A handy online guide shows you how to create a thematically consistent icon [4].
The orientation
field in line 16 allows you to decide how your app will be shown on the device: portrait
, landscape
, portrait-primary
, landscape-primary
, portrait-secondary
, or landscape-secondary
.
For example, if you specify portrait-primary
in your manifest file, your app appears in portrait mode with the top of your UI at the top of the device, and the bottom of the UI at the bottom of the device's display. The portrait-secondary
option flips the orientation 180 degrees. By using portrait
, your app will flip in portrait mode depending on how the device is being held, but it will not rotate 90 degrees when you turn the device on its side.
You can also combine these options. For example,
"orientation": ["portrait", "landscape-secondary"]
allows your app to flip either way in portrait mode (right-side up or upside down) and will display correctly on one of its sides but not the other. The Mozilla Developer Network has a good tutorial on how to write a good manifest [5].
The Software
In my example project, I'll be implementing Conway's Game of Life (GoL) [6], which is probably one of the most popular and simplest life simulators. If you are unfamiliar with GoL, check out the "The Game of Life" box.
The Game of Life
In GoL, you set up a culture of cells in a virtual petri dish and then watch the cells reproduce. The rules are simple: Your Petri dish is a grid of square cells. The cells can be alive (filled in) or dead (empty). When you run the simulation, the program calculates the next generation by deciding which cells stay in the same state, which die, and which reproduce according to the following rules:
- If a cell has zero or one neighbor, it dies from isolation; with four or more neighbors, it dies from overcrowding.
- If a cell has two neighbors, it stays in the same state in the next generation (i.e., if it's dead in the current generation, it will be dead in the next generation; if it's alive in the current generation, it will be alive in the following generation).
- If a cell has three neighbors, it either stays the same (if occupied) or comes to life (if empty).
When all the cells are plotted in the newest generation, it becomes the current generation, and the cycle begins again.
These simple rules can lead to extremely complex configurations that are nearly impossible to foresee, unless you have a large tablet of graph paper and, ironically, no life of your own. Consider the R-pentomino initial state as an example (Figure 3). It is a seed of only five cells that grows to an enormous size; generates shapes called gliders, toads, and loaves; and does not stabilize until generation 1,103.
If you have had any experience with JavaScript in the last few years, you will have witnessed the rise of JavaScript libraries, none of which is more popular than jQuery. jQuery [7] has simplified the creation of dynamic web programming to the point of forcing Flash nearly to extinction (which, by the way, is an excellent thing). jCanvas [8], on the other hand, is an extension of jQuery that makes programming on a canvas object much easier.
In my implementation of the GoL (Listing 2), I will use the HTML5 canvas
object as a playing board (line 17). To help, I also will use jQuery and jCanvas (lines 7 and 8). In lines 150 to 159 you can see how easy it is draw a cell on the canvas. Note that because I considered a single pixel too small, I decided to go with a 2x2 box for the cells. Therefore, with a 300x300 canvas, the playing field can hold 150x150 cells.
Listing 2
Life for Firefox OS (index.html)
The code in Listing 2 also uses jQuery extensively to refer to and manipulate some of the elements, such as the status bar (Figure 4), which will slowly appear and then fade out if you tap the playing field twice (the equivalent of a double-click) and show you how many live cells are in the current generation (lines 38-42). The HTML to include the status bar in your app is very simple (lines 22-24), although you will have to modify the status.css
file to use the clean, elegant font provided by Mozilla (Listing 3).
Listing 3
Modified status.css File
The Start(Stop) and Clear buttons (Figure 5) are included in the user interface in lines 18 and 19 (Listing 2). When you click Start or Stop (lines 193-212), you either start the mainLoop
function (which runs the simulation) or stop it.
The Clear button uses a jCanvas function to erase all pixels from the canvas and empties the CULTURE
array that holds the coordinates of the live cells in the current generation (lines 214-220).
The biggest chunk of code (lines 81-142) is the mainloop
mentioned previously. This section calculates the next generation based on the current generation stored in CULTURE
. The most obvious way to do this is to loop over every cell in a 150x150 array and examine each of the eight possible neighbors, changing their states as necessary. However, this approach is a very slow, very inefficient way of doing things.
Instead, the CULTURE
array contains the coordinates of only the live cells in the current generation. By examining only live cells and their immediate neighbors, you can skip enormous empty chunks of the playing board. All of the white space above, between, and below the live cells is ignored (lines 90-138).
The jQuery $.each()
loops over all the elements in CULTURE
and avoids examining a cell twice by storing it in the cellExamined
array (line 106) and skipping it if it is encountered again (line 104). The new cell configuration is gradually stored in the nextCulture
array.
Note that the cells are stored as strings. Thus, cell (130, 45) is stored as [130,45]
. Arrays in JavaScript are flat, so a two-dimensional array like
a = [[130, 45], [20, 130], [45, 10]]
is actually stored like
a = [130, 45, 20, 130, 45, 10]
making searches for duplicate coordinates (i.e., lines 62-71) very difficult. The conversion from string to numbers and back again, which is going on within the loops, certainly has an effect on performance, but the only other way would be to store cells as an array of objects. Unfortunately, looping and searching for duplicates within an array of objects is also difficult, hence the string-based solution.
Finally, nextCulture
is dumped into CULTURE
, and the new generation is drawn to the playing board (lines 140-141).
The Distribution
Now that your app works, it's time to package it and get it distributed. The packaging process is very straightforward. All you need to do is create a ZIP file that has the manifest.webapp
file in its root. In Linux, you would cd
into the root of your app and type:
zip -r <appname>.zip *
Now, you have two choices: You can host the app yourself on your own site, which Mozilla is perfectly okay with, or you can upload it to the Firefox OS Marketplace (Figure 6) [9]. To use the Marketplace, you need a Firefox OS developer account (Figure 7) [10]; the submission process, is very straightforward (Figures 8 and 9).
Apart from providing more exposure with the marketplace, the wizard helps you weed out any errors you might have in your manifest; moreover, in the future, you will be able to sell your apps using Mozilla's framework.
« Previous 1 2 3 Next »
Buy this article as PDF
(incl. VAT)