HTML5 Zone is brought to you in partnership with:

Andrew Trice is a Technical Evangelist with Adobe Systems. Andrew brings to the table over a decade of experience designing, implementing, and delivering rich applications for the web, desktop, and mobile devices. Andrew is an experienced architect, team leader, accomplished speaker, and published author, specializing in immersive experiences, mobile development, realtime data systems, and data visualization. Andrew is a DZone MVB and is not an employee of DZone and has posted 53 posts at DZone. You can read more from them at their website. View Full User Profile

PhoneGap Legends – A Sample Game App

03.25.2013
| 5872 views |
  • submit to reddit

Next week I’ll be representing Adobe at GDC 2013, and demonstrating how Adobe Creative CloudPhoneGap, and PhoneGap Build can be great tools for building casual gaming experiences. In preparation, I’ve been working on a gaming sample application that shows off the potential of HTML games packaged with PhoneGap.

…and now I’d like to introduce you to PhoneGap Legends. PhoneGap Legends is a fantasy/RPG themed demo that leverages HTML DOM animation techniques and targets webkit browsers. I was able to get some really outstanding performance out of this example, so be sure to check out the video and read the details below. The name “PhoneGap Legends” doesn’t mean anything; I just thought it sounded videogame-ish and appropriately fitting.

PhoneGap Legends

PhoneGap Legends

This game demo is an infinitely-scrolling top-view RPG themed game that is implemented entirely in HTML, CSS, and JavaScript. There is a scrolling background, enemy characters, HUD overlays, and of course, our “protagonist” hero – all that’s missing is a story, and general game mechanics like interacting with sprites.

Again, I was able to get some *really outstanding performance* out of this sample, so I wanted to share, complete with source code, which you’ll find further in this post (and I encourage you to share it too). Take a look at the video below to see the game in action on a variety of devices. Every single bit of this is rendered completely with HTML, CSS, and JavaScript – there are no native portions of the application.


Update 3/24:  If you’d like to test this out on your own devices, you can now access it online at http://tricedesigns.com/portfolio/phonegap_legends/   However, it will still only work on webkit browsers (Chrome, Safari, Android, iOS, etc…), and is optimized for small-device screens.  If you attempt to use this on a very large screen, you’ll probably see some sprite clipping.

Disclaimer: This sample app is by no means a complete game or complete game engine. I’ve implemented some techniques for achieving great performance within a PhoneGap application with game-themed content, but it still needs additional game mechanics. I also wrote this code in about 2 days – it needs some additional cleanup/optimization before use in a real-world game.

Source

Full source code for this demo application is available on github. This code is provided as-is: https://github.com/triceam/PhoneGap-Legends. I will be making a updates over the next few days in preparation for GDC next week, but for the most part, it is stable.

Development Approach

The PhoneGap Legends application was built following the performance tips that I posted earlier this month. The game is built so that it uses a game loop based upon requestAnimationFrame to perform all UI updates. This gives it a scheduled interval that is in sequence with the browser’s redraw cycle.

In general, the DOM is as shallow as possible for achieving the desired experience. All “sprites”, or UI elements are basic DOM nodes with a fixed position and size.  All DOM elements have an absolute position at 0,0 and leverage translate3d for their x/y placement.  This is beneficial for 2 reasons: 1) It is hardware accelerated, and 2) there are very, very few reflow operations.  Since all the elements are statically positioned and of a fixed size, browser reflow operations are an an extreme minimum.

The background is made up a series of tiles that are repeated during the walk/movement sequence:

Sprite Sheet for Background Tiles

In the CSS styles, each tile is 256×256 square, with a background style that is defined for each “type” of tile:

.tile{
    width: 256px;
    height:256px;
    overflow: hidden;
    position: absolute;
    top:0px;
    left:0px;
    background-repeat: repeat;
    background-clip:border-box;
}
.tile_0 {      background: url('../images/background_tiles.png');     background-position: 0px 0px;}
.tile_1 {      background: url('../images/background_tiles.png');     background-position: 256px 0px;}
.tile_2 {      background: url('../images/background_tiles.png');     background-position: 512px 0px;}
.tile_3 {      background: url('../images/background_tiles.png');     background-position: 0px 256px;}
.tile_4 {      background: url('../images/background_tiles.png');     background-position: 256px 256px;}

The content displayed within each of the “sprite” DOM elements is applied using sprite sheets and regular CSS background styles. Each sprite sheet contains multiple images, the background for a node is set in CSS, and the position for each image is set using the “background-position” css style.  For example, the walking animation for the hero character is applied just by changing the CSS style that is applied to the “hero” <div> element.

Sprite Sheet for Hero

There is a sequence of CSS styles that are used to define each state within the walking sequence:

.hero_0_0{ background: url('../images/rpg_sprite_walk.png'); background-position:0px 0px;}
.hero_0_1{ background: url('../images/rpg_sprite_walk.png'); background-position:0px 96px;}
.hero_0_2{ background: url('../images/rpg_sprite_walk.png'); background-position:0px 192px;}
.hero_0_3{ background: url('../images/rpg_sprite_walk.png'); background-position:0px 288px;}
...

This game demo extensively uses translate3d for hardware accelerated composition.  However, note that the 3d transforms are all applied to relatively small elements, and are not nested. All of the “textures” are well below the max texture size across all platforms (1024×1024), and since it use sprite sheets and reusable CSS styles, there are relatively few images to load into memory or upload to the GPU.

Attribution

The following Creative Commons assets were used in the creation of this sample app and the accompanying video:

Image – Grass Texture:http://opengameart.org/content/grass-with-moss
Image - Trees/Bushes:http://opengameart.org/content/2d-rpg-character-walk-spritesheet
Image - Main Character:http://opengameart.org/content/lots-of-hyptosis-tiles-organized
Image - Enemies:http://opengameart.org/content/rpg-enemies-11-dragons
Image - Compass Rose:http://en.wikipedia.org/wiki/File:Compass_rose_en_04p.svg

Font – Avalon Quest: http://www.ffonts.net/Avalon-Quest.font
Note: I used a free/open licensed font that could be embedded in the app for offline usage. This font was converted to a web-font package that can be embedded in the PhoneGap application using http://www.fontsquirrel.com/

Audio – Monster:http://www.freesound.org/people/Erdie/sounds/167890/
Audio – Music:http://www.freesound.org/people/rap2h/sounds/115261/

Source

Again, in case you missed it above, Full source code for this demo application is available on github. This code is provided as-is: https://github.com/triceam/PhoneGap-Legends.



Published at DZone with permission of Andrew Trice, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)