A lot of my talk about Witch's Brew so far has been fairly high level stuff, the "why" more than the "how", with a few little references to code stuff.
This time I want to take a slightly deeper look at how I am coding something (without posting walls of code) and I think the best place to start is a feature which I am working on right now - player inventory!
Don't worry if you are not so interested in the coding side of things. I will warn you when you should skip to the end to avoid the technical stuff. But for now, a small introduction to what inventory means to this game and how it affects gameplay....
The basis of player inventory for Witch's Brew is that the player will have a limited number of ingredients they can carry at any time. You must return to near the sister witch who is stirring the cauldron in the bottom corner to drop off what you've collected before you can pick up more. For now there is a barrel next to her as a drop-off point, but I would like to find something better.
Your carrying limit is 4 ingredients, but it may change depending on eventual gameplay balance. Also when I get around to adding a full story mode I've considered increasing the limit past 4, either incrementally and permanently at specific points of the story, or through a rare power-up like a strength potion. That decision hasn't been fully thought out yet.
Also, instead of scoring each ingredient as you pick it up now you will only score when you deliver what you are carrying.
Ok, I'm about to get into the heavier stuff so if you aren't interested in coding talk go ahead and skip to the last few paragraphs.
/* Begin code talk */
- Create an array for the inventory
- Set a number of items equal to the inventory limit to a default value to indicate the slot is empty
- Whenever the player touches a collectable object check to see if it is something that can go to inventory - if so, iterate through the inventory and find the first slot with the default value
- If there is no slot with the default value return something so the calling code knows the ingredient can't be picked up
- Otherwise set the value of the first "empty" slot to the ingredient and return something so the calling code knows the ingredient was able to be picked up
- When clearing the inventory just set every slot back to the default value and do any other logic needed
That is the bare basics of the idea but of course it all depends on code, and it doesn't take into account anything to do with actually showing the inventory on screen.
A quick overview of my code layout for the pertinent bits:
- I am using classes for everything to separate concerns
- I have a
Playerclass to encapsulate my player logic
- I have a
Collectableclass for all types of collectable items, which is then extended by an
- I have a
UIclass that manages the screen overlay, but each component (score, health, inventory, and pause button) are their own separate class - so we only care about the
- Technically I could put all the inventory logic into the
Playerclass and just use a normal array of objects to track it, but I have chosen to make an
InventorySlotclass as well to separate out that logic
InventorySlot class has 4 class methods:
empty which are used by logic in the
Digging a little deeper into each of these:
isEmpty()- Simply enough, this just returns if the slot has the default value set
getIngredient()- Not used quite yet because I don't have any recipes to interact with, but this just returns the
Collectableobject currently set in the slot
setIngredient(collectable)- This sets the slot to the passed in
Collectableobject and emits an event for the UI to update this slot's graphic
empty()- Set the slot's value to
nulland emit an event for the UI to update this slot
Then in the constructor for the
Player class I loop through the required number of inventory slots and create an
InventorySlot for each.
Also in the
Player class I have class methods
deliverIngredients which do the following:
trueif at least one slot is empty
canPickUp(collectable)- If the passed
Collectableis an ingredient and there is an empty slot, or if it is a power-up, return
pickUp(collectable)- If the passed
Collectableis an ingredient call
addToInventory, or if it is a power-up call a method on the
Collectableclass to impart its effect(s) on the player (not yet finished)
getFirstEmptySlot- Iterate through the slots and return the first one that is empty
setIngredienton the slot returned by
getFirstEmptySlot, passing in the ingredient
deliverIngredients- Calculate score for the items being delivered and emit an event to update the score, and empty every slot
Then putting it all together, in my collision handler for the player and collectables I simply check if the player can pick up the collectable using
canPickUp. If that is true I call
pickUp. Everything else is handled by the class methods on the player and the inventory slot, plus a few related bits of code on the collectable!
Then on to the surprisingly easy bit - displaying the inventory state in the UI!
My Inventory class is very simple. A bit of logic in the constructor to create 4
Phaser.GameObject.Images at the correct positions and hide them, a class method to draw the outer box (this could honestly be moved into the constructor since this is such a simple shape and doesn't need redrawing during gameplay), then class methods for
removeItem which are linked to events by the
addItem receives the slot number and collectable object through the event, so it just sets the new texture & frame it needs from the collectable, and sets the image in the slot to visible.
removeItem receives the slot number through the event, and simply sets the image in that slot to be not visible.
/* End code talk */
So there we go, now you know the basics of why and maybe of how I added inventory to the game. It is not very pretty (yet), but it works.
The only thing really left to do is add in the obligatory link to the updated game. But before I do, you might notice if you've played previous versions that this one has only pumpkin ingredients while the other ingredients like candles and eyeballs are missing.
That happened when I moved the ingredients to their own Collectable class, and I haven't figured out yet how I want ingredient types to become available within the game, so I haven't bothered adding more types back in yet. They will come back soon enough.
And finally the link to Witch's Brew v0.3.0!