Jump to content


Photo

Custom Inventory


  • Please log in to reply
12 replies to this topic

#1 Criminon

Criminon

    Final Element

  • GMC Member
  • 155 posts
  • Version:GM:Studio

Posted 20 March 2012 - 01:25 PM

Currently I've been racking my brain on how to do an inventory system without drawing the inventory. My inventory screen is it's own level, and it is accessed through the start menu. There are 18 inventory slots. The way I set up moving on the inventory screen is through variables.

Each inventory slot is identified with "global.item_1", "global.item_2 etc". The back button is "global.item_back". (for example - global.item_back =true, the rest =false. if you press up, global.item_back =false and global.item_1 =true. etc) This is so I can track where the glowing select options is. An example of an item I use is "Item_Health". If I were to collide into the health object, it should go to my inventory. My plans were to use this to let the game know which one to select. On the image, I have put the corresponding numbers to the variables.

I've been struggling on how I can implement this menu design into an inventory controller for my character. How can I tell the game to place the items on the screen in my inventory level using this system, and how can I get it to display the item description for each item?

Any help would be greatly appreciated. I would be happy to put you in the credits for your time and effort. Not to mention, I think it would be nice to understand how this system would work.


Screenshot -

Posted Image

Edited by Criminon, 20 March 2012 - 11:53 PM.

  • 0

#2 Reefpirate

Reefpirate

    GMC Member

  • GMC Member
  • 333 posts

Posted 20 March 2012 - 02:58 PM

You need to modify the way you think about the inventory a bit, I think... You're almost there, but you're just sort of contorting your way around it. It should be simpler than you're imagining though...

What you really want is an array. Make a global array and call it inventory, like so:

globalvar inventory;

for (i = 0; i < 18; i += 1)
{
inventory[i] = 0;
}

(Lately I've been using ds_lists for this kind of thing, so if you can get comfortable with them I think they're better... But since your inventory seems to be a fixed size an array should work too.)

Now you have an array where you can store items and things... And you can store whatever object id you want in the 18 inventory slots. And instead of setting 18 different true of false variables, you can just have a variable that is something like: selected_slot, which will track which inventory slot is selected at the moment.

For example, if you want to know what item is in slot 15, you go like this:

Item_to_use = inventory[15];

or, as a variable, like this:

instance_create(x,y,inventory[selected_slot]);

So as you move through the inventory screen, through different slots, don't worry about true or false variables... If you can only select one slot at a time, then you just need one variable, which is selected_slot. Example:

if (keyboard_check_pressed(vk_right)) selected_slot += 1;
if (keyboard_check_pressed(vk_left)) selected_slot -= 1;
if (selected_slot < 0) selected_slot = 18;
if (selected_slot > 18) selected_slot = 0;

Bingo, you now know which slot you want to use based on the selected_slot variable, and you can figure out what is in each inventory slot with your inventory[] array.

You follow? I don't know if I explained that very well...

(Edit: Cool art in that screenshot, by the way...)

Edited by Reefpirate, 20 March 2012 - 03:00 PM.

  • 0

#3 Criminon

Criminon

    Final Element

  • GMC Member
  • 155 posts
  • Version:GM:Studio

Posted 20 March 2012 - 04:39 PM

You need to modify the way you think about the inventory a bit, I think... You're almost there, but you're just sort of contorting your way around it. It should be simpler than you're imagining though...

What you really want is an array. Make a global array and call it inventory, like so:

globalvar inventory;

for (i = 0; i < 18; i += 1)
{
inventory[i] = 0;
}

(Lately I've been using ds_lists for this kind of thing, so if you can get comfortable with them I think they're better... But since your inventory seems to be a fixed size an array should work too.)

Now you have an array where you can store items and things... And you can store whatever object id you want in the 18 inventory slots. And instead of setting 18 different true of false variables, you can just have a variable that is something like: selected_slot, which will track which inventory slot is selected at the moment.

For example, if you want to know what item is in slot 15, you go like this:

Item_to_use = inventory[15];

or, as a variable, like this:

instance_create(x,y,inventory[selected_slot]);

So as you move through the inventory screen, through different slots, don't worry about true or false variables... If you can only select one slot at a time, then you just need one variable, which is selected_slot. Example:

if (keyboard_check_pressed(vk_right)) selected_slot += 1;
if (keyboard_check_pressed(vk_left)) selected_slot -= 1;
if (selected_slot < 0) selected_slot = 18;
if (selected_slot > 18) selected_slot = 0;

Bingo, you now know which slot you want to use based on the selected_slot variable, and you can figure out what is in each inventory slot with your inventory[] array.

You follow? I don't know if I explained that very well...

(Edit: Cool art in that screenshot, by the way...)



I super appreciate it! I've skimmed over it and I'll try it out now. I don't completely follow, but I'll give it a shot. I just have two questions. The reason I have it set up like this is wherever your selection is, a glowing sprite appears. I've done this because you are actually moving one sprite. (the glowing thing is the sprite you are moving) When you hit up, the game checks to see what variables are true, and that allows you to move the sprite. This is done to prevent moving off one of those slots, and it is also done to allow you to go back down to the back button at the bottom, which has a completely different outcome of you have it selected.

My other question is how would I display what text an item has if I hover over a slot? I guess what is bothering me is that I have an idea of how the system should work, I just don't understand how to implement it. If I pick up an item, I need to tell the game that it is stored in the inventory. From there the game needs to determine if slot 1 is available, if it is then to put it in that slot, if it is not, then to put it in the next slot. From there it needs to save the location of that item most likely with a variable, then when I go to that level, to be able to understand that I'm selecting it and then show me text, and prompting me on using it. I just for some reason can't think of a good system that makes sense.

I don't know. I'm usually pretty solution oriented with this kind of stuff, but inventory is really boggling me right now. I'll do some reading on ds_lists and arrays. I don't think I'm familiar with the terms yet.

Also, thanks so much for the complement! I'm super happy with how this game is turning out. It's starting to look semi-professional. I'm combining a lot of RPG elements into a beat em up, and it's turning out better than I had imagined. I just wish my coding was better. If there is any way you could explain a bit better, I would be all ears.

EDIT-

also, another question I had while trying to implement your code is: how would I go about telling the game to add an item to this inventory list?

I added the array code, then used the item_to_use code. I tried using my variables and this code together.

example:
if global.item_18 = true
Item_to_use = inventory[18];


None of them did anything when I hit my select button, which they shouldn't, as there is no item there. But in testing them, the 18th slot gave this argument:

"Error in code at line 655:
Item_to_use = inventory[18];
^
at position 16: Unknown variable inventory or array index out of bounds"

I'm trying to understand a little bit more about this code and why its only giving me the error on 18.

Edited by Criminon, 20 March 2012 - 04:52 PM.

  • 0

#4 Reefpirate

Reefpirate

    GMC Member

  • GMC Member
  • 333 posts

Posted 20 March 2012 - 05:34 PM

Beat-em-up RPG, I like the sound of that :) Ever played River City Ransom?

About the slot 18 error, it's because slot 18 is actually inventory[17], because the array was initialized from 0-17, so 'Slot 18' in the game is actually inventory[17]. This can get tricky with data in RPGs, but just try to stick with it...

So, I avoided this in my first post just to see how you received that info I gave you.... But basically you NEED to get rid of the global.item18 = true structure to really get the flexibility and power... And for the other issues you had, you need another array, an array of ITEMS to go in your INVENTORY.


So, you have inventory array:
inventory[0] = -1;
inventory[1] = -1;
inventory[2] = -1;
...
inventory[17] = -1;

(I changed it from 0 to -1 to mean an empty slot... it will make sense eventually...)

Now you make a 2-dimensional 'item' array:

// ITEM 1 IS A SMALL HEALTH PACK
item[0,0] = "Small Health Pack" // string for the name
item[0,1] = "A small health pack that heals a small amount of health." // string for description
item[0,2] = 10; // amount of Health the health pack heals
item[0,3] = obj_small_healthPack; this is the object that the item is in the game

// ITEM 2 IS A LARGE HEALTH PACK
item[1,0] = "Large Health Pack";
item[1,1] = "A large health pack that heals a large amount of health."
item[1,2] = 25;
item[1,3] = obj_small_healthPack;

// AS MANY ITEMS AS YOU WANT, ETC...

Still with me? Ok, now hopefully you'll see how it comes together:

So to store a Large health pack in inventory slot 15, you go like this:
inventory[14] = 1;
Inventory slot (15-1) gets you the right spot in the inventory array, and the value 1 is the index for the large health pack in the item array.

So, as you're moving around your inventory screen, you have the selectedSlot variable that stores which slot you're on, which then can get the index for what item is in which slot:
inventory[selectedSlot] = the item index for what is in that slot... So it can either be empty (-1), or contain a small health pack (0) or a large health pack (1). So, for the displaying text part, you go:

var itemID;
itemID = inventory[selectedSlot];
draw_text(x, y, item[itemID, 0]); // Writes the string for the name
draw_text(x, y, item[itemID, 1]); // Writes the string for the description

For the item array, you can store all sorts of item info in there... For example the sprite to use to draw it, the price of it, how much it weighs, whatever information you want your items to have. You can then access that information whenever you need it with the item[x,y].

Phew! A lot longer than I thought... But hopefully that shows you roughly how an inventory/item system might work...
  • 0

#5 Follomania

Follomania

    Unum Mirabile

  • GMC Member
  • 445 posts
  • Version:GM:Studio

Posted 20 March 2012 - 05:36 PM

None of them did anything when I hit my select button, which they shouldn't, as there is no item there. But in testing them, the 18th slot gave this argument:

"Error in code at line 655:
Item_to_use = inventory[18];
^
at position 16: Unknown variable inventory or array index out of bounds"

I'm trying to understand a little bit more about this code and why its only giving me the error on 18.


The reason for that error is due to you have not initialized inventory[18]. If you're looping with a repeat loop, keep in mind that when including "0", when you loop a given number of times the last value you initialize the number of times looped minus one. So you have eighteen slots, but slot one is inventory[0] and slot 18 is inventory[17]. If you're using the "for" statement provided, make sure you're running it in the create event to initialize all the inventory slots.
You mentioned having text appear when you hover over the item slot. You can program this quite easily in the draw event.
To draw your inventory from an array, use a code like this one:
inventory_x = 16    //starting position for inventory
inventory_y = 192
max_slots = 18      //number of inventory slots
slot_width = 32      //dimensions of slots
slot_height = 32
slot_xoffset = 64    //spacing between slots
slot_yoffset = 48
for (ii = 0; ii < max_slots;ii += 1){
    if ((mouse_x >= inventory_x)&&(mouse_x <= inventory_x + slot_width)&&(mouse_y >= inventory_y)&&(mouse_y <= inventory_y + slot_height)){
        /*mouse is over this slot.  Draw text and do mouse events*/
        draw_text(inventory_x,inventory_y-32,/*string for this item*/)
        if (mouse_check_button_pressed(mb_left) == 1){
            /*mouse button is pressed; do your stuff*/
        }
        draw_sprite(glowing_sprite,0,inventory_x, inventory_y)
    }
    draw_sprite(inventory_slot_sprite,0,inventory_x,inventory_y)
    /*this is a good trick for fast inventory drawing.
    Make a sprite whose sub-images correspond to the item being used
    sub-image 0 is empty
    sub-image 1 is a sword
    etc.
    Then you can draw the sub-image of the sprite based in the inventory[ii] value
    */
    draw_sprite(items_for_inventory,inventory[ii],inventory_x,inventory_y)
    inventory_x += slot_width + slot_xoffset
    if (inventory_x > 590) {   //change 590 to your maximum x
        inventory_x = 16         //this is your starting x position
        inventory_y += slot_height + slot_yoffset
    }
}

  • 0

#6 Criminon

Criminon

    Final Element

  • GMC Member
  • 155 posts
  • Version:GM:Studio

Posted 20 March 2012 - 06:44 PM

Thanks for your help. Both of you. I'll post a video of the game in it's current progress now. I appreciate the coding. I think I understand it now. :D I'll keep you guys informed. After I put the code in, I'll post the results.





EDIT-
without putting a variable of selectedSlot =-1 I get an unknown variable error. if I put it in I get:

" itemID = inventory[selectedSlot];
^
at position 21: Negative array index"


I just want to confirm that selectedSlot is different from selected_slot. I noticed you used both of them. I'm just trying to find out what things do what, and what makes things work. Whether or not the thing is something I should identify, or if it is a command that the engine will understand.


EDIT-
the more I read the code, and try to work with it, I understand it a bit better. Still a lot I don't understand. The video also finished uploading. Sorry for the poor quality!




I created a separate controller. I've made it a persistent controller at the start of the game. this is what it does:

On Create: Set variable selectedSlot to -1

globalvar inventory;   /////What does this statement do? 

for (i = 0; i < 18; i += 1)
{
inventory[i] = 0;
}


inventory[0] = -1;  /// I understand the inventory[0] = -1. etc. this part makes sense. So does adding the items to it. It's unfortunate that items can only go in their respected slots though. (still completely fine)
inventory[1] = -1;
inventory[2] = -1;
inventory[3] = -1;
inventory[4] = -1;
inventory[5] = -1;
inventory[6] = -1;
inventory[7] = -1;
inventory[8] = -1;
inventory[9] = -1;
inventory[10] = -1;
inventory[11] = -1;
inventory[12] = -1;
inventory[13] = -1;
inventory[14] = -1;
inventory[15] = -1;
inventory[16] = -1;
inventory[17] = -1;


var itemID;
itemID = inventory[selectedSlot];
draw_text(x-5, y-5, item[itemID, 0]); // Writes the string for the name                         ///this makes sense. I'm familiar with draw_text and the [0,0] just made sense to me now.
draw_text(x-5, y-5, item[itemID, 1]); // Writes the string for the description

// ITEM 1 IS A HEALTH ORB
item[0,0] = "Health Orb" // string for the name                                 
item[0,1] = "A mysterious red glowing orb." // string for description
item[0,2] = 5; // amount of Health the health pack heals                                              ///what is this for? This isn't an action or anything, right? How do I link the "5" to doing anything?
item[0,3] = Item_Health; //this is the object that the item is in the game

// ITEM 2 IS A MANA ORB
item[1,0] = "Mana Orb";
item[1,1] = "A mysterious blue glowing orb."
item[1,2] = 5;
item[1,3] = Item_Mana;


so the problem lies right here:
var itemID;
itemID = inventory[selectedSlot];
draw_text(x-5, y-5, item[itemID, 0]); // Writes the string for the name                         ///this makes sense. I'm familiar with draw_text and the [0,0] just made sense to me now.
draw_text(x-5, y-5, item[itemID, 1]); // Writes the string for the description


I thought that you might have typed it wrong, logically, it makes sense for it to look like this:

var itemID;
itemID = selected_slot;
draw_text(x-5, y-5, item[itemID, 0]); // Writes the string for the name
draw_text(x-5, y-5, item[itemID, 1]); // Writes the string for the description

I only changed inventory[selected_slot].

if we are saying for it to draw item[0,0] and we are telling it that it equals item[inventory[0],0] that doesn't seem right.


Another EDIT -

I got it to stop giving me error messages. I think I fully understand everything except for the first part of the code I linked.

"globalvar inventory; /////What does this statement do?

for (i = 0; i < 18; i += 1)
{
inventory[i] = 0;
}"

I think right now I just have to find the correct x and y to see if it's drawing the information correctly. Be back soon.

Edited by Criminon, 20 March 2012 - 08:57 PM.

  • 0

#7 Criminon

Criminon

    Final Element

  • GMC Member
  • 155 posts
  • Version:GM:Studio

Posted 20 March 2012 - 08:10 PM

Bumping in case the edits didn't bump. Just want you to know I replied.
  • 0

#8 Reefpirate

Reefpirate

    GMC Member

  • GMC Member
  • 333 posts

Posted 20 March 2012 - 08:55 PM

The selectedSlot variable and selected_slot were supposed to be the same thing :P

And this variable should never go to -1... Its range should be between 0 and 17, because it is indexing the inventory slots in the inventory[x] array, which goes from 0-17. It is the inventory[x] that might equal -1 if it is an empty inventory slot. (I would have made 0 be empty, but then 0 would be equal to the first item in the item array... You should just figure out a standard for yourself here, whether your arrays will start at 1 or 0, and whether 0 will be an empty slot, or -1, etc.)

So you can initialize your selectedSlot variable at 0... Think of this variable as "what inventory slot the player has selected right now". You then use that information to figure out what is actually IN that inventory slot: inventory[selectedSlot]. You can then use THAT information to reference all the item's info in the item array:
item[inventory[selectedSlot], 0 or 1 or 2...]. Often it is VERY useful to use temporary variables for this stuff otherwise you get ugly looking array calls like that one :)

Now... Take this part:

var itemID;
itemID = inventory[selectedSlot];
draw_text(x-5, y-5, item[itemID, 0]); // Writes the string for the name                         ///this makes sense. I'm familiar with draw_text and the [0,0] just made sense to me now.
draw_text(x-5, y-5, item[itemID, 1]); // Writes the string for the description

And take that out of the creation code... That should be in the draw event in your inventory menu screen. In a step event somewhere you'll want the actual controls that scrolls the selectedSlot variable up and down. Follomania has a good example of how to do the sprite drawing for how to draw the sprite in the right spot, etc.

And make sure up where you have globalvar inventory; you add in the item array too (we want it to be globally accessible as well).
You can do that all in one nice line like so:
globalvar inventory, item;

Your long list of inventory[0-17] = -1; can all go in one for loop like so:
for (i = 0; i < 18; i += 1)
{inventory[i] = -1;}

Lastly, I found this sad comment in your code comments: "It's unfortunate that items can only go in their respected slots though. (still completely fine)"
But cheer up! It's not true! If you want 18 large health packs in your inventory, you can go like this:
for (i = 0; i < 18; i += 1)
{inventory[i] = 1;}

1 is the item index for large health packs, based on what we have so far, so you can have up to 18 of them in your 18 inventory slots, you just have to put the item id in the right inventory slot.... You see now?

You game looks pretty damn good so far! Frankly I'm kind of amazed you got as far as you did without arrays! LOL

(I might need some help with art in the future, wink wink)
  • 0

#9 Criminon

Criminon

    Final Element

  • GMC Member
  • 155 posts
  • Version:GM:Studio

Posted 20 March 2012 - 10:05 PM

I got it working. Ha. Thanks so much for your help, and I'm glad you liked the vid. Any time you need help, just let me know. I'm not too good with anything past pixel art.
  • 0

#10 Criminon

Criminon

    Final Element

  • GMC Member
  • 155 posts
  • Version:GM:Studio

Posted 20 March 2012 - 11:22 PM

So I lied. I got it semi working. It seems to draw the text no matter if I have the item, or not. The text also looks strange because it's not centered, and I can't seem to find a good thread on centering text. I was being a sneaky snake and wormed your code into my pre-existing code to determine where the glowy select thing was. I didn't want to have to deal with figuring out how I could move through the array options, then back down to the
back button. (imagine you only use a select button and your arrow keys) and you have to go on the array and then back down to the back button.

I will literally paypal you 20 dollars (I know it's not much) to just take my file and fix it for me. It's driving me nuts. Let me know if you're interested.

Edited by Criminon, 21 March 2012 - 12:01 AM.

  • 0

#11 Follomania

Follomania

    Unum Mirabile

  • GMC Member
  • 445 posts
  • Version:GM:Studio

Posted 21 March 2012 - 02:43 AM

If you upload your file and pm me a link, I'll check it out. No need to send me money, though. :)
  • 0

#12 Criminon

Criminon

    Final Element

  • GMC Member
  • 155 posts
  • Version:GM:Studio

Posted 21 March 2012 - 10:21 AM

If you upload your file and pm me a link, I'll check it out. No need to send me money, though. :)


I'll send you a PM!

Edited by Criminon, 21 March 2012 - 10:29 AM.

  • 0

#13 larrimo

larrimo

    GMC Member

  • New Member
  • 7 posts
  • Version:Unknown

Posted 02 April 2012 - 02:57 PM

This might actually help me with a project I'm working on. Not a game, but an app. I'm having trouble getting selected images to be replicated on a bar. Someone pointed out that using a global array might be the best thing to use. I'll have to dig into the explanations that Reefpirate gave. You've helped so many people with a few posts!

Actually, if you could pop in to this thread: http://gmc.yoyogames...howtopic=535458

and give me some pointers, I'd REALLY appreciate it.

Edited by larrimo, 02 April 2012 - 04:30 PM.

  • 0




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users