Article

Home » Client-side Coding » JavaScript & Ajax Tutorials » Hacking JavaScript for Fun and Profit: Part I
SitePoint Feature Article

About the Author

Myles Eftos

author_myles Myles Eftos is a Perth-based web developer that jumped on the Rails express and never looked back. He is the event co-ordinator for the Australian Web Industry Assocation which explains why most of their events are at the pub near his house.

View all articles by Myles Eftos...

Hacking JavaScript for Fun and Profit: Part I

By Myles Eftos

September 12th, 2008

Reader Rating: 9

Page: 1 2 3 Next

JavaScript has become a large part of the web development and design experience in the past few years. It allows us to spruce up dull, static pages, avoid page refreshes, and accomplish some amazing feats of interface engineering—things that would not have been possible using just HTML and CSS. Of course, Ajax and DOM Scripting is seen as run of the mill now, and is part of every web developer’s tool kit when building web sites. But how far can we push it? It’s a powerful, object oriented language that has a rich output mechanism, so surely we can use it for more than launching popup windows?

So what does any self-respecting geek do when confronted with such a question? They write a 2-D, side-scrolling platform game, of course!

In this two-part series, you will learn enough HTML, CSS, and JavaScript to enable you to build your very own JavaScript platform game. I’ve used the Prototype JavaScript library in the examples, simply because it was what I know—many of the other JavaScript libraries available may well have equivalent capabilities.

Before we get to the fun stuff, we need to run through some of the advanced JavaScript techniques that will allow us to trick your browser into thinking it’s an 8-bit game console.

Construction 101

JavaScript (JS) is a prototyped object oriented programming (OOP) language. This means we can represent constructs—for example, a video game character—as an object within our code. Building a JS class might seem a little weird if you’re familiar with some of the more traditional OOP languages. For starters, rather than everything being an object, like in Ruby, everything in JS is a data type. These data types have an internal data type—called the prototype—that tells the data type how to behave. So we need to define the class in such a way that it:

  1. knows that it is a class

  2. can be created and initialized into a defined initial state

Let’s look at some JS code that builds a new class, and then creates a new object:

// Declare the class
function WalkingSprite(element, x, y) {
 this.x = x;
 this.y = y;
 this.element = element;
}

WalkingSprite.prototype = {
 x: 0,
 y: 0,
 element: null,
 
 walk: function(direction) {
   this.x += direction;
 }
}

koopa = new WalkingSprite(null, 10, 10);
koopa.walk(20);
alert(koopa.x + "," + koopa.y);

A cursory glance over this code shows that we have built a new class called WalkingSprite that has three properties (element, x and y) and one function, called walk. If we instantiate a new version of the object and call it walk function, our koopa object will now be at coordinate point (20, 30). Declaring classes this way is a little cumbersome—we have to create a class, and then update the prototype. Thankfully, Prototype (the library) has encapsulated it into a handy function called Class.create. The above code becomes this:

var WalkingSprite = Class.create({
 x: 0,
 y: 0,
 element: null,

 initialize: function(element, x, y) {
   this.element = element;
   this.x = x;
   this.y = y;
 },

 walk: function(steps) {
   this.x += steps;
 }
});

koopa = new WalkingSprite(null, 10, 10);
koopa.walk(20);
alert(koopa.x + "," + koopa.y);

Working with Class Inheritance

Another fundamental component of OOP is the concept of inheritance. Basically, if you have a base class that has certain variables and functions, all classes that extend that class inherit those variables and functions. You can then add additional functions and even override those functions to do something else. This could be really useful in our game, because all of our characters will probably exhibit some common attributes—they may all be able to walk around the screen—but maybe only one type of character can jump. Sounds like a perfect candidate for inheritance.

Unfortunately, JavaScript doesn’t support inheritance natively. So, why have I wasted the last paragraph telling you about it? Well, with a bit of trickery, we can emulate class inheritance in JavaScript.

Because everything in JavaScript (including functions in our classes) are variables, we can assign their values to other variables. So, if we think about what inheritance is for a second, all we need to do to emulate it, is to copy the properties and functions from the parent class to the child class. If we want to inherit from the class we created above, we could do this:

// Declare the class
function WalkingSprite(element, x, y) {
 this.x = x;
 this.y = y;
 this.element = element;
}

WalkingSprite.prototype = {
 x: 0,
 y: 0,
 element: null,
 
 walk: function(direction) {
   this.x += direction;
 }
}

// Create the child class
JumpingAndWalkingSprite = WalkingSprite;
JumpingAndWalkingSprite.prototype = {
 x: 0,
 y: 0,
 walk: WalkingSprite.prototype.walk
 jump: function() {
   y += 20;
 }
}

Run the code, and you will have a new class that has the two properties and one function from its parent, plus one new function: jump. The only thing is, coding like this doesn’t really scale; what if you add a duck function to the parent class? You would have to go through every child class and add the function signature. Once again, Prototype to the rescue! The Class.create function we learned about before can take another class as its first argument. This supplied class will become the parent, and it will dynamically find all of the properties and functions for us, automatically injecting them into the child class. So the above will become:

var JumpingAndWalkingSprite = Class.create(WalkingSprite);

mario = new JumpingAndWalkingSprite(null, 10, 10);
mario.walk(10):
alert(mario.x + "," + mario.y);
mario.jump();
alert(mario.x + "," + mario.y);

As expected, the new class has all of the same properties of the parent class! So what about adding and overriding properties and functions? We demonstrated above how to do this manually, but Prototype allows us to define new functions using Class.create:

var JumpingAndWalkingSprite = Class.create(WalkingSprite, {
 walk: function($super, steps) {
   $super(steps * 2);
 },

 jump: function() {
   this.y += 20;
 }
});

Here, we have overridden the walk function and added a jump function. Hang on—back the truck up—where did that $super variable pop up from? Good question! When using inheritance, it can sometimes be useful to run the parent class’ version of the function. In this case, we make the character walk twice as far as originally requested by doubling the input variable, and passing this new value to the parent class. Prototype will supply the parent class’ version of the function in the $super variable, if you declare $super as the first argument of the function’s signature. This allows you to easily call the parent version of the function from within the overridden version. You’ll notice that the new jump function doesn’t have the $super variable; we don’t use it, so we don’t need to supply it. If we did need it, we could just add it as the first argument of the function signature.

If you liked this article, share the love:
Print-Friendly Version Suggest an Article

Sponsored Links