making a pokemon game

Pages: 123
i have a class for pokemon, player, and attacks.

this is my player data structure

class player
{
public:

Pokemon Pokemon[6]; //array to hold 6 pokemon in your party
};


heres the class for the pokemon

class pokemon
{
public:

Attacks Attacks[4]; //array to hold 4 attacks
};


class attacks
{
public:
int power;
int pp;
int accuracy;

};

what is the best way to create attack objects and store them in the array in the pokemon class?
Well, you could create them dynamically, but since you have a set limit on how many you want to create, you could just do something like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int main()
{
    attacks att1, att2, att3, att4;
    pokemon pok1;
    player ply1;

    att1.power = 50;
    att1.pp = 5;
    att1.accuracy = 85;
    pok1.Attacks[1] = att1;
    ply1.Pokemon[1] = pok1;

    ...
    ...
}
what if i say do this?

attack Ember;
Ember.power=40;

how would i store that and call it during the battle loop?

not looking for you to do my work just need to be pushed in the right direction. any help is 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
#include <iostream>
#include <string>

struct attack
{
    std::string name;
    int power;
    int pp;
    int accuracy;
} att1, att2, att3, att4; // make 4 attack slots e.g "attack att1"

struct attack_ember: public attack
{
    attack_ember() // constructor
    {
        name = "Ember";
        power = 40;
        pp = 30;
        accuracy = 95;
    }
} ember; // the same as "attack_ember ember"

struct attack_hydropump: public attack
{
    attack_hydropump()  // constructor
    {
        name = "HydroPump";
        power = 120;
        pp = 5;
        accuracy = 75;
    }
} hydropump; // the same as "attack_hydropump hydropump"

int main()
{
    att1 = ember; // initialize values of att1(name, power, pp, accuracy) with the constructor values of attack_ember.
    att2 = hydropump; // initialize values of att2(name, power, pp, accuracy) with the constructor values of attack_hydropump.

    std::cout << att1.name << ": " << att1.power << " power" <<  std::endl; // ember on slot 1
    std::cout << att2.name << ": " << att2.power << " power" <<  std::endl; // hydropump on slot 2

    att1 = hydropump; // make slot 1 hydropump
    att2 = ember; // make slot 2 ember

    std::cout << att2.name << ": " << att2.accuracy << " accuracy" << std::endl; // hydropump on slot 1
    std::cout << att1.name << ": " << att1.accuracy << " accuracy" <<  std::endl;  // ember on slot 2
}


hope that helps, took me a while to figure it out, good fun doing it though.
Last edited on
You're kind of missing the point of classes and inheritance. That's a very bad example.
why is it a bad example? from what I know, classes are just a kind of structure, heck just change it to work with classes instead of structures if it is so bad, I used structures because I found it simpler.

but I really would love an explanation as to why it is a bad way of doing it.
Last edited on
Because the point of an object is that you can create a type of object, such as an attack. Then you can create multiple instances of that object that have different characteristics such as the names being different from one another, or the power, pp or accuracy.

Like with a pen. My pen is black with a silver tip. It has a soft ridged grip, writes with black ink, and is a click pen. Each of those are characteristics of my pen. You probably have a different pen. It might be a twist or a fountain pen. It might write in blue ink, or it could be a quill type that writes in whatever color it's dipped in. It could be gold on the outside, but it's still a pen.

That's the point of classes/structs. You define what types of characteristics that the pen has, like mBarrelColor, mInkColor, mClip, mWritingType, mSize, etc.

Then each instance of pen has slightly different values for each of those characteristics.

EDIT: Grammar
Last edited on
How did my code before not do that? you can make any number of new attack_xyz structures and then define different objects of the attack structure to have the same values for their attributes. in any case, here it is but with classes.

Unless I've misunderstood why he wanted to be able to just say [attack att1; att1 ember;] instead of [attack att1; att1.name = "Ember"; att1.power = 40; att1.pp = 30; att1.accuracy = 95;]

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
#include <iostream>
#include <string>

//http://www.cplusplus.com/forum/general/63358/

class attack
{
public:
    std::string GetName() {return name;} //loads of Get's and Set's, use accordingly.
    int GetPower() {return power;}
    int GetPP() {return pp;}
    int GetAccuracy() {return accuracy;}

    void SetName(std::string n) {name = n;}
    void SetPower(int x) {power = x;}
    void SetPP(int x) {pp = x;}
    void SetAccuracy(int x) {accuracy = x;}
private:
    std::string name;
    int power;
    int pp;
    int accuracy;
} att1, att2, att3, att4; // make 4 attack slots e.g "attack att1"

class attack_ember: public attack
{
public:
    attack_ember() // constructor to set values of parent object
    {
        attack::SetName("Ember");
        attack::SetPower(40);
        attack::SetPP(30);
        attack::SetAccuracy(95);
    }
} ember; // the same as "attack_ember ember"

class attack_hydropump: public attack
{
public:
    attack_hydropump()  // constructor to set values of parent object
    {
        attack::SetName("HydroPump");
        attack::SetPower(120);
        attack::SetPP(5);
        attack::SetAccuracy(75);
    }
} hydropump; // the same as "attack_hydropump hydropump"

int main()
{
    attack att1;

    att1 = ember; // initialize values of att1(name, power, pp, accuracy) using the attack_ember constructor
    att2 = hydropump; // initialize values of att2(name, power, pp, accuracy) using the attack_hydropump constructor

    std::cout << att1.GetName() << ": " << att1.GetPower() << " power" <<  std::endl; // ember on slot 1
    std::cout << att2.GetName() << ": " << att2.GetPower() << " power" <<  std::endl; // hydropump on slot 2

    att1 = hydropump; // make slot 1 hydropump
    att2 = ember; // make slot 2 ember

    std::cout << att2.GetName() << ": " << att2.GetAccuracy() << " accuracy" << std::endl; // hydropump on slot 1
    std::cout << att1.GetName() << ": " << att1.GetPP() << " PP" <<  std::endl;  // ember on slot 2

}
Last edited on
This:

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
class attack
{
private:
    std::string mName;
    int mPower, mPP, mAccuracy;
public:
    attack(const std::string& inName, int inPower, int inPP, int inAccuracy);
    ~attack() {}
};

attack::attack(const std::string& inName, int inPower, int inPP, int inAccuracy)
{
    mName = inName;
    mPower = inPower;
    mPP = inPP;
    mAccuracy = inAccuracy;
}

int main()
{
    attack *att1 = new attack("HydroPump", 120, 5, 75);
    attack *att2 = new attack("Ember", 40, 30, 95);

    ...
    delete att1;
    delete att2;
    return 0;
}
Last edited on
I wouldnt even use inheritance in this, its not needed, just a simple class that has pointers to another class would work because you arent going to be changing the accuracy/power of each ability, just maybe add modifiers in combat, therefore you can just use a constant for each attack eg:

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 Attack
{
public:
	Attack (int, int, int);
	int power,
		pp,
		accuracy;
}

constant Attack Hydropump (120, 5, 75),
	Ember (40, 30, 95),
	Splash (0, 15, 0),
	Dig (90, 20, 90);

class Pokemon
{
	Pokemon (Attack, Attack, Attack, Attack);
	
	Attack *attack1,
		*attack2,
		*attack3,
		*attack4;
	
	int offense,
		defense,
		specOffense,
		specDefense,
		pp; //OG blue/red stats :P
	
	double health;
	
} Blastoise (Hydropump, Ember, Splash, Dig);
:b that looks amazingly nice and clean compared to what I wrote, however there are errors, did you try and compile it beforehand?

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
#include <iostream>
#include <string>

class Attack
{
public:
	Attack (int, int, int);
	int power,
		pp,
		accuracy;
}

constant Attack Hydropump (120, 5, 75),
	Ember (40, 30, 95),
	Splash (0, 15, 0),
	Dig (90, 20, 90);

class Pokemon
{
	Pokemon (Attack, Attack, Attack, Attack);

	Attack *attack1,
		*attack2,
		*attack3,
		*attack4;

	int offense,
		defense,
		specOffense,
		specDefense,
		pp; //OG blue/red stats :P

	double health;

} Blastoise (Hydropump, Ember, Splash, Dig);

int main()
{
    std::cout << Blastoise.attack1->power;
}


I believe I did that right (Blastoise.attack1->power;)

1
2
3
4
5
6
7
8
9
|13|error: expected initializer before 'Attack'|
|35|error: 'Hydropump' was not declared in this scope|
|35|error: 'Ember' was not declared in this scope|
|35|error: 'Splash' was not declared in this scope|
|35|error: 'Dig' was not declared in this scope|
||In function 'int main()':|
|22|error: 'Attack* Pokemon::attack1' is private|
|39|error: within this context|
||=== Build finished: 7 errors, 0 warnings ===|
You can't access it...it's private.
herpa derp

and no i did not compile it, im texting this from my phone :)

i can when i get home if u cant get it to work still

plus i did not finish the constructors, you would have to do something like this:

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
#ifndef PKMN_H
#define PKMN_H

constant Attack Hydropump (120, 5, 75),
	Ember (40, 30, 95),
	Splash (0, 15, 0),
	Dig (90, 20, 90); //can add more constants here, just moved it to the top

class Attack
{
public:
	Attack (int, int, int);
	int power,
		pp,
		accuracy;
}

Attack::Attack(int pow, int pp, int ac)
{
	this->power = pow;
	this->pp = pp;
	this->accuracy = ac;
}

class Pokemon
{
public:
	Pokemon (Attack, Attack, Attack, Attack); //you could add arguements for stats :/
	
	Attack *attack1,
		*attack2,
		*attack3,
		*attack4;
	
	int offense,
		defense,
		specOffense,
		specDefense,
		pp; //OG blue/red stats :P
	
	double health;
	
} Blastoise (Hydropump, Ember, Splash, Dig); //just an example, should be deleted for real use

Pokemon::Pokemon (Attack one, Attack two, Attack three, Attack four) //you would also have to add those stat args here (from the class constructor line)
{
	this->attack1 = &one;
	this->attack2 = &two;
	this->attack3 = &three;
	this->attack4 = &four;
}

#endif 


now put all that in a header, and you can #include "YourHeader.h"

and you can just create new pokemon via:

Pokemon Charizard (Fly, FireBreath, BodySlam, Ember)

assuming you make constants for those abilities, then something like this:

1
2
3
4
Charizard->offense = 80;
Charizard->defense = 95;
Charizard->specOffense = 110;
Charizard->specDefense = 75;


come to think of it, you could actually make the stats short ints
and also come to think of it, you definately should not do this as two classes extending each other because then the initializer for the attack class will be called every time the initializer for the pokemon is called, making the a combination (attack+pokemon) object, which would be kinda retarded :/
it should only be done with things that are also something else, for example:

class Boss is a type of unit
class FootSoldier is another type of unit

BUT

since they are both types of units, they both extend the base unit class Unit

but although they contain data for other classes like location class Loc they do not extend it, get it?
Last edited on
I realize that, cipher, that isn't the real problem as making it public is easy enough, I meant the errors before that, expected intializer before Attack, and the arguments of the Blastoise object not being declared.

I can't personally get it to work, me and pointers don't share the same brain cells, not yet anyway, hence why I mentioned (Blastoise.attack1->power;) as I've never done that before.
constant
doesn't mean anything.
1
2
3
4
const Attack Hydropump (120, 5, 75),
	Ember (40, 30, 95),
	Splash (0, 15, 0),
	Dig (90, 20, 90);
That doesn't fix any of the errors.
Why don't you just do it the way I showed you?
I don't like the way you did it, dynamic memory and inability to pre-fill the variables of moves.

Edit:

Gfreak, moving them to the top only makes it worse, since the compiler doesn't know what "Attack" is. and I'm pretty certain that you can't do

1
2
3
4
const Attack Hydropump (120, 5, 75),
	Ember (40, 30, 95),
	Splash (0, 15, 0),
	Dig (90, 20, 90); //can add more constants here, just moved it to the top 


inside the global scope, it will have to be in a function or class.
Last edited on
closed account (zb0S216C)
This thread is starting to turn into a bit of a war on who's code is better.

Wazzak
Then change
attack *att1 = new attack("HydroPump", 120, 5, 75);
to
attack att1("HydroPump", 120, 5, 75);
Pages: 123