Skip to content

Instantly share code, notes, and snippets.

@jamesflorentino
Created November 7, 2012 23:09
Show Gist options
  • Save jamesflorentino/4035225 to your computer and use it in GitHub Desktop.
Save jamesflorentino/4035225 to your computer and use it in GitHub Desktop.
PWDO FFC 2012 James Florentino - From Flash to HTML5

From Flash to HTML5

Introduction

This talk will be mostly about my experience on how I moved from Flash to using HTML5 as a platform for my game which includes libraries that I've used and techniques I've contrived during my learning experience.

I will be using my game, Wings Of Lemuria, as an example for this talk.

About my game

It's something I started out in late 2009 as a pet project with the purpose of pushing the limitations of what I can do creatively and technically. It's a turn-based game.

Prototyping in Flash

I initially built the prototype in Flash with ActionScript 3.0 and thought the concept was playable enough. I decided to dedicate some time to it and hopefully get something up for people to try out. My first problem surfaced when some parts of the animation became choppy and CPU intensive because I was using Sprite objects and MovieClips.

Improving performance

Upon researching, I discovered a technique used traditionally by game developers called Blitting where you copy some pixels and paint it over a raster canvas. I developed my own blitting library in Flash and was pretty happy with the results due to its incredible performance. However, the limitation was that you can't scale or rotate any pixel data since you're just storing them into a buffer and re-painting them using bitmapData.copyPixels command. So in a way, my efforts became useless.

At some point, I grew frustrated with the project and decided to put it into hiatus.

First look at HTML5 and JavaScript

After a while and in mid-2011, HTML5 was becoming more prevalent to the Flash community as an alternative for building rich interactive media. So I tried it, read the Canvas 2D API and wrote a quick demo that worked with the sprite animations I've already made months prior.

The performance was neither better nor worse. But the Canvas 2D API allowed me to scale, rotate and animate the bitmap data the way I want to which solves the problem I had before in my blitting library.

Also since JavaScript is a scripted language, there's no compiling process which enabled me to code and debug faster.

I felt comfortable with my new found technology and invested a year's time learning it.

In the end, I went with it and decided to develop my game in HTML5.

Personal reasons why I switched

Cross platform

Playable in both desktop and mobile.

Emerging Technology

Huge potential in terms of market share. Google, Apple, and Microsoft are supporting it.

A Plethora of Open Source libraries

You can use a library and still have access to the annotated version of the code. Helps me become a better developer by learning from the work of experienced programmers.

Yay HTML5, now what?

Months that preceeded my decision to build my game in HTML5, is knowing what available libraries that are already out there. As much as possible, I avoid the itch to re-invent the wheel so I could focus on the actual product itself.

"Any time you're solving a problem that's already been solved, you're being inefficient."

Only invent something when necesarry or when your idea solves a particular set of problems.

Tools of the trade

The CreateJS suite by Grant Skinner as an HTML5 Library

HTML5 utility belt. It includes a canvas library, a sound manager, a tweening engine, and a preloader utility.

EaselJS works as a canvas library. It has an API similar to Flash.

Adding display object to the canvas

ActionScript

var container:Sprite = new Sprite();
stage.addChild(container);

JavaScript with EaselJS

var canvas = document.querySelector('canvas#game');
var stage =  new createjs.Stage(canvas);
var container = new createjs.Container();
stage.addChild(container);

Adding sounds

ActionScript

var sound:Sound = new Sound(new URLRequest('sound.mp3'));
sound.play();

JavaScript with SoundJS

var sound = new createjs.SoundJS();
sound.play('sound.mp3');

without SoundJS using the Audio API

var sound = new Audio('sound.mp3');
sound.play();

without SoundJS using the AudioContext API for more sound control.

var buffer = null;
var context = new webkitAudioContext();

function loadSound(url) {
  var request = new XMLHttpRequest();
  request.open('GET', url, true);
  request.responseType = 'arraybuffer';
  request.onload = function() {
    context.decodeAudioData(request.response, function(buffer) {
      buffer = buffer;
    }, onError);
  }
  request.send();
}

loadSound();

Preloading assets

private var loader:Loader;

public function Main() {
  load = new Loader();
  loader.contentLoaderInfo.addEventListener(Event.COMPLETE, this.onComplete);
  loader.load('image.png');
}
private function onComplete(e:Event):void {
  trace('preload complete!');
}

JavaScript with PreloadJS

var loader = new createjs.Preloader();
loader.onComplete = function() {
  console.log('preload complete!');
};
loader.loadFile('image.png');
loader.load();

JavaScript without PreloadJS

var image = new Image();
image.onload = function() {
  console.log('preload complete!');
};
image.load('image.png');

RequireJS

For loading dependencies using the AMD pattern.

Stylus and Nib as my CSS preprocessor

For taking care of the nesting and vendor prefixes.

ExpressJS and Socket.IO for the networking layer

Express JS for running the server application, and Socket.IO for managing WebSockets and its fallback protocols.

Chrome Developer Tools

For Ninja style HTML/CSS development.

Elastic Cloud Compute in Amazon Web Service

This isn't part of web design, but I use this to host my node.js app.

Preparing Game Assets

I still rely on the Flash IDE for animating my sprites mainly because it's something I'm fairly familiar with. In order to get this to work with the HTML5 canvas, I publish the SWF and load it into Zoé which is a Sprite sheet exporter of the CreateJS suite. It exports a JSON file with the frameData in it, along with the compressed PNG image.

For static bitmap elements, I use a software called TexturePacker which is widely used in the Corona SDK community for game development in iOS and Android. It basically does the same thing as Zoé with the exception that I don't need to import the individual elements in Flash anymore. It reads a directory automatically.

Making the game client in JavaScript

In Flash, one of the things I liked is how everything is packaged and easily managed as class files. In JavaScript, there's no official way of doing this. One solution is using namespaces for your app. Problem is, it's still accessible at the global scale.

Luckily we have AMD to the rescue. It allows the code to be separated and modularized as much as possible.

Modules are asynchronusly loaded during development then concatenated, minified and baked during deployment.

This solution enables me to debug the JavaScript code easily.

Basic AMD Usage

define(moduleId, dependencies, definition);

Example code

define('carClass', ['settings'], function(settings) {
  return function() {
    var Car() {
      this.speed = settings.speed;
    }
    return Car;
  }
});

Building the front-end client

I separated the UI from the game canvas for a variety of reasons.

  • It's easier to set the texts and styling of the UI through CSS.
  • CSS3 transitions and transforms are hardware accelerated.
  • CSS3 Keyframe animations are more maintainable than hardcoded JavaScript animation behaviors.

For images, I used a CSS sprites for combining PNG assets into one file. This reduces HTTP requests which is perfect for a browser-based game.

Using Stylus along with Nib as preprocessor

Although not necesarry, stylus provides me with a minimalistic coding environment for writing CSS allowing me to code faster.

Pros

  • Variables
  • Computation
  • Mixins
  • Nesting
  • Optional colon-less and semi-colonless syntax
  • Optional indented syntax

Cons

  • Not as mature as SASS with Compass
  • No support for image spriting
  • Pre-requisite knowledge has high learning curve

Creating the game server

I chose node as my web server because it uses JavaScript. It allows me to use client-side code with the server and vice versa.

Express.js

  • Simplicity and ease of use
  • Ease to configure routes
  • Sinatra-like design

Socket.io

  • Has fallback mechanisms
  • Uses event emissions

Acknowledgement

My name is James Florentino and I'm a creative and passionate front-end designer who's currently working for a startup building web-based chat applications. My roots originate from the Flash design era but now have fully migrated to utilizing HTML5 technologies for web applications and games.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment