Movement speeds on different tile types

Surface movement speeds

Ever tried running in deep snow? Chances are, you've noticed different surfaces may help or hamper the speed at which you can comfortably walk. In this tutorial, we'll be doing the same for our Character.

View example
tileset

The tilesheet used is the same as in the previous tutorial.

Firstly, the Character delayMove property, which before was simply our single-tile movement speed in milliseconds, becomes a list of movement speeds for all of the floorTypes we want our Character to be able to walk on:


	this.delayMove	= {};
	this.delayMove[floorTypes.path]		= 400;
	this.delayMove[floorTypes.grass]	= 800;
	this.delayMove[floorTypes.ice]		= 300;
	this.delayMove[floorTypes.conveyorU]	= 200;
	this.delayMove[floorTypes.conveyorD]	= 200;
	this.delayMove[floorTypes.conveyorL]	= 200;
	this.delayMove[floorTypes.conveyorR]	= 200;

As you can see, we've given grass a movement speed of 800 milliseconds per tile, and path a movement speed of 400 milliseconds per tile. Simply put, our Character will be able to cross 2 path tiles in the time it takes to cross 1 grass tile!

We'll add a new temporary variable to the Character processMovement method; immediately after our first if statement to check the Character is truly moving, we'll assign the new moveSpeed variable the delayMove value corresponding to the floorType of the map tile our Character is moving from (tileFrom):


	var moveSpeed = this.delayMove[tileTypes[gameMap[toIndex(this.tileFrom[0],this.tileFrom[1])]].floor];

We'll then replace every occurrence of delayMove in this method after this line with the moveSpeed variable. The method, after editing, will look like this:


Character.prototype.processMovement = function(t)
{
	if(this.tileFrom[0]==this.tileTo[0] && this.tileFrom[1]==this.tileTo[1]) { return false; }

	var moveSpeed = this.delayMove[tileTypes[gameMap[toIndex(this.tileFrom[0],this.tileFrom[1])]].floor];

	if((t-this.timeMoved)>=moveSpeed)
	{
		this.placeAt(this.tileTo[0], this.tileTo[1]);

		var tileFloor = tileTypes[gameMap[toIndex(this.tileFrom[0], this.tileFrom[1])]].floor;

		if(tileFloor==floorTypes.ice)
		{
			if(this.canMoveDirection(this.direction))
			{
				this.moveDirection(this.direction, t);
			}
		}
		else if(tileFloor==floorTypes.conveyorL && this.canMoveLeft())	{ this.moveLeft(t); }
		else if(tileFloor==floorTypes.conveyorR && this.canMoveRight()) { this.moveRight(t); }
		else if(tileFloor==floorTypes.conveyorU && this.canMoveUp())	{ this.moveUp(t); }
		else if(tileFloor==floorTypes.conveyorD && this.canMoveDown())	{ this.moveDown(t); }
	}
	else
	{
		this.position[0] = (this.tileFrom[0] * tileW) + ((tileW-this.dimensions[0])/2);
		this.position[1] = (this.tileFrom[1] * tileH) + ((tileH-this.dimensions[1])/2);

		if(this.tileTo[0] != this.tileFrom[0])
		{
			var diff = (tileW / moveSpeed) * (t-this.timeMoved);
			this.position[0]+= (this.tileTo[0]<this.tileFrom[0] ? 0 - diff : diff);
		}
		if(this.tileTo[1] != this.tileFrom[1])
		{
			var diff = (tileH / moveSpeed) * (t-this.timeMoved);
			this.position[1]+= (this.tileTo[1]<this.tileFrom[1] ? 0 - diff : diff);
		}

		this.position[0] = Math.round(this.position[0]);
		this.position[1] = Math.round(this.position[1]);
	}

	return true;
}

Finally, we'll change the way the canMoveTo suitable floorType check works. Instead of listing all the floorTypes we can move to and returning false if the destination tile floorType isn't in that list, we'll do one simple check: if they Character does not have a value assigned for floorType of the destination tile (ie; if it is undefined), we know the Character cannot move there, and so return false:


	if(typeof this.delayMove[tileTypes[gameMap[toIndex(x,y)]].floor]=='undefined') { return false; }

That's all there is to it! Load up the HTML document, and try moving across the different tile types. You'll see big differences in movement speeds!

Page loaded in 0.01 second(s).