Object oriented programming adventure game

I'm trying to build an adventure game using object oriented programming and have hit a wall;
I have gotten classes to declare attacks and their values, but I can't figure out what I'm missing in order to have the classes take the damage away from their health points. Any assistance would be greatly appreciated.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
//This is declaring class warrior and its base class player.

class Player{
	protected:
		int AttackPower;
	public:
		void setAttackPower(int b){
			AttackPower = b;
		}
		virtual void PlayerHealth(){	
		}
		virtual void TakeDamage(){
		}
};
class Warrior:public Player{
	public:
	void PlayerHealth(int b){
	b = 50;
	}
	void Attack(){
		cout << "Warrior charge! - " << AttackPower << endl;
	}
	void TakeDamage(int c){
		c ==  random2;
		cout << "Warrior has taken " << random2 << "damage!" << endl;
	}
};

//This is declaring the ninja class and its base class enemy.
class Enemy{
	protected:
		int AttackPower;

	public:
		virtual void EnemyHealth(){}
			
		void setAttackPower(int a){
			AttackPower = a;
		}
		virtual void TakeDamage(){}
};
class Ninja:public Enemy{
	public:
	void Attack(){
		cout << "Ninja! - " << AttackPower << endl;
	}
	void EnemyHealth(int a){
	a = 40;
	}
	void TakeDamage(int c){
		c = random1;
		cout << "Ninja has taken " << random1 << "damage!" << endl;
	}
	
};

I have declared random1 and 2 in the int main(). The program outputs damage amounts if I remove all code pertaining to TakeDamage.
Get rid of the two equal signs in line 24. Two equal signs check if both the left and right sides of the operator are equal. Putting it in a statement as follows, it would be like writing the code:

 
true;


Change the 2 equal signs to 1, and it will set the variable to the random num
closed account (Sw07fSEw)
Here's my advice, I think you may have a little too much polymorphism going on.

First, let's start with the Player's health. Where is it? I see you have a function PlayerHealth(), but all that does is set a temporary local variable which is then immediately lost. If you're trying to implement a game with attacking, you'll almost certainly want a member health. It's up to you what type you want health to be, but I'd keep it simple and use an int.

Now where would you put a member health?

Well, since every player is going to have a health, I would implement the health member within your base class Player. That way every class, like Warrior, that inherits from Player, will have a member health. Furthermore, you'd probably want the player's health to be public since other enemies can attack and lower a player's health.

1
2
3
4
5
6
7
8
9
10
class Player{
	protected:
		int AttackPower;
		
	public	
		int health; //I think health should be public because other enemies can attack and diminish a players health.
	
		void setAttackPower(int b){ AttackPower = b; }
		virtual void Attack() = 0; // Pure virtual
};


Next, I would implement constructors for the child classes. If you want all Warriors to have the same attack power, then you can define it within the constructor.

1
2
3
4
5
6
7
8
9
10
11
12
13
class Warrior:public Player{
	public:
	Warrior(){ AttackPower = 80; health = 120; } //initialize the inherited members from Player
	    
	void Attack(Enemy &enemy){ //Attack takes a reference to an Enemy because a player will attack different types of enemies
		cout << "Warrior charge! - " << AttackPower << endl;
		
		enemy.health -= AttackPower; // equivalent to takeDamage();
		if(enemy.health <= 0){
			//player killed the enemy, you could delete or destory the enemy depending how you implement it
		}
	}
};


I also made changes to your Attack function. It's defined as pure virtual because every child class Warrior, Musketeer, etc. will presumably have different attack modes and strengths. Therefore, each of their Attack methods may be slightly different from one another. For example, maybe the Musketeer can deal varying damage depending if he shoots the enemy in the chest or head, whereas the Warrior might have the same attack type dealing the same damage every time.

By implementing health as public, players and enemies can attack each other and remove each other's health. I got rid of the takeDamage() function all together because an Enemy attacking a Player is the same thing as the Player taking damage and visa versa.

Here's the full implementation:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <iostream>
#include <string>
using namespace std;

class Enemy;
class Player{
	protected:
		int AttackPower;
		
	public:	
		int health; 
	
		void setAttackPower(int b){ AttackPower = b; }
		virtual void Attack(Enemy &enemy) = 0;
};

class Enemy{
	protected:
		int AttackPower;

	public:
		int health;
		
		void setAttackPower(int a){ AttackPower = a; }
		virtual	void Attack(Player &player) = 0;
};

class Warrior:public Player{
	public:
	Warrior(){ AttackPower = 80; health = 120; }
	    
	void Attack(Enemy &enemy){ 
		cout << "Warrior charge! - " << AttackPower << endl;
		
		enemy.health -= AttackPower; // equivalent to takeDamage();
		if(enemy.health <= 0){
			//player killed the enemy, you could delete or destory the enemy
		}
	}
};
class Musketeer:public Player{
	public:
	Musketeer(){ AttackPower = 150; health = 200; } 
	
	void Attack(Enemy &enemy){
		cout << "Musketeer shoot! - " << AttackPower << endl;
	}
};
class Ninja:public Enemy{
	public:
	Ninja(){ AttackPower = 60; health = 90; }
	
	void Attack(Player &player){
		cout << "Ninja! - " << AttackPower << endl;
		
		player.health -= AttackPower; 
	}
};

int main(){
	Warrior warrior1;
	Ninja ninja1;
	
	cout << "The enemy has health: " << ninja1.health << endl;
	
	warrior1.Attack(ninja1);
	
	cout << "The enemy now has health: " << ninja1.health << endl;
	
	return 0;
}

Thank you for your suggestions, in all honesty, I've just begun trying to implement oop hence why I went overboard.
The code words great, thank you so much, kind stranger.

As a secondary note, I can't seem to be able to declare a random integer to define AttackPower, as they need to be defined in the main and if I use 1+ rand()%50 as AttackPower, it returns 'rand' was not defined in this scope, even with <cstdlib> as a header.
Last edited on
edpgolfer wrote:
By implementing health as public, players and enemies can attack each other and remove each other's health. I got rid of the takeDamage() function all together because an Enemy attacking a Player is the same thing as the Player taking damage and visa versa.

IMO, implementing health as public is a poor idea. It breaks encapsulation. Consider if the OP wants to report the player's new health when it changes, or the fact that the player has died. The logical place to do that is within takeDamage(). By eliminating takeDamage(), you have to go through the program and find every place that changes a player's health and make the changes there. Not a good idea.
if I use 1+ rand()%50 as AttackPower, it returns 'rand' was not defined in this scope, even with <cstdlib> as a header.

Do you have using namespace std;, if not you need to qualify rand() as std::rand().
rand() is in the std namespace.
Topic archived. No new replies allowed.