Building an RPG-Style Inventory

22

Index

Attached Files

The following files have been attached to this tutorial:

.c3p

inventory-system.c3p

Download now 344.98 KB

Stats

11,896 visits, 33,576 views

Tools

Translations

This tutorial hasn't been translated.

License

This tutorial is licensed under CC BY 4.0. Please refer to the license text if you wish to reuse, share or remix the content contained within this tutorial.

Global Variables

This project runs on quite a few global variables – some to track the inventory's current attributes, some for scrolling through the inventory and a Boolean for opening and closing the inventory. To set up the project, you'll need the following global variables:

  • InvOpen: A Boolean used to open and close the inventory. When the spacebar is pressed, the Boolean is toggled true/false, opening and closing the inventory as needed.
  • CurrentItemSlot: This variable stores the slot ID number of the item slot the player is currently selecting.
  • CurrentItemID: This variable stored the numeric ID of the item that is currently selected.
  • CurrentInvID: The numerical ID of the inventory category the player is currently looking at.
  • CurrentInvCat: The string ID of the inventory category the player is currently looking at.
  • CurrentInvPage: The page of the current inventory category the player is looking at.
  • ScrollCatLeft & ScrollCatRight: These two Booleans dictate whether the player can scroll left or right through inventory categories.
  • ScrollsPageLeft & ScrollPageRight: These two Booleans dictate whether the player can scroll left or right through category pages.

Functions

The project uses a variety of functions to help keep the code tidy and reduce repeated events. Each function will be laid out here so that when they're referenced later in the tutorial, you're aware of what they do.

UpdateArray

Parameters: ArrayName (String)

Condition

On Function UpdateArray

Inventories ▶︎ CategoryName = ArrayName

Action

Inventories ▶︎ Set InvPages to ceil(Self.Height/20)

UpdateInv

Parameters: None

Condition

On function UpdateInv

Action

InvCategory ▶︎ Set text to CurrentInvCat

Sub-Event Condition

ItemSlot ▶︎ SlotID = CurrentItemSlot

Sub-Event Action

Selector ▶︎ Set position to ItemSlot (image point 0)

Sub-Event Condition

Selector ▶︎ Is overlapping ItemSlot

Sub-Event Action

System ▶︎ Set CurrentItemID to ItemSlot.ItemID

ItemShowcase ▶︎ Set animation frame to CurrentItemID

Sub-Event Condition

System ▶︎ CurrentItemID ≠ 0

Sub-Event Action

ItemName ▶︎ Set text to ItemData.Get("items." & CurrentItemID & ".name")

ItemDescription ▶︎ Set text to ItemData.Get("items." & CurrentItemID & ".description")

NumberHeld ▶︎ Set text to "Number Held: " & Dictionary.Get(ItemData.Get("items." & CurrentItemID & ".name"))

Sub-Event Condition

System ▶︎ CurrentItemID = 0

Sub-Event Action

ItemName ▶︎ Set text to ""

ItemDescription ▶︎ Set text to ""

NumberHeld ▶︎ Set text to ""

SetInvPage

Parameters: NewCat (String)

Condition

On Function SetInvPage

Inventories ▶︎ CategoryID = NewCat

Action

System ▶︎ Set CurrentInvPage to (Inventories.InvPages)-1

CategoryCheck

Parameters: CheckWhich (String), Direction (String)

This function gets a little complicated, so for the purposes of this tutorial, the events have been split into two sections – Checking Categories and Checking Pages. Each exists as its own sub-event under the function call like so:

Starting with checking pages:

Sub-event condition

System ▶︎ CheckWhich = "Page"

Sub-event condition

System ▶︎ Direction = "Right"

Sub-event condition

Inventories ▶︎ CategoryName = CurrentInvCat

Sub-event condition

System ▶︎ Is ScrollPageRight

Sub-event action

System ▶︎ Add 1 to CurrentInvPage

System ▶︎ Set CurrentItemSlot to 0

Sub-event condition

System ▶︎ Is ScrollCatRight

System ▶︎ Is NOT ScrollPageRight

Sub-event action

System ▶︎ Add 1 to CurrentInvID

System ▶︎ Set CurrentInvPage to 0

System ▶︎ Set CurrentItemSlot to 0

Sub-event condition

System ▶︎ Direction = "Left"

Sub-event condition

Inventories ▶︎ CategoryName = CurrentInvCat

Sub-event condition

System ▶︎ Is ScrollPageLeft

Sub-event action

System ▶︎ Subtract 1 from CurrentInvPage

System▶︎ Set CurrentItemSlot to 0

Sub-event Condition

System▶︎ Is ScrollCatLeft

System ▶︎ Is NOT ScrollPageLeft

Sub-event Action

System ▶︎ Subtract 1 from CurrentInvID

System ▶︎ Set CurrentItemSlot to 0

Functions ▶︎ Call SetInvPage (NewCat: Inventories.NextCatL)

Then when the system needs to check Categories:

Sub-event condition

System ▶︎ CheckWhich = "Cat"

Sub-event Condition

System ▶︎ Direction = "Right"

System ▶︎ Is ScrollCatRight

Sub-event Action

System ▶︎ Add 1 to CurrentInvID

Sub-event Condition

System ▶︎ Direction = "Left"

System ▶︎ Is ScrollCatLeft

Sub-event Action

System ▶︎ Subtract 1 from CurrentInvID

MoveCursor

Parameters: Direction (String)

On function MoveCursor:

Sub-event Condition

System ▶︎ Direction = "Right"

Sub-event Action

System▶︎ Add 1 to CurrentItemSlot

Sub-event Condition

System ▶︎ Direction = "Left"

Sub-event Action

System▶︎ Subtract 1 from CurrentItemSlot

Sub-event Condition

System ▶︎ Direction = "Up"

Sub-event Action

System▶︎ Subtract 5 from CurrentItemSlot

Sub-event Condition

System ▶︎ Direction = "Down"

Sub-event Action

System▶︎ Add 5 to CurrentItemSlot

SaveInventories

Parameters: None

This function is used to save the data from the inventory arrays and numbers of items. The ItemNumbers dictionary is saved directly into Local Storage, while the JSON strings for the arrays are added to a new dictionary object InvData which is then saved to Local Storage.

On function SaveInventories:

Sub-event Condition

[/h]3

System ▶︎ For Each Inventories

Sub-event Action

InvData ▶︎ Add key Inventories.CategoryName with value Inventories.AsJSON

Sub-event Action

[/h]3

Local Storage ▶︎ Set item "InvData" to InvData.AsJSON

Sub-event Action

Local Storage ▶︎ Set item "ItemNumbers" to ItemNumbers.AsJSON

LoadInventories

Parameters: None

This function loads the JSON strings stored in the InvData object back into the correct arrays.

On function LoadInventories:

Sub-event Condition

[/h]3

InvData ▶︎ For Each key

Sub-event Condition

Inventories ▶︎ CategoryName = InvData.CurrentKey

Sub-event Action

Inventories ▶︎ Load from JSON string InvData.CurrentValue

Project Files

The next step is to create the events needed to call the various project files used in this example. To do this, a combination of Local Storage and AJAX requests will load all the relevant data into their respective objects.

On the start of the layout, an AJAX request is made for the ItemData JSON file. Once that request is completed, the JSON data is loaded into the JSON object and the two Local Storage checks are made to see if either the InvData or ItemNumbers keys exist.

If the InvData exists then the JSON value from local storage is loaded into the InvData dictionary object before calling the LoadInventories function. If the ItemNumbers key exists then the JSON value from local storage is loaded into the ItemNumbers dictionary.

If the InvData key is missing then the first of the array project files is requested via AJAX. This starts off a cascade of AJAX requests which loads the correct array files into their corresponding objects.

If the ItemNumbers key is missing then the ItemNumbers project file is requested. When the file has been retrieved it is loaded into the ItemNumbers dictionary.

There are neater ways of doing this, but I've left it deliberately expanded to better demonstrate what's being loaded and where.

  • 10 Comments

  • Order by
Want to leave a comment? Login or Register an account!
  • Seriously one of the best tutorials/guides on Construct. This should have won some awards! :)

    My question is, next step, how would you set this up so that certain items are only available based on your character's level? Obviously you would need some value to increase (XP?) and when it hit a certain value (level?), new items could be "found" but putting that together is beyond me. However, for a superhero like Laura_D, it could be a fun project building off this gem.

    Thanks for all that you do!!

  • Hi Laura! I'm struggling to understand where the images for the items are being pulled in from. I don't see it mentioned in the tutorial. Could you please explain? Thanks!

      • [-] [+]
      • 1
      • Laura_D's avatar
      • Laura_D
      • Construct Team Community Manager
      • 1 points
      • (1 child)

      So, both the ItemShowcase and the ItemSlot objects have animation frames for each item. Then, in the JSON file, each item has an ID and these ID numbers dictate the order that the frames are stored in on the Showcase and Slot sprites.

      The Slot images are set from these ID numbers in the Inventory Category Settings event group, and the Showcase images are set during the UpdateInv function.

      Does that help?

  • Thanks for the tutorial Laura! Just a question, is there any reason you specify the items on a JSON file?

    Feels to me that it would be easier to manage if they were created individually under a folder or family since we load the json to memory anyway, unless there is a performance gain I'm missing.

      • [-] [+]
      • 2
      • Laura_D's avatar
      • Laura_D
      • Construct Team Community Manager
      • 2 points
      • (0 children)

      I've not done any testing in terms of performance, but for me, it was down to preference. I didn't want to have loads of different objects even if they were nicely sat in a folder! I assume it would still work using a different object for each item, but I've not tried it!

  • we know that CategoryName is an instance variable of the array(inventory) but where did ArrayName come from?

    edit:o, i just now know it, we can add a thing called parameter in the function.

  • i hope the no. of events is not greater than 50 cause i havent bought construct yet. maybe i can cut down some events for strings.

  • Load more comments (2 replies)