Monday, December 7, 2015

c++ - How can I handle inventory in an object-oriented way?


I'm trying to think of the best way to handle player inventory following an object oriented approach.


For example, sword and axe are two different classes, both inheriting from weapon. Weapon and potion are also different classes both inheriting from item.


Ideally, the inventory would be implemented as a container of items, but that can't be done for several reasons. So it has to be a container of item (smart) pointers. Since I don't want to liter my code with calls to new and delete, I'll wrap it in an ItemWrapper class which news/deletes on ctor/dtor.


So the code will look something like this


class Sword;
class ItemWrapper;


//Prepare the long sword.
const Sword longSword(...params...);

//Declare the inv
vector inv;

//Add it to inventory
inv.push_back(longSword); //compiles if ItemWraper(const Sword&) is defined.

This approach was the best I could come up with in terms of code clarity and ease of writing. The problem is that ItemWrapper will need one constructor for each leaf class that inherits from Item (which is a lot).



This is my first attempt at this, so I'd like to know: am I going the right way? or if there's a better way of doing it (perhaps one that avoids so many constructors)?



Answer



There is something you are doing right now that you may find that you regret later, even though it seems like a logical thing to do.


You are likely to find that making each type of item its own class hard to manage once you have more than about twelve of them.


My own inventory management systems don't have different types for items. Instead, I use a "Descriptor" class, which has a set of properties (Name-Value pairs, stored in an associative container [in C++ you would likely use std::map])


The property getter is a template function that casts the property from the map into the appropriate type.


The way I differentiate between item types is to have an ItemType property, usually some sort of enum with entries like WEAPON, ARMOR, etc. Other properties contain damage ranges, references to images to use to render it, name description, etc.


Now, these descriptors aren't for item instances. They describe the item type as a whole. Item instances contains some sort of reference to the descriptor as well as a similar map of properties for values needed for an item instance (like individual durability, for example). In this way, one avoids repeating the same information over and over again. After all, one sword is about the same as another sword, it just might be closer to wearing out.


As far as avoiding constructor calls, I recommend a factory method.


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...