Chapter 9

image

Google Play Store

9.1 Source Code

All the distribution project files and examples are available at the website http://HTML5GameEnginesBook.com/. All the code, graphics, and sound are licensed free for personal and commercial use (MIT and CC-BY-3.0). The Impact engine is proprietary and is not distributed.

9.2 Introduction

Despite accounting for roughly 70% of all smartphones worldwide [68], Android distribution always seems to be a second class citizen when it comes to game engine support. Game engine maintainers go far and out of their way to make sure iOS is well supported and Android becomes an afterthought. However, the game engine maintainers cannot be faulted entirely. Android development is very hard in that the number devices running on it are extremely varied, and each could be running a different version of the Android operating system, a problem called “fragmentation.”

When an iOS developer finishes a game for the iPhone and iPad running the latest version of iOS plus one version back (a good development strategy), the developer can be assured that a very large majority of all iPads and iPhones can install and run their app. Android does not have that luxury. The only sure way to test is to build up a collection of tablets and phones with different Android versions and run the app. As HTML5 web developers, we are familiar with this test strategy by juggling browsers and operating systems inside virtual machines. Unfortunately, with Android, we are now juggling actual hardware. The Android development tools do have an Android emulator capable of launching a variety of Android test scenarios, but it is very slow and cumbersome. (Tip: For a better emulator experience, try an Intel-based Android image instead of ARM.)

Though the test strategy for Android may be complex, at least the build strategy is not that difficult. As mentioned before, game engine support is not quite as polished on iOS, but at least the tools that are available do work well. This chapter will get your HTML5-based game to run native on an Android device so it can eventually be distributed in Google Play or any other store.

Our targets are usually chosen for us when we use commercial HTML5wrapping tools. If you are looking to build a standard Android app using the standard SDK tools, my personal recommendation is dial back no farther than Android 4.0. Android went through a lot of rapid changes from 2.x, 3.x, and 4.x. Google introduced a lot of standard themes and a native action bar system in 4.0. This is now the method of navigation users expect. Therefore, consider saving yourself a lot of backwards-compatibility hassle and start at 4.0. The glut of 2.3 Gingerbread users will eventually catch up.

9.3 CocoonJS

Last chapter, we used Ejecta for our Impact game, but Ejecta is not supported for Android. CocoonJS is a commercial HTML5 wrapper for both Android and iOS maintained by Ludei [69]. The setup is the same for each platform, so we could have just used CocoonJS for both Android and iOS, but that wouldn’t have been as fun, would it? Also, CocoonJS uses its own “cloud” compiler. That means you upload your code to Ludei, and their server compiles your code. It then lets you download your final package. The pros and cons of being dependent on “the cloud” could fill an entire book. Here is a summary:

Cost

CocoonJS is currently free, but it may not always be. CocoonJS also requires their logo shown during startup.

Internet

CocoonJS requires an Internet connection to use. You may not always have stable fast connection during development.

Control

CocoonJS uses its own compiler with its own capabilities. You may wish to have more, but you can only have what they give you.

Ejecta is free, open source, not dependent on an Internet connection, and doesn’t require a splash screen. It is more difficult to set up, but these benefits make it worth it for the iOS version. However, there is the cost of having 2 build structures to maintain if you wish to support both Android and iOS. If you are willing to do the cost/benefit trade and be CocoonJS-only, you can make that decision.

9.3.1 Setup

As mentioned before, CocoonJS uses the cloud to compile code. Eclipse and the Android developer tools do not even need to be installed (though the Java Development Kit will be needed eventually to sign your apk (Android packaged kit) to upload to Google Play). However, you will want to keep MAMP, XAMPP, or WAMP to easily fetch the zip package and install it on your Android device. To get started, download and install the free CocoonJS launcher from Google Play. This is what you will use to locally develop and test your app. Once installed, you will need to register an account with Ludei. From there, Ludei will email you a registration code to enable the CocoonJS launcher.

After everything is configured and registered, your launch screen will look like Figure 9.1 (Nexus 7 being shown).

Figure 9.1.

Figure showing CocoonJS launcher.

CocoonJS launcher.

CocoonJS comes with demo apps to install and test its system. These demo apps are also available from its website. They are invaluable in determining the CocoonJS methods and API for developing HTML5 games. Our game will need to be modified to work with their tools, which we will get to shortly. For now, download one of its sample games, put it on your local web server (MAMP, WAMP, etc.), and then download it using their launcher. See Figure 9.2.

Figure 9.2.

Figure showing CocoonJS fetch app.

CocoonJS fetch app.

If everything is set up correctly, its demo app will download and launch. We can now begin the process of replacing its app with ours.

9.3.2 MechaJet on CocoonJS

Download the MechaJet project from the book’s website. The only piece missing is the Impact engine (which cannot be distributed in raw form). Drop your Impact library into the normal “lib/” location. The example project is already set up to look for it there. Zip up the project, and then send it to the CocoonJS launcher. You should see MechaJet playing on your Android device. If you do not own a copy of Impact, there is a baked version of MechaJet available that also will launch and play using CocoonJS.

Backtracking starting with MechaJet from Part II, it is not a simple copy-paste-replace to get an Impact app running with CocoonJS. There are a couple tweaks to get the app to work. Particularly,

HTML

CocoonJS has very minimal HTML support. Essentially, CocoonJS just gives us a blank web document. We have to create the Canvas manually. This is not so much different than the Ejecta framework from the last chapter.

Touch events

CocoonJS has a little trouble with our HUD arrows. This is not a big deal. We just need to rewrite our touch handlers so CocoonJS understands them. That part of our game was removed from our Impact entities and made custom anyway.

If you were to load the desktop Part II MechaJet right now, you would get a blank screen. The first problem we need to solve is the missing canvas. To do this, we add these lines right before initializing the game. (See below.) While we are at it, we will enable audio again. Before, we had it disabled on mobile devices. CocoonJS supports it.

/* CocoonJS lets us have our audio back .
if(ig.ua. mobile) {
 // Disable sound for all mobile devices
 ig. Sound . enabled = false ;
}
*/
// create canvas for CocoonJS .
var c = document . createElement (' canvas '),
c.id = 'canvas ';
document . body . appendChild (c);
// start game
ig. main ('#canvas ', MyGame , 60 ,480/2 ,320/2 , 2);

Now the game loads and runs. However, touch controls do not work. As mentioned before, CocoonJS has trouble accepting our touch controls. We need to add our own touch listeners. See the additions in Listings 9.1.

ig. touchLocation = Object ();
ig. touchactive = false ;
c. addEventListener (
  " touchstart ",
  function (touchEvent) {
 var e= touchEvent . targetTouches [0];
 var touch = Object ();
 touch ['x '] = e. pageX /2; touch ['y '] = e. pageY /2;
 ig. touchLocation = touch ;
 ig. touchactive = true ;
 });

  c. addEventListener (
  " touchend ",
  function (touchEvent) {
 ig. touchactive = false ;
 });

  c. addEventListener (
  " touchmove ",
  function (touchEvent) {
 var e= touchEvent . targetTouches [0];
 var touch = Object ();
 touch ['x '] = e. pageX /2; touch ['y '] = e. pageY /2;
 ig. touchLocation = touch ;
 ig. touchactive = true ;
 });

Listing 9.1. CocoonJS touch impact.

We have added a listener to touchstart, touchmove, and touchend. We keep track of this activity by adding new objects to the ig global object. We know if it is active and we know the location. We can now change our buttons to look at these to see if it needs to react. See this change below:

buttonCheck : function (theButton) {
/* OLD METHOD
 if (! ig. input . state (" CanvasTouch "))
 {
  return false ;
}
 return this . collisionDetect (theButton , ig. input . mouse);
*/
 // NEW METHOD
 if (! ig. touchactive)
 {
  return false ;
}
 return this . collisionDetect (theButton , ig. touchLocation);
},

Since we are tracking the touches ourselves, we remove Impact’s CanvasTouch check and replace it with our own. Send the new parameter for the collision detect routine, and we are good to go. If we send the game right now to CocoonJS launcher, it will be playable. CocoonJS is heavily optimized for HTML5-based games, so our game runs at a good speed as well.

9.3.3 Generating an APK (Android Package Kit)

To create an apk suitable for native Android installation, you must use the CocoonJS cloud compiler. Login to their web service, create a project, fill out the form, and then upload the exact same zip package that you used for their launcher app. After a few minutes, you will receive an email with links to download your natively compiled apk. As mentioned before, you also can have it generate an iOS project from your zip package.

9.3.4 Distribution

Android apps are distributed as “apk” files. The apk file is simply a collection of files zipped. If you want to look inside it, you can easily append “.zip” and then open it with your file manager. Inside, you will find several Android-related directories and files, such as “assets”, “META-INF”, “res”, “AndroidManifest.xml”. Desktop Java developers may recognize this format since Java distributables, “.jar” files, are also zip files set up in a similar way.

Take a look inside “assets”, and you will find the JavaScript files and other assets that contain your game. This brings us to the point of the exercise of opening up the Android package. There is little worry about extracting your game from an iOS device. Apple has gone to great lengths to remove a user’s ability to do that. However, with Android, extracting an apk and unzipping it to get access to the JavaScript for your game is not a difficult task. Consider running your files through obfuscation or minify before final deployment (such as Impact’s “baking”, or UglifyJS used by Turbulenz). Naturally, the paranoid may have considered doing that anyway before uploading it to the CocoonJS Cloud compiler (their terms of service state they discard your source package after they compile).

Assuming you went through all the necessary JavaScript obfuscation techniques, we can proceed to putting this app in the Google Play Store. This process is easier than the Apple App Store.

9.3.5 Signing the APK

All Android apps must be signed before they are allowed on an Android device [87]. To aid debugging, Android devices allow debug-signed applications if “Unknown Sources” is checked on the device. Google Play will not allow a debug-signed apk into the store. Therefore, CocoonJS makes available two versions of the apk: One is debug-signed that can be used for testing. The other is unsigned ready to be signed and sent to Google Play (or other app store) [88].

Here is the signing process:

  1. Install the Java Development Kit (JDK) if you do not have it. This will install Keytool and Jarsigner tools for you. If you have gone through the process of installing the Android SDK, then you already have the JDK.
  2. Create a keystore to sign your apk. In Windows, the utility may be located in a place such as “C:Program FilesJavajdk1.7.0 21jre inkeytool.exe”. On Mac, it is located in “/usr/bin/keytool” and is probably available in our system path. The command is :

    keytool -genkey -v -keystore mykey . keystore 
     -alias mykeyalias -keyalg RSA -keysize 2048 
     -validity 10000

    Replace the mykey and mykeyalias to something more appropriate. Do not forget the passwords or lose this keystore. This certificate and alias must be reused to sign all updates.

  3. Sign your apk using jarsigner. The utility is located in the same place you found keytool. Here is the command:

    jarsigner -verbose -keystore mykey . keystore 
     -storepass KEYSTOREPASSWORD -keypass KEYPASSWORD 
     unsigned_app .apk mykeyalias

Your app is now signed and ready for Google Play. Next:

  1. Go to https://play.google.com/apps/publish/.
  2. Fill out the forms and upload the required graphics.
  3. Upload the apk binary.

If you have not done so, you will be prompted to pay the one-time $25 Google Play developer fee to list your app. Unlike Apple, there is no review process once your app is submitted. There is also no annual renewal fee. The pros and cons of a cheap no-review style app market versus Apple’s process-heavy with higher fee-style app market is a very fruitful debate that will not be discussed here.

9.4 Summary

The Android market is massive. At Google’s annual developer conference in March 2013, they announced 900 million Android activations to date and 48 billion app installs from Google Play [81]. As mentioned before, despite the huge install base and large app market, the mindshare and game engine support is still with Apple iOS. However, these numbers cannot be denied. Android is taking over the mobile world. Ignore the naysayers. Pay the extremely small $25 fee and make the effort to list your game in the store. Google has made the barrier to entry too small to dismiss. The problem of finding HTML5 compilers with good game performance will be solved. We have a good solution with CocoonJS now and more will come along.

The next chapter takes a break from devices and goes back to online distribution through Facebook.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset