Thursday, January 19, 2012

JavaScript 30 day Retrospective

It's been about a month since I began my javascript deep dive. I'm ready to take a short break from the subject but I thought it would be fun to write up a retrospective and then post a demo.

Pre-Production

My prior experience with JS was one of cut and paste. I had never really needed to build anything substantial with it. However like many developers, I naively felt that I could just jump into scripting with it. I found that brute force was definitely not the way to go. Before jumping in I, at least, picked up a copy of JavaScript the Definitive Guide:



I'm fluent in AS3 which is held to the same ECMA Standards as JS. However, the languages are far from similar. They both include the basic structures that you'd expect from any language (arrays, objects, variables, etc.). But one stark contrast is that AS3 has classes built in whereas JS doesn't. JS uses prototypal inheritance instead of classical. At one time back when I was using AS2, I knew a thing or two about the subject but those days have long since passed.

An odd thing about JS is its lack of block scoping which ends up resulting in the use of closures to maintain references to data. Suffice it to say that it takes some getting used to.

Rapid Prototype: first iteration

I skimmed through the aforementioned book but still didn't feel that I had a grasp on JS best practices. It's a great book that covers the language as a whole but doesn't really go into detail on how to use the it effectively. Regardless, I took what I learned and started production on a simple game. I went with the card game High Low. I figured that it was a good choice because I didn't need much art. Via Google, I found a spritesheet similar to this:



Where to start? That's what you always ask yourself when you start a project like this. Well, I wanted to start blitting as quickly as possible so set about building something ( __ click here to see!!__ ) that would do that. It didn't take all that long to get that working. However, during my research on how to emulate class construction, I ran across some musing about best practices in JS by Douglas Crockford. Which inspired me to read his book. He wrote JavaScript the Good Parts:


Rapid Prototype: second iteration

Armed with Crockford's take on JS. I decided to refactor everything that I had built. Among Crockford's many contributes, he's credited with popularizing the Module Pattern in JS. I used a slightly more advanced version of this for the core of my application. Here's the psuedocode version from Crockford's book:

 
var constructor = function (spec, my) {
var that, other private instance variables;
my = my || {};

Add shared variables and functions to my

that = a new object;

Add privileged methods to that

return that;
}


The pattern basically creates an object that allows for private and public access to methods and variables. It also gives you a unique way to implement inheritance. This is good because javascript doesn't give you this functionality out of the box. Everything in JS is globally scoped and accessible by default. My research project definitely didn't require this sort of structure but I'm just used to thinking with private and public members and it was some good practice.

Of note, I was put off by the void of a proper namespace, such as I'm used to in classical langs. So, I used a solution similar to this (see below) to create a single object that I could use to keep my code separate from other JS that may end up on a page:

/***************
* Call this at the top of a file and pass in your desired namespace
* Example: NS.provide('GAME');
* this will give you the ability to add to that NS
* Example: GAME.gGameObject = function () {};
**************/
NS.provide = function() {
var a=arguments, o=null, i, j, d;
for (i=0; i<a.length; i=i+1) {
d=a[i].split(".");
o=window;
for (j=0; j<d.length; j=j+1) {
o[d[j]]=o[d[j]] || {};
o=o[d[j]];
}
}
return o;
};


This also allowed me to separate my JS files and maintain a unique namespace. I'm not sure if there is a better way to handle it but it worked for my needs.

After all that, I knocked out what you'll see below pretty quick. My goal was to build a game with multiple states, a dynamic UI, programmatically generated animation, and some basic sprite sheet handling. The main menu state has 200+ animated entities with a stable framerate which is pretty rad.

The code isn't commented very well but it's functional. Here's what I ended up with:



It's definitely not anywhere close to finished but I learned a great deal by building it!

No comments:

About Me

I produce and engineer games and applications. | Portfolio | LinkedIn