Using PNG Tilesheets for Graphics

Defining Sprite dimensions

Chances are, we may not want our map tiles to simply be blocks of colour. In this lesson, we'll be replacing our basic drawRect calls to make use of a tileset - an image containing sprites for all the different tile Types.

View live Example

We'll be building on the previous tutorial, and will also need to put our tileset PNG image in the same folder as our HTML document. You can download this image here.

We'll begin by adding several more global variables:


var tileset = null, tilesetURL = "tileset.png", tilesetLoaded = false;

The tileset will store our image once it is loaded by the script, which our script will look for at the address specified by tilesetURL. If you put the image in a subfolder, or rename the file, you'll need to change the value of this variable accordingly. Finally, tilesetLoaded is simply a boolean flag which we change to true on successful loading of the image.

We also want to change our tileTypes variable. Each entry will now also have a sprite property, which is an array that currently contains one entry for each tile type: an object with the properties x and y, which states where the tiles image is on the tilesheet, and a w and h property which is the width and height of the area of the tilesheet we'll be drawing for each tile (which is 40x40 pixels, the same as the tileW and tileH variables.


var tileTypes = {
	0 : { colour:"#685b48", floor:floorTypes.solid, sprite:[{x:0,y:0,w:40,h:40}]	},
	1 : { colour:"#5aa457", floor:floorTypes.path,	sprite:[{x:40,y:0,w:40,h:40}]	},
	2 : { colour:"#e8bd7a", floor:floorTypes.path,	sprite:[{x:80,y:0,w:40,h:40}]	},
	3 : { colour:"#286625", floor:floorTypes.solid,	sprite:[{x:120,y:0,w:40,h:40}]	},
	4 : { colour:"#678fd9", floor:floorTypes.water,	sprite:[{x:160,y:0,w:40,h:40}]	}
};

We're making the sprite property and Array, despite the fact each tile currently only has one entry, to prepare for supporting animations.

Directions

In-game Characters, and also objects, items, projectiles, and other features we may add might often require directionality. To allow this, we'll begin by creating an object to represent the 4 cardinal directions. Once again, in other languages we may use an enum to achieve this, but in Javascript we're just using a simple object.


var directions = {
	up		: 0,
	right	: 1,
	down	: 2,
	left	: 3
};

We could simply type the numbers 0-3 anywhere we want to represent a direction, but this method is much more readable.

We'll also extend our Character class so each Character can keep track of their current direction, by adding a simple direction property:


	this.direction	= directions.up;

We also need to add sprites for Characters. We'll extend the Character class further, by creating a new property sprites, and adding an entry for each direction. Once again, the entries will be Arrays with single entries, containing the x, y and w, h information for the sprite to use from the tilesheet.


	this.sprites = {};
	this.sprites[directions.up]		= [{x:0,y:120,w:30,h:30}];
	this.sprites[directions.right]	= [{x:0,y:150,w:30,h:30}];
	this.sprites[directions.down]	= [{x:0,y:180,w:30,h:30}];
	this.sprites[directions.left]	= [{x:0,y:210,w:30,h:30}];

Now we want Characters to change their direction when they move - we'll do this by extending the moveUp, moveLeft, etc., Character methods to set the Character direction property to the appropriate directions value:


Character.prototype.moveLeft	= function(t) { this.tileTo[0]-=1; this.timeMoved = t; this.direction = directions.left; };
Character.prototype.moveRight	= function(t) { this.tileTo[0]+=1; this.timeMoved = t; this.direction = directions.right; };
Character.prototype.moveUp		= function(t) { this.tileTo[1]-=1; this.timeMoved = t; this.direction = directions.up; };
Character.prototype.moveDown	= function(t) { this.tileTo[1]+=1; this.timeMoved = t; this.direction = directions.down; };

The code simply sets this.direction to directions.up in the moveUp method, and so on for each of the 4 directions.

Page loaded in 0.011 second(s).