Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 6 sur 6
  1. #1
    Invité de passage
    Homme Profil pro
    Inscrit en
    décembre 2011
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : décembre 2011
    Messages : 4
    Points : 2
    Points
    2

    Par défaut Problème de pointeur

    Depuis mon autre problème d'hier, qui a heureusement été résolu, je me confronte aujourd'hui à un second problème, qui je pense est du aux pointeurs (je ne dois probablement pas encore en savoir assez sur eux pour les utiliser correctement, et pourtant je me suis déjà beaucoup renseigné sur eux à travers différents tuto...).

    Mon problème est le suivant: j'ai une classe GameLaunch qui me permet de générer un monde à travers une classe WorldManager, qui contient tout simplement un tableau créé dynamiquement à deux dimensions, auquel on peut accéder via des mutateurs (get et set) qui renvoient ou change la valeur du tableau via son pointeur (int** worldTab). Cette classe WorldManager est donc créée dans une des méthodes de ma classe GameLaunch (void lauchGame() qui fait tourner la boucle principale du jeu), et j'ai créé un pointeur ptrWorldManager qui pointe sur cette classe pour pouvoir ensuite l'envoyer en argument à d'autres classes lors de leur construction.

    Le problème survient à ce moment là. Par exemple, je crée dynamiquement ma classe GenerateWorld en envoyant comme argument à son constructeur le pointeur ptrWorldManager, qui est alors stocké dans une variable à l'intérieur même de GenerateWorld. Puis le constructeur appel l'une de ses fonctions privées (void biomeCollines(...)). Cette fonction est donc censée utiliser worldManager->setWorldTab(i , j , set), ce qu'elle fait très bien, mais si par exemple set vaut 2, et que tout de suite après j'appel worldManager->getWorldTab(i , j), ce dernier me renvoi 0!!!

    J'ai le même problème dans toutes mes autres classes possédant un pointeur sur le fameux worldManager, dans tous les cas, un set ne changera rien et un get renverra toujours 0!

    Je suppose donc que mes pointeurs sur worldManager se mélangent, ou alors créent de nouvelles instances de WorldManager, ce que je ne comprend pas...
    J'implore donc votre aide, amis développeurs, et voici mon code:

    WorldManager.cpp:

    Code :
    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
    #include "WorldManager.h"
     
    #include <SFML/Graphics.hpp>
    #include <iostream>
     
    WorldManager::WorldManager(int const a_tailleX , int const a_tailleY): tailleX(a_tailleX), tailleY(a_tailleY), worldTab(0)
    {
        /* Allocation dynamique du tableau */
        worldTab = this->constructeurTableauDynamique();
     
        /* Initialisation */
        for (int i = 0 ; i < tailleX ; i++)
        {
            for (int j = 0 ; j < tailleY ; j++)
            {
                this->setWorldTab(i , j , 0);
            }
        }
    }
     
    WorldManager::~WorldManager()
    {
        /* Destruction du double tableau */
        this->destructeurTableauDynamique(worldTab);
    }
     
    int** WorldManager::constructeurTableauDynamique()
    {
        int** worldTab = new int* [tailleX];
        for (int i = 0 ; i < tailleX ; i++)
        {
            worldTab[i] = new int[tailleY];
        }
     
        return worldTab;
    }
     
    void WorldManager::destructeurTableauDynamique(int** worldTab)
    {
        for (int i=0; i < tailleX; i++)
        {
            delete[] worldTab[i];
        }
        delete[] worldTab;
    }
     
    int WorldManager::getWorldTab(int i , int j)
    {
        return worldTab[i][j];
    }
     
    void WorldManager::setWorldTab(int i , int j , int set)
    {
        worldTab[i][j] = set;
    }
    WorldManager.h:

    Code :
    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
    #ifndef WORLDMANAGER_H_INCLUDED
    #define WORLDMANAGER_H_INCLUDED
     
    #include <SFML/Graphics.hpp>
     
    class WorldManager
    {
        public:
     
        WorldManager(int const a_tailleX , int const a_tailleY);
        ~WorldManager();
     
        int** constructeurTableauDynamique();
        void destructeurTableauDynamique(int** worldTab);
     
        int getWorldTab(int i , int j);
        void setWorldTab(int i , int j , int set);
     
        private:
     
        //Variables stockant la taille du tableau
        int const tailleX;
        int const tailleY;
     
        int **worldTab;
    };
     
    #endif // WORLDMANAGER_H_INCLUDED
    GameLauch.cpp:

    Code :
    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
    #include "GameLaunch.h"
    #include "WorldManager.h"
    #include "Camera.h"
    #include "GenerateWorld.h"
    #include "ImageManager.h"
    #include "BlockManager.h"
     
    #include <SFML/Graphics.hpp>
    #include <iostream>
     
    GameLaunch::GameLaunch(sf::RenderWindow *a_app):  worldLength(200), worldHeight(100), app(a_app), camera(0), Event(), framerate(), LeftKeyDown(), RightKeyDown(), LeftButtonDown(), RightButtonDown(), MouseX(), MouseY()
    {
        camera = new Camera(worldLength * 10 - app->GetWidth() / 2 , worldHeight * 10 - app->GetHeight() / 2 , app->GetWidth() , app->GetHeight());
        std::cout << "Launching game loop" << std::endl;
    }
     
    GameLaunch::~GameLaunch()
    {
        delete camera;
    }
     
    void GameLaunch::launchGame()
    {
        //Activation de la synchronisation vertcale
        app->UseVerticalSync(true);
     
        //Création du tableau dans la classe WorldManager
        WorldManager *ptrWorldManager;
        WorldManager worldManager(worldLength , worldHeight);
        ptrWorldManager = &worldManager; //Le fameux pointeur
     
        GenerateWorld *generator;
        generator = new GenerateWorld(ptrWorldManager, worldLength, worldHeight);
     
        ImageManager *imageManager;
        imageManager = new ImageManager();
     
        BlockManager *blockManager;
        blockManager = new BlockManager(ptrWorldManager, worldLength, worldHeight, imageManager, app, camera);
        //Le problème se situe dans les classes GenerateWorld et BlockManager
     
        //Création d'une constante input permettant de récupérer les entrées claviers/souris ou la position de la souris -> cette classe n'a pas été initialisée dans le constructeur, mais pourrait l'être à l'avenir
        const sf::Input& Input = app->GetInput();
     
        // Exécution de la boucle principale du jeu
        while (app->IsOpened())
        {
            //Efface l'écran (remplissage avec du noir)
            app->Clear();
     
            //On récupère les IPS actuels de notre fenêtre
            framerate = 1.f / app->GetFrameTime();
     
            // Traitement des évènements: fermeture de la fenêtre
            while (app->GetEvent(Event))
            {
                // Fenêtre fermée : on quitte
                if (Event.Type == sf::Event::Closed)
                    app->Close();
            }
     
            // Traitement des entrées
            LeftKeyDown     = Input.IsKeyDown(sf::Key::Left);
            RightKeyDown    = Input.IsKeyDown(sf::Key::Right);
            LeftButtonDown  = Input.IsMouseButtonDown(sf::Mouse::Left);
            RightButtonDown = Input.IsMouseButtonDown(sf::Mouse::Right);
            MouseX          = Input.GetMouseX();
            MouseY          = Input.GetMouseY();
     
            //Affichage du monde
            blockManager->blitMap();
     
            // Affichage du contenu de la fenêtre à l'écran
            app->Display();
        }
     
        delete generator;
        delete imageManager;
        delete blockManager;
    }
    GameLaunch.h:

    Code :
    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
    #ifndef GAMELAUNCH_H_INCLUDED
    #define GAMELAUNCH_H_INCLUDED
     
    #include <SFML/Graphics.hpp>
     
    #include "WorldManager.h"
    #include "Camera.h"
     
    class GameLaunch
    {
        public:
     
        GameLaunch(sf::RenderWindow *a_app);
        ~GameLaunch();
     
        void launchGame();
     
        private:
     
        int const worldLength;
        int const worldHeight;
     
        sf::RenderWindow *app; // Création d'un pointeur sur la fenêtre de rendu
     
        Camera *camera; //Création d'un pointeur sur la caméra
        WorldManager *worldManager; //Création d'un pointeur sur le manageur de monde
     
        sf::Event Event; //Création de l'évènement event (pas de pointeur)
     
        float framerate; //Fréquence de rafraîchissement de l'image
     
        //Différentes variables qui stockent les entrées claviers/souris et la position de la souris
        bool         LeftKeyDown;
        bool         RightKeyDown;
        bool         LeftButtonDown;
        bool         RightButtonDown;
        unsigned int MouseX;
        unsigned int MouseY;
     
    };
     
    #endif // GAMELAUNCH_H_INCLUDED
    GenerateWorld.cpp:

    Code :
    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
    #include "GenerateWorld.h"
    #include "WorldManager.h"
     
    #include <SFML/Graphics.hpp>
    #include <iostream>
    #include <cstdlib>
     
    GenerateWorld::GenerateWorld(WorldManager *a_worldManager, int a_tailleX, int a_tailleY): worldManager(0), tailleX(a_tailleX), tailleY(a_tailleY), seaLevel(tailleY * (1/2))
    {
        worldManager = a_worldManager;
        this->biomeCollines(tailleX , 0 , 10 , 3);
        std::cout << "Biome Collines has been generated" << std::endl;
        std::cout << "Generation done" << std::endl;
        std::cout << "Gen : " << worldManager->getWorldTab(156 , 86); //Normalement, il devrait s'afficher Gen : 2 suite à la génération du monde (j'ai fait les tests pour 156 86), or ce n'est pas le cas (Gen : 0)
    }
     
    void GenerateWorld::biomeCollines(int length , int biomeX , int heightMax , int layersTerre) //Où biomeX est la place du biome dans le monde, et lenght la longueur du biome -> à noter que le biome occupe toute la hauteure du monde
    {
        int progress = 0;
        int pProgress;
        int rep = (rand() % 2) + 2;
        int height = seaLevel;
        int r1 , r2;
        int q , i , j;
     
        while (progress < length - 6 * rep)
        {
            if (height < seaLevel + heightMax - rep && height > seaLevel - heightMax + rep) {r1 = rand() % 2;}
            else if (height >= seaLevel + heightMax - rep) {r1 = 1;}
            else {r1 = 0;}
     
            for (q = 0 ; q < rep ; q++)
            {
                if (r1 == 0) {height++;}
                else {height--;}
     
                r2 = rand() % 9;
     
                if (r2 == 0) {pProgress = 2;}
                else if (r2 > 0 && r2 < 3) {pProgress = 3;}
                else if (r2 > 2 && r2 < 6) {pProgress = 4;}
                else if (r2 > 5 && r2 < 8) {pProgress = 5;}
                else {pProgress = 6;}
     
                for (i = 0 ; i < pProgress ; i++)
                {
                    for (j = height ; j < tailleY ; j++)
                    {
                        if (j - height < layersTerre) {worldManager->setWorldTab(i + biomeX , j , 1);}
                        else {worldManager->setWorldTab(i + biomeX , j , 2);}
                    }
                }
                progress += pProgress;
            }
            rep = (rand() % 2) + 2;
        }
     
        for (int a = 0 ; a < length - progress ; a++)
        {
            for (int b = height ; b < tailleY ; b++)
            {
                if (b - height < layersTerre) {worldManager->setWorldTab(a + biomeX , b , 1);}
                else {worldManager->setWorldTab(a + biomeX , b , 2);}
            }
        }
    }
    GenerateWorld.h:

    Code :
    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
    #ifndef GENERATEWORLD_H_INCLUDED
    #define GENERATEWORLD_H_INCLUDED
     
    #include <SFML/Graphics.hpp>
     
    #include "WorldManager.h"
     
    class GenerateWorld
    {
        public:
     
        GenerateWorld(WorldManager *a_worldManager, int a_tailleX, int a_tailleY);
     
        private:
     
        void biomeCollines(int length , int biomeX , int heightMax , int layersTerre);
     
        WorldManager *worldManager;
     
        int const tailleX;
        int const tailleY;
        int seaLevel;
    };
     
    #endif // GENERATEWORLD_H_INCLUDED

  2. #2
    Membre Expert
    Homme Profil pro
    Étudiant
    Inscrit en
    juin 2012
    Messages
    852
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : juin 2012
    Messages : 852
    Points : 1 599
    Points
    1 599

    Par défaut

    C'est ton algo qui renvoi 0, pas un soucis de pointeur
    Code :
    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
    #include <stdlib.h>
    #include <iostream>
     
     
    const int tailleY = 100;
    const int tailleX = 200;
    int seaLevel = 50;
    int tab[tailleX][tailleY];
     
    void biomeCollines(int length , int biomeX , int heightMax , int layersTerre)
    {
     
    	int progress = 0;
    	int pProgress;
    	int rep = (rand() % 2) + 2;
    	int height = seaLevel;
    	int r1 , r2;
    	int q , i , j;
     
    	while (progress < length - 6 * rep)
    	{
    		if (height < seaLevel + heightMax - rep && height > seaLevel - heightMax + rep) {r1 = rand() % 2;}
    		else if (height >= seaLevel + heightMax - rep) {r1 = 1;}
    		else {r1 = 0;}
     
    		for (q = 0 ; q < rep ; q++)
    		{
    			if (r1 == 0) {height++;}
    			else {height--;}
     
    			r2 = rand() % 9;
     
    			if (r2 == 0) {pProgress = 2;}
    			else if (r2 > 0 && r2 < 3) {pProgress = 3;}
    			else if (r2 > 2 && r2 < 6) {pProgress = 4;}
    			else if (r2 > 5 && r2 < 8) {pProgress = 5;}
    			else {pProgress = 6;}
     
    			for (i = 0 ; i < pProgress ; i++)
    			{
    				for (j = height ; j < tailleY ; j++)
    				{
    					if (j - height < layersTerre) {tab[i + biomeX][j] = 1;}
    					else {tab[i + biomeX][j] = 2;}
    				}
    			}
    			progress += pProgress;
    		}
    		rep = (rand() % 2) + 2;
    	}
     
    	for (int a = 0 ; a < length - progress ; a++)
    	{
    		for (int b = height ; b < tailleY ; b++)
    		{
    			if (b - height < layersTerre) {tab[a + biomeX][b] = 1;}
    			else {tab[a + biomeX][b] = 2;}
    		}
    	}
    }
     
    int main(int argc, char** argv) {
     
    	biomeCollines(tailleX , 0 , 10 , 3);
    	std::cout << tab[156][86];
    	return 0;
    }
    -> Affiche 0 (oui variables globales etc... J'assume :p)

    Sinon tu devrais utiliser des smart ptr pour "generator", "imageManager" et "blockManager" (dans GameLaunch::launchgame() ). La si une exception est lancée tu te retrouve avec une fuite mémoire.

    edit: Heu... il ya que des tab[x][y] = 1 ou 2 dans le code, pas de memset ni de ZeroMemory et pourtant ça me donne 0, les tableaux de int sont initialisés à 0 ? *_*

  3. #3
    r0d
    r0d est déconnecté
    Expert Confirmé Sénior

    Profil pro
    Inscrit en
    août 2004
    Messages
    4 088
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : août 2004
    Messages : 4 088
    Points : 5 129
    Points
    5 129

    Par défaut

    Bonjour,

    si tu veux faire un minecraft en c++, il faut que tu commences par arrêter d'utiliser des pointeurs partout

    Concrètement, au lieu de:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
        //Création du tableau dans la classe WorldManager
        WorldManager *ptrWorldManager;
        WorldManager worldManager(worldLength , worldHeight);
        ptrWorldManager = &worldManager; //Le fameux pointeur
     
        GenerateWorld *generator;
        generator = new GenerateWorld(ptrWorldManager, worldLength, worldHeight);
     
        ImageManager *imageManager;
        imageManager = new ImageManager();
     
        BlockManager *blockManager;
        blockManager = new BlockManager(ptrWorldManager, worldLength, worldHeight, imageManager, app, camera);
     
        // code
     
        delete generator;
        delete imageManager;
        delete blockManager;
    }
    Préférer le code:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
        //Création du tableau dans la classe WorldManager
        WorldManager worldManager(worldLength , worldHeight);
        GenerateWorld generator(worldManager, worldLength, worldHeight);
        ImageManager imageManager;
        BlockManager blockManager(ptrWorldManager, worldLength, worldHeight, imageManager, app, camera);
     
        // code
     
        // pas besoin d'appeler les destructeurs
    }
    C'est plus court, plus facile, et surtout, ça t'éviteras de nombreuses erreurs. Les pointeurs sont sources de problèmes, il faut les éviter tant que faire se peut.

    De même, si tu a besoin de ton worldManager dans ton generator, passes-le par référence, et non par pointeur. Du coup, GenerateWorld ressemblera à quelque chose comme ceci:
    Code :
    1
    2
    3
    4
    5
    // le contructeur:
    GenerateWorld::GenerateWorld(WorldManager & a_worldManager, int a_tailleX, int a_tailleY);
     
    // et la variable membre
    WorldManager & worldManager;
    Si tu fais ce que je t'explique là (bannir les pointeurs de ton code), tu verras tout fonctionnera sans prise de tête.

  4. #4
    r0d
    r0d est déconnecté
    Expert Confirmé Sénior

    Profil pro
    Inscrit en
    août 2004
    Messages
    4 088
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : août 2004
    Messages : 4 088
    Points : 5 129
    Points
    5 129

    Par défaut

    J'insiste lourdement, mais c'est important. Tu as écrit:
    Code :
    GameLaunch(sf::RenderWindow *a_app);
    Si tu regardes un peu les en-têtes de la SFML, tu verras que tous les paramètres sont passés par référence. Il FAUT que tu fasses pareil, c'est à dire:
    Code :
    GameLaunch(sf::RenderWindow & a_app);

  5. #5
    Invité de passage
    Homme Profil pro
    Inscrit en
    décembre 2011
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : décembre 2011
    Messages : 4
    Points : 2
    Points
    2

    Par défaut

    Effectivement Iradrille tu avais raison c'était bien un problème dans mon algo (tout simplement un - ou lieu d'un + )... C'est bête tout ce que cela peut engendrer comme problèmes... Donc je m'excuse pour ce post si long alors que le problème était vraiment tout bête...

    r0d: oui je crois que je vais arrêter avec tous ces pointeurs, et utiliser des références (je pensais que les pointeurs permettaient de faire plus de chose, mais effectivement, il y a beaucoup plus simple ).
    Donc merci à tous deux pour vos réponses rapides, et encore désolé pour ce mes stupides erreurs!!!

  6. #6
    r0d
    r0d est déconnecté
    Expert Confirmé Sénior

    Profil pro
    Inscrit en
    août 2004
    Messages
    4 088
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : août 2004
    Messages : 4 088
    Points : 5 129
    Points
    5 129

    Par défaut

    Citation Envoyé par Iradrille Voir le message
    edit: Heu... il ya que des tab[x][y] = 1 ou 2 dans le code, pas de memset ni de ZeroMemory et pourtant ça me donne 0, les tableaux de int sont initialisés à 0 ? *_*
    ça dépend du compilateur et des options de compilation.

+ Répondre à la discussion
Cette discussion est résolue.

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •