'Creating a simple inventory system in JavaScript

I'm trying to make a simple text adventure/farming simulator, but I'm new to JavaScript and I'm stuck trying to plan out how my inventory system will work. The main problem I have is that there are two main types of items: food/consumables and tools/durable goods. Food will be created and consumed at a regular rate, whereas tools will need to be bought, and lose durability with each use.

The simplest solution I could think of was to have the quantity of each food item to be a property of the player (player.meat, player.vegetable, etc.) since quantity would be the only thing changing. Tools were a little more complex, so I figured I could create a Tool prototype, then give the player an inventory array that would store all their tools. However the more I thought about it, the more I realized food would need to be a prototype as well (it has properties like price and nutritional value as well).

My head is kind of spinning right now trying to think of the most effective way of doing this. Do I create 2 separate prototypes, then give the player an array for each of them? Would I need to create a prototype for the array so it can keep track of both item type and quantity? And will I need to search for each item in the array when I want to modify it? This seems needlessly complicated, but I can't really think of anything simpler. Can anyone help?



Solution 1:[1]

You could keep an array of food items and an array of Tool items. Here is an example of creating a food item and using it.

function FoodItem(options){
    var options = options || {};
    this.name = options.name || "DefaultFood";
    this.amount = options.amount || 100;
    this.decrease = options.decrease || 1;
    this.eat = function(){
        this.amount -= this.decrease;
        if (this.amount < 0){
            console.log("Food Gone");
        }
    }
}

// Then create new foods.
var carrots = new FoodItem({
    name:"Carrots",
    amount:50,
    decrease:2
});

carrots.eat();

Solution 2:[2]

It's critical not to overcomplicate on the technical side. As you evolve your gameplay, you'll need to change things anyway, so start simple and add complexity only when you're sure you need to.

I assume that by "prototype" you mean something like a base class. I'd advise against this until you're farther into your project. The cool thing about JS which tends to trip up classically-trained coders is that objects are "mushy" you can add or remove methods to each object to your heart's content. The same goes for nested sub-objects, so you can keep everything clean and tidy in your inventory without limiting yourself later on.

Something like this is the first thing that comes to my mind.

player.inventory = {
  tools: [
  ],
  food: [
  ]
};


// when player picks up hammer
player.inventory.push({
  name: 'hammer',
  icon: 'images/hammer.png',
  effect: function(target) {
    console.log('whacked the ' + target.name);
  }
});

The most important thing is to err towards under-engineering rather than over-engineering. This is sometimes known as compression-oriented programming

Good luck and have fun.

Solution 3:[3]

If you want to create an easy way to look items up and you have a unique, string-based ID (either a number or a name), you could use an Object as a hash.

var player = {
  tools: {}
};

Then when that player acquires a new tool, you can add an instance of the tool to the hash:

player.tools['hammer'] = new Tool(...);

Then when you want to retrieve it later, you can just do something like:

player.tools['hammer'].durability -= wear;

Using underscore, you can iterate these objects as easily as an array:

var inventoryWorth = _.reduce(player.tools, function(totalCost, tool) {
  return totalCost + tool.cost;
}, 0);

As for the objects you put in these arrays, creating prototypes and constructor functions might be useful, but you could also just stamp out one off objects unless you plan on adding lots of methods to them.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Andrew Sellenrick
Solution 2 Cheezmeister
Solution 3 Andrew Noyes