Accéder à des membres d'une autre classe?

Signaler
Messages postés
8
Date d'inscription
mercredi 21 février 2007
Statut
Membre
Dernière intervention
6 janvier 2010
-
Messages postés
1466
Date d'inscription
mardi 20 février 2007
Statut
Membre
Dernière intervention
7 février 2011
-
bonjour a tous,
voila je programme en ce moment un FPS, et pour mieux structurer mon jeu, je veux creer des class (oui j'en avait pas fait au début, c'est la structure bête de DarkGDK pour ceux qui connaissent!).

Donc j'utilise VS8 avec Dark GDK, ensuite j'ai:
>> une classe CMap qui contient entre autre LoadMap (...)
>> une classe CPlayer qui contient les données du joueur, avec entre autre une struct "tsDataPlayer".

J'ai donc crée 2 objet pour les 2 classes, et je souhaite donc appeler la struct de joueur dans la méthode LoadMap() pour y entrer les valeur récupéré comme la position de départ!

J'ai tapé "class CMap : public CPlayer" pour la classe CMap.

Dans la méthode LoadMap() j'ai bien accès aux membre de CPlayer. Tout compile, et en mode pas à pas je vois bien les variable de la struct changer. Mais des que je quitte la méthode LoadMap (), tous les membres de la struct valent 0.

La méthode avec static marche mais je trouve ca moche... ya pas autre chose ? j'ai du faire une boulette...

5 réponses

Messages postés
3819
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
28 septembre 2020
113
J'ai tapé "class CMap : public CPlayer" pour la classe CMap.


Y a quand même une sacrée erreur de conception !
Pour savoir si une classe peut hériter d'une autre, la règle 'est un' doit s'appliquer.
Ici une "map" n'est pas un "joueur", donc il ne devrait pas y avoir héritage. (Peut être une aggrégation ?).

une classe CPlayer qui contient les données du joueur, avec entre autre une struct "tsDataPlayer".

Tu sais qu'en C++ une struct et une classe sont identiques (mise à part le niveau de visibilité par défaut). Donc tu aurais pu ajouter des méthodes directement dans "tsDataPlayer".

Dans la méthode LoadMap() j'ai bien accès aux membre de CPlayer. Tout compile, et en mode pas à pas je vois bien les variable de la struct changer. Mais des que je quitte la méthode LoadMap (), tous les membres de la struct valent 0.

Ou est cette struct ? Est-elle passé quelque part, par copie ? Si c'est le cas, tu modifies sûrement une copie de ton véritable objet.
Messages postés
8
Date d'inscription
mercredi 21 février 2007
Statut
Membre
Dernière intervention
6 janvier 2010

Merci pour ta réponse !

Tu sais qu'en C++ une struct et une classe sont identiques (mise à part le niveau de visibilité par défaut). Donc tu aurais pu ajouter des méthodes directement dans "tsDataPlayer".


Pour la struct je sais qu'elle est "quasi" semblable a une classe, mais ce que je voulais c'est ca :
dans mon éditeur de niveau j'ai un "infoPlayerStart" qui possède les coordonnée du point de départ du joueur en X,Y,Z. Ensuite dans LoadMap(), je cherche tte les entités, et quand je tombe sur "infoPlayerStart", je voudrais stocker les coordonnées dans une structure qui est dans la classe CPlayer.

Ou est cette struct ? Est-elle passé quelque part, par copie ? Si c'est le cas, tu modifies sûrement une copie de ton véritable objet.

La struct est simplement dans la classe CPlayer. C'est celle-ci:
typedef struct tsDataPlayer
{
int numPlayer;
char* nomPlayer;
float positionCamPlayerX; // position du joueur en X Cam
float positionCamPlayerY; // position du joueur en Y Cam
float positionCamPlayerZ; // position du joueur en Z Cam
float angleCamPlayerX;// angle du joueur en X Cam
float angleCamPlayerY;// angle du joueur en Y Cam
float angleCamPlayerZ;// angle du joueur en Z Cam
float positionPlayerStartX; // position du joueur en X Cam
float positionPlayerStartY; // position du joueur en Y Cam
float positionPlayerStartZ; // position du joueur en Z Cam
float anglePlayerStartX;// angle du joueur en X Cam
float anglePlayerStartY;// angle du joueur en Y Cam
float anglePlayerStartZ;// angle du joueur en Z Cam
int vieRestante;
int vieMax;
int combiRestante;
int combiMax;
int numObjetAction; // le numéro d'objet que le joueur veut "actionner"
float distancePlayerToObjetAction; // la distance qui sépare le joeur de l'objet souhaité "actionner"
};
Messages postés
3819
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
28 septembre 2020
113
CMap ne doit pas hériter de CPlayer, mais doit avoir un tableau de CPlayer.
(std::vector ou std::list, ou encore std::set, tout dépend de ce que tu en fais).

Dans ta méthode LoadMap(), à chaque fois que tu trouves une entité, tu crées un objet de type CPlayer, tu le remplis, et tu l'ajoute à ta liste.

Néanmoins c'est très dur de t'aider sans voir ta modélisation (ton UML). Si tu n'as pas fait de modélisation, ça revient à coder à l'aveugle, et tu te retrouveras avec un code inmaintenable.
Pour ton erreur, j'ai besoin de voir le code qui pose problème.

typedef struct tsDataPlayer


Le typedef n'est pas nécessaire, tu peux écrire:

struct tsDataPlayer


Ceci:
char* nomPlayer;


Peut être remplacé par cela:
std::string nomPlayer;
Messages postés
8
Date d'inscription
mercredi 21 février 2007
Statut
Membre
Dernière intervention
6 janvier 2010

Rebonjour

pour ce qui est de la modélisation, je l'ai fait sur une feuille... Je n'est plus Rational Rose sur mon PC! Sinon la j'ai repris tout mon code après le menu! Et j'ai ainsi fais comme ceci: la map contient un joueur, des ennemis, des entités, des sons... Et par exemple le joueur, lui, contient des armes.

voici ma nouvelle classe CMap_HL2:
class CMap_HL2
{
public:
//fonctions
CMap_HL2();
CMap_HL2(std::string nameMap);
~CMap_HL2();
bool		LoadMap		(std::string OptionalPathToTextureRoot,std::string OptionalPathToModelRoot,float TextureMapScale,int OCMode);
std::string	getMsgError	(void);

//variables
static enum {Normal, AllObjects};


private:
// structures
struct tsDataWorld 
{
char*		OCMode;	
int			FPS;
int			POLYS;
int			totalObjets;
int			totalLimbs;
string		nomMap3DW;
};

// autre variables
bool m_LoadFailed;
std::string m_MsgError;
std::string m_NameMapLoad;

// création des vecteurs perso !
vector<tsDataWorld> m_vDataWorld;

// poointeur sur un objet du joueur!
CPlayer_HL2 * o_Player;
};


et un des constructeur:
CMap_HL2::CMap_HL2(string nameMap) : m_NameMapLoad(nameMap)
{
o_Player = new CPlayer_HL2;
}


Donc je crée un joueur qui est lié a la map, si elle est détruite lui aussi (avec le "delete o_Player" dans le destructeur).
Bon pour le moment je crois pas m'être trompé mais faut me corriger si il le faut!

Maintenant j'ai une grande question : le joueur par exemple possède des armes qui elles, possèdes des sons! Est ce que je dois créer un objet pour chaque arme, et chaque son? Ou je dois utiliser un seul objet pour gérer toutes les armes du joueurs??!

2eme question : Si je veux utiliser l'objet du joueur dans le MAIN(), comment je dois l'appeler?

merci d'avance !
Messages postés
1466
Date d'inscription
mardi 20 février 2007
Statut
Membre
Dernière intervention
7 février 2011
1
Salut,
Pour répondre à ta 2ème question, un objet s'utilise sur le même principe que n'importe quel type de variable.

Pour ta 1ère question, tout dépend de l'importance des armes. Si chaque arme possède un son, et ça s'arrête là, une bête table de correspondance suffit (style un tableau 2D).
Si tu veux stocker pour chaque arme sa durée de vie, sa puissance, ses dégâts, etc, je te conseillerais de faire une classe générique (template) ou au pire un héritage virtuel (au cas ou certaines armes aient plus de caractéristiques que d'autres), les armes peuvent alors être stockées dans un conteneur.

Pour les conteneur... je te déconseille vector. Officiellement, je ne suis pas censé l'avoir utilisé (on ne l'a pas encore vu en cours, donc ma prof m'apprendra sans doute des bonnes choses là dessus), mais vis à vis de mon expérience perso, j'ai préféré coder un conteneur perso qu'utiliser vector qui, par exemple, réalloue une zone et recopie tout le tableau en mémoire pour un simple ajout d'élément dans le tableau. Après, c'est sur que le code est blindé, mais bon... C'est sans doute ma réticence envers le C++ (qui ne nous permet pas toujours de savoir ce qui se cache derrière notre code) qui me fait dire ça.


Cordialement, uaip.