vendredi 4 août 2017

How to create game inventory system, without casting to derived

I am trying to implement a high-performance game inventory system. I have This abstract base class to store different type of items in Inventory, for example, Coin, Flashlight, Knife etc..

public abstract class ObtainableItem 
{
    public string Name { get; private set; }

    public ObtainableItem(string name)
    {
        Name = name;
    }
}

For example, I have a DoorKey which opens a door. DoorKey has a property KeyCode which will be used for opening a door.

public class DoorKey : ObtainableItem
{
    public int KeyCode { get; private set; }

    public DoorKey() : base("key")
    {
        KeyCode = 1234;
    }
}

All ObtainableItem are stored in Inventory

public class Inventory
{
    const int slotCount = 2;
    ObtainableItem[] slots = new ObtainableItem[slotCount];

    public Inventory()
    {
        slots[0] = new DoorKey();
    }
}

Now imagine user drags DoorKey from his Inventory on a Door and triggers Open method

public class Door
{
    public void Open(ObtainableItem key)
    {
        if (key is DoorKey)
        {
            DoorKey doorKey = (DoorKey)key;
            if (doorKey.KeyCode == 1234)
            {
                // Open door
            }
        }
        else
        {
            // "can't use this item on a door"
        }
    }
}

How to avoid cast from ObtainableItem to a DoorKey? I have read that using casting is bad practice and it points at a bad code oop design. Ideally, a Door class should look like this. Is there any pattern I should for my inventory system?

public class Door
{
    public void Open(DoorKey key)
    {
        if (key.KeyCode == 1234)
        {
            // Open door
        }
    }
}

Aucun commentaire:

Enregistrer un commentaire