Bonjour a toutes et tous, je reviens vers vous encore une fois (et normalement c'est la dernière, promis ).

Je suis un train de développer un mini RPG pour appliquer ce que j'ai appris sur le c++ et j'ai un petit souci qui mélange polymorphisme et héritage. En gros mon idée de RPG est un duel de mage, on choisi le nom de son mage et son type (feu, glace, eau, etc ...) et puis on se lance dans la bataille (chaque mage à des sorts spécifiques à son type).

Pour l'instant j'en suis à: une classe mère nommé Mage qui me sert de base pour tous les mages, me permettant ainsi d'initialiser des points de vie, les points de mana, le traitement des dégâts, les gain ou perte de points de vie et de mana, etc ...

Voici les fichiers .h et .cpp pour vous donner l'idée
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
 
#ifndef MAGE_H_INCLUDED
#define MAGE_H_INCLUDED
 
#include <iostream>
#include <vector>
#include <string>
 
class Mage
{
    public:
        //Constructeur
        Mage(std::string nom);
 
        //Destructeur
        virtual ~Mage();
 
        //Methodes
        virtual void recevoirDegats(int degats);
        virtual void perteMana(Mage &cible, int pmana);
        virtual void gainMana();
        virtual void boirePotion();
        virtual void attaqueBase(Mage &cible) const;
        virtual void sePresenter () const;
        virtual void afficherEtat() const;
        virtual int etatVie();
 
    protected:
        //Attributs
        int m_vie;
        int m_mana;
        std::string m_nom;
};
 
#endif // PERSONNAGE_H_INCLUDED
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
 
#include "Mage.h"
 
using namespace std;
 
 
//Constructeur
Mage::Mage(string nom) : m_vie(100), m_mana(100), m_nom(nom)
{
 
}
 
//Destructeur
Mage::~Mage()
{
 
}
 
 
//Méthode "de base" pour tous les personnes
void Mage::recevoirDegats(int degats)
{
    m_vie -= degats;
}
 
void Mage::perteMana(Mage &cible, int pmana)
{
    m_mana -= pmana;
}
 
void Mage::boirePotion()
{
    m_vie += 20;
}
 
void Mage::gainMana()
{
    m_mana += 5;
}
 
void Mage::attaqueBase(Mage &cible) const
{
    cible.recevoirDegats(10);
}
 
void Mage::sePresenter() const
{
    cout << "Bonjour, je m'appelle " << m_nom << "." << endl;
    cout << "J'ai encore " << m_vie << " points de vie et " << m_mana << " points de mana." << endl << endl;
}
 
 
void Mage::afficherEtat() const
{
    cout << "Etat de " << m_nom << endl;
    cout << "Vie : " << m_vie << endl;
    cout << "Mana : " << m_mana << endl << endl;
}
 
int Mage::etatVie()
{
    return(m_vie);
}
Puis (pour l'instant), j'ai créé un mage de type feu qui hérite de ma classe mère Mage nommé MageFeu dont voici les fichiers .h et .cpp

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
 
#ifndef MAGEFEU_H_INCLUDED
#define MAGEFEU_H_INCLUDED
 
#include <iostream>
#include <string>
#include "Mage.h"
 
class MageFeu : public Mage
{
    public:
        //Constructeurs
        MageFeu(std::string nom);
 
        //Destructeur
        virtual ~MageFeu();
 
        //Methodes
        virtual void sePresenter () const;
        virtual void bouleDeFeu(Mage &cible) const;
 
    protected:
        //Attributs spécifiques a la classe Magicien
 
};
 
#endif // MAGEFEU_H_INCLUDED
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
 
#include "Mage.h"
#include "MageFeu.h"
 
using namespace std;
 
//Constructeurs
MageFeu::MageFeu(string nom) : Mage(nom)
{
 
}
 
//Destructeur
MageFeu::~MageFeu()
{
 
}
 
 
//Méthodes spécifiques à la classe Mage de feu
void MageFeu::sePresenter() const
{
    cout << "Bonjour, je m'appelle " << m_nom << ". Je suis un Mage de feu" << endl;
    cout << "J'ai encore " << m_vie << " points de vie et " << m_mana << " points de mana." << endl << endl;
}
 
 
void MageFeu::bouleDeFeu(Mage &cible) const
{
    cible.recevoirDegats(35);
}
Dans mon main maintenant, je gère la création de mes deux personnages mais ne sachant pas de quel type ils sont (vu que c'est au joueur de choisir) j'utilise le polymorphisme avec le code suivant:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
 
string nomMage1;
    string nomMage2;
    int choixType1(0);
    int choixType2(0);
 
    //Creation du premier mage
    Mage* pMage1 = NULL;
	cout << "Rentrez le nom du premier mage svp:" << endl;
	getline(cin, nomMage1);
	cout << "Choisissez le type de mage:" << endl;
	cin >> choixType1;
	if(choixType1 == 1)
	{
		pMage1 = new Mage(nomMage1);
	}
	else if(choixType1 ==2)
	{
		pMage1 = new MageFeu(nomMage1);
	}
    pMage1->sePresenter();
    std::cin.ignore( std::numeric_limits<std::streamsize>::max(), '\n' );
 
    //Creation du deuxième mage
    Mage* pMage2 = NULL;
	cout << "Rentrez le nom du deuxieme mage svp:" << endl;
	getline(cin, nomMage2);
	cout << "Choisissez le type de mage:" << endl;
	cin >> choixType2;
	if(choixType2 == 1)
	{
		pMage2 = new Mage(nomMage2);
	}
	else if(choixType2 ==2)
	{
		pMage2 = new MageFeu(nomMage2);
	}
    pMage2->sePresenter();
Jusqu'ici, je ne rencontre aucun problème, la création de mes personnes se fait bien et ils sont bien du type choisi (vérification faite avec la méthode sePresenter()).

C'est après que j'ai un problème dans ma boucle de comabt (pour l'instant la boucle n'est pas implémentée) dont voici le code:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
 
int choixAction1(0);
    //int choixAction2(0);
    int choixAttaque1(0);
    //int choixAttaque2(0);
    int compteurTour(1);
 
    //int etatVie1(0);
    //int etatVie2(0);
 
    cout << "TOUR " << compteurTour << endl << endl;
    cout << nomMage1 << ", choisissez l'action a effectuer" << endl;
    cin >> choixAction1;
    switch(choixType1)
    {
        case 1:
            switch(choixAction1)
            {
                case 1:
                    cout << nomMage1 << ", a vous d'attaquer. Veuillez choisir une attaque entre:" << endl << "1 - Attaque de base" << endl;
                    cin >> choixAttaque1;
                break;
                default:
 
                break;
            }
        break;
        case 2:
               switch(choixAction1)
            {
                case 1:
                    cout << nomMage1 << ", a vous d'attaquer. Veuillez choisir une attaque entre:" << endl << "1 - Attaque de base" << endl << "2 - Boule de Feu" << endl;
                    cin >> choixAttaque1;
                    switch(choixAttaque1)
                    {
                        case 1:
                            pMage1->attaqueBase(*pMage2);
                        break;
                        case 2:
                            pMage1->bouleDeFeu(*pMage2);
                            pMage1->perteMana(*pMage1, 5);
                        break;
                        default:
 
                        break;
                    }
                break;
                default:
 
                break;
            }
    }
Alors, déjà, oui je sais que c'est un peu une usine à gaz (comme on dit par chez moi) mais pour l'instant je n'ai pas d'autre idée de syntaxe donc veuillez me pardonner.

Mon problème viens de la ligne de code suivante
Code : Sélectionner tout - Visualiser dans une fenêtre à part
pMage1->bouleDeFeu(*pMage2);
qui me génère comme erreur
"error: 'class Mage' has no member named 'bouleDeFeu' "

Alors l'erreur je l'a comprend, ma classe Mage (donc ma classe mère ne connait pas la méthode bouleDeFeu, cette erreur doit très probablement venir du fait que lorsque je crée un personnage j'ai cette ligne de code
(on utilise le constructeur de la classe mère)

Donc ma question est: est-ce que je dois la faire version méga-bourrin (enfin je pense) où je déclare toutes les méthodes de sorts (quelque soit le type) dans la classe mère et après j'adapte dans mes switchs en fonction du type choisi par le joueurs ou alors est-ce qu'il y a un moyen de garder les méthodes dans les classes filles ?

Dans l'attente de vos réponses,
Cordialement,
Clairetj