# Inventar - Doppelte Items zusammenfügen



## Hercules (20. Jan 2013)

Hi Leute ich habe gerade ein Problem mit meinen Inventar.
Also ich habe das Inventar als ArrayList erstellt.

So wenn man jetzt ne Kiste öffnet kann ich Items hinzufügen.


```
inventar.add(trank);
```

Anzeigen tu ich das Inventar dann so.

```
for(int i = 0; i < inventar.size();i++)
             {
                g.drawString(""+inventar.get(i).name, 100, 20*i + 80);      
                g.drawString(" x"+inventar.get(i).anz, 240, 20*i + 80);             

             }
```
Das funktioniert auch alles.
Jetzt kommen aber Items doppelt vor.
Deswegen hab ich der Itemklasse das Attribut Anzahl gegeben.
Wenn man jetzt ein Item aufnimmt was es schon im Inventar gibt soll einfach nur die Anzahl erhöht werden.
Überprüfe ich das für nur ein Item geht es auch, aber bei mehreren weiss ich nicht wie ich das machen soll.

Hab es jetzt so versucht.
Es wird einmal durch das Inventar gegangen und durch den Inhalt der Kiste.
Also zuerst nimmt er das erste Item des Inventars, dann geht er alle Items der Kiste durch.
Wenn es das Item in der Kiste sowie im Inventar gibt soll er die Anzahl erhöhen.
Ansonsten soll das item zum Inventar hinzugefügt werden.


```
// Spieler nimmt den Inhalt der Kiste
 if(value.enter)
             {
                // Anzahl der Items im Inventar                
                 for(int w = 0; w < inventar.size();w++)
                 {   // Anzahl der Items in der Kiste          
                     for(int z = 0; z < chestList.get(value.chestNr).items.size();z++){
                    // Wenn ein Item in der Kiste schon im Inventar ist erhöhe die Anzahl
                     if(!inventar.isEmpty() &&        inventar.get(w).name.matches(chestList.get(value.chestNr).items.get(z).name))
                         inventar.get(w).anz += chestList.get(value.chestNr).items.get(z).anz;
                     else
                     inventar.add(chestList.get(value.chestNr).items.get(z));
                     }
                 }
                                      
                chestList.remove(value.chestNr); 
                 
             }
```

value.chestNr ist nur die ID der Kiste die der Spieler gerade öffnet.

Das Problem ist jetzt das am Anfang das Inventar ja leer ist also wird die Schleife gar nicht erst ausgeführt.
Wie kann ich das lösen weiss das wer? Oder wie habt ihr das gemacht.


----------



## vanny (20. Jan 2013)

schreib dir ne Klasse für das Item, mit id, name etc. 
Dann eine Klasse für den Slot, mit anzahl, item und Methoden(nullprüfung, putmethode(ersetzen oder anzahl erhöhen etc.))
diese slots packst du dann in deine InventarListe.

Mit den drei Klassen sollte es sehr einfach sein, dein Problem zu lösen.

wenn es nicht gerade ein Endlosinventar werden soll, dann würde ich auch ein Array in der Größe des Inventars vorziehen.

Gruß Vanny


----------



## vanny (20. Jan 2013)

```
public class Item {
	
	private final int itemId;
	private final String name;
	
	public Item(int itemId, String name){
		this.itemId = itemId;
		this.name = name;
	}

	public int getItemId() {
		return itemId;
	}

	public String getName() {
		return name;
	}

}
```


```
public class InventarSlot {

	private Item item;
	private int anzahl;

	public int getItemId() {
		if (item != null || anzahl == 0) {
			return item.getItemId();
		} else {
			return 0;
		}
	}

	public String getItemName() {
		if (item != null || anzahl == 0) {
			return item.getName();
		} else {
			return "leer";
		}
	}

	public void putItem(Item item) {
		if (this.item == null || item.getItemId() != this.item.getItemId()) {
			this.item = item;
		} else {
			anzahl++;
		}
	}

	public Item takeItem() {
		if (anzahl == 0) {
			if (item != null) {
			}
			return null;
		} else {
			anzahl--;
			return item;
		}
	}

}
```


```
public class Inventar {

	public InventarSlot[] inventar;

	public Inventar(int groesse) {
		// Inventargroesse festlegen
		inventar = new InventarSlot[groesse];
		// Slots instanzieren
		for (int i = 0; i < inventar.length; i++) {
			inventar[i] = new InventarSlot();
		}
	}

	public void itemReinLegen(Item item) {
		int slotIndex = 0;
		if (item.getItemId() != 0) {
			slotIndex = containsItem(item.getItemId());
		}
		if (slotIndex != -1) {
			inventar[slotIndex].putItem(item);
		}
	}

	private int containsItem(int id) {
		int slotIndex = -1;// Rückgabe, wenn ID nicht existiert
		for (int i = 0; i < inventar.length; i++) {
			if (inventar[i].getItemId() == id) {
				slotIndex = i;
			}
		}
		return slotIndex;
	}

}
```

irgendwie sowas vielleicht (!ungetestet!)


----------



## fastjack (21. Jan 2013)

Eigentlich sind das ja stapelbare Items. Also würde ich ein "Stackable" schreiben, daß von Item erbt und eine Anzahl speichert. Dann Inventory-Klasse selbst schreiben, die auf ArrayList aufsetzt und Items verwalten kann. Bei Add/Remove mußt Du nur festellen, ob "Stackables" rein oder raus sollen.


----------



## vanny (21. Jan 2013)

@fastjack
Ist eigentlich, dass was ich mir auch dachte, nur hat der TO dann immer noch nicht das Problem mit der leeren ArrayList gelöst.

PS: hab grad nen Fehler gesehn, bei den gettern für ItemId und ItemName sollte die Prüfung natürlich 
	
	
	
	





```
anzahl != 0
```
 lauten. Sry war halt nur mal fix runtergetippt.

Gruß Vanny


----------



## Hercules (23. Jan 2013)

Danke für deinen Vorschlag!
Also meinst du ich setze vorher schonmal alle Slots ins Inventar?
Dann müsste ich aber vorher schon alle Slots + Items erstellen.

Ich probiere es gleich mal. Allerdings haben die Items ja dann einen festen Platz.
Oder ich versuche sie dann immer nach der ID zu sortieren mal gucken.

Ich glaube aber das es funktioniert.


----------



## vanny (23. Jan 2013)

Hercules hat gesagt.:


> Also meinst du ich setze vorher schonmal alle Slots ins Inventar?



Genau, bei ner Arraylist mind. den ersten Slot.



Hercules hat gesagt.:


> Dann müsste ich aber vorher schon alle Slots + Items erstellen.



nein, nur die Slots.


Hercules hat gesagt.:


> Allerdings haben die Items ja dann einen festen Platz.



wenn du gleiche Items stapeln willst, istt es schon sinnvoll, wenn sie das auf einem Inventarslot tun.
Es hindert dich natürlich nichts daran, auch 2 Slots mit der gleichen ItemId zu stapeln um z.Bsp. eine anzahl von 25 und 10 zu schaffen.


...mein Beispiel is ja auch nur eine Verdeutlichung zu meinem Vorschlag, da muss noch jede Menge mit gemacht werden, je nachdem, was du dir vorstellst.

Gruß Vanny


----------



## Hercules (24. Jan 2013)

Ich habe es jetzt so ähnlich gemacht wie du vorgeschlagen hast.
Nur hab ich keine Klasse genommen. Ich habe als Slot einfach ein Item genommen mit ID 99.

So habe ich das jetzt gemacht, in der Menü Klasse:


```
static Item trank;
        static Item nektar;
        static Item gegengift, ether , belebungskraut ,elixier ;
        static Item nichts;

//[...]

                 //Items
                 trank = new Item("Trank","Heilt 50 HP",1,0);
                 nektar = new Item("Nektar","Heilt 150HP",1,1);
                 gegengift = new Item("Gegengift","Heilt Gift",1,2);
                 ether = new Item("Ether","Heilt 50MP",1,3);
                 belebungskraut = new Item("Belebungskraut","Heilt TOT",1,4);
                 elixier = new Item("Elixier","Heilt 150 HP/MP",1,5);
                 nichts = new Item("Nichts","",0,99);

               for(int i=0;i<inventar.length;i++)
                   inventar[i] = nichts;



//[...]


else if(Values.menu_item)
            {
                g.setFont(font);
                g.drawImage(itemMenu, 0, 0);
              
                
                for(int i=0;i<inventar.length;i++)
                {
                if(inventar[i].anz == 0 )
                    inventar[i].id=99;
                }
              
                // Inventar nach ID sortieren      
                Arrays.sort(inventar);
              
              for(int i = 0; i < inventar.length; i++)
              {
                  
               if(i % 2 * 160 == 0) x = 30;
                 else x = 330;    
                  
               if(inventar[i].anz>0){
                  g.drawString(inventar[i].getName(), x,(i / 2 * 35)+82); 
                  g.drawString(": "+String.valueOf(inventar[i].anz) ,x + 235,(i / 2 * 35)+82); 
                  g.drawString(inventar[0].description,20,20); 
               }
              }
            }
```

So werde ich dann die Item hinzufügen bzw entfernen.
Muss dann noch angepasst werden damit ich nicht jedes Item manuell abfragen muss.

```
//Hinzufügen
 if(Arrays.binarySearch(Menu.inventar, Menu.gegengift)>=0)
              Menu.inventar[Arrays.binarySearch(Menu.inventar, Menu.gegengift)].anz+=1;
          else{
              Menu.inventar[Menu.inventar.length-1] = Menu.gegengift;
               Menu.inventar[Menu.inventar.length-1].anz=1;
          }

//Entfernen
 Menu.inventar[Arrays.binarySearch(Menu.inventar, Menu.gegengift)].anz-=1;
              if(Menu.inventar[Arrays.binarySearch(Menu.inventar, Menu.gegengift)].anz<=0)
                  Menu.inventar[Arrays.binarySearch(Menu.inventar, Menu.gegengift)] = Menu.nichts;
```

Und so sieht es dann aus:
Java 2D RPG - Item Inventar - YouTube


----------

