Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Question referring to classes

Status
Not open for further replies.

shadowsilver

Programmer
Nov 26, 2002
10
US
I have taught myself C++ and have quite a bit of experience, but I am just now getting to understand classes. I am writing a simple two-player turn-based game
and have decided to use classes to make it easier. I have already made part of it, but I have a question about using member functions.

I plan on having it like this:

struct Player {
int Def, Att, Hp;
void UseSpec();
};
Player one,two;

One player, depending on what type they were would have a special attack they could use, and it would be defined like this:

void Player::FactionOneSpec()
{
Hp+=50;
}

So that I could call the FactionOneSpec for either player instead of having to write two different versions for each player, eg. if I did, to add 50 to one.Hp or two.Hp, depending on which player used the special.

But my question is how I could have it take away from the enemy's health AND add to your own health in the same function.
Like:

void Player::FactionOneSpec()
{
Hp += 50;
enemyHp -= 50;
}

How would I do that? I know the Hp would apply to the Player instance that called it, but how could I make the enemy's Hp be used too, and still be able to call with either Player? Or should I just put both player's info in one class?

Any suggestions would be extremely helpful. Please!
And by the way, I would search for this, I don't know what I should search for!
 
To access the enemy, you'd either have to pass in the enemy Player as a parameter to the function or have the function start out by somehow acquiring a target (possibly have each player contain pointers to potential targets; that seems like an easy, feasible way). Don't put both players' info in one class unless you have some compelling logical reason to do so (e.g. the players share the same body, so they share the same hit points).

The problem I see you having with this, however, is that you can only define the one UseSpec() function for the Player class. To really do what you want to do, you'd have to use inheritance and virtual functions; so you'd have a FactionOne class and a FactionTwo class derived from Player, each overriding the UseSpec() function from the base Player class.
 
Thanks, man. I don't really understand some of the parts of inheritance and virtual functions, but that's something I'll have to learn.
 
Here's a quick explanation of inheritance/virtual functions as they apply to your situation:


First, you'd define a class, Player, to serve as the base of your class heirarchy.

[tt]class Player
{};
[/tt]

Next, you'd derive several classes from Player. These would be the different types of characters.

[tt]class FactionOne : public Player
{};

class FactionTwo : public Player
{};

// etc.
[/tt]

These classes are said to inherit from Player. This means they both have all the public (and protected) functions in Player.

More importantly (in your case), however, a Player* can point to objects of type FactionOne and FactionTwo. So you could have an array of Player* where some pointers in the array point to FactionOne objects and others point to FactionTwo objects (and FactionThree, FactionFour, etc.)


How is that useful? That's where virtual functions come in. First, define a virtual function in Player.

[tt]class Player
{
public:
virtual void special() = 0;
};
[/tt]

We'll look at what virtual means later. The "= 0" part essentially means that you have no good definition to give the special() function for Player. Each of your Factions has a defined special ability, but Player, as your base class, does not (at least in this example). This also means Player is an abstract class; you can't make objects of type Player, although you can make pointers to Player.

Next, override that function in each of your derived classes.

[tt]class FactionOne : public Player
{
public:
virtual void special()
{
hp += 50;
}
};

class FactionTwo : public Player
{
public:
virtual void special()
{
Player* targ = acquireTarget();
targ->hp -= 50;
}
};
[/tt]

Now, you could do this:

[tt]Player* array[ 4 ];

array[ 0 ] = new FactionOne;
array[ 1 ] = new FactionTwo;
array[ 2 ] = new FactionOne;
array[ 3 ] = new FactionTwo;

for ( int i = 0; i < 4; ++i )
{
array[ i ]->special();
}
[/tt]

This would loop through the array of Player* and call the special() function through each pointer. For array[ 0 ] and array[ 2 ], it would call FactionOne's special(); for the others, it would call FactionTwo's special(). This is because special() is a virtual function. When a virtual function is called through a pointer, the program can figure out at run-time what class's function it should invoke (FactionOne's, FactionTwo's...)


So there's a page-long overview of a topic that takes up 3 chapters in textbooks. That should give you some idea of what's involved. It's pretty easy, but you'll probably want to pick up a textbook and read the relevant chapters to get a better understanding of what's going on. Let me know if I was unclear on anything.
 
I appreciate all the help, chipperMDW, it helps a lot. I have learned about inheritance, but did not really understand how it could be used in practical situations. But this helps a lot. Oh, and that helps me alot about the virtual functions!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top