Basic Inventory System using DS Lists (GMS 1.4/2.0)

Hello there! In this post we’re going to make a simple inventory system using DS Lists. If you aren’t familiar with DS Lists, don’t worry, I’m going to explain how they work too.

This should work with both GMS 1.4 and 2.0, since the GML is the same, but I haven’t tested it with 2.0. Please inform me in case it doesn’t work properly there.

DS Lists

Well, you know what variables are like, don’t you? Something that stores a value…

item = "apple";

And, you also know an array, don’t you? Well it’s fine if you don’t. An array stores a lot of values, like this:

item[0] = "apple";
item[1] = "orange";
item[2] = "mango";
item[3] = "apple";
item[4] = "banana";
item[5] = "mango";

A DS List is similar to an array, but more flexible and has a lot of functions.

We’ll build a very simple inventory system with a DS List.

Inventory System

Player Object

For this I have a little project with a 4-directional player. So you need to create one too if you want to replicate this example.

So now we need to create a DS List. Here’s how you do it:

obj_player Create event:
globalvar inv;
inv = ds_list_create();

So this has created a global DS List with the name of inv. 

Item Object

Now we need to have actual collectibles, so for that I’ve created three sprites: spr_apple, spr_mango and spr_banana.

For those items I’ll make an object called obj_item. This is the item that the player will collect and will be added to the inventory.

I’ll add some code now:

obj_item:
Create event:
item_name = choose("apple", "mango", "banana");
sprite_index = asset_get_index("spr_" + item_name);

//^ This creates a variable that contains the type of item it will be. So
//  it will be chosen at random from the three type of items we have.
//  Naming them the same way they are named in their sprites (excluding
//   spr_)
//  The second line chooses a sprite for the item based on the item name.

Step event:
if (place_meeting(x, y, obj_player)){
    ds_list_add(inv, item_name);
    instance_destroy();
}

//^ With this, when the item collides with the player, it will add its
//  item_name to the inv list (which is the inventory) using ds_list_add().
//  Then it destroys the item instance.

Back to the Player Object

So now that we’re done with the item object, let’s add some code to the player object:

obj_player:
Draw event:
draw_self();
for(var i=0; i<ds_list_size(inv); i++){
    draw_text(5, 5 + (24*i), inv[| i]);
}

If you’re not sure what a for loop is, read this.

So let me explain what this code does. It loops through the inv (inventory) DS List we have (using ds_list_size() in the condition, which returns the total number of items in a list). It then draws the names of the items that are inside the inventory list. (It draws text not because that’s the way it works but because that’s the way we are making it. Instead of the text there can be anything in a list, like a sprite, an instance or another data structure, but we are using text to store the item name).

See the third argument in the draw_text() function?

inv[| i]

This is a way to get a value from a DS List (the other way is ds_list_find_value()). It’s like an array, where you get the value by putting the index number in square brackets.

array[i]

In data structures, you have to put the accessor (which, for a list, is “|”) inside the brackets. That’s why it looks like this:

inv[| i]

 

Now that everything is ready, we need to add a little thing – the ability to place items with the mouse (just for testing purposes). I’ll add this code in obj_player’s Step event:

if (mouse_check_button_pressed(mb_left)){
    instance_create(mouse_x, mouse_y, obj_item);
}
//If you're using GMS2:
if (mouse_check_button_pressed(mb_left)){
    instance_create_depth(mouse_x, mouse_y, 0, obj_item);
}

Testing

Now ready your room by placing the player inside it and run the game! Place the items with your left mouse button and collect them with the player.

1.gif
See? As I collect the items, they go into the inventory!

 

Menu

Okay, we made an inventory, but how do we use it? We need to create a menu which shows all the items you have collected and where you can use them. This menu will come up on pressing Escape.

Here I’ll create a menu where when you use an item, it gets removed from the inventory.

For this I’ll create a new object called “obj_menu” with no sprite and place it in the room. This will contain all the menu code.

obj_menu Create event:
active = false;

active will tell whether the menu has been activated or not.

Menu Button

First we need to create a button object for the menu. I’ll be using this 64×64 sprite for it:

2.png

Feel free to use it or make one on your own (64×64 size for this example).

I’ll name the object obj_button. Set its depth to a very low value (like -10000) so that it appears on top of everything.

Back to obj_menu

The button code can be understood nicely only after coding the menu, so let’s get on with it first.

Open the Draw GUI event of obj_menu (it’s under Draw > Draw GUI), where we’ll write…

I’m using the Draw GUI event because for the x/y coordinates it refers to the screen space (0, 0 being to top-left corner of the screen) rather than the room space (where 0, 0 is the top-left corner of the entire room). This way it’s easier to place buttons on the screen.

if (keyboard_check_pressed(vk_escape)) active = !active;
    else exit;
//Turns active to true/false if escape pressed, but if not,
//exits the event

//If activated:
if (active){
    var w=0, h=0;
    for(var i=0; i<ds_list_size(inv); i++){
        var btn = instance_create(32 + (w*96), 32 + (h*96), obj_button);
        //GMS2 variant of the statement above:
        var btn = instance_create_depth(32 + (w*96), 32 + (h*96), 0, obj_button);
        btn.item_id = inv[| i];
        btn.inv_id = i;
        //^ assigns item value and list item index to the button
        //moves to the next line if current one filled:
        w++;
        if (w >= (floor(window_get_width()/96))){
            w = 0; h++;
        }
    }
}
else
//If deactivated, remove the buttons:
if (instance_exists(obj_button)){
    with (obj_button) instance_destroy();
}

So now the basic menu is ready. You can test your game and see that the menu opens with the buttons in it, for all the items you have collected. But no item is shown inside those buttons and you can’t do anything with it, so for that we’ll have to work with obj_button.

obj_button Step event:
//Mouse hover effect:
if (position_meeting(mouse_x, mouse_y, id)) image_alpha = 0.8;
else image_alpha = 1;

//Do something if mouse left button pressed:
if (position_meeting(mouse_x, mouse_y, id) && mouse_check_button_pressed(mb_left)){
    /*add your code here to do something. If you want different behavior
    depending on the type of item, you can do something like:
        if (item_id=="apple") health+=10;
        else if (item_id=="mango") {health+=20; armor+=10;}
        <else...>
    */
    ds_list_delete(inv, inv_id);
    //^ removes item from inventory list
    //deactivate menu and destroy buttons:
    if (instance_exists(obj_button)) with (obj_button) instance_destroy();
    obj_menu.active = false;
}

obj button Draw event:
draw_self();
draw_sprite(asset_get_index("spr_" + item_id), 0, x + 32, y + 32);
//^ draws the item sprite in the center of the button

Try it now! Place the items, press Escape, and click on an item.

3.gif

Scroll

What if your inventory has just too many items and the menu goes off the screen? We need to add the option to be able to scroll with the mouse wheel. For this we’ll first add some code to obj_menu:

Create event:
y_scroll = false;

Step event:
if (y_scroll > 0) y_scroll -= mouse_wheel_up() * 10;
y_scroll += mouse_wheel_down() * 10;
//10 is the scroll speed. You can change it to scroll faster/slower.

So here we’ve created a variable called y_scroll that increases as you scroll your mouse wheel downwards. Now we’ll add some code in obj_button’s Step event:

//Scroll
y = ystart - obj_menu.y_scroll;

So this will move the buttons upwards as we scroll downwards. Try it out!

4.gif


Conclusion

So that was a really basic inventory system using DS Lists. You can add a lot more functionality to it and make it even better.

You can download this project here (GMS 1.4). Feel free to modify it to learn more about how the code works.


Need more help, or want to ask something? Or want to inform me of any mistake in this post? In any case, please feel free to comment below.

Also, make sure you join the GameMaker Mentors Discord Server (Click here). It’s the best place you can be at as a beginner, as the server is fully dedicated to helping newbies out, with many Mentors and Helpers to help you on your way. Text chatting provides a quick way to get help on any issue.

Follow this blog (see the bottom of this page) to be notified about new posts. Also, feel free to share this website if you feel it could help anyone! 🙂

Happy game dev’ing!

Advertisements

One thought on “Basic Inventory System using DS Lists (GMS 1.4/2.0)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s