Connecting two independent classes

Started by
14 comments, last by SolarChronus 10 years, 8 months ago

So I feel as though this could be either in the Game Programming forum or General Programming forum, but posted here out of safety, please move it if need be!

One of my on-going problems when writing code for games has been trying to neatly connect two independent systems. Such as that of a player attempting to purchase items from a store. I have a neatly written up player inventory, a store inventory, and a class that kind of acts of intermediary between the two.

Classes involved

Player Inventory

The player inventory is pretty self explanatory, has a few methods to adding/remove objects from a list of items, and a few other things to keep track of capacity and such.

Store Inventory

Same as with the player inventory, minus the need to track capacity

Store Browser

Takes a player inventory and store inventory and has functions for purchasing an item from the store which then does the swap of currency and item(s) between the store and player.

The player will be able to press a UI button that will create an instance of the ShopBrowser and open a window to display a small list of items w/prices. This is the point where I am stuck, how would I go about grabbing an instance of the players inventory and shops inventory for the ShopBrowser without resorting to some type of static/global call? I feel like I'm missing a design pattern or there is an obvious solution and I'm too close to the code to see it, cannot see the forest for the trees so to speak.

If there is any code that needs to be posted, please let me know!

Advertisement

You need to pass references to the PlayerInventory and StoreInventory objects to the StoreBrowser (or the underlying object which handles just the lists of items to display), usually via the constructor.

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

Thanks for your response, but I believe you mis-read the problem. I'm talking about getting the instance of the player and store when I do the StoreBrowser construction, not passing the instances in when I call new StoreBrowser(...).

How does the UI know about the store? The UI needs to activate the button, and display information about the player, so presumably it knows about the player, and the player knows they are at a store? Or does the UI just receive messages about what to display posted by the player? (In which case you should probably have the message which tells the UI the player is at the store contain the references).

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley
The ui would be the logical brdge between the two since it should already know of all the components.

So it would be considered, good oop practice to give the UI an instance of the player and shops during the initialization of the game?

I.e

Initialize Player

Initialize Shop(s)

...more initialization

Initialize UI with an instance of pretty much every class that will interact with the UI?

No, have objects trigger events which send messages to the UI. The messages can contain information that is cached with the UI element and is valid until some other event cancels it. (So, enter shop->send message to UI player enters shop, leave shop->cancel the activation of the ShopBrowser UI element).

The UI should probably know about the player though, although that isn't strictly necessary either.

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

Didn't see your first reply before Apoxol Paradign, so let me answer that before responding to your 3rd post.

When the player enters an area with a shop, a UI button on the screen will be enabled allowing them to click it. When clicked (part I'm trying to solve) the StoreBrowse is created with an instance of the player inventory and store inventory passed into its constructor.

This originally lead me to believe the UI needs to know about the player and any and all stores - basically store a reference to these objects. However, I feel as though that's not what I should be doing, as the game may have anywhere between 5 and 20 different shops depending on the level size and difficulty set, and having the UI know about all of the shops (and anything else) seems wrong.

Now I understand about sending events but where I'm a bit lost is how would I end up sending a message containing the player inventory and store inventory. I feel like your 3rd post contains the answer but I'm not sure I understand it - I've been in a fog this past week and its been wrecking my ability to think clearly!

Have an EnableShopUIMessage which has a reference to the player (or just the inventory) and the shop (or just the contents), both of which you know at the point you enter the shop. You can derive the message from a common base, or you can just build a message packet and cast it when you decode the message (like in raw Win32 messages), or you can use text or a script (with e.g. lists of player items and shop items) instead if you want.

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

As with many of my answers, I might turn this whole thing around and consider it from different angles. Much like what Paradigm is saying, it seems that whatever event takes place that says "hey, player is near shop" is a logical starting point. Now, on the other hand, I might not use explicit references to the shop and the inventory but instead when creating the UI button I bind an appropriate callback which contains the information. Using C++11, I might do it this way:

// Assumptions, at the point the "Enter Shop" button is activated:
// this code knows the player and shop instances....
// A ui system that can bind generic callbacks.  In C++ a lambda is used.
// Modify for language/ui/etc as required of course.
MakeEnterShopActive( UISystem& ui, Player& player, Shop& shop )
{
  UI::Button* enterShop = ui.CreateButton( "Enter Shop", ... x,y location, graphics etc ... );
  enterShop->OnClick( [=](){ CreateShopBrowser( player, shop ); } );
  ui->AddButton( enterShop );
}

The advantage should be obvious, the item which knows the source instances involved in the interaction supplies the functionality to a UI system which remains completely oblivious to any of the game classes. No special derivations, new structures to define and fill in etc, just a function to be called eventually. This is a common pattern for Lua, C# and other languages with delegates and functions as variables though not as familiar to C/C++ types. Of course with C languages it would just be a function pointer and a void* pair passed in as the callback to achieve the same thing which of course applies to many other languages also.

Hope this makes sense, it is a bit backwards but I believe solves all your goals.

This topic is closed to new replies.

Advertisement