【问题标题】:Java: Creating multiple separate objects from one base type. TextAdventureJava:从一种基本类型创建多个单独的对象。文字冒险
【发布时间】:2011-12-25 09:28:06
【问题描述】:

在我的小文本游戏中,我有一个 Item 类,它从 .txt 文件加载它的对象,然后将对象添加到 Item 类型的 ArrayList 中。我正在尝试使用 Item 类中的 upgrade() 方法进行升级。它可以工作,但是如果我的库存中有两个相同的物品,因为如果我升级一个它们会引用相同的物品,我会升级该类型的所有物品。

有没有办法创建一个新项目(青铜头盔),它在创建时将与从文本文件加载的青铜头盔相同,但在升级时它不会更改静态头盔 ArrayList 中的原始对象项目.java。

Player 类的 openInventory() 方法:

public void openInventory(){
        //newWindow();
        int selection;
        boolean upgraded = false;

            backPack.printInventory(this);
            println("[1] UseItem  [2] Upgrade Item  [3] Item Details");
            selection = getInt();
            if(selection == 1){
                println("Type the number of the corresponding Item Slot you would like to use.");
                    int itemNum = (getInt() - 1);
                    Item itemSelection = backPack.itemSlot[itemNum].oi;
                    if(backPack.itemSlot[itemNum].stack.size() > 0){
                        itemSelection = backPack.itemSlot[itemNum].stack.get(0);
                    }
                    itemSelection.printStats();
                    this.useItem(itemSelection);
            }
            if(selection == 2){

                int sInt;
                Item scroll = new Item();
                Item item = new Item();

                while(upgraded == false){
                    println("Pick a scroll");
                    sInt = getInt();
                    if(backPack.itemSlot[sInt - 1].oi.type.equals("scroll")){
                        scroll = backPack.itemSlot[sInt - 1].oi;
                    }
                    else
                        println("Not a Scroll");

                    println("Pick which " + scroll.category + " to upgrade.");
                    sInt = getInt();
                    if(backPack.itemSlot[sInt - 1].oi.type.equals(scroll.category)){
                        item = backPack.itemSlot[sInt - 1].oi;
                    }
                    else
                        println("Wrong type of Item");

                    if(scroll.name != "None" && item.name != "None"){
                        backPack.itemSlot[sInt - 1].oi.upgrade(scroll);
                        upgraded = true;
                    }
            }
        }
            if(selection == 3){
                println("Pick item to display details.");
                int i = getInt();

                backPack.itemSlot[i - 1].oi.printStats();
            }
    }

升级“青铜头盔”之一后的库存

—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
[1]  Bronze Helmet [+1]  [2]  Bronze Helmet [+1]  [3]  Helmet Def Scroll   [4]  None                [5]  None                

[6]  None                [7]  None                [8]  None                [9]  None                [10] None                
—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————
                                                        [Gold]:  $50
—————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

Item.java:

import static com.projects.aoa.Print.*;
import static com.projects.aoa.Input.*;

import java.util.*;
import java.io.*;

class Item {

    //Item
    String name, type, category, statUpgrade;
    int remSlots, maxSlots, upgraded, probability, statIncrease;
    int hp, mp, str, def, atk, dex, duration;
    Area shopPurchased;


    //Inventory
    public boolean filled;
    public int count, stackLimit;


    public static List<Item> helmets = new ArrayList<Item>();
    public static List<Item> potions = new ArrayList<Item>();
    public static List<Item> swords = new ArrayList<Item>();
    public static List<Item> scrolls = new ArrayList<Item>();

    Item(){
        name = "None";
        maxSlots = 5;
        remSlots = 5;
    }
    public String toString(){
        return (name);
    }

    static void loadItems(){

        try {
            //System.out.println(System.getProperty("user.dir"));

            FileInputStream fstream = new FileInputStream(System.getProperty("user.dir") 
                    + "/LoadFiles/" + "itemLoad.txt");

            DataInputStream in = new DataInputStream(fstream);

            BufferedReader br = new BufferedReader(new InputStreamReader(in));

            String line, itemType = "none";
            int counter = 0;
            Item newItem = new Item();

             while((line = br.readLine()) != null) {
                 if(line.length() == 0){
                        newItem.printStats();
                        if(itemType.equals("helmet")){
                            helmets.add(newItem);
                        }
                        if(itemType.equals("potion")){
                            potions.add(newItem);
                        }
                        if(itemType.equals("sword")){
                            swords.add(newItem);
                        }
                        if(itemType.equals("scroll")){
                            scrolls.add(newItem);
                        }
                        counter = -1;
                        }
                 if(line.equals("#"))
                     break;

                switch(counter) {
                    case -1:
                        counter++;
                        break;

                    case 0:

                        itemType = line;
                        counter++;
                        break;


                    case 1:
                        if(itemType.equals("helmet")){
                            //tempName = line;
                            newItem = new Helmet(line);
                            newItem.type = itemType;
                        }
                        if(itemType.equals("potion")){
                            newItem = new Potion(line);
                            newItem.type = itemType;
                        }
                        if(itemType.equals("sword")){
                            newItem = new Sword(line);
                            newItem.type = itemType;
                        }
                        if(itemType.equals("scroll")){
                            newItem = new Scroll(line);
                            newItem.type = itemType;
                            counter = 9;
                        }
                        counter++;
                        break;

                    case 2:
                        newItem.hp = Integer.parseInt(line);
                        counter++;
                        break;

                    case 3:
                        newItem.mp = Integer.parseInt(line);
                        counter++;
                        break;

                    case 4:
                        newItem.def = Integer.parseInt(line);
                        counter++;
                        break;

                    case 5:
                        newItem.str = Integer.parseInt(line);
                        counter++;
                        break;

                    case 6:
                        newItem.atk = Integer.parseInt(line);
                        counter++;
                        break;

                    case 7:
                        newItem.dex = Integer.parseInt(line);
                        counter++;
                        break;

                    case 8:
                        newItem.stackLimit = Integer.parseInt(line);
                        counter++;
                        break;

                    case 9:
                        newItem.duration = Integer.parseInt(line);
                        counter++;
                        break;
                    case 10:
                        newItem.category = line;
                        counter++;
                        break;
                    case 11:
                        newItem.statUpgrade = line;
                        counter++;
                        break;
                    case 12:
                        newItem.statIncrease = Integer.parseInt(line);
                        counter++;
                        break;
                    case 13:
                        newItem.probability = Integer.parseInt(line);
                        counter++;
                        break;
                }

             }

                in.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    } 


    void printStats(){
        line();
        println("[" + name + "]");
        println("Type: " + type);
        println("Stack Limit: " + stackLimit);
        println("Duration: " + duration);
        println("HP:  " + hp);
        println("MP:  " + mp);
        println("Def: " + def);
        println("Str: " + str);
        println("Atk: " + atk);
        println("Dex: " + dex);
    }

    void upgrade(Item scroll){
        Random rand = new Random();

        int geti;

            if(remSlots > 0){
                if(this.type.equals(scroll.category)){
                    int prob = rand.nextInt(99);
                     println("Prob: " + prob);

                     if(prob < scroll.probability){
                         if(scroll.statUpgrade.equals("def")){
                             this.def += scroll.statIncrease;
                             this.upgraded++;
                             println("Upgraded: " + this.upgraded);
                         }
                     }

                     remSlots--;
                        println("Slots: " + this.remSlots + " / " + this.maxSlots);
                }
        }
            else
                println("No slots remaining.");
    }

static Item getItem(String searchedName){

        Item item = new Item();

        for(int i = 0; i < potions.size(); i++){
            if(potions.get(i).name.equals(searchedName)){
                item = potions.get(i);
                return item;
            }
        }
        for(int i = 0; i < helmets.size(); i++){
            if(helmets.get(i).name.equals(searchedName)){
                item = helmets.get(i);
                return item;
            }
        }
        for(int i = 0; i < swords.size(); i++){
            if(swords.get(i).name.equals(searchedName)){
                item = swords.get(i);
                return item;
            }
        }

        for(int i = 0; i < scrolls.size(); i++){
            if(scrolls.get(i).name.equals(searchedName)){
                item = scrolls.get(i);
                return item;
            }
        }
        return item;
    }
}

库存:

public class Inventory {

    int useableSlots, slots = 50;
    Itemslot[] itemSlot = new Itemslot[slots];


    Inventory(int slots){
        this.useableSlots = slots;
    }

    public void printInventory(Player playerOne){
        newWindow(5);

        int excess, lineTotal = 0, invSlotSize = 25, maxLineLength = 125;
        String invItem, difference = "";
        String inventoryTitle = "[" + playerOne.name + "'s BackPack]";
        String invTitleIndent = "";

        for(int i = 0; i < (maxLineLength - inventoryTitle.length()) / 2; i++){
            invTitleIndent += " ";
        }

        println(invTitleIndent + inventoryTitle);

        printMult("—", maxLineLength);

        line();


        for(int i = 0; i < useableSlots; i++){

            if(lineTotal >= maxLineLength){
                line();
                lineTotal = 0;
                line();
            }

            if(i < 9){
                difference = " ";
            }
            else{
                difference = "";
            }

            invItem = ("[" + (i + 1) + "] " + difference);
            if(itemSlot[i].stack.size() > 0){
                invItem += (itemSlot[i].stack.get(0).name + "(" + itemSlot[i].stack.size() + ")");
            }
            else {
                invItem += itemSlot[i].oi.name;

                if(itemSlot[i].oi.upgraded > 0){
                    invItem += " [+" + itemSlot[i].oi.upgraded + "]";
                }
            }


            excess = (invSlotSize - invItem.length());

            for(int v = 0; v < excess; v++){
                invItem += " ";
            }

            //print(invItem.length());
            print(invItem);

            lineTotal += invItem.length();

        }

        line();
        printMult("—", maxLineLength);
        line();

        String printGold = "[Gold]:  $" + playerOne.gold;
        String goldIndent = "";     

        for(int i = 0; i < (maxLineLength - printGold.length()) / 2; i++){
            goldIndent += " ";
        }

        println(goldIndent + printGold);

        printMult("—", maxLineLength);
        line();

        line(2);

    }


    void addItem(Item item){
    for (int i = 0; i < useableSlots; i++){
        if (itemSlot[i].occupied == false) {
            itemSlot[i].oi = item;
            itemSlot[i].occupied = true;
            break;
        }
    }
}

物品槽:

public class Itemslot extends Item{

    List<Item> stack = new ArrayList<Item>();
    Item oi = new Item();
    boolean occupied;

}

很可能只是我很愚蠢,但对于解决这个问题的任何帮助,或者采取什么方向,我们将不胜感激。

编辑:已解决

向 Item 添加了复制构造函数

Item(Item item){
        this.name = item.name;
        this.type = item.type;
        this.category = item.category;
        this.statUpgrade = item.statUpgrade;
        this.remSlots = item.remSlots;
        this.maxSlots = item.maxSlots;
        this.upgraded = item.upgraded;
        this.probability = item.probability;
        this.statIncrease = item.statIncrease;
        this.hp = item.hp;
        this.mp = item.mp;
        this.str = item.str;
        this.def = item.def;
        this.atk = item.atk;
        this.dex = item.dex;
        this.duration = item.duration;
    }

改变了添加项目

void addItem(Item item){
        Item newItem = new Item(item);
        for (int i = 0; i < useableSlots; i++){
            if (itemSlot[i].occupied == false) {
                itemSlot[i].oi = newItem;
                itemSlot[i].occupied = true;
                break;
            }
        }
    }

【问题讨论】:

  • 请更具体一些,以便我们为您提供帮助
  • 我的问题不清楚,能否请您显示实际调用upgrade() 方法的代码
  • 抱歉,忘记添加 Player 类中的方法了……快凌晨 5 点了。如果您需要更多信息,请告诉我。
  • @iRector 没有人会阅读所有这些代码。请更具体。仔细阅读您的代码,并以最简单的方式将您的问题告诉我们,以便我们为您提供帮助

标签: java object


【解决方案1】:

根据Effective Java 2 复制对象的推荐方式是提供一个复制构造函数

public Foo(Foo foo){
//.. copy all members
this.name=foo.name;
this.age=foo.age;

}

注意clone方法是broken in Java,根据同一本书。

我认为您的方法是错误的,您可以使用 ObjectInputStream 和 ObjectOutputStream 将对象写入数据文件

public class Item implements java.io.Serializable{
  ....
}

{
  Item item=new Item();
  ObjectInputStream stream=new ObjectInputStream(fileStream);
  stream.write(item);
}

【讨论】:

  • 是的,Object 的 clone() 方法给出了一个浅拷贝。但是,在您自己的类 (Item) 中的 clone() 方法实现中,您可以执行与复制构造函数中相同的深度复制。
【解决方案2】:

我没有阅读所有代码,但是 addItem 对我来说看起来很可疑,很可能会导致您的问题:

    void addItem(Item item){
    Item newItem = new Item();
    newItem = item;
    for (int i = 0; i < useableSlots; i++){
        if (itemSlot[i].occupied == false) {
            itemSlot[i].oi = newItem;
            itemSlot[i].occupied = true;
            break;
        }
    }
    }

你可能想在这里做的是

   newItem = item.clone()

这只是一个猜测,因为我不知道你实际上是怎么称呼addItem的。

http://en.wikipedia.org/wiki/Clone_(Java_method)

编辑: 我刚刚看到你在loadItems 中打电话给addItem。要么你按照 Tom Ingram 的建议去做,要么改变addItem 的实现。效果应该是一样的。

编辑 2: 如果您不打算继承 Item,这将是一个快速的解决方案:

 void addItem(){
 Item newItem = new Item();
 for (int i = 0; i < useableSlots; i++){
     if (itemSlot[i].occupied == false) {
         itemSlot[i].oi = newItem;
         itemSlot[i].occupied = true;
         break;
     }
 }
 }

【讨论】:

  • newItem 实际上是我试图弄清楚这一点的结果。生病将其编辑为行为相同的原件。不过,我会尝试使用 clone()。
【解决方案3】:

而不是在库存中为同一物品拥有两个对象,而是一个对象和一个计数器。 (计数器会告诉你这个对象代表了多少个项目)

【讨论】:

  • 对于某些物品我有这样的,但对于装备一个物品需要一个插槽。
【解决方案4】:

而不是

Item newItem = new Item();

for ... 
  helmets.add(newItem);

不应该

for ...
  helmets.add(new Item());

for ...
  Item newItem = new Item();
  helmets.add(newItem);

【讨论】:

    猜你喜欢
    • 2016-08-25
    • 2022-06-15
    • 1970-01-01
    • 2014-06-07
    • 1970-01-01
    • 2011-06-28
    • 2011-04-28
    • 2013-07-08
    • 1970-01-01
    相关资源
    最近更新 更多