question about classes

Hello. 

I made a mockup game with just classes and no actual real code yet to just see
if this would be the way to setup a game using classes. If it is not, can 
someone specify what I could/should change about it....or add to it. Just really 
concerned about how the class is setup. Thanks for any comments. 



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
#include <iostream>
#include <vector>
using std::cin;
using std::cout;
using std::endl;
using std::string;

/** comments

- make a mockup program that has 4 enemies and use classes to make them

**/

class baddies
{
    public:
            void displayRulesIntro();//the introduction
            void startUpData();//outputs to the screen n amount of bullets health each enemy starts off with
            void gameUpdate();//outputs to the screen ALL enemies health, bullets, and damage taken after each round
            void death();//outputs to the screen if someone died
            int numOfBulletsShot(int x);//bullets shot
            int numOfBullersLeft(int x);//remaining bullets
            int healthLeft(int x);//health left
            int damage (int x);//damage taken
            int atomicBomb(int x);//remaining a-bomb

    private:
            int bullets;
            int lives;
            int health;
            int aBomb;
};

baddies enemy1;
baddies enemy2;
baddies enemy3;
baddies enemy4;
baddies dialogue;

int main()
{
    dialogue.displayRulesIntro();


    return 0;
}
//end main

//start functions

void baddies::displayRulesIntro()
{
        cout<<"-- MOCKUP SHOOTING GAME --"<<endl<<endl
            <<"* Each enemy starts off with 100 health and 1000 bullets\n"
            <<"* If a enemy runs out of bullets, they have one chance to kill everyone w/the a-bomb\n"
            <<"* A_BOMB: kills everyone instantly....including the person who deployed the bomb\n"
            <<"* if the enenmy has no bullets or a-baombs left, they will run away\n"
            <<"* if two people are left and both have no bullets, they have to play the number game\n"
            <<"* NUMBER GAME: whichever enemy guesses the higher number wins\n"
            <<"* Last person standing wins"<<endl<<endl;
}
Looks fine to me for a start. Once it gets bigger u'll probably want separate classes for each of PLAYER, ENEMY, GAMEUPDATES, GRAPHICS, WEAPONS...

Maybe I'll point out some naming conventions. Functions usually start with a Capitol letter to distinguish them from variables. At first glance it can be hard to tell if 'damage' is a variable or a function (why not call it DamageTaken ? so u don't need the commented part).

Classes are also at least the first letter capitol but often all upper case 'BADDIES'

member variables are often prefixed with 'm_' like int m_aBomb

All of this is to make things clearer and easier for u in the future once this becomes a bigger program. suerte !

Last edited on
closed account (o3hC5Di1)
Hi there,

Your class baddies is implementing a bunch of member functions that have nothing to do with the enemy character itself.

Think of classes as blueprints for houses. The blueprint itself is not a house, you need to create a house according to that blueprint for it to become reality. The same goes for classes and objects, objects are the houses that are built according to the blueprint in the class.

So if you want to make a blueprint for a house, you wouldn't put in there how your car should start, right?
You would only put things in there that describe the house and the functions that the house needs to fulfil.

Same in your program.
Try to redesign the baddies class so that it only contains member data and functions related to an enemy character.

displayRulesIntro() Is a good example - it isn't a characteristic of a baddie, so it shouldn't belong in there.

Hope that makes sense and gets you on your way, please do ask if you have any further questions.

All the best,
NwN
Thanks. That really helped a lot. Can any changes still be made to the code?....and one more question. Does it matter if a programmer 
were to declare their objects in the main function or declare them globally? In the function below, I have objects declared globally. 


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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
#include <iostream>
#include <vector>
#include <iomanip>
using std::cin;
using std::cout;
using std::endl;
using std::string;

/** comments

- make a mockup program that has 4 enemies and use classes to make them

**/

class BADDIES
{
    public:
            void BaddyInfo();//outputs to the screen n amount of bullets, health each enemy starts off with, and a-bomb
            int NumOfBulletsShot(int x);//bullets shot
            int NumOfBullersLeft(int x);//remaining bullets
            int HealthLeft(int x);//health left
            int Damage (int x);//damage taken
            int AtomicBomb(int x);//remaining a-bomb

    private:
            int m_bullets;
            int m_health;
            int m_aBomb;
};

class INITIAL_UPDATE_INFO
{
    public:
            void DisplayRulesIntro();//the introduction
            void GameUpdate();//outputs to the screen ALL enemies health, bullets, and damage taken after each round
            void Death();//outputs to the screen if someone died
};

//objects for both classes
BADDIES enemy1;
BADDIES enemy2;
BADDIES enemy3;
BADDIES enemy4;
INITIAL_UPDATE_INFO dialogue;

int main()
{
    dialogue.DisplayRulesIntro();
    cout<<endl;

        cout<<"Enemy 1"<<endl;
        enemy1.BaddyInfo();
        cout<<endl<<endl;
        cout<<"Enemy 2"<<endl;
        enemy2.BaddyInfo();
        cout<<endl<<endl;
        cout<<"Enemy 3"<<endl;
        enemy3.BaddyInfo();
        cout<<endl<<endl;
        cout<<"Enemy 4"<<endl;
        enemy4.BaddyInfo();
        cout<<endl<<endl;

    return 0;
}
//end main

//start functions

void INITIAL_UPDATE_INFO::DisplayRulesIntro()
{
        cout<<"-- MOCKUP SHOOTING GAME --"<<endl<<endl
            <<"* Each enemy starts off with 100 health and 1000 bullets\n"
            <<"* If a enemy runs out of bullets, they have one chance to kill everyone w/the a-bomb\n"
            <<"* A_BOMB: kills everyone instantly....including the person who deployed the bomb\n"
            <<"* if the enenmy has no bullets or a-baombs left, they will run away\n"
            <<"* if two people are left and both have no bullets, they have to play the number game\n"
            <<"* NUMBER GAME: whichever enemy guesses the higher number wins\n"
            <<"* Last person standing wins"<<endl<<endl;
}

void BADDIES::BaddyInfo()
{
        cout<<"bullets: 1000"<<endl
            <<"health: 100"<<endl
            <<"a-bomb: 1";
}
Last edited on
closed account (o3hC5Di1)
Hi there,

It's usually recommended not to make any global variables.
The problem with those is that they are there for everyone to see and change.

One of the fundamentals of object oriented design is to hide data as much as you can from other functions to prevent them from changing it. That's the whole purpose of making class member data private, protected or public.

So yes, in this case they would be better in the main() function.

That new design you're using looks a lot better, well done!

All the best,
NwN
One good thing about classes is that much can be done automatically. The main thing is a constructor/destuctor. The class should be responsible for itself in many ways. Here are some things from your code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void INITIAL_UPDATE_INFO::DisplayRulesIntro()
{
        cout<<"-- MOCKUP SHOOTING GAME --"<<endl<<endl
            <<"* Each enemy starts off with 100 health and 1000 bullets\n"
        //...  
}

void BADDIES::BaddyInfo()
{
        cout<<"bullets: 1000"<<endl
            <<"health: 100"<<endl
            <<"a-bomb: 1";
}

// From inside your class
int NumOfBulletsShot(int x);//bullets shot
int NumOfBullersLeft(int x);//remaining bullets 


From this, I come up with three suggestions. First, set the values of health and bullets in the constructor. Second, create "get" functions so that your second function there actually prints the amount of health/bullets. Third, you may want to consider changing the way main interacts with your class in general. One basic idea with classes is that they should be as private as possible.

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
class Baddies
{
private:
  int health;
  int bullets;
public:

  //Constructor
  Baddies(void)
  {
    health = 100;
    bullets = 10; // I've made this a little smaller for my taste
  }

  //Accessors
  int getHealth(void) { return health; }
  int getBullets(void) {return bullets; }

  // Modifiers
  bool shoot(void)
  {
    if (bullets == 0)
      return false;
    buillets--;
    return true;
  }
  bool damage(void)
  {
    health -= 5;
    return health > 0;
  }
};


Maybe you would want different buillets to do different amounts of damage... one of the tough things about making a game.

Anyway, you could implement it like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int main(void)
{
  Baddies badGuy;
  
  cout << "I am a Baddy.  I have " << badGuy.getHealth() << " health and "
       << badGuy.getBullets() << " bullet(s)\n";
  cout << "I am going to shoot my bullets\n";
  while (badGuy.shoot())
    cout << badGuy.getBullets() << " left\n";

  cout << "It looks like I hit myself one of those times\n";
  if (badGuy.damage())
    cout << "Now I only have " << badGuy.getHealth() << " health left\n";
  else
    cout << "I killed myself\n";

  return 0;
}


It's probably better to do a bool isAlive() rather than have the damage return this info, but there you go.
Last edited on
@NwN Thanks So the program is revamped according to everyone's specifications and honestly it is better to use classes/constructors in these ways.

Also, I understand constructors but I feel like I might not know how to implement them well yet....or at least efficient enough to make a big game. For the last time, can someone check this code to see if the classes and constructors are solid.

Also I think there might be a better way to get and output values the way I did in the main function. It seems kind of lengthy.

This is the whole program


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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include <iostream>
#include <vector>
#include <iomanip>
using std::cin;
using std::cout;
using std::endl;
using std::string;

/** comments

- make a mockup program that has 4 enemies and use classes to make them
- this game will probably be the most fun if people were to bet on which 'enemy' would last
- start putting m_ in front of my member variables to distinguish them from regular variables
- when the constructor changes the variables, they will be what the constructor specified them to be when they are called via a function
- work with constructors more

**/

class BADDIES
{
    public:
            int NumOfBulletsShot(int x);//bullets shot
            int NumOfBullersLeft(int x);//remaining bullets
            int HealthLeft(int x);//health left
            int Damage (int x);//damage taken
            int AtomicBomb(int x);//remaining a-bomb
            int getBullets(int x);
            int getHealth(int x);
            int getABomb(int x);
            BADDIES();//constructor

    private:
            int m_bullets;
            int m_health;
            int m_aBomb;
};

class INITIAL_UPDATE_INFO
{
    public:
            void DisplayRulesIntro();//the introduction
            void GameUpdate();//outputs to the screen ALL enemies health, bullets, and damage taken after each round
            void Death();//outputs to the screen if someone died
};
//end classes



int main() /**MAIN FUNCTION**/
{
    int bullets, health, aBomb;

    //declaring objects
    INITIAL_UPDATE_INFO dialogue;
    BADDIES enemy1;
    BADDIES enemy2;
    BADDIES enemy3;
    BADDIES enemy4;

    dialogue.DisplayRulesIntro();
    cout<<endl;

        cout<<"Enemy 1:"<<endl<<enemy1.getBullets(bullets)<<" bullets"<<endl<<enemy1.getHealth(health)<<" health"<<endl<<enemy1.getABomb(aBomb)
            <<" A- Bomb"<<endl<<endl;
        cout<<"Enemy 2:"<<endl<<enemy1.getBullets(bullets)<<" bullets"<<endl<<enemy1.getHealth(health)<<" health"<<endl<<enemy1.getABomb(aBomb)
            <<" A- Bomb"<<endl<<endl;
        cout<<"Enemy 3:"<<endl<<enemy1.getBullets(bullets)<<" bullets"<<endl<<enemy1.getHealth(health)<<" health"<<endl<<enemy1.getABomb(aBomb)
            <<" A- Bomb"<<endl<<endl;
        cout<<"Enemy 4:"<<endl<<enemy1.getBullets(bullets)<<" bullets"<<endl<<enemy1.getHealth(health)<<" health"<<endl<<enemy1.getABomb(aBomb)
            <<" A- Bomb"<<endl<<endl;
    return 0;
}
//end main



//start functions

void INITIAL_UPDATE_INFO::DisplayRulesIntro()
{
        cout<<"-- MOCKUP SHOOTING GAME --"<<endl<<endl
            <<"* Each enemy starts off with 100 health and 1000 bullets\n"
            <<"* If a enemy runs out of bullets, they have one chance to kill everyone w/the a-bomb\n"
            <<"* A_BOMB: kills everyone instantly....including the person who deployed the bomb\n"
            <<"* if the enenmy has no bullets or a-baombs left, they will run away\n"
            <<"* if two people are left and both have no bullets, they have to play the number game\n"
            <<"* NUMBER GAME: whichever enemy guesses the higher number wins\n"
            <<"* Last person standing wins"<<endl<<endl;
}


BADDIES::BADDIES()//constructor to output default parameters/attributes for the enemies in the game
{
    m_bullets = 1000;
    m_health = 100;
    m_aBomb = 1;
}

int BADDIES::getBullets(int x)
{
    return m_bullets;
}

int BADDIES::getHealth(int x)
{
    return m_health;
}

int BADDIES::getABomb(int x)
{
    return m_aBomb;
}
Last edited on
You don't need to pass those variables to the get functions. "Get" and it's opposite "set" functions do make you need to write more code, but the purpose is to keep your variables secure (with these functions you can make your member variables private). It might not be vital for you. Think about a rectangle though. If a rectangle has a width, height, and area, you don't want to be able to change the width/height without updating area. setWidth might look like this:
1
2
3
4
5
void setWidth(double y)
{
  width = y;
  area = base * width;
}


Keeps "area" safe.

Along with the default constructor, which you are using fine, you can also have custom constructors:
1
2
3
4
5
6
BADDIES(int h, int b, int a)
{
  health = h;
  buillets = b;
  aBomb = a;
}


Which is used:
1
2
BADDIES anotherBaddie(100, 1000, 5);
BADDIES oneMoreBaddie(1000, 10, 10);


So now you can have varying toughness of baddies.
Last edited on
@ LowestOne

I meant to ask you about this in my last post. What would make "bullets doing different amounts of damage hard" in a game? I feel like a total noob for what I am about to say because my solution is so simple anyone can do it.......couldn't the programmer just increase/decrease the value for different bullets?....or is it not that easy?
Last edited on
Here's food for thought.

Instead of starting with a Team of Baddies start with a single Baddy. Create a class that encapsulates a single Baddy and everything about him, including his name, health, abilities, ammo, and attacks.

Then redesign your Baddies class to contain and vector of Baddies that can load either a single Baddy one at a time or an array of Baddies all at once using overloaded constructors.

With this Baddies class you can focus on Team methods such as print team or find dead players, print score, etc.

Then you could try to create a Board class using a 2D array if you want it be a real board game.

@IceThatJaw I'd definitely learn a lot from that.....will definitely try to pull that off to see if I can do it. Thanks
closed account (o3hC5Di1)
Hi there,

Seems like you're getting on pretty well here, good on you.

dtaqee88 wrote:
Also, I understand constructors but I feel like I might not know how to implement them well yet....or at least efficient enough to make a big game. For the last time, can someone check this code to see if the classes and constructors are solid.

Also I think there might be a better way to get and output values the way I did in the main function. It seems kind of lengthy.


Construcotrs are usually used to set initial data for the object. For instance, when creating a new baddie, setting his health to 100 is something you woul do upon creating the object, so it makes sense to put it in the constructor.

Outputting those values could be replaced by a member function in the baddie class:

1
2
3
4
5
6
7
8
9
void BADDIE::print_status()
{
    cout<<bullets<<" bullets"<<endl<<health<<" health"<<endl<<aBomb
            <<" A- Bomb"<<endl<<endl;
}

...

cout << "Enemy 1: " << endl << enemy1.print_status();



As a last remark, you could create a class named BULLET, that will hold properties of bullets. If they only contain data, for example bullet.damage, and no functions, it's semantically more correct to use a struct, although there's not much difference.

It may seem like OO-overkill, but if you think of objects as things in the program representing real world objects, it makes more sense to make it a separate entity with its own characteristics.

Hope that helps.

All the best,
NwN
Topic archived. No new replies allowed.