Looking for some "best practices" advice

Started by
15 comments, last by Delphawi 12 years, 7 months ago

So I gave each weapon its own struct with its own stats already initialized when the code was compiled. I wasn't satisfied with that either.
[/quote]

Why weren't you satisfied with this? All weapons are going to share a set of stats, so make a Weapon object (class or struct, whatever is appropriate for the language). If a particular weapon type never changes its state (stats) during the game, then you will not need a separate instance for each weapon - just keep a master list of weapon types and their stats, and index into it as needed. If weapons can change state during the game (their stats can change, such as current ammo, upgrades, wear and tear), then each weapon will have its own instance. In this case, the master list of weapon types is like a collection of blueprints, and is used to initialize a weapon instance.[/quote]

I was unable to figure out how to use structs in a way that would allow for multiple versions of them. For example, I did not know how to work it to where a player could have multiples of a particular weapon in their inventory that was stored in an array. I initially had the struct system working beautifully so long as the player (and enemies) were locked into having only one weapon. But when the idea of having the potential for multiple instances of a particular weapon came up, that is when I started stumbling.

Here is a bit of code for how I set up the weapon struct:

struct Weapon
{
string mName;
Range mRange;
}


The range links to a Range.h file that has "mLow" and "mHigh" variables that determine the weapon's damage. Like I said, this code worked fine when you selected your class and were given the default weapon and the values for that weapon were set. But like I said, I was unsure how to implement this when I needed multiple instances of them in a player's inventory. This could easily be a case of me not being able to see the forest because of the trees and I am missing an obvious solution right in front of me. And perhaps I am trying to be too much of a slave to OOP (as suggested by one poster). This is great stuff and I appreciate all the replies! :)

Ulfhedhin

Advertisement

Here is a bit of code for how I set up the weapon struct:

struct Weapon
{
string mName;
Range mRange;
}


The range links to a Range.h file that has "mLow" and "mHigh" variables that determine the weapon's damage. Like I said, this code worked fine when you selected your class and were given the default weapon and the values for that weapon were set. But like I said, I was unsure how to implement this when I needed multiple instances of them in a player's inventory. This could easily be a case of me not being able to see the forest because of the trees and I am missing an obvious solution right in front of me. And perhaps I am trying to be too much of a slave to OOP (as suggested by one poster). This is great stuff and I appreciate all the replies!

No, I would say that's excellent OO design. Your Range class, for example, should have some functions that operate on it (constructor, copy operators, min(), max(), what have you). that's good encapsulation. Your weapon: it's good encapsulation.

It seem what you might need to do is to realize the difference between classes (or structs) and objects (instances of structs).

For example, if you want a player to have zero or more weapons, the player should have a [font="Courier New"]std::vector<Weapon>[/font]. You can even initialize it at compile time if you have an up-to-date compiler that implements the current C++ standard (most of them on consumer dev platforms do). If you want to get fancy (and I recommend you do this later, but not too much later) you could use a [font="Courier New"]std::vector<std::shared_ptr<Weapon>>[/font].

Stephen M. Webb
Professional Free Software Developer

I think I see where you're going with this. But what I don't understand is how it is implemented into that vector array. Let's say that a player has 3 weapons in his inventory (not counting the one he's using). How would that be expressed from within an array? I did have a point where I wondered if this could work but since I didn't know how to (or even if it could be) implemented, I had to skip over it. Would it be a case of something like this (I just thought of it LOL)?

Weapon weapon; // create weapon object
vector<weapon> inventoryWeapons; // create vector array for inventory that holds weapons

inventoryWeapons[0] = // not sure what goes here...how can this hold the weapon name and the range?


Would this array hold separate structs somehow? If I understand it right, an array can hold objects but I'm not sure about structs. For example, in the code I have using the struct, a weapon is initialized this way:

weapon.mName = "Sword";
weapon.mRange.mLow = 4;
weapon.MRange.mHigh = 8;


Like I said, I'm not sure how this would go into an array. Especially if there are a handful of other weapons such as daggers and axes. Do each of these different weapons need to be initialized within their own struct or can their values be set up elsewhere? I tried this way as well but again, I didn't know how to use them in arrays. That really seems to be my hangup right there.

Ulfhedhin

Let's just say you had a Range class (or struct) that looked something like this.

struct Range
{
Range(int low, in high) : mLow(low), mHigh(high) {}
int mLow;
int mHigh;
};

Let's also suppose your Weapon struct looked like this.

struct Weapon
{
Weapon(const std::string& name, int min, int max) : mName(name), mRange(min, max) { }
std::string mName;
Range mRange;
};

Finally, I'll assume you have a Player class that looks like this, eliding stuff like cup size and drinking prowess. I don't know what kind of RPG you like, I'll keep mine a secret too.

struct Player
{
std::string mName;
std::vector<Weapon> mWeapons;
};

Somewhere in you code, you're going to do something like this.

Player player;

// Create some weapons
Weapon intruder("dagger", 1, 4);
Weapon venusButterfly("butterfly", 1, 8);

// Equip the player.
player.mWeapons.push_back(intruder);
player.mWeapons.push_back(venusButterfly);

The code marked Create some weapons creates two weapon objects -- instances of the Weapon struct. The Equip the player lines then add copies of those objects to the players [font="Courier New"]mWeapons[/font] member variable. Viola, your player will have his hands busy.

Note that it's copies of the original objects that are added to the vector, and that the vector's [font="Courier New"]push_back[/font] member function is used to insert the weapons, not its overloaded [font="Courier New"]operator[][/font] (like an array).

I think the key is that the [font="Courier New"]intruder[/font] is an object of type Weapon. Weapon is a struct (or class, same diff).

You might want to start by read up on an introduction to the standard library, starting with [font="Courier New"]std::vector[/font]. It's an excellent way to learn about OO design and encapsulation. It's also a very useful tool.

Once your player has his weapon in hand, er, so to speak, you will want to learn how to iterate over the vector (hint: [font="Courier New"]begin()[/font] and [font="Courier New"]end()[/font]).

Stephen M. Webb
Professional Free Software Developer

Bregma's example is pretty much what I had in mind.

I don't want to add more to it at this point other than the fact that its necessary to get used to C++ vectors

There is a decent introduction here to get you started
Effective C++ by Scott Meyers has good advice about language-specific coding details.

Like I said, I'm not sure how this would go into an array. Especially if there are a handful of other weapons such as daggers and axes. Do each of these different weapons need to be initialized within their own struct or can their values be set up elsewhere? I tried this way as well but again, I didn't know how to use them in arrays. That really seems to be my hangup right there.

You can make the inventory as a class , and give it some stats (Item count , Weight , and an Array of numbers)
You can use this array of numbers to store the weapons ? Yes , if every weapon has its number (pistol 0 , smg 1 , rpg 5 , ...) you can fill the array with the appropriate numbers of the weapons currently with the player .
So when the player presses 1 to use his SMG , you can just check the array .

This topic is closed to new replies.

Advertisement