How to make an Inventory System for RPG Game?

I stucked with inventory system in my game. I decided to create a new prototype of inventory. I'm not using any game engines and I will make this with a game library called SFML. 

Let's think about inventory system and we have define all requirements about it. 
inventory system for game

In the above image, I have two types items and a player which I will controll. Let every object in the game have a certain id. For example, the purple star item's id is 8, and the id of orange quads is 6. Also there is a player, but it's not important at this point because it's not an item.

We need to create an inventory system. This inventory system will be specific to the player. We already saw this system in the most of the games. The inventory that I will create, will contain these limitations:
  • An inventory can contain up to 9 different items.
  • Items will have one of two states, quantity and non-quantity.
  • If the item is quantity, then a maximum of 8 identical items can be stored in a single slot.
  • If the item is non-quantity then there can be at most one of that item in a single slot.
According to these informations, The inventory should look like in the below:
inventory
After this information, I think we can represent the inventory with a class structure. Well, We don't have many options anyway. Let's create this class using C#:
    class Inventory
    {
        Dictionary<uint, Entity> items;
        Dictionary<uint, int> itemsQuantity;
        uint length = 0; // 9 slot and max 8 items for each one if it is quantity

        public Inventory()
        {
            items = new Dictionary<uint, Entity>();
            itemsQuantity = new Dictionary<uint, int>();
        }
        ...
I will hold the ID of items and their quantity if there is, in the dictionarys or we can call them as hash tables. The important things is here about data. We can just store the data how many we have items in the inventory. So, we can use the chosen entity as much as we have. But we haven't gotten there yet. Our priority is to collect items at first. In our game, there will be items around the player we will use. In this case, if the player collides with these items, they must be added to their inventory. We will do this operation in the method of player class. But first we need to create a method called addItem in the inventory class:
        public void addItem(Entity entity)
        {
            if(length < 9)
            {
                length++;

                // if the same item is already added then increase the quantity of item 
                if(items.ContainsKey(entity.ID) && entity.Quantity)
                {
                    itemsQuantity[entity.ID] += 1;
                }
                // if item does not exist in inventory, add this item to the dictionary of items.
                else if(!items.ContainsKey(entity.ID))
                {
                    items[entity.ID] = entity;
                    itemsQuantity[entity.ID] = 1;
                }                
            }
            showItem();
        }

        public void showItem()
        {
            Console.Clear();
            foreach (var item in items)
            {
                // show item id and the quantity of item
                Console.WriteLine(item.Key + " : " + itemsQuantity[item.Key]);
            }
        }
        ...
Also, I added a method called showItem to track the inventory. Now, we can create an inventory for the player. I will define a field in the player class:
    class Player: Entity
    {
        Inventory inventory;

        Vector2f position;
        const float PLAYER_SPEED = 4f;

        public Player(Vector2f pos, Texture texture, uint id, bool quantity = false)
            :base(pos, texture, id, quantity)
        {
            inventory = new Inventory();
            position = pos;
        }
Now, we came the important part of adding item to the inventory; colliding part:
        public override void update(List<Entity> entities)
        {
            move();
            entity.Position = position;

            foreach (var item in entities)
            {
                if(this.entity.GetGlobalBounds().Intersects(item.entity.GetGlobalBounds()))
                {
                    if(item != this){
                        inventory.addItem(item);
                        item.Destroyed = true;
                    }
                }
            } 
        }
if you noticed, Destroyed is assigned as true. The reason for doing this is to delete the object from the game environment. In fact, what we are doing here is, in a sense, converting the object into data. If the entities destroyed value is true, these entities will be removed from the list of entities. We will do it this operation in the game loop.
            while (window.IsOpen)
            {
                window.DispatchEvents();

                // update entities
                for (int i = 0; i < entities.Count; i++)
                {
                    entities[i].update(entities);
                }

                // delete entity if it is destroyed
                for (int i = 0; i < entities.Count; i++)
                {
                    if(entities[i].Destroyed)
                    {
                        entities.Remove(entities[i]);
                    }
                }

				// draw entities
                window.Clear(new Color(150, 150, 150));
                
                ...
                
                window.Display();
            }
Now, let's look at the result, and also we will see output in console:
Inventory System
We have a long way to go. I want to show the invontery panel in the window with the icon of items. I want the inventory panel on the screen when I press the E key. However, this task is really complex and it needs too progress, and this is the first part of the making an inventory system.

No comments:

Post a Comment