Friday, April 20, 2012

Dirty rectangles

Recently I’ve been experimenting in HTML5 game development and like my last post, this post is to document my findings.

Dirty Rectangles, what are they?

Imagine canvas animation is similar to cel animation, in that you compose your animation using serveral layers. Cel animators don’t want to have to draw the entire character for each frame if the only thing that is moving is the character’s mouth. (thanks to @speakersfive for this analogy)

With dirty rectangles, we detect which areas of our game have changed and therefore need updating.

How do we detect a dirty rectangle

The simplest way is to keep an array of ractangles, foreach over them on the next draw pass and clear those areas of our canvas.

You might be thinking; “what about my background or HUD?”, remember the cel animation analogy? Well just like cel animation we’d create our game in layers, leaving our background unaffected by our player’s movement.

Whenever we make a change to the player’s position, we’d mark the player sprite as dirty and add its rectangle to the array of dirty rectangles

How do we code this>

Coding this is fairly straight forward, so lets start with our game object.

// Game is our game object and hold all data about our game
// as well as update and draw methods
Game.dirtyRectangles = [];
function Player(x, y, width, height) {
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
}


/**
 * Move player by x and y increments
 * @param  {Number} x player x increment
 * @param  {[type]} y player y increment
 * @return {void}
 */
Player.prototype.move = function Player_move(x, y) {
    var original_x = this.x;
    var original_y = this.y;

    this.x += x;
    this.y += y;

    // if some change to the position was made
    if (original_x != this.x || original_y != y) {
        this.dirty = true;

        // add this rectangle to the dirty rectangles array
        // note: it's the rectangle before the movement was made
        Game.dirtyRectangles.push({
            x: original_x,
            y: original_y,
            width: this.width,
            height: this.height
        });
    }
};

So let me explain what we are doing here.

This prototype is configured to have an x and y position and a width and height. These properties control the position of the player and dirty rectangle size and position.

When we call move() to move out player we first store the existing position and then update it. Next we check if the position changed since the start of the method, when we stored the position, if it did then we set the dirty property and push an object holding the bounding rectangle of the previous position into the dirty rectangle array.

Next we move on to our game loop’s draw method.

Game.draw = function Game_draw() {
    var ctx = Game.canvasContext;


    var i, dirtyRectangleCount = this.dirtyRectangles.length;
    for (i = 0; i < dirtyRectangleCount; i+= 1) {
        var rect = this.dirtyRectangles[i];

        // clear this rectangle from the canvas
        ctx.clearRect(rect.x, rect.y. rect.width, rect.height);
    }

    // clear the dirty rectangle list
    this.dirtyrectangles = [];

    // then redraw any dirty sprites
    var spritesCount = this.sprites.length;
    for(i = 0; i < spritesCount; i += 1) {
        var sprite = this.sprites[i];

        // is the sprite dirty?
        if (sprite.dirty) {
            sprite.draw(ctx); // pass canvas context to the sprite
        }
    }
};

Okay, here we iterate of the the dirty rectangles array and clear those parts of the canvas. then we iterate over the sprites and redraw any sprites that have been marked as dirty. Simple.

Next we’ll need to mark our sprite as clean again. The best place to do this is probably the sprite’s draw method.

/**
 * Draw the player
 * @param  {CanvasContext} ctx canvas context
 * @return {void}
 */
Player.prototype.draw = function Player_draw(ctx) {
    /*
        ...
        our drawing code
        ...
    */
   
   // set our sprite to clean again
   this.dirty = false;
};

And that’s it. Only the changed parts of our screen will be updated using dirty rectangles.

Feel free to give me feedback on twitter @bytespider

Wednesday, April 4, 2012

requestAnimationFrame and HTML5 game loops

When looking at writing a HTML5 game, I first went down the usual route of using setTimeout(run, 1000/60);. However due to the nature of javascript, this isn’t always optimal. Javascript is single threaded so you can’t always guarantee that your frame will be rendered when you expected it.

In walks requestAnimationFrame

Thankfully there’s a new kid on the block, requestAnimationFrame, and the browser will call your function when it has rendering time free and passing the time.

But how do we update our game loop to use this? In much the same way as setTimeout() thankfully.

function main(time) {
    run();
    window.requestAnimationFrame(main);
}
window.requestAnimationFrame(main);

Gotcha

This one stumped me for a while, but in my simple game the CPU was hitting 100%. So I added code to reduce the frame rate.

var skipTicks = 1000 / 30, nextTick = new Date().getTime();
function run(time) {
    while (time > nextTick) {
        update();
        draw();

        nextTick += skipTicks;
    }
};

However my CPU usage was still 100%. I had a think and it dawned on me, requestAnimationFrame makes a request for rendering time and the browser will give the next available spot. But the browser is so fast, we’re practically requesting a frame every millisecond, no wonder my CPU hits 100%.

So I’ve updated my code, to wait 10ms before requesting the next animation frame.

function main(time) {
    run();
    setTimeout(function () {
        window.requestAnimationFrame(main);
    }, 10);
}
window.requestAnimationFrame(main);

Object cloning using ES5

function clone(object) {
    var cloned = Object.create(object.prototype || null);
    Object.keys(object).map(function (i) {
        cloned[i] = object[i];
    });

    return cloned;
}

Thursday, March 1, 2012 Tuesday, February 28, 2012

Using CommonJS modules for UI View components in Titanium

I’ve been playing with using CommonJS modules in Appcelerator Titanium to create reusable components and prototypes. I start with a basic object structure:

function Car() {
    this.init.apply(this, arguments);
}

Car.prototype.init = function (make, model) {
    this.make = make;
    this.model = model;
};

Car.prototype.make = null;
Car.prototype.model = null;

Car.createWithMakeAndModel = function (make, model) {
    return new Car(make, model);
};

module.exports = Car;

Whilst you may argue there is some redundancy in the pattern I use, I makes sections of code easy to override later on if I decide to use it as a prototype.

You may also frown upon the use of module.exports = Car;. However I find that

var Car = require("Car");

looks and feels better than

var Car = require("Car").Car;

You may argue that you should never have access to the constructor and that you should use factory methods. Whilst your argument is valid, I prefer to be able to make sure that my object X is an instance of Y using the built in instanceof operator.

How this applies to views and windows

For views and windows I add .view and .wnd properties to my object inside my init() method, which is where I call all other parts of my view construction. Take the following example of a list view.

function UIListView()
{
    this.init.apply(this, arguments);
}

UIListView.prototype.init = function () {
    this.view = Ti.UI.createTableView();
};

UIListView.prototype.populate = function (data) {
    var i = 0, len = data.length, row;
    for (; i < len; ++i)
    {   
        row = Ti.UI.createTableViewRow(data[i].asTableViewRow());
        this.view.appendRow(row);
    }
};

module.exports = UIListView;

As you can see I can now call populate() at anytime to update my view with new data.

I’d like to experiment more with patterns like this. I’d love to hear your opinions and suggestions for other patterns or structures, so tweet me or send me an email.

Friday, February 24, 2012

Chosen does allow you to set when the search box should show

I started using chosen in a few projects but it frustrated me that the search box would always show regardless of how many options I had.

I read through the website and discover theres no mention of a setting, so being a good little community developer I decide to implement the functionality.

After getting my head round the coffeescript source, which in my opinion is far worse to read and grok than javascript, I add the code. Then i think I’ll be really good and make it configurable before I submit a pull-request.

Thats when I discover disable_search_threshold, and wondering what it was I try it. Turns out that it’s exactly the functionality I had just written and wasted time on.

So next time you’re using chosen and you need to hide search for the first, lets say, 10 items do this:

$(".chzn-select").chosen({
    disable_search_threshold: 10
});
Thursday, January 19, 2012

jsOAuth in the browser, my response to OAuth in web browsers

  • Developer:
  • We are on a look out for a Javascript OAuth library that works in browsers.
  • Rob Griffiths:
  • There are some things you need to consider when trying to get OAuth working in the browser using Javascript.
  • Firstly, Javascript source is viewable by anyone with the inclination to do so, this means that your OAuth Key and Secret are publicly accessible, meaning that an attacker could use your credentials to sign requests and gain access tokens, in theory at least. In my opinion the attacker would have to fool a user into thinking they were your site, which isn't too hard but users are stupid and can be fooled easily.
  • Secondly, if your site contacts a third party webservice, you'll be bound by in build browser security as you are making a cross domain request. The security disables any XHR from talking to a domain other than the one it was created on.
  • Unless you use CORS (cross origin resource sharing), however most web services dont support this, which is a shame as this would make the web a better place allowing sites to interact at the client level creating interesting application mashups.
  • So I'd ask this;
  • - Does the webservice you're planning to use support CORS?
  • - Do you have a plan to hide your secret in plain sight?
  • Most people solve these issue by building a server-side script to proxy their XHR.
Thursday, October 27, 2011

Why make Promises

Whatever you may call them, Promises, Futures or even Deferred the concept is the same. You ask an asynchronous task to do something, and it gives you a promised result back instantly which you can then act upon.

Take this trivial example in javascript:

var results = searchTwitter("Starwars");
filterByAuthor("@darthvader1977", results);
displayTweets(results);

Now wouldn’t that be great? Looks synchronous but behaves asynchronously? Sadly, I believe that this would require a language construct not native to most programming languages.

There are a few promise libraries written in Javascript that provide an API we can utilise on our previous example.

searchTwitter("Starwars").
    then(filterBydarthvader1977).
    then(displayTweets);

An heres where I’m confused. Why is this better then doing:

searchTwitter("Starwars", function (results) {
    displayTweets(filterByAuthor("@darthvader1977", results));
});

Yes I guess, yes it does look prettier and more concise, and the API is explicit in its intent, but is that enough? This covers the Promises/A proposal as detailed on the CommonJS wiki. In my opinion pretty useless, at least in Javascript. From what I can tell, all of the proposals seem require the supply of a callback of some sort. This to me is interesting as I thought the whole idea behond promises was to get rid of the layers of nested callback, not just to reduce them.

So this leads me to an idea, which after a conversation with a collegue seems to make sense. So lets start with an example.

var tweets = searchTwitter("Startwars");
tweets.filterByAuthor("@darthvader1977");
tweets.display();

As you can see, we call method on the tweets variable. I’m assuming that the searchTwitter method instantly returns a tweets object, with each method queuing the call until the asynchronous call to searchTwitter completes, which then calls each method in turn in the order it was invoked.

Now I’m certain this isn’t a new idea, and there must be a library out there or a specification, can someone tell me where?

Friday, April 15, 2011

Using OpenStreetMap.org with the Google map API

Using a custom map type, its really simple to use the Google map API with tiles from open street map.

function OSMMapType() {}
OSMMapType.prototype = {
	tileSize: new google.maps.Size(256,256),
	maxZoom: 18,
	getTile: function(coord, zoom, ownerDocument) {
		var tileUrl = 'http://tile.openstreetmap.org/' + zoom + '/' + coord.x + '/' + coord.y + '.png';

		var tile = ownerDocument.createElement('img');
		tile.width = this.tileSize.width;
		tile.height = this.tileSize.height;
		tile.src = tileUrl;

		return tile;
	}
};

With this map type we instantiate a google map, and tell it to use our custom type

var latLng = new google.maps.LatLng(54.572061655658494, -3.7408447265625);
var map = new google.maps.Map(document.getElementById("map"), {
	zoom: 5,
	center: latLng,
 	mapTypeId: 'osm'
});

map.mapTypes.set('osm', new OSMMapType());
map.setMapTypeId('osm');

So you you end up with something like this: