Thursday, June 13, 2013

Dev Blog #5

Thursday June 13, 2013

Sorry for this blog being late. I totally forgot last night to write one. This week I will have a code snippet to show you guys in illustrate one of the issues with OOP that can be somewhat frustrating to fix if you don't know where to look.

The problem stemmed from a bug Matt and I were having with items. You could use items just fine and buy items, but that is where the problem reared its nasty head. When you would go to buy potions from the merchant, the game would show you buying 1 potion and then get stuck at 2 potions left in the shop. If you left the shop interface and opened your inventory, there were 2 potions there, even though the game only showed you buying 1. If you used 1 potion or both, the amount in the shop would go down to 1. It frustrated me for days. Finally, I had a breakthrough two days ago.

I saw that we weren't giving the player a brand new version of the item he was trying to buy. We were essentially copying the exact item the merchant had, which is not a good idea in languages like Java. Java passes everything by reference by default, so if you gave the player an item directly from the merchant, those two items were tied together in memory. So, my idea was to set a bunch of variables to hold the data from the item you were trying to buy and then pass those to the constructor for the Pickups class. Then, that Pickups constructor was used as a parameter for the giveItem() function that is part of the InventoryManager class. I will show you in the code snippet below:

This is only a partial code snippet, but it illustrates my point:

if(tempNPC.getItems().get(ShopInventory.getMerchantSlot()).getStackable())
{
int i = tempNPC.getItems().get(ShopInventory.getMerchantSlot()).getItemID();
int d = tempNPC.getItems().get(ShopInventory.getMerchantSlot()).getDefence();
int a = tempNPC.getItems().get(ShopInventory.getMerchantSlot()).getAttack();
int h = tempNPC.getItems().get(ShopInventory.getMerchantSlot()).getHealth();
double s = tempNPC.getItems().get(ShopInventory.getMerchantSlot()).getSpeed();
String n = tempNPC.getItems().get(ShopInventory.getMerchantSlot()).getItemName();
boolean b = tempNPC.getItems().get(ShopInventory.getMerchantSlot()).getStackable();
int m = tempNPC.getItems().get(ShopInventory.getMerchantSlot()).getMaxStack();
String type = tempNPC.getItems().get(ShopInventory.getMerchantSlot()).getItemType();
EntityManager.getInstance().getDaniel().getInvManager().giveItem(new Pickups(i,d,a,h,s,n,b,m,1, type));
}

Blogger isn't the best on HTML tags, so I just pasted in the code. If it is difficult to read, I apologize. The initial if-statement checks to see if the item you are trying to buy is stackable. Why, you ask? Because stackable and non-stackable items are handled differently by the engine. Above this initial if-statement there is another one that check to see if the item you are trying to buy is already in your inventory. If it is, there is a different part of the code that just adds 1 whenever you buy that item. If it isn't in your inventory, the engine creates a brand new object (you can see this happening in the last line of the code) and places it into an arraylist.

Moral of the story: Be careful about how you pass object around. It could have some nasty consequences that will leave you with a ton of headaches over such a simple coding error.

No comments:

Post a Comment