Inventory System?

Okay so I’m working on a game and I’ve been really conflicted recently on how I want to go about doing the inventory system.

What I mean is like how it actually works.

My friend suggested that each inventory item would have an XML file where you could load data from it, but I’m not sure how I would get the rendering to work for that and I’m not sure it’s efficient. Along with that, some items (weapons) need to have functionality to them when they are selected/equipped so I’m not really sure how that would work with XML.

I myself had two ideas: Classes for each type of item with each their own rendering method, or Enum values for each item where a switch statement would decide what to render and what kind of functionality it would have, although that would create a ton of lag the more items that were added into the game.

So, if I could get some opinions and ideas on this, that would be lovely! Thanks!

In your case, I’d just do it all within hard code. Make a grid-like (double array) or menu (single array) system, then assign a class called Item to it, sort of like this.


public class Item{

        //The type of item (can also be string)
        public int itemType;

        //The image icon... if manageable
        public Image icon;
        //All things describing the item goes here
}


public class Inventory{

       public Item[][] gridofItems;

       //or...

       public Item[] menuOfItems;

       //implement code that renders and controls items here     
}

This is extremely vague, but it takes you on the right path. You want to make sure that you set up Items in a way that you can visualize their place on the inventory sheet. The link below gives a little bit more information about these systems.

XML is not really for drawing an inventory. It is more like a way of saving it to a text file. This is only useful if you wanted to make a customizable inventory, or if you wanted to save it. However, you can just as easily use JSON, or Java serialization to do it. So, I’d just ignore that advice until you feel the need to save your inventory to a save file.

I know how to make the inventory work, I am talking about loading the data for the inventory items, obviously I would have to load an image path from the XML and have my code render it based on where it is inside the inventory.

I am going to need to save it, so that’s why I was thinking of hard coding it because I could make the objects serializable.

With using an Enum, I would need to have a switch statement to decide how to render the item, wouldn’t this slow performance the more items I add?

Here is how I did it for one of my games.

Inventory is made up of like 85 inventory slots or something. Basically Item[] items=new Item[85];
Each slots contains an item. When I want to render inventory, I go through all the item slots and if there is an item in the slot, I do item[slotIndex].render();
I mean, what do you even want to ask?

If you’re asking about item system itself, I made it like this. Every item extends Item.class. Every item has its own class. Every items needs to define few parameters like sprite used, name and some other custom ones. I also have a static instance of each item in my Item class.

When I want to add item to inventory, I just do items[index]=item and the item appears in the inventory.

If you want to have more customized items like each having each own’s durability, special effects, you will need to create a class like ‘SpecializedItem.class’. It would accept ‘base item’ as parameters. When you render specializeditem, render the base item, and render the effects you want on top of it.

It is probably really hard to understand, but the easiest way to do it, would be to actually do it, and not think about it. Think about performance and saving/loading later.

What I really wanted to know was whether I should have the Arrays hold Enum values or actual Objects.

But I’m pretty positive that actually having Objects is probably the better option. Thanks everyone!

Enum values in java are Objects…

I know this, but creating a class specifically for each item I could have rendering properties, update properties, ect. for each item.

Well you can do that with enums as well, but I don’t want to talk you into this :wink:

Other than that, I don’t know if I get your problem.

I would say, just create a Player class with an Inventory property that can have a ArrayList in there. Make your subclasses of Item, fill in the desired functionality and resource properties. If you need to save the player state, either serialize it yourself or use 3rd party libs like xstream to make things easy.

To avoid serializing everything and the kitchen sink, make all fields transient that can be reconstructed dynamically after loading (like textures, sound clips etc.), so only serialize primitive types and simple datamodel like objects.

Then if you need to load the player state, reconstruct the transient fields again. To do that you’ll need to implement readResolve() or readObject(instream)

To render your inventory, create a render() method in your Inventory class that iterates over the ArrayList and render each Item at the desired position. You can either implement a render(x,y) method in your Item class, but I would probably just get an Image from the Item and put the render-code in the Inventory class.

To handle equiping your Player, you can create a special ArrayList named slots or something in your Inventory. Create another class like PlayerAttributes that hold armor, strength etc. properties. Every time the content of the slots change, reset the PlayerAttributes and iterate over all Items in the slots, calling a method like equip(PlayerAttributes attributes) and let the Items modify the given attributes object.

Just give it a shot, even if the post is not fully detailed. You’ll find out the bits and pieces on your way.

Btw. don’t think about something being slow when you are dealing with <10000 objects. Just make it so that you can easy manage the code und functionality. Think about performance, when you have performance problems (or you plan something with >10000 objects/items/entities)

You can use the enum values as an Object as well
for e.g
enum Direction
{
// enum constants
NORTH {
@Override
public String showDirection() {
return NORTH.toString();
}
},
SOUTH {
@Override
public String showDirection() {
return SOUTH.toString();
}
},
EAST {
@Override
public String showDirection() {
return EAST.toString();
}
},
WEST {
@Override
public String showDirection() {
return WEST.toString();
}
};

public abstract String showDirection();

}

public class EnumAbstractMethodExample {
public static void main (String args[])
{
String movingDir = Direction.NORTH.showDirection();
System.out.println(movingDir);
}
}
As you can see we can call showDirection() method on enum object Direction.NORTH . You can find more here https://javahungry.blogspot.com/2018/12/enum-in-java-complete-guide-with-examples.html

If you just want to render(), then you need to use polymorphism, where each class should render their own way. So, yes, you’ll probably gonna haver a LOT of classes.

But things can be smarter: you can, for example, name your files the same name as the Enums. This way, you just need to call something like this:

In the constructor:

public class Item {

      private itemTypeEnum type;
      private Texture texture;

      public Item(itemType type){

             this.type = type;
             //now the smart thing:
             String myFileTexture = type.toString();
             texture = SomeLoadMethod(myFileTexture);
             //other stuff....

      }

      //other methods
}

And the render will be the same to everyone:

public void render() {

        graphicsEngine.render(texture);

}

That is just an idea, but you can do in many ways.