簡體   English   中英

將對象項添加到數組會產生錯誤的結果

[英]Adding object item to array giving wrong results

目前正在使用基本的RPG系統,並且在使用方法時遇到了錯誤。 該方法旨在將一個項目 (代碼中的類)和一個可選的數量添加到玩家清單中(一個Item []數組)。

這是item類的代碼:

public class Item

{
    public string Name;
    public int quantity;
    public int maxstack;

    public int[] stats = new int[5];

    public Item(string name, int Amount = 1, int MaxStack = 10, int ATK = 0, 
    int DEF = 0, int MAT = 0, int MDF = 0, int SPD = 0)
    {
        Name = name;
        quantity = Amount;
        maxstack = MaxStack;
        stats[0] = ATK;
        stats[1] = DEF;
        stats[2] = MAT;
        stats[3] = MDF;
        stats[4] = SPD;
    }
}

關鍵變量是“數量”和“最大堆棧”。

現在,將這些變量添加到玩家庫存中時,問題就來了。 該方法在將項目添加到清單時,使用Array.IndexOf()搜索清單中的空插槽和同一項目的任何堆棧

這是AddItem()方法的代碼:

public void AddItem(Item item, int Amount = 1)
{
    for (int i = Amount; i > 0; i--)
    {
        int ItemIndex = Array.IndexOf(inv, item); // Searches for a matching item
        int EmptySlot = Array.IndexOf(inv, null); // Searches for an empty slot

        ItemCheck:
        if (ItemIndex != -1) // ItemIndex will equal -1 if no matching item was found
        {
            if (inv[ItemIndex].quantity >= inv[ItemIndex].maxstack) // Is the quantity/stack of the found item equal to its maximum stackable value?
            {
                ItemIndex = Array.IndexOf(inv, item, ItemIndex + 1); // If yes, search for another index.
                goto ItemCheck;
            } else {
            inv[ItemIndex].quantity++; // If the stack hasn't reached its max, increase it by one.
            }
        }
        else
        {
            inv[EmptySlot] = item; // If no matching item was found, use an empty slot to create a new stack.
            inv[EmptySlot].quantity = 1;
        }
    }
}

現在,假設我創建了一個名為“ stick”的項目,它最多只能堆疊3個。運行AddItem(stick,3)並列出每個堆疊的數量時,控制台將返回

Stick x1
Stick x1

誰能幫我? 為什么我的代碼將堆棧變回1?

編輯:

添加1、2或3個搖桿可返回正確的數量,但是只有在堆棧達到最大堆棧數時才添加更多搖桿會拋出錯誤的結果。

編輯:

添加6個棍棒將返回2個堆棧,每個堆棧3個項目。 添加7條棍棒將返回3個堆棧,每個堆棧1個項目。

這里最大的問題是您使用物料存儲數量...但是物料在庫存中的多個位置使用。 因此,當您將數量改回1時,您正在為庫存中存在該物料的每個插槽都進行更改。

也就是說,您沒有該項目的副本,而是多次擁有相同的對象。

您可以通過多種方式解決此問題,但也許您應該創建一個名為InventorySlot的新類並將數量放入其中。

public class InventorySlot
{
   public Item Item {get; set;}
   public int Quantity {get; set;}
}

現在您的玩家庫存是一個InventorySlots數組...就像這樣,假設您的玩家中有類似的東西...

 public InventorySlot[] inv = new InventorySlot[5];

然后

public void AddItem(Item item, int amount = 1)
{
    var slot = inv.FirstOrDefault(s => s?.Item == item && s.Quantity < item.maxstack);
    if (slot != null)
    {
        slot.Quantity++;
    }
    else
    {
        slot = inv.FirstOrDefault(s => s == null);
        if (slot != null)
        {
            slot.Item = item;
            slot.Quantity = 1;
        }
    }
}

我不明白您為什么要嘗試將一個項目添加到數組中,因為它就是一個列表!
您可以簡單地使用List<T> ,它提供諸如AddRemoveRemoveAtInsertIndexOf
如果要獲取數組,則可以調用yourList.ToArray()

  • 是一個使用一些值初始化List<string>的示例。
  • 是一個從List<T>刪除項目的示例。

看這個例子:

List<Item> yourList = new List<Item>(); //Create an empty list
/* Or
 * List<Item> youtList = new List<Item>()
 * {
 *     new Item(),
 *     new Item() //etc
 * }
 */
yourList.Add(new Item()); //Add an item 
yourList.Insert(0, new Item()); //Insert an item to the 0 index
yourList.Remove(yourItem); //Remove an item directly
yourList.RemoveAt(0); //Remove an item by its index in the list
Item[] yourArray = yourList.ToArray(); //Convert the list List<T> to an array T[]

如有疑問,請查看List<T>文檔

如果出於任何特殊原因需要使用數組,請告訴我,我將編輯此答案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM