2

到目前为止,我有这个:

class Inventory {
     private Potion[] potions;
     private Weapon[] weapons;
     private Armor[]  armor;
     private Food[]   food;
     private Ore[] ores;

     public int InventorySlots {get;set;}
     public Inventory() {
            InventorySlots = 10;
            BuildInventory();
     }
     public Inventory(int slots) {
            InventorySlots = slots;
            BuildInventory();
     }
     public void BuildInventory() {
            potions = new Potion[InventorySlots];
            weapons = new Weapons[InventorySlots];
            armor = new Armor[InventorySlots];
            food = new Food[InventorySlots];
            ores = new Ore[InventorySlots]
     }
}

Itf,例如,我想在 10 个插槽的库存中添加一个新武器,我将如何添加和删除它?

4

4 回答 4

5

为了显着简化问题,您可以创建一个基类“项目”,您的所有项目类型都来自:

public class Item
{
    // put any common attributes here
}

public class Armor : Item
{
    // define properties for Armor here
}

public class Weapon : Item
{
    // define properties for weapons here
}

当您像这样创建子类时,您可以使用Item变量来存储任何派生类。您可以创建一个新Weapon实例并将其分配给Item实例类型的库存槽。所以你的Inventory类变成了Items 的集合。

假设您想要数组到库存位置的 1 对 1 映射,并且不希望自己重新排列东西,那么数组方法可能是要走的路。

class Inventory
{
    // Array to store items
    public Item[] Items { get; private set; }

    // Inventory capacity is array length
    public int Capacity { get { return (Items == null) ? 0 : Items.Length; } }

    // Constructor
    public Inventory(int capacity = 10)
    {
        SetInventorySize(capacity);
    }

    // Set size of inventory, retaining contents where possible
    public void SetInventorySize(int cap)
    {
        if (cap <= 0)
            Items = null;
        else if (Items == null)
            Items = new int[cap];
        else
            Array.Resize(ref Items, cap);
    }

    // Get index number of first free slot in inventory
    public int FirstAvail()
    {
        if (Items != null)
        {
            for (int i = 0; i < Items.Length; ++i)
            {
                if (Items[i] == null)
                    return i;
            }
        }
        return -1;
    }

    // Add item to array, returning index or -1 on failure
    public int AddItem(Item item)
    {
        if (Items != null)
        {
            for (int i = 0; i < Items.Length; ++i)
            {
                if (Items[i] == null)
                {
                    Items[i] = item;
                    return i;
                }
            }
        }
        return -1;
    }
}

Items属性是一个数组,您可以存储任何Item衍生对象,如ArmorWeapon以上。要将项目添加到列表中,请找到一个清晰的位置(FirstAvail例如使用方法)并将项目放入该位置的项目列表中。

当您使用库存中的物品时,您需要确定它们是什么来弄清楚如何处理它们。您可以as这样使用操作:

// get the first item in the inventory
Item item = inventory.Items[0];

if ((Armor armorItem = item as Armor) != null)
{
    // Code to execute for Armor items
    armorItem.Wear();
}
else if ((Weapon weaponItem = item as Weapon) != null)
{
    // Code to execute for Weapon items
    weaponItem.Equip();    
}
else if ((Potion potionItem = item as Potion) != null)
{
    // Code to execute for Potion items
    potionItem.Drink();
}

as操作将检查对象的真实类型,如果不匹配则返回 null。因此,如果您将物品存储Potion在库存的插槽 0 中,它不会尝试将其用作ArmorWeapon物品。

当然,这是一个人为的例子。Item在类中定义基本的通用操作并在子类中覆盖它们会更有用。然后,您只需调用(例如)item.DefaultAction()DefaultAction为每个子类型实现覆盖以执行适当的操作。

于 2013-02-23T10:30:25.817 回答
1

看起来您将无法在 Inventory 类之外设置武器,因为它是私有的,但如果您在 Inventory 类中进行设置,因为它是一个数组,您只需将武器分配给武器数组的索引。要删除它,您只需将该武器索引设置为空。

weapons[index] = weapon;  // add
weapons[index] = null;  // remove
于 2013-02-23T00:31:20.530 回答
1

我个人会公开这些

private Potion[] potions;
private Weapon[] weapons;
private Armor[]  armor;
private Food[]   food;
private Ore[] ores;

但是,如果您想让它们保持私有,则可以使用方法来访问不同数组的不同位置。

例子。

public Weapon getWeaponAtPositon(int index)
{
    if (index >= 0 && index < InventorySlots)
        return weapons[index];
    else
        return null;
}

public void setWeaponAtPositon(Weapon weapon, int index)
{
    if (weapon != null && index >= 0 && index < InventorySlots)
        weapons[index] = weapon;
}

public void deleteWeaponAtPositon(int index)
{
    if (index >= 0 && index < InventorySlots)
        weapons[index] = null;
}

您可以为您拥有的不同数组重复这些操作,这样您一次只能访问一个字段,这为您提供了从类外部修改数组的更安全的方式(即使它是仍然很容易)

希望它有所帮助。

于 2013-02-23T00:42:47.380 回答
0

在数组位置使用对象之前,请务必检查null :

if (potions[4] != null)
{
    potions[4].DrinkMe();
}

您可以通过重新分配null来删除项目

potions[4] = null;

请注意,所有数组位置都将从null开始。编码:

potions = new Potion[InventorySlots];

分配一个数组Potion但不在Potion每个数组槽中放置一个新实例。这取决于你。

于 2013-02-23T00:34:44.833 回答