Pitfalls to look out for when writing a canvas game for Android devices

Recently a client approached Metal Toad to develop a prototype game for Android devices and leaving the option of porting it to other devices open. We decided to develop the game using HTML5's canvas element and wrap it in phonegap to bring it to Android devices. In this post I'll talk about the major pitfalls I encountered while working on the project and provide you with some points to keep in mind while developing canvas games for mobile devices.

JawsJS

Let me speak a bit about the game engine I decided to use: JawsJS. This canvas game engine made development a breeze. It is a lightweight game engine that provides many features to speed up development. Sprites, Spritesheets/animations, collision detection, tile maps, parallax scrolling and viewports are all handled by JawsJS in addition to the basic game loop (setup, update, draw). It also features a nice asset manager that will allow you to preload all the necessary assets for your game before hand.

I had been doing most of my development in my computer's browser, with the mindset of "Hey, if it works in a chrome browser on the desktop, it'll work in a webview on the Android device!" I was so wrong, so very, very wrong. After a while of coding the game and its mechanics, I went ahead and packaged up a test build for an Android tablet. After the app installed and began to run, it quickly threw up some errors in my debug log and proceeded to crash.

Preload *all* the things

Upon further investigation, this error was due to JawsJS attempting to draw the images before they had finished loading. Even though I was using the asset manager, my images weren't being preloaded properly. This only occurred in the webview though. On the desktop and on the tablet's native browser where it would seem more likely to draw before loading has completed, this worked fine! The only way I could fix this was by hacking JawsJS to actually store the image object in memory when the asset manager loaded it.

Android's webview has poor-to-no support for the <video> element

The second major issue I encountered in my journey to Android-land, was the lack of support for the <video> tag in Android. The game has some cut-scenes and a video tutorial. I was creating a video element and displaying the frames onto the canvas to accomplish this. On Android this would not do. When I entered a cut-scene, the app would freeze and I'd see a bunch of "call to OpenGL ES API with no current context" errors in the debug log. Initially I had thought I was generating the video element incorrectly and/or there was some odd encoding setting involved with the video file itself. I decided to make a simple page with a few different videos with varying markup to see if any worked on the tablet. In the tablet's native browser I could get the videos to load fine in a <video> tag, but not in the webview. This seems to be a limitation of the webview itself and I was able to implement a workaround using the Video plugin for phonegap. This opens the video in the native player — removing any status/events I was using to check when the video had ended. This was a bit of a hack, but it worked. There is probably room for improvement here via some hefty phonegap plugin that might be worth researching and developing if support for the <video> element remains minimal in the Android webview.

My tablet can't focus

The game was so close to being in a working state by now. There was one big issue remaining. My touch events seemed to fire only some of the time when I was touching the screen. When they would fire, a large light-blue overlay would envelope the entire canvas for a few seconds. This bug turned out to be focus related. I had to ensure that the webview had the current focus after each video played (since it was now playing in the external media player). To do this I had to extend a small phonegap plugin to call webView.requestFocus(View.FOCUS_DOWN); when returning to the game from a cut-scene. With that fixed, I had a complete canvas game running both for desktops and Android devices.

Success!

I was overly ecstatic that all of the major bugs were resolved finally! I only had a few non-platform related issues to hammer out and the game would be complete. As happy as I was, when I realized the poor performance of canvas on the tablet, my happiness faded away. While the desktop I was testing with made my app seem fast and responsive, the tablet ran like molasses on a cold day. However, after some speed improvements, the prototype ran at a decent speed. If the game were to evolve beyond the prototype stage, it might need some additional hacking, or a different approach to achieve faster speeds.

In brief, here's a few things to keep in mind when developing an HTML 5 application for a mobile device:

  • Always test on your device alongside any desktop testing.
  • Canvas game engines are very new, they might have a few bugs in them.
  • Be prepared for differences even between the device's browser and the device's webview.
  • Don't be afraid to write some native code!
  • Spend even more time researching the current limitations of your device.
  • Run a few small speed tests to see if your game will run as fast as you desire (on both desktop and tablet!).

Good luck and happy coding!

Filed under 


Very nice summary of the issues. Sorry I cannot contribute more to this than to agree that HTML5 canvas games on Android tablets run very poorly. Your list of suggestions is very good.


I am also encountering the "call to OpenGL ES API with no current context" errors while trying to play the videos inside droid's WebView and I wanted to ask you which approach did you take with the PhoneGap plugin.

I tried several ways for my application:
1. Opening another activity through intent (aVideo plugin) that uses the VideoView. This works just fine, but I didn't succeed to make the video occupy only a part of the screen.
2. Opening a VideoView that was initially hidden. This works, but for some reason I cannot control the video position and I didn't succeed to make the video switch to full screen and back on double tap.

Recently I found another option - a very beautiful and feature-rich VideoView implementation for Android that I am definitely going to give a try, but first I will need to wrap it with the PhoneGap plugin. Here it is: http://blog.denivip.ru/index.php/2011/09/developing-video-player-for-an…

Add new comment

Restricted HTML

  • Web page addresses and email addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd> <h4> <h5> <h6>
  • Lines and paragraphs break automatically.
  • You can enable syntax highlighting of source code with the following tags: <code>&lt;code&gt;</code>, <code>&lt;blockcode&gt;</code>, <code>&lt;apache&gt;</code>, <code>&lt;c&gt;</code>, <code>&lt;cpp&gt;</code>, <code>&lt;css&gt;</code>, <code>&lt;drupal5&gt;</code>, <code>&lt;drupal6&gt;</code>, <code>&lt;html&gt;</code>, <code>&lt;java&gt;</code>, <code>&lt;javascript&gt;</code>, <code>&lt;mysql&gt;</code>, <code>&lt;php&gt;</code>, <code>&lt;python&gt;</code>, <code>&lt;ruby&gt;</code>, <code>&lt;sql&gt;</code>, <code>&lt;xml&gt;</code>. The supported tag styles are: <code>&lt;foo&gt;</code>, <code>[foo]</code>.

About the Author

Chris Svajlenka, Development Team Lead

Chris is a web developer with many years of experience developing web applications. PHP is his go-to language, with experience with others such as Ruby and Python. He has provided systems administration to large organizations and enjoys hunting down bugs in code.

Chris enjoys a love of documentaries with an emphasis on nature, the cosmos, and sustainable business practices. He also has a love for plants, gardening and a fine IPA.