Multi-Resolution Game Development With GameBuilder Studio Check it out!
NEW Version 0.9.7 has arrived! New Blazing Fast Particle Engine & More Game Actions. Check it out
Best way to do an inventory?
  • I'm thinking about the possibility to do an ingame drag&drop equipment inventory. The drag&drop part should be easy with mouse-constrains on mouse down and collisions with the places to put the equipment on mouse up. But how can I arrange the items in the area to choose from?

    Lets say the player collected three lasers and two rockets from about 10 things he potentially can have in different quantities. So I have a DataContainer saying: lasers = 3, plasma = 0, rockets = 2 and so on. Now lets say my item pool is like a chessboard. So I want to display a laser icon in the first three squares and rocket icons in the next two and the rest of the squares is empty. How to do something like that?
  • 8 Comments sorted by
  • Hum... I tried to do an Inventory Drag and Drop but it did not go too well. I think the easiest way it´s a make an Click and Click Inventory... Like, you have 3 lasers in the Slot 1, 2 rockets in the slot 2, you click in this 2, then they switch the slot... Or something like that. But in all tipes of inventories, you must create a system to the game knows where is the last slot, to go the item you pick, understand? So you can create a DataContainer with Slot=1, and when you pick an item you must do a RulesMap with Spawn "Item" in Slot1.x and Slot1.y ,and Slot = Slot+1... Maybe you won´t undersand this... but it´s hard to explain. The best simple inventory it´s an inventory like CS:GO like you open a Case, then spawn the item you got in the next slot.

    But if you really want to do just and DragAndDrop System... It´s like, Ok, You must have the items and slots... and you must do a rulesmap in all items with When Click on Entity, Item"Number".x = Mouse.x and Item"Number".y = Mouse.y. This is the way to move the items... And the way to put the items in the slot it´s you create 2 Collisions, Slots and Items. And When an Item collides with a slot Item"Number".x = Slot"Number".x and "Number".y = Slot"Number".y... And you must create a text renderer in all items to show the quantity of that item. Well, I tried to do this at some time ago, but I couldn´t. 

    I hope it helped you. Good Luck!
  • @Cavaron this would be very easy to do. In the Multiplayer demo there is a sample project that shows how to automate the creation of a grid display like a tic tac toe board using a Rules Component and a Loop action. Anytime you are working with a grid of items just think of it as a list. I will see if I can create a little sample project and post it here later.

    My suggestion would be to group the items in the inventory board by displaying one unique item type and displaying a number showing how many items of that type the user has in the inventory. But this is a little bit more complex because it would require checking the list for an item of the same type before adding new entries and you would have to manage two List components and keep them in synch as the inventory changed.

    To keep it simple just use one List Component and enter the amount of slots you will allow in your inventory. You could do this manually in-editor or at runtime using a Loop action and a List action to push items onto the list. This list would be used to hold the inventory item type value for the inventory grid. Create a value map like 1 = lasers, 2 = plasma, etc. You will loop through the list to Spawn an entity object that will manage each inventory slot and convert the stored value into a visual representation of the item. So if the value of slot 1 is 1 the entity should show a Laser, and so on. You can access the value of the current list item using the currentIndex property in the "CurrentActionData" property while using a Loop action. To access the value in the list just concatenate the list entry name with the currentIndex property by using an expression ( i.e. Entity.InventoryManager.InventoryList["item"+currentIndex] ) Use this to copy over the current list item value to a property on the newly spawned object after spawning it. You will need to give the newly spawned object a name. 

    **Another approach would be to have a dummy (throw away) Data component on the entity handling the inventory grid creation with all of the properties you want to copy over to the newly spawned object, then set the values of those properties each time the loop happens right before spawning the new object and pass the dummy Data component to the Spawn Entity action as the Data component to copy over to the newly created entity. You will need to make sure the entity you are spawning has a Data component on it to receive the copied values.

    Each entity spawned during the creation of the inventory grid should be an inventory slot entity that manages displaying the type of item based on the value in the slot of the List component and maybe even how many of the items the player has in that slot. Or you could use a second List component to keep track of the quantity of each slot and reference it using the slot index value. You would have to keep the two List components in synch however as the inventory list changes.

    So as the player removes items or adds new items to their inventory just have a Rules component that re-paints the inventory grid any time the main inventory List changes. You could use a Boolean property to trigger the logic that creates the grid.
  • @Sonic Thanks for your suggestions - that gave me some ideas. I think I have what I wanted now - but I'm not sure if it is overly complex. I will upload my testproject, it can be used (and hopefully be improved) freely:

    @Lavon Thanks for your reply, I would love to see your solution to my problem. If you like my Inventory (probably has to be improved), I would be honored if you include it in the GBS example projects. So far it is capable to bind items to slots and to fill the slots where ever there is a free slot. The player can replace or trash items freely and he can equip three slots in a beautiful spaceship with these items.

    A few glitches I noticed while doing this (not sure if my fault because bad logic or bugs):
    - If you move one of the Test Items really fast between Slot1 and Slot2 (the up left orange boxes) with your mouse, the engine gets the impression that the item has collided with both boxes at the same time, setting both Slots occupied and in doing so, rendering one Slot useless from there on.
    - If the mouse is up on the Items, they should either snap to a new Slot they are in collision-contact with, or they should fall back to their last position (if mouse is up somwhere on screen or on an occupied Slot). This does not work if the collision shape of the Items is in contact with the "Test Items"-Label or if it is exactly on top of another Item. In that cases they stick where they are. I suppose this has to do with the layer-position/render-order/z-position. I could set an Item to semthing like z-position=1000 if mouse down to prevent that. But I'm not sure if this is an unwanted behaviour anyway?
    - I couldn't get the Trash-Logic on the Items to work on the RulesMap conditions "collision with trash started" AND "mouse up on entity". I thought it would work if I set the "continously collide"-option, but it didn't. I want the Items to be destroyed when they are in collision with the Trash AND the mousebutton is released.
    - I don't have a clue how to set the color-code with expressions, I tried it with "#FF0000", then without the "" and without the #, nothing worked. I finally used a reference on the color of another object to get a black to red interpolation on the Inventory-Label if the slots are full and the user tries to spawn more.
  • @Sonic a couple of suggestions. When creating objects of the same type with just one component having a difference like your Inventory Slot squares you should clone them so that they reference the original object and you don't have to copy logic between them once editing one of them. Each clone can have its DataContainer unlocked in the editor and you can add custom values if you need to on a per component basis. Just a little tip.

    To fix that little issue where dragging between two slots causes the second one to be considered filled thus making it useless. All you have to do is add a Mouse Up condition to the "Logic_PlaceOnSlot" component and that will only fill the slot when the item overlaps the slot and the player has released it onto the slot. Not just when hovering over it.

    Also if you want to prevent the object snapping to the mouse position consider subtracting the object's position from the mouse position. So instead of Applying the Exact mouse position using  setPoint( Game.Mouse.x, Game.Mouse.y ), do this instead  setPoint( Game.Mouse.x - Self.Spatial.x, Game.Mouse.y - Self.Spatial.y ). That will allow the object to move with the mouse at the point where the player puts their mouse down on the object being dragged.

    Yes that mouse up issue when dragging and releasing objects over the "Test Items" label is being caused because the "Test Items' object is on a higher layer and the Mouse Up does get to the item being dragged. To fix this just uncheck "On Entity" in the Mouse Up condition. There is no need to know if the mouse was released on the object just if it was released at all. This should also fix the trash release on top of logic that you want.

    If you run into that issue and you need to dynamically swap the rendering layer depth yes you can change the "zIndex" property on the renderer to dynamically change the layer depth at runtime.

    To dynamically set a color using an expression use the "0x" syntax (i.e.  0x0 (black) 0xFFFFFF (white), etc... not the "#" symbol)
  • @Sonic just realized that you will need more than just a Mouse Up event added to your "Logic_PlaceOnSlot" component. What you are trying to determine is if the object is currently overlapping the target drop zone. So it would be a good idea to set a Boolean value of "currentlyColliding" that gets turned on when collision starts and turned off when collision stops. We should add an isOverlapping Condition in the future. You can check for that property instead of detecting the On Collision started because the on collision started evaluates to true once and then gets reset because it is an event notification that the entity receives. So we don't cache the state of the collision.

    Also turning off "on Entity" for the Mouse Up condition on the actual Item "Logic_Position" component. This will give you the desired result.
  • @Sonic the way you have it setup makes things overly complicated and tedious to setup or even edit. I will create an inventory demo to show you how you can store all the information of an inventory slot on the slot itself and also auto create the inventory slots at runtime just by using a List Component and a Loop Action.
  • @Lavon *cough* the overly complicated setup is my work ;) But Sonic did indeed give me some ideas. I can't await to see your solution Lavon, many thanks!

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion