IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

creation d'une classe balle pour un petit jeu


Sujet :

C++

  1. #1
    Membre très actif Avatar de fifafou
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2016
    Messages
    173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Janvier 2016
    Messages : 173
    Par défaut creation d'une classe balle pour un petit jeu
    bonjour,
    je cherche a créer une classe balle pour un petit jeu de tank mais c'est la première fois que je fais une classe C++ et évidemment je me retrouve avec pas mal d'erreurs à la compilation
    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
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    -------------- Build: Debug in Tank (compiler: GNU GCC Compiler)---------------
     
    mingw32-g++.exe -Wall -g -Iinclude -c "C:\Users\___\Documents\c++ prog\Tank\sources\balle.cpp" -o obj\Debug\sources\balle.o
    In file included from C:\Users\baud\Documents\c++ prog\Tank\sources\balle.cpp:1:0:
    C:\Users\___\Documents\c++ prog\Tank\sources\balle.h:8:17: error: 'SDL_Surface' has not been declared
         void update(SDL_Surface* ecran,int mat[][25]);
                     ^
    C:\Users\___\Documents\c++ prog\Tank\sources\balle.h:15:5: error: 'SDL_Surface' does not name a type
         SDL_Surface* balle;
         ^
    C:\Users\___\Documents\c++ prog\Tank\sources\balle.h:16:5: error: 'SDL_Rect' does not name a type
         SDL_Rect pos_balle;
         ^
    C:\Users\___\Documents\c++ prog\Tank\sources\balle.cpp: In constructor 'Balle::Balle()':
    C:\Users\___\Documents\c++ prog\Tank\sources\balle.cpp:9:5: error: 'SDL_Surface' was not declared in this scope
         SDL_Surface* balle=IMG_Load("data/balle.png");
         ^
    C:\Users\___\Documents\c++ prog\Tank\sources\balle.cpp:9:18: error: 'balle' was not declared in this scope
         SDL_Surface* balle=IMG_Load("data/balle.png");
                      ^
    C:\Users\___\Documents\c++ prog\Tank\sources\balle.cpp:9:49: error: 'IMG_Load' was not declared in this scope
         SDL_Surface* balle=IMG_Load("data/balle.png");
                                                     ^
    C:\Users\___\Documents\c++ prog\Tank\sources\balle.cpp:10:5: error: 'pos_balle' was not declared in this scope
         pos_balle.x=this.x;
         ^
    C:\Users\___\Documents\c++ prog\Tank\sources\balle.cpp:10:22: error: request for member 'x' in '(Balle*)this', which is of pointer type 'Balle*' (maybe you meant to use '->' ?)
         pos_balle.x=this.x;
                          ^
    C:\Users\___\Documents\c++ prog\Tank\sources\balle.cpp:11:22: error: request for member 'y' in '(Balle*)this', which is of pointer type 'Balle*' (maybe you meant to use '->' ?)
         pos_balle.y=this.y;
                          ^
    C:\Users\___\Documents\c++ prog\Tank\sources\balle.cpp:5:12: warning: unused variable 'x' [-Wunused-variable]
         double x=50;
                ^
    C:\Users\___\Documents\c++ prog\Tank\sources\balle.cpp:6:12: warning: unused variable 'y' [-Wunused-variable]
         double y=50;
                ^
    C:\Users\___\Documents\c++ prog\Tank\sources\balle.cpp:7:12: warning: unused variable 'vy' [-Wunused-variable]
         double vy=1;
                ^
    C:\Users\___\Documents\c++ prog\Tank\sources\balle.cpp:8:12: warning: unused variable 'vx' [-Wunused-variable]
         double vx=1;
                ^
    C:\Users\___\Documents\c++ prog\Tank\sources\balle.cpp:12:9: warning: unused variable 'd' [-Wunused-variable]
         int d=1000;
             ^
    C:\Users\___\Documents\c++ prog\Tank\sources\balle.cpp: At global scope:
    C:\Users\___\Documents\c++ prog\Tank\sources\balle.cpp:14:1: error: prototype for 'Balle::Balle(double, double, double, double)' does not match any in class 'Balle'
     Balle::Balle(double m_x,double m_y,double m_vx,double m_vy)
     ^
    In file included from C:\Users\baud\Documents\c++ prog\Tank\sources\balle.cpp:1:0:
    C:\Users\___\Documents\c++ prog\Tank\sources\balle.h:3:7: error: candidates are: Balle::Balle(const Balle&)
     class Balle
           ^
    C:\Users\___\Documents\c++ prog\Tank\sources\balle.h:7:5: error:                 Balle::Balle(double, double)
         Balle(double x,double y);
         ^
    C:\Users\___\Documents\c++ prog\Tank\sources\balle.cpp:3:1: error:                 Balle::Balle()
     Balle::Balle()
     ^
    C:\Users\___\Documents\c++ prog\Tank\sources\balle.cpp:25:20: error: variable or field 'update' declared void
     void Balle::update(SDL_Surface* ecran,int mat[][25])
                        ^
    C:\Users\___\Documents\c++ prog\Tank\sources\balle.cpp:25:20: error: 'SDL_Surface' was not declared in this scope
    C:\Users\___\Documents\c++ prog\Tank\sources\balle.cpp:25:33: error: 'ecran' was not declared in this scope
     void Balle::update(SDL_Surface* ecran,int mat[][25])
                                     ^
    C:\Users\___\Documents\c++ prog\Tank\sources\balle.cpp:25:39: error: expected primary-expression before 'int'
     void Balle::update(SDL_Surface* ecran,int mat[][25])
                                           ^
    Process terminated with status 1 (0 minute(s), 41 second(s))
    17 error(s), 5 warning(s) (0 minute(s), 41 second(s))
    voici le code:
    Code main.cpp : 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
    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
    #include <SDL/SDL.h>
    #include <SDL/SDL_image.h>
    #include <stdio.h>
    #include <SDL/SDL_rotozoom.h>
    #include "balle.h"
    int bloc(int x,int y,int mat[][25])
    {
        return mat[x/20][y/20];
    }
    int main(int argc, char *argv[])
    {
        SDL_Surface *ecran = NULL,*block = NULL,*ice = NULL,*perso = NULL,*tank = NULL;
        SDL_Rect pos_bloc,pos_perso;
        pos_perso.x=30;
        pos_perso.y=60;
        SDL_Event event;
        int continuer = 1;
        int tempsPrecedent = 0, tempsActuel = 0;
        SDL_Init(SDL_INIT_VIDEO);
        ecran = SDL_SetVideoMode(1000,500, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
        SDL_WM_SetCaption("Jeu en SDL", NULL);
        tank = IMG_Load("data/perso.png");
        perso=tank;
        block = IMG_Load("data/bloc.png");
        ice = IMG_Load("data/glace.png");
        FILE* fichier = fopen("matrice.txt", "r");
        double px=30,py=60,vx=0,vy=0,an=0;
        int mat[50][25],symb,i,j;
        for(j=0;j<25;j++)
        {
            for(i=0;i<50;i++)
            {
                symb=fgetc(fichier);
                if(symb=='\n')
                    symb=fgetc(fichier);
                mat[i][j]=symb;
            }
        }
        SDL_EnableKeyRepeat(10, 10);
        while (continuer)
        {
            SDL_PollEvent(&event); /* On utilise PollEvent et non WaitEvent pour ne pas bloquer le programme */
            switch(event.type)
            {
                case SDL_QUIT:
                    continuer = 0;
                    break;
            }
            SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 180,180, 250));
            for(int i=0;i<50;i++)
            {
                for(int j=0;j<25;j++)
                {
                    pos_bloc.x=20*i;
                    pos_bloc.y=20*j;
                    switch(mat[i][j])
                    {
                        case '1':
                            SDL_BlitSurface(block, NULL, ecran, &pos_bloc);
                            break;
                        case '2':
                            SDL_BlitSurface(ice, NULL, ecran, &pos_bloc);
                            break;
                    }
                }
     
            }
            Uint8 *state=SDL_GetKeyState(NULL);
            if(state[SDLK_q])
                an+=2;
            if(state[SDLK_w])
                an-=2;
            if(state[SDLK_LEFT])
                if(bloc(px-1,py,mat)!='0' || bloc(px-1,py+19,mat)!='0')
                    px=20*int((px+10)/20);
                else px-=3;
            if(state[SDLK_RIGHT])
                if(bloc(px+21,py,mat)!='0' || bloc(px+21,py+19,mat)!='0')
                    px=20*int((px+10)/20);
                else px+=3;
            if(state[SDLK_UP])
                if(bloc(px,py-1,mat)!='0' || bloc(px+19,py-1,mat)!='0')
                    py=20*int((py+10)/20);
                else py-=3;
            if(state[SDLK_DOWN])
                if(bloc(px,py+21,mat)!='0' || bloc(px+19,py+21,mat)!='0')
                    py=20*int((py+10)/20);
                else py+=3;
            px+=vx;
            py+=vy;
            perso = rotozoomSurface(tank, an, 1.0, 1);
            pos_perso.y=py+10-perso->h/2;
            pos_perso.x=px+10-perso->w/2;
            SDL_BlitSurface(perso, NULL, ecran, &pos_perso);
            SDL_Flip(ecran);
            tempsActuel = SDL_GetTicks();
            if (tempsActuel - tempsPrecedent > 20)
            {
                tempsPrecedent = tempsActuel;
            }
            else
            {
                SDL_Delay(20 - (tempsActuel - tempsPrecedent));
            }
        }
        SDL_FreeSurface(block);
        SDL_FreeSurface(perso);
        SDL_FreeSurface(ice);
        SDL_Quit();
        return EXIT_SUCCESS;
    }
    Code balle.h : 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
    #ifndef DEF_BALLE
    #define DEF_BALLE
    class Balle
    {
        public:
        Balle();
        Balle(double x,double y);
        void update(SDL_Surface* ecran,int mat[][25]);
        private:
        double x;
        double y;
        double vy;
        double vx;
        int d;
        SDL_Surface* balle;
        SDL_Rect pos_balle;
    };
    #endif
    Code balle.cpp : 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
    #include "balle.h"
    using namespace std;
    Balle::Balle()
    {
        double x=50;
        double y=50;
        double vy=1;
        double vx=1;
        SDL_Surface* balle=IMG_Load("data/balle.png");
        pos_balle.x=this.x;
        pos_balle.y=this.y;
        int d=1000;
    }
    Balle::Balle(double m_x,double m_y,double m_vx,double m_vy)
    {
        double x=m_x;
        double y=m_y;
        double vy=m_vy;
        double vx=m_vx;
        SDL_Surface* balle=IMG_Load("data/balle.png");
        pos_balle.x=x;
        pos_balle.y=y;
        int d=1000;
    }
    void Balle::update(SDL_Surface* ecran,int mat[][25])
    {
     
    }
    merci a ceux qui peuvent m'aider

  2. #2
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2015
    Messages
    51
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2015
    Messages : 51
    Par défaut
    Salut !
    J'ai un peu du mal à lire ton code (manque de description et surtout pas d'espace) et je ne pense pas que cela t'aide beaucoup à trouver les différentes erreurs. Mais je vais quand même essayer de te donner les plus évidentes
    malgré le fait que je n'utilise pas SDL :p

    -"'SDL_Surface' has not been declared" : cela veut tout simplement dire que le compilateur ne trouve pas SDL_Surface et l'erreur apparaît dans le header de la balle. Le problème c'est que tu ne lui as pas dis qu'il a besoin de SDL_Surface. Il faut ajouter les includes de la SDL dans le .h de la balle (même chose pour IMG_load, SDL_Rect etc...).

    - "error: request for member 'x' in '(Balle*)this', which is of pointer type 'Balle*' (maybe you meant to use '->' ?)" : Ici on te donne la solution à ton problème lorsque tu utilise "this", ça te retourne un pointer et donc il faut utiliser
    "->" au lieu du "."

    -"error: prototype for 'Balle::Balle(double, double, double, double)' does not match any in class 'Balle'" : Tu n'as pas déclaré ce constructor dans le header de la classe Balle.

    La plupart sont des erreurs d'inattention, lorsque tu tombes sur autant de problème, résous les dans l'ordre !

  3. #3
    Expert éminent

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par défaut
    Et surtout, ton constructeur ne fais pas du tout ce que tu crois.

    D'un point de vue bassement matériel, une classe, c'est comme une structure: un ensemble de variables regroupées, auxquelles se joignent des fonctions dites "membres".
    (en C++, class et struct sont identiques à un détail près: la visibilité par défaut est private pour les class, et public pour les struct)

    Je reprends en la réduisant ta classe (et avec une présentation un minimum différent:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    class Balle {
    public:
        Balle();
        Balle(double x,double y);
     
    private:
        double x;
        double y;
        int d;
     
        SDL_Surface* balle;
        SDL_Rect pos_balle;
    };

    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
    Balle::Balle() {
        double x=50;
        double y=50;
        SDL_Surface* balle=IMG_Load("data/balle.png");
        pos_balle.x=this.x;
        pos_balle.y=this.y;
        int d=1000;
    }
     
    Balle::Balle(double m_x,double m_y,double m_vx,double m_vy)
    {
        double x=m_x;
        double y=m_y;
        double vy=m_vy;
        double vx=m_vx;
        SDL_Surface* balle=IMG_Load("data/balle.png");
        pos_balle.x=x;
        pos_balle.y=y;
        int d=1000;
    }
    première chose, il n'y a pas de magie.

    Balle::Balle() est une fonction membre, dans le corps de sa définition, this est un pointeur désignant l'objet sur laquelle la méthode a été appelée.
    en l'occurence c'est un constructeur, donc this désigne l'objet en cours de création.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Balle::Balle() {
        double x=50;
        double y=50;
        SDL_Surface* balle=IMG_Load("data/balle.png");
        pos_balle.x=this.x;
        pos_balle.y=this.y;
        int d=1000;
    }
    tu définis trois variables locales: x, y et balle.
    puis tu affectespos_balle.x avec this.x, et de même pour y. Avec deux erreurs: un, this étant un pointeur, this.x n'existe pas, c'est this->x, et deux, this->x n'est pas le x que tu viens de déclarer.
    et enfin tu définis d.

    A la fin de la fonction, x, y, balle et d sont rendues à la mémoire, car c'était des variables locales.
    Les variables membres de this n'ont pas été initialisées.

    La mauvaise "bonne solution" serait ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Balle::Balle() {
        this->x=50;
        this->y=50;
        this->balle=IMG_Load("data/balle.png");
        this->pos_balle.x = this->x;
        this->pos_balle.y = this->y;
        this->d=1000;
    }
    ou en version courte, parce que this est implicite:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Balle::Balle() {
        x=50;
        y=50;
        balle=IMG_Load("data/balle.png");
        pos_balle.x = x;
        pos_balle.y = y;
        d=1000;
    }
    Mais la bonne solution, c'est de passer explicitement par la liste d'initialisation.
    En effet, dans cette mauvaise "bonne solution", on initialise arbitrairement chaque variable membre, puis on remplace les valeurs par d'autres.

    La vraie bonne solution est donc:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Balle::Balle():
        x(50),
        y(50),
        balle( IMG_Load("data/balle.png") ),
        d(1000)
    {
        pos_balle.x = x;
        pos_balle.y = y;
    }
    Ici, les variables membres x, y, balle et d sont initialisées directement avec les bonnes valeurs, évitant l'appel aux opérateurs de copie, et les constructions par défaut inutiles.
    pos_balle doit être initialisée dans le corps car c'est une structure à la C, n'ayant pas de constructeur C++.
    Si ca avait été le cas, tu aurais pu écrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Balle::Balle():
        x(50),
        y(50),
        balle( IMG_Load("data/balle.png") ),
        d(1000),
        pos_balle(x, y)
    {}
    A présent, tu as beaucoup de soucis à te faire:
    • un pointeur est fragile, il convient de recourir à une capsule RAII, on en parlera quand tu auras posé tes questions
    • tu devrais vérifier que le chargement de l'image a réussi (via un if (!balle) throw std::runtime_error("échec de chargement de data/balle.png");)
    • Tu ne devrais pas dupliquer l'information, x et pos_balle.x n'ont aucune raison d'être différents, pourquoi avoir les deux. A moins d'avoir une transformation entre coordonnées dans le jeu et coordonnées à l'écran.

  4. #4
    Membre très actif Avatar de fifafou
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2016
    Messages
    173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 23
    Localisation : France, Seine Maritime (Haute Normandie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Janvier 2016
    Messages : 173
    Par défaut
    C'est bon, ça marche,merci beaucoup

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

Discussions similaires

  1. Réponses: 8
    Dernier message: 27/10/2015, 16h50
  2. Creation d'une class "proxy" pour un objet
    Par alexNe dans le forum C#
    Réponses: 2
    Dernier message: 09/11/2008, 21h41
  3. Réponses: 8
    Dernier message: 21/04/2007, 16h15
  4. recherche une classe KZtransImg pour delphi 7
    Par plante20100 dans le forum Composants VCL
    Réponses: 2
    Dernier message: 21/07/2005, 13h56
  5. Réponses: 11
    Dernier message: 01/09/2004, 19h04

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo