Transfer an item from world to inventory [SOLVED]

Hi guys,

I am struggling a bit with my libgdx game design regarding how items should be handled with an inventory system. Currently, my item class is based on a generic GameObject which has properties like position, velocity, and can interact with the world.


package net.bigfootsoftware.seacraft.objects;

import net.bigfootsoftware.seacraft.engine.World;

import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.Rectangle;


public abstract class GameObject
{
	// FIELDS
		
	public Physics physics;
	
	protected World world;
	protected float width;
	protected float height;
	
	private String id;
	private Rectangle bounds;
	private boolean alive;
	
	public GameObject(String id, World world, float x, float y, float width, float height)
	{
		this.world = world;
		this.physics = new Physics(this);
		this.physics.position.set(x,y);
		this.id = id;
		this.width = width;
		this.height = height;
		this.bounds = new Rectangle();
		this.alive = true;
	}
	
	// GETTERS AND SETTERS
	
	public String getID()
	{
		return id;
	}
	
	public boolean isAlive()
	{
		return alive;
	}
	
	public void setAlive(boolean b)
	{
		alive = b;
	}
	
	public Rectangle getBounds()
	{
		bounds.set(physics.position.x, physics.position.y, width, height);
		return bounds;
	}
	
	public float getWidth()
	{
		return width;
	}
	
	public float getHeight()
	{
		return height;
	}
	
	public World getWorld()
	{
		return world;
	}

	
	// ABSTRACT METHODS
	
	public abstract void update(float dt);
	public abstract TextureRegion getTextureRegion();
	public abstract void collision(float dx, float dy);
	
	
	
}


My Item class looks like this. Notice the abstract method onUse().


package net.bigfootsoftware.seacraft.items;

import net.bigfootsoftware.seacraft.Game;
import net.bigfootsoftware.seacraft.engine.World;
import net.bigfootsoftware.seacraft.objects.GameObject;

import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.math.MathUtils;

public abstract class Item extends GameObject
{
	private TextureRegion region;
	
	public Item(String id, World world, float x, float y, float width, float height)
	{
		super(id,world,x,y,width,height);
		region = Game.res.getTextureRegion(id);
		physics.setJumpSpeed(-0.2f);
		physics.velocity.x = MathUtils.random(-0.05f, 0.05f);
		physics.jump();
	}

	
	public void update(float dt)
	{
		physics.apply(dt);
	}
	
	public abstract void onUse(float x, float y);


	@Override
	public TextureRegion getTextureRegion()
	{
		return region;
	}


	@Override
	public void collision(float dx, float dy)
	{
		physics.stopXVelocity();
	}
	
	
}


This works great because it allows each item to decide what should happen when it used. The problem is how do I represent these items using a String id only as opposed to having hundreds of live Item objects in the players inventory? I want to be able to remove the item from the world when collided with it, add that item as some sort of array of item id’s, then select an item from inventory, and when “used” it will simply call the abstract method onUse().

I thought about creating one static instance of each Item with some sort of Item registry but all GameObject requires a position and world reference making that impossible. Do I just make an entirely new class to represent each item? I might be over thinking this and I really could use some good advice.

Sounds like a case for a Map collection. i.e.

Map<String,Item> inventory = new HashMap<>();

since a Map is a java.util collection, you can iterate over the inventory:

for (Item item : inventory) { System.out.println(item.getId();}

To add to the inventory:

inventory.put(item.getId(),item);

To remove from the inventory:

inventory.remove(item.getId());

To use the item:

inventory.get(item.getId()).onUse();

Moogle thanks but what I was trying to avoid was having hundreds of Item objects in inventory because it’s not very efficient. I actually solved this by trimming the Item class down to a bare minimum removing all references to position, vecloity, etc and making an ItemContainer class derived from GameObject which has an Item as a class field.

In addition, I’m using a ItemRegistry class which holds one instantiated Item of each type in an ObjectMap. This allows me to destroy the ItemContainer after collision but retain a String key reference to the appropriate Item which then allows me to call the onUse() method. God I love Java!

I can’t tell you how many problems I’ve solved just by getting away from the computer and laying down at night. The answers seem to come to me most of the time. I’m marking this one solved.

You could try using JSON for the items. It can store tons of useful data for items and stuff without creating a class for each item

David this is an interesting idea. I believe that LIBGDX has a JSON loader but is there an editor available that you know of? I’ve never worked with it other than looking at some example files.

Have you thought of seperating an item and the definition of one? The definition contains the name, description, properties (special stats, buffs etc.), sprites. If you have this you can have a “GameObject” item which is displayed in the game world. This item references a definition. If you then pick up the item, you can “destroy” the item instance and just reference the definition from your inventory… When you drop an item from your inventory in the game world you then just need to create a new instance again. To save space in the inventory you could make an “InventoryItem” class which references the item definition and has an integer to store the item count.

I would do probably something along those lines. Hope this gives you some ideas. Probably have a look at the flyweight pattern ( http://gameprogrammingpatterns.com/flyweight.html ), which is basically what I’m suggesting here.