Inventories and Items

Inventory and Item classes

In this lesson we'll be looking at collectable items and simple inventories. In our example below, you can now press the letter P on the keyboard when standing on tiles with the stars to collect them!

You'll need the updated tileset to follow along with this example:

Tileset
Inventories and items example

We'll start by creating our list of itemTypes. This will be a map/associative array, where each item is an object represented by a unique numeric ID, with the properties name, the name of the item, maxStack, the maximum number of this item that can be in a single stack, sprite, which is the sprite details on the tileset, and offset, the amount the sprite position will be modified by relative to the top-left of the tile they occupy when drawn on the map.

var itemTypes = {
	1 : {
		name : "Star",
		maxStack : 2,
		sprite : [{x:240,y:0,w:40,h:40}],
		offset : [0,0]
	}
};

We'll now be creating a Stack object, that will keep track of a stack of items on the floor or in an inventory. The Stack will have two attributes; type, the ID of the itemTypes entry that this stack will contain, and qty, the number of items in the stack.

These will be populated by two arguments given when creating a new stack, id and qty.

function Stack(id, qty)
{
	this.type = id;
	this.qty = qty;
}

We'll also add an Inventory class for keeping track of groups of stacks. This will be created with one argument, s, which will be the maximum number of stacks this inventory can contain. It will have two parameters; spaces, the maximum number of stacks the inventory can contain (set by the sargument), and stacks, an empty array that will contain a list of Stack objects when items are added to the inventory.

function Inventory(s)
{
	this.spaces		= s;
	this.stacks		= [];
}

Our Inventory class will have an addItems method that will take two arguments; id, the itemTypes entry for the type of items we're trying to add, and qty, the number of this item we wish to add. We'll begin by looping through all of the possible spaces for stacks in the inventory:

Inventory.prototype.addItems = function(id, qty)
{
	for(var i = 0; i < this.spaces; i++)
	{

If the current iteration of our loop is a higher value than the current length of the stacks array, we can just add a new Stack to the array. We start by calculating maxHere - the value of which will be the maximum stack size for the given item type, or the qty argument, whichever is smaller.

		if(this.stacks.length<=i)
		{
			var maxHere = (qty > itemTypes[id].maxStack ?
				itemTypes[id].maxStack : qty);

We'll then push a new Stack object of the given item type with the quantity maxHere on to the stacks array, and reduce the qty argument by the value of maxHere before closing this if block:

			this.stacks.push(new Stack(id, maxHere));
			
			qty-= maxHere;
		}

Otherwise, we'll check and see if the current stacks entry is of the same item type id as that passed to the function, and if the Stack.qty is less than the maximum stack size for this item type:

		else if(this.stacks[i].type == id &&
			this.stacks[i].qty < itemTypes[id].maxStack)
		{

We'll then calculate how many items we can add to this stack, by subtracting the qty argument from the item types maximum stack size and storing this in the maxHere variable. If the value is higher than qty, we simply change it to this value.

We then increase the Stack.qty value by maxHere, remove this amount from the qty argument, and close the if block.

			var maxHere = (itemTypes[id].maxStack - this.stacks[i].qty);
			if(maxHere > qty) { maxHere = qty; }
			
			this.stacks[i].qty+= maxHere;
			qty-= maxHere;
		}

We check at the end of each loop iteration to see if qty has got down to 0 - if so we return 0; to leave the method and close the loop.

		if(qty==0) { return 0; }
	}

At the end of the method, we return the remaining qty value. This is the number of items we couldn't find space for in the inventory.

	return qty;
};

Placed items

When items are placed on the ground, alone or in a stack, they'll be represented by the PlacedItemStack object. Instances are created with the arguments id, the itemTypes entry id, and qty, the number of items in this stack. The class also has the properties x, y, which will be the map position this stack is placed at.

function PlacedItemStack(id, qty)
{
	this.type = id;
	this.qty = qty;
	this.x = 0;
	this.y = 0;
}

To set the position of the stack on the map, it will have a method called placeAt, which takes the arguments nx, ny, the coordinates to place the stack at. The method begins by checking if the tile at the stacks current x, y position contains a reference to this stack, and if so removes it:

PlacedItemStack.prototype.placeAt = function(nx, ny)
{
	if(mapTileData.map[toIndex(this.x, this.y)].itemStack==this)
	{
		mapTileData.map[toIndex(this.x, this.y)].itemStack = null;
	}

After, it simply sets the x, y properties of the stack, and updates the map tile at the given positions itemStack reference to point to this stack:

	this.x = nx;
	this.y = ny;
	
	mapTileData.map[toIndex(nx, ny)].itemStack = this;
};
Page loaded in 0.013 second(s).