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

SDL Discussion :

[SDL] Création d'un shoot'em up type flying shark


Sujet :

SDL

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2012
    Messages : 11
    Points : 5
    Points
    5
    Par défaut [SDL] Création d'un shoot'em up type flying shark
    Bonsoir à toutes et à tous !

    Je viens poster ici car j'ai un petit soucis avec SDL et j'aimerais bien votre aide

    En fait, j'ai comme projet en cours de faire une sorte de Shoot'em Up genre Flying Shark. (D'ailleurs décidasse à tout les gens de B1 à Supinfo en galère qui tomberont sur ce thread.)

    J'arrive à faire défiler le background vers le bas, puis sur les cotés, pas de soucis. J'arrive aussi à déplacer mon avion dans tous les sens aussi.

    Sauf qu'avant de commencer à gérer le tir des missiles, j'aimerais faire un peu d'ordre dans mon main (car oui, tout est dans mon main), et par exemple, mettre la partie qui gère le clavier, dans une fonction a part, et appeler cette fonction dans mon main (histoire d'organiser un peu mon code).

    J'ai donc créé la fonction gestionClavier()
    Je vais vous mettre mon code :

    ini.h
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    #ifndef FONCTIONS_H  // Si FONCTIONS_H n'est pas défini...
    #define FONCTIONS_H  // On défini FONCTIONS_H
     
    #include <stdlib.h>
    #include <stdio.h>
    #include <SDL/SDL.h>
    #include <SDL/SDL_image.h>
    #include <windows.h>
     
    void gestionClavier(SDL_Surface *screen, SDL_Surface *background, SDL_Surface *airplane[], SDL_Surface *plane, SDL_Surface *ombre[], SDL_Surface *ombreActuelle, SDL_Rect positionAirplane, SDL_Rect cplane, SDL_Rect decoupe, int continuer);
    #endif // FONCTIONS_H

    gestionClavier.c
    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
    74
    75
    76
    77
    78
    79
    80
    81
    #include "ini.h" //prototypes
     
    void gestionClavier(SDL_Surface *screen, SDL_Surface *background, SDL_Surface *airplane[], SDL_Surface *plane, SDL_Surface *ombre[], SDL_Surface *ombreActuelle, SDL_Rect positionAirplane, SDL_Rect cplane, SDL_Rect decoupe, int continuer,Uint8 *keystates,SDL_Event event)
    {
        plane = airplane[0];
        ombreActuelle = ombre[0];
     
        SDL_PollEvent(&event);
     
        if (keystates[ SDLK_ESCAPE ] || event.type == SDL_QUIT)
        {
            continuer=0;
        }
     
        if (keystates[ SDLK_SPACE ])
        {
            //gestion du tir
        }
     
        if(keystates[SDLK_UP] || keystates[SDLK_w])
     
        {
            positionAirplane.y-=3;
            plane = airplane[1];
            ombreActuelle = ombre[1];
        }
     
        if(keystates[SDLK_RIGHT] || keystates[SDLK_d] && cplane.x + plane->w/2 < screen->w)
        {
            plane = airplane[2];
            ombreActuelle = ombre[2];
            if(cplane.x + plane->w/2 < screen->w)
                positionAirplane.x+=3;
        }
     
        if(keystates[SDLK_LEFT] || keystates[SDLK_a] && positionAirplane.x > 0)
        {
            plane = airplane[4];
            ombreActuelle = ombre[4];
            positionAirplane.x-=3;
        }
     
        if(keystates[SDLK_DOWN] || keystates[SDLK_s])
        {
            if(cplane.y < screen->h - plane->h) 
            {
                positionAirplane.y+=2;
            }
     
            if(keystates[SDLK_LEFT])
            {
                ombreActuelle = ombre[4];
                plane = airplane[5];
            }
     
            else if(keystates[SDLK_RIGHT])
            {
                ombreActuelle = ombre[2];
                plane = airplane[6];
            }
     
            else
            {
                ombreActuelle = ombre[3];
                plane = airplane[3];
            }
        }
     
        if(keystates[SDLK_LEFT] && cplane.x < 350 && decoupe.x > 0)
        {
            decoupe.x-=2;
            positionAirplane.x+=2;
        }
     
     
        if(keystates[SDLK_RIGHT] && cplane.x > 450 && decoupe.x < background->w - decoupe.w) 
        {
            decoupe.x+=2;
            positionAirplane.x-=2;
        }
    }
    et le main :

    main.c
    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
    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
    #include "ini.h"
     
    int main(int argc, char *argv[])
    {	
        /*VARIABLES*/
        int i = 0;
        int continuer = 1;
     
        SDL_Event event;
        SDL_Surface *airplane[7] = {NULL}, *ombre[5] = {NULL};
        SDL_Surface *screen = NULL, *background = NULL, *plane = NULL, *ombreActuelle = NULL;
        SDL_Rect positionBackground, positionAirplane, decoupe, cplane, positionOmbre;
        Uint8 *keystates = SDL_GetKeyState( NULL );
     
        positionBackground.x = 0;
        positionBackground.y = 0;
        cplane.x = 0;
        cplane.y = 0;
     
     
        /*PROGRAMME*/
     
        //Résolution 800x600 32bit double buffer permettant un rafraichissement fluide
        SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
        screen = SDL_SetVideoMode(800, 600, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
        //On donne un nom à notre fenêtre
        SDL_WM_SetCaption("Air Wars - Projet C", NULL);
     
        //On définit notre image de fond
        background = IMG_Load("img/map3.jpg");
        //On définit les images de l'avion
        airplane[0] = IMG_Load("img/aviondefault.png"); //Par defaut
        airplane[1] = IMG_Load("img/avionup.png"); //Quand on avance
        airplane[2] = IMG_Load("img/avionright.png"); //Quand on tourne à droite
        airplane[3] = IMG_Load("img/aviondown.png"); //Quand on recule
        airplane[4] = IMG_Load("img/avionleft.png"); //Quand on tourne à gauche
        airplane[5] = IMG_Load("img/aviondownleft.png"); //Quand on recule à gauche
        airplane[6] = IMG_Load("img/aviondownright.png"); //Quand on recule à droite
        plane = airplane[0];
        ombre[0] = IMG_Load("img/aviondefaultombre.png"); //Par defaut
        ombre[1] = IMG_Load("img/avionupombre.png"); //Quand on avance
        ombre[2] = IMG_Load("img/avionrightombre.png"); //Quand on tourne à droite
        ombre[3] = IMG_Load("img/aviondownombre.png"); //Quand on recule
        ombre[4] = IMG_Load("img/avionleftombre.png"); //Quand on tourne à gauche
     
        decoupe.x=background->w-screen->w-100; //le x de ta découpe, donc 0 puisque tu pars à gauche de ton image de fond.
        decoupe.y=background->h-screen->h; //y= la hauteur du fond moins la hauteur de ton ecran
        decoupe.h=screen->h; //la hauteur de découpe est égale à la hauteur de ton ecran
        decoupe.w=screen->w;// la largeur de la découpe 
        //Initialistion des coordonnées de l'avion
        positionAirplane.x = screen->w/2 - plane->w/2;
        positionAirplane.y = screen->h - plane->h;
     
     
        while (continuer)
        {
     
            //appelle de la fonction 
            gestionClavier(screen,background,airplane,plane,ombre,ombreActuelle,positionAirplane,cplane,decoupe,continuer,keystates,event);
     
     
     
     
            cplane.x = positionAirplane.x + plane->w/2;
            cplane.y = positionAirplane.y - plane->h/2;
     
     
            decoupe.y-=2;
     
            if(decoupe.y <= -background->h)
                decoupe.y=background->h;
     
     
            if(cplane.y < screen->h - plane->h) 
            {
                positionAirplane.y++;
            }
     
            positionOmbre.x = positionAirplane.x - 60;
            positionOmbre.y = positionAirplane.y + 75;
     
     
            SDL_BlitSurface(background, &decoupe, screen, &positionBackground);
            SDL_BlitSurface(plane, NULL, screen, &positionAirplane);
            SDL_BlitSurface(ombreActuelle, NULL, screen, &positionOmbre);
            SDL_Flip(screen);	
     
        }	
     
        //On libère les surfaces
        SDL_FreeSurface(background);
     
        for (i = 0 ; i < 7 ; i++)
        {
            SDL_FreeSurface(airplane[i]);
        }
     
        for (i = 0 ; i < 5 ; i++)
        {
            SDL_FreeSurface(ombre[i]);
        }
        //On ferme la fenètre
        SDL_Quit();
        return EXIT_SUCCESS;
    }

    Bon bien sûr l’appel ne fonctionne pas, il n'y a pas d'erreur mais quand le programme, on ne peut rien gérer au clavier du tout comme si la fonction n'existait pas, alors qu'elle est bien là et elle marche !

    Je pense que c'est dû au SDL_Rect, qu'on ne peux pas convertir en pointeur et donc, lorsque qu'on incrémente la positionAirplane, ça ne met pas à jour la véritable variable, mais plutôt une copie.

    Si vous avez des idées de comment faire ça serait génial...
    Car j'ai essayé beaucoup de chose sans succès, je commence à croire que c'est pas possible.

    Merci beaucoup !

  2. #2
    Expert éminent sénior
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 214
    Points : 10 140
    Points
    10 140
    Par défaut
    Alors un c'est déjà bien que tu vienne ici pour qu'on puisse d'aider et qu'on t'apprenne les vrai méthode

    Je vais pas de donner la solution directement mais quelque indice.
    Alors déjà ta fonction clavier est très mauvaise (trop arguments),bon et j'ai pas lu ton code mais une meilleur incrémentation le rendrais plus jolie.
    En fait il faut suivre une logique qu'on on creer une fonction , cette fonction doit être indépendante du programme.

    Alors indice , si tu veux rendre la fonction des évènements clavier indépendante il faut que cette fonction renvoie des booléens(et le mieux c'est de créer une structure qui prend toutes les variable de gérer clavier).

    Une autre fonction qui prend en argument SDL_Rect et la structure clavier , et qui modifiais la déplacement (fonction qui pourrais s’appellé gameplay).

    Apres la fonction qui affiche a écran.

    Voila (j'ai impression de donner un devoir info xD).
    Montre moi ton code je te dirai ou ça cloche si tu as du mal,mais si je te donne pas la solution c'est que c'est très important d'avoir cette pensée de programmation (histoire de sois apprendre a pêcher sois donner le poisson).

  3. #3
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Bonjour

    Citation Envoyé par MacMah0n Voir le message
    Je pense que c'est dû au SDL_Rect, qu'on ne peux pas convertir en pointeur et donc, lorsque qu'on incrémente la positionAirplane, ça ne met pas à jour la véritable variable, mais plutôt une copie.
    Cette phrase me fait penser que tu n'as pas compris les pointeurs (en l’occurrence, on ne convertit pas en pointeur, on créé un pointeur sur une structure). Je te conseille de lire un cours ou la faq sur le passage de paramètres aux fonctions

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2012
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    Merci pour vos réponses !
    Je pense avoir compris le principe de fonction indépendante mais je sais pas trop comment m'y prendre.

    J'ai pensé à quelque chose comme ça :

    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
     
    #include "ini.h" //prototypes
     
    typedef struct defClavier Booleen; 
     
    struct defClavier{
     
    	int up;
     
    	int right;
     
    	int down;
     
    	int left;
     
    	int tir;
     
    	int quit;
     
    };
     
     
    void gestionClavier()
    {		
    		Booleen clavier;
    		SDL_Event event;
    		Uint8 *keystates = SDL_GetKeyState( NULL );
    		SDL_PollEvent(&event);
     
     
     
     
    		if (keystates[ SDLK_ESCAPE ] || event.type == SDL_QUIT)
    		{
    			clavier.quit = 1;
    		}
     
    		if (keystates[ SDLK_SPACE ])
    		{
    			clavier.tir = 1;
    		}
     
    		if(keystates[SDLK_UP] || keystates[SDLK_w])
     
    		{
    			clavier.up = 1;
    		}
     
    		if(keystates[SDLK_RIGHT] || keystates[SDLK_d])
    		{
    			clavier.right = 1;	
    		}
     
    		if(keystates[SDLK_DOWN] || keystates[SDLK_s])
    		{
    			clavier.down = 1;	
    		}
     
    		if(keystates[SDLK_LEFT] || keystates[SDLK_a])
    		{
    			clavier.left = 1;
    		}
     
     
    }
    J'ai pas d'erreur mais bon... je sais pas si c'est vraiment ce qui faut faire.

  5. #5
    Expert éminent sénior
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 214
    Points : 10 140
    Points
    10 140
    Par défaut
    C'est vrai que gbdivers a raison maîtriser les pointeurs c'est important.
    Pour la fonction indépendante ,oui c'est pas évident c'est surtout la pratique qui te permettra de appréhender.

    C'est un bon début ta fonction est indépendante ^^
    Mais elle manque encore quelque chose pour etre encore utilisable ta structure Booleen clavier; , tu dois pas la déclarer a intérieur de ta fonction mais au dehors , ta fonction doit prendre en argument Booleen clavier; et un pointeur (pour pouvoir modifier les booléen) comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void gestionClavier(Booleen *clavier)
    { 
          //...
    }
    ou alors tu met un return Booleen.

    Apres des variable = 1;
    c'est bien mais il n'y a pas de remise a zero ?
    Sois tu met ta remise a zero au 'up' des touches , soit tu initialise des variable a zéro avant évènement (initialisation a zero reste dans ta fonction).
    Les deux déterminera un peu comment on 'utilise' cette touche , la premier le '1' restera tant qu'on reste appuyer si on relche la touche sera '0'.
    Le deuxième des qu'on appuie il sera '1' apres 0 donc ça sera seulement dans le down de la touche (ça oblige le joueur a marteler le clavier).

    Sinon autre 'erreur' , Booleen est un nom trop vague , ta Structure aurait du rester s’appeler Clavier.
    Moi j'aime pas ton 'ini.h' , on général on utilise pas les header de cette manière, un headers doit juste mettre les fonctions appelé (et les Defines) de ton fichier.

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2012
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    C'est ce que je me suis dit pour les pointeurs et d'ailleurs j'avais commencé à essayer.
    INI
    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
     
    #ifndef FONCTIONS_H  // Si FONCTIONS_H n'est pas défini...
    #define FONCTIONS_H  // On défini FONCTIONS_H
     
     
    #include <stdlib.h>
    #include <stdio.h>
    #include <SDL/SDL.h>
    #include <SDL/SDL_image.h>
     
    typedef struct defClavier Clavier; 
     
    struct defClavier{
     
    	int up,right,down,left,quit,tir;
     
    };
     
    #endif // FONCTIONS_H
    gestionClavier
    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
     
    #include "ini.h" //prototypes
     
    void gestionClavier(Clavier * clavier)
    {		
     
    		SDL_Event event;
    		Uint8 *keystates = SDL_GetKeyState( NULL );
    		SDL_PollEvent(&event);
     
     
    		clavier->quit=0;
    		clavier->up=0;
    		clavier->right=0;
    		clavier->down=0;
    		clavier->left=0;
     
    		if (keystates[ SDLK_ESCAPE ] || event.type == SDL_QUIT)
    		{ 
    			clavier->quit=1;
    		}
     
    		if (keystates[ SDLK_SPACE ])
    		{
    			clavier->tir = 1;
    		}
     
    		if(keystates[SDLK_UP] || keystates[SDLK_w])
     
    		{
    			clavier->up = 1;
    		}
     
    		if(keystates[SDLK_RIGHT] || keystates[SDLK_d])
    		{
    			clavier->right = 1;	
    		}
     
    		if(keystates[SDLK_DOWN] || keystates[SDLK_s])
    		{
    			clavier->down = 1;	
    		}
     
    		if(keystates[SDLK_LEFT] || keystates[SDLK_a])
    		{
    			clavier->left = 1;
    		}
     
     
    }

    MAIN
    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
     
    #include "ini.h"
     
    void gestionClavier(Clavier * clavier);
     
    int main(int argc, char *argv[])
    {	
    	/*VARIABLES*/
    	Clavier * clavier = NULL;
    	SDL_Surface *screen = NULL;
     
     
     
    	//Résolution 800x600 32bit double buffer permettant un rafraichissement fluide
    	SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
        screen = SDL_SetVideoMode(800, 600, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
    	//On donne un nom à notre fenêtre
        SDL_WM_SetCaption("Air Wars - Projet C", NULL);
     
    clavier->quit = 0;
    	 do
        {
     
     
    		gestionClavier(clavier);
    		if(clavier->down = 1)
    			printf("down !\n");
     
    	 }while(clavier->quit = 0);
     
     
    	//On ferme la fenètre
        SDL_Quit();
    	return EXIT_SUCCESS;
    }


    Ben le programme plante dès que je compile :/

  7. #7
    Membre expérimenté Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    625
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 625
    Points : 1 564
    Points
    1 564
    Par défaut
    Ben le programme plante dès que je compile :/
    Dès que l'exécutes, tu veux dire.
    Et c'est normal, clavier n'est pas initialisé:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Clavier * clavier = NULL;
    .
    .
    .
    clavier->quit = 0;
    Tu dois fournir un espace mémoire pour clavier, p.ex.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    clavier=malloc(sizeof Clavier);
    Attention: ceci n'initialise pas la zone que tu réserves.

    Et aussi (mais ça n'a rien à voir)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    if(clavier->down = 1)
    .
    .
    while(clavier->quit = 0);
    ne sont pas des tests, mais des assignations.
    On écrit "J'ai tort" ; "tord" est la conjugaison du verbre "tordre" à la 3ème personne de l'indicatif présent

  8. #8
    Expert éminent sénior
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 214
    Points : 10 140
    Points
    10 140
    Par défaut
    Oui tu dois réviser les pointeurs ^^'
    Parce que si tu savais ce que tu écris tu aurais remarqué que c'est plus que normal que ça marche pas.
    Quand tu écris
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Clavier * clavier = NULL
    C'est une adresse qui a la valeur NULL (donc adresse memoire zero)
    Quand tu exécute ton programme et que tu fais ceci

    Tu écris sur l'adresse mémoire de 0 ou un peu plus , et sur les OS un programme n'a pas le droit ecrire dans une autre adresse qui ne lui est pas alloué , et dans ton cas adresse NULL doit etre celui du systeme exploitation donc normal qu'il t'en refuse accès.

    Bon le malloc est de 'trop' je te conseillerais de utiliser comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    Clavier clavier;
    gestionClavier(&clavier);

  9. #9
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 860
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 860
    Points : 219 064
    Points
    219 064
    Billets dans le blog
    120
    Par défaut
    Bonjour,

    Je fais un peu hors sujet. Mais si c'est une reprise de Flying Shark, je dis super . Et qu'il faudra nous montrer le programme une fois fini (ou tout les programmes de la promo même ).

    Sinon, les réponses des autres membres devraient suffire. Juste un petit détail, pour diminuer le nombre de paramètre que l'on passe à une fonction, il suffit d'utiliser des structures (je crois que c'est bon ce coté là).
    De plus, n'oubliez pas le mot clé "enum" il est intéressant et bien pratique .

    Dans le ini.h

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    #include <stdlib.h>
    #include <stdio.h>
    #include <SDL/SDL.h>
    #include <SDL/SDL_image.h>
    N'est pas à mettre dans le .h (car non nécessaire dans le .h) mais dans le .cpp. Cela permet d'éviter que les include se répondent partout dans le programme alors qu'il ne sont pas nécessaire pour tous les fichiers incluant votre ini.h.

    Normalement, il y a un .h par .c

    Il faut vérifier les retours des fonctions (comme SDL_Init() / SDL_SetVideoMode()) afin d'être sur qu'il n'y a pas de problème ...


    Bonne continuation
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  10. #10
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2012
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    Merci à tous pour votre aide !
    J'ai commencé le C il y a quelques mois et on a eu que 3 semaines de cours dessus, et ça c'est notre deuxième projet (le premier était plus facile, c'était un Gomuko Ninuki sur la console Windows)... Alors les pointeurs c'est pas encore tout à fait ça, mais ça commence à rentrer, surtout depuis que vous êtes venu à la rescousse !

    Alors, la fonction qui gère le clavier marche niquel !

    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
     
    #include "ini.h"
     
    void gestionClavier(Clavier * clavier)
    {	
    	//Déclaration des variables
    	SDL_Event event;
    	Uint8 *keystates = SDL_GetKeyState(NULL);
    	SDL_PollEvent(&event);
     
    	//Réinitialisation de la touche à chaque fois qu'elle n'est plus appuyée.
    	clavier->up=0;
    	clavier->right=0;
    	clavier->down=0;
    	clavier->left=0;
    	clavier->tir=0;
    	clavier->quit=0;
     
    	//On vérifie si il n'y a pas un evènement sur le clavier et on met le booleen à 1 lorsque la touche est appuyée.
    	if (keystates[ SDLK_ESCAPE ] || event.type == SDL_QUIT)
    	{ 
    		clavier->quit=1;
    	}
     
    	if (keystates[ SDLK_SPACE ])
    	{
    		clavier->tir = 1;
    	}
     
    	if(keystates[SDLK_UP] || keystates[SDLK_w])
     
    	{
    		clavier->up = 1;
    	}
     
    	if(keystates[SDLK_RIGHT] || keystates[SDLK_d])
    	{
    		clavier->right = 1;	
    	}
     
    	if(keystates[SDLK_DOWN] || keystates[SDLK_s])
    	{
    		clavier->down = 1;	
    	}
     
    	if(keystates[SDLK_LEFT] || keystates[SDLK_a])
    	{
    		clavier->left = 1;
    	}
     
    }
    Dans ma lancer, j'ai donc aussi créer qui déplace l'avion : une réussite !
    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
     
    #include "ini.h"
     
    void gamePlay(Clavier * clavier, SDL_Rect * positionAirplane)
    {	
    	if(clavier->up == 1)
    		positionAirplane->y-=2;//L'avion accèlère.
    	if(clavier->right == 1)
    		positionAirplane->x+=2;//L'avion tourne à droite.
    	if(clavier->down == 1)
    		positionAirplane->y++;//L'avion ralentit.
    	if(clavier->left == 1)
    		positionAirplane->x-=2;//L'avion tourne à gauche.
    	if(clavier->tir == 1)
    		printf("tir !\n");//Partie tir à faire plus tard...
    }
    Jusque la je croyais que plus rien ne pouvais m'arrêter
    Sauf que je suis arrivé à la fonction qui gère l'affichage.
    Bon je voulais pas venir direct demander de l'aide du coup j'ai galéré 3 bonnes heures dessus ^^ Mais j'ai compris des choses au niveaux des pointeurs.
    Même si ça marche pas vraiment comme je le voudrais...
    En effet, l'avion et son ombre sont bien affichés, et l'image se modifie bien en fonction de la touche appuyée...
    Sauf que, lorsque qu'on appuie sur droite par exemple, l'avion tourne bien à droite et change d'image, sauf que quand on relâche la touche, l'avion reste sur l'image au lieu de revenir à l'image pas défaut... :/ (idem pour toutes les touches)

    Voici la fonction :
    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
     
    #include "ini.h"
     
    void gestionAffichage(Clavier * clavier, SDL_Surface * airplane[], SDL_Surface * ombre[], SDL_Surface * plane, SDL_Surface  * ombreActuelle)
    {	
     
     
    	if(clavier->up == 1)
    	{
    		*plane = *airplane[1];
    		*ombreActuelle = *ombre[1];
    	}
     
    	if(clavier->right == 1)
    	{
    		*plane = *airplane[2];
    		*ombreActuelle = *ombre[2];
    	}
     
    	if(clavier->down == 1)
    	{
    		*plane = *airplane[3];
    		*ombreActuelle = *ombre[3];
    	}
     
    	if(clavier->left == 1)
    	{
    		*plane = *airplane[4];
    		*ombreActuelle = *ombre[4];
    	}
     
            *plane = *airplane[0];
            *ombreActuelle = *ombre[0];
    }
    Et l'endroit où j'ai le plus galéré : le main !
    Pour l'appel de cette fonction, comprendre ce qu'il fallait mettre en paramètre alors que cette fois-ci, SDL_Surface était un pointeur. Mais j'ai compris
    INI.h
    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
     
    #ifndef FONCTIONS_H  // Si FONCTIONS_H n'est pas défini...
    #define FONCTIONS_H  // On défini FONCTIONS_H
     
    //Includes
    #include <stdlib.h>
    #include <stdio.h>
    #include <SDL/SDL.h>
    #include <SDL/SDL_image.h>
     
    //Structures
    typedef struct varClavier Clavier; 
     
    struct varClavier{
     
    	int up,right,down,left,quit,tir;
     
    };
     
    //Prototypes
    void gestionClavier(Clavier * clavier);
    void gamePlay(Clavier * clavier, SDL_Rect * positionAirplane);
    void gestionAffichage(Clavier * clavier, SDL_Surface * airplane[], SDL_Surface * ombre[], SDL_Surface * plane,SDL_Surface * ombreActuelle);
     
    #endif // FONCTIONS_H
    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
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
     
    #include "ini.h"
     
    int main(int argc, char *argv[])
    {	
    	/*VARIABLES*/
    	Clavier clavier;
    	int i=0;
    	SDL_Surface *airplane[7] = {NULL}, *ombre[5] = {NULL};
        SDL_Surface *screen = NULL, *background = NULL, *plane = NULL, *ombreActuelle = NULL;
        SDL_Rect positionBackground, positionAirplane, decoupe, cplane, positionOmbre;
    	positionBackground.x = 0;
        positionBackground.y = 0;
        cplane.x = 0;
        cplane.y = 0;
    	//Création de la fenêtre
    	SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER);
    	screen = SDL_SetVideoMode(800, 600, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
    	//On donne un nom à notre fenêtre
    	SDL_WM_SetCaption("Air Wars - Projet C", NULL);
    	 //On définit notre image de fond
        background = IMG_Load("img/map3.jpg");
        //On définit les images de l'avion
        airplane[0] = IMG_Load("img/aviondefault.png"); //Par defaut
        airplane[1] = IMG_Load("img/avionup.png"); //Quand on avance
        airplane[2] = IMG_Load("img/avionright.png"); //Quand on tourne à droite
        airplane[3] = IMG_Load("img/aviondown.png"); //Quand on recule
        airplane[4] = IMG_Load("img/avionleft.png"); //Quand on tourne à gauche
        airplane[5] = IMG_Load("img/aviondownleft.png"); //Quand on recule à gauche
        airplane[6] = IMG_Load("img/aviondownright.png"); //Quand on recule à droite
        plane = airplane[0];
        ombre[0] = IMG_Load("img/aviondefaultombre.png"); //Par defaut
        ombre[1] = IMG_Load("img/avionupombre.png"); //Quand on avance
        ombre[2] = IMG_Load("img/avionrightombre.png"); //Quand on tourne à droite
        ombre[3] = IMG_Load("img/aviondownombre.png"); //Quand on recule
        ombre[4] = IMG_Load("img/avionleftombre.png"); //Quand on tourne à gauche
    	ombreActuelle = ombre[0];
     
        decoupe.x=background->w-screen->w-100; //le x de ta découpe, donc 0 puisque tu pars à gauche de ton image de fond.
        decoupe.y=background->h-screen->h; //y= la hauteur du fond moins la hauteur de ton ecran
        decoupe.h=screen->h; //la hauteur de découpe est égale à la hauteur de ton ecran
        decoupe.w=screen->w;// la largeur de la découpe 
        //Initialistion des coordonnées de l'avion
        positionAirplane.x = screen->w/2 - plane->w/2;
        positionAirplane.y = screen->h - plane->h;
     
    	do
    	{	
    		gestionClavier(&clavier);
    		gestionAffichage(&clavier,airplane,ombre,plane,ombreActuelle);
    		gamePlay(&clavier,&positionAirplane);
     
    		//cplane.x = positionAirplane.x + plane->w/2;
           // cplane.y = positionAirplane.y - plane->h/2;
            decoupe.y-=2;
     
           // if(decoupe.y <= -background->h)
           //     decoupe.y=background->h;
     
     
           // if(cplane.y < screen->h - plane->h) 
           // {
           //     positionAirplane.y++;
           // }
     
    		positionOmbre.x = positionAirplane.x - 60;
           positionOmbre.y = positionAirplane.y + 75;
     
     
            SDL_BlitSurface(background, &decoupe, screen, &positionBackground);
            SDL_BlitSurface(plane, NULL, screen, &positionAirplane);
            SDL_BlitSurface(ombreActuelle, NULL, screen, &positionOmbre);
            SDL_Flip(screen);
    	 }while(clavier.quit == 0);
     
     
    	 //On libère les surfaces
        SDL_FreeSurface(background);
     
     
        for (i = 0 ; i < 7 ; i++)
        {
            SDL_FreeSurface(airplane[i]);
        }
     
        for (i = 0 ; i < 5 ; i++)
        {
            SDL_FreeSurface(ombre[i]);
        }
     
    	SDL_FreeSurface(ombreActuelle);
    	SDL_FreeSurface(plane);
        //On ferme la fenètre
        SDL_Quit();
        return EXIT_SUCCESS;
    }
    En plus de l'erreur que je vous expliquait de l'avion qui revient pas dans sa forme d'origine après le relâchement de la touche (ce qui doit encore être une histoire de pointeurs... --') j'ai aussi une erreur lorsque que je ferme le programme et qu'il arrive aux deux "for" à la fin :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     for (i = 0 ; i < 7 ; i++)
        {
            SDL_FreeSurface(airplane[i]);
        }
     
        for (i = 0 ; i < 5 ; i++)
        {
            SDL_FreeSurface(ombre[i]);
        }
    Le programme plante quand on le ferme en fait ^^'

    Pour répondre à LittleWhite, merci pour ton message !
    J'essaierais de récolter les jeux de ma classe une fois fini.
    Il devrait en avoir 3/4

    Oui j'ai bien compris le système de structure, c'est franchement super pratique :') Mais comme les paramètres à passer ici sont pour beaucoup des structure SDL, ça ne joue pas beaucoup (pour le moment!) !

    Oui j'ai vu ce fameux enum, qui risque d'être fort pratique pour rendre le code plus clair, je verrais ça plus tard !

    Niveau des headers je vais essayé de voir si je peux pas en créer un par fonction

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    #include <stdlib.h>
    #include <stdio.h>
    #include <SDL/SDL.h>
    #include <SDL/SDL_image.h>
    Enlever ça de mon ini.h ? Et le mettre au début de tout les sous-programmes qui en ont besoin? A vrai dire j'ai pas vraiment compris le vrai but des headers a part éviter de recopier le même code dans tous les sous-programmes ?


    Merci à tous et bonne nuit

  11. #11
    Expert éminent sénior
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 214
    Points : 10 140
    Points
    10 140
    Par défaut
    Alors c'est déjà bien que tu as assimilé certaine base de prog et avoir compris comment doit être utiliser une fonction.
    On s'enflamme toujours au début après quand on remarque un mur ça eteint notre flamme.

    De mon point de vue (on tous de je que je lis) , je me demande comment image peut bien changer vu que les modification ne doivent pas etre pris en compte vu que a la fin tu met
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    *plane = *airplane[0];
    *ombreActuelle = *ombre[0];
    L'autre point le gameplay doit se faire avant affichage.
    Tu met Clavier *clavier en pointeur ,mais quelquefois c'est inutile dans le sens ou tu modifie rien.
    gbdivers avait incrémenter ton code , et j’espère que pour le prochain code du main tu incrémente comme il faudra ce code.
    Le but du header et de dire dans ce fichier , on appelle tel fonction et on utilise tel Define.

    PS: pour coder le tir tu vas souffrir

  12. #12
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 860
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 860
    Points : 219 064
    Points
    219 064
    Billets dans le blog
    120
    Par défaut
    Je reviens un peu à la charge, pour cette fois conseiller les assertions.

    Pour l'image de l'avion qui ne se remet pas en plus, c'est surement car vous ne définissez pas l'image de défaut lorsque aucune touche n'est appuyée (bon, dit comme cela, ce n'est peut être pas totalement juste pour votre architecture).

    Les en-têtes (.h) servent à indiquer l'existence de fonction / structure au reste d'un programme. Son but premier n'est pas d'éviter la copie, mais de donner accès à des fonctions en les rendant "visible". C'est dans le sens, que si on respecte la règle de ne jamais inclure un .c, si la déclaration n'est pas dans le .h, cette fonction ne sera visible que dans le .c courant et dans aucun autre.

    Finalement, si vous avez un crash, il est utile d'utiliser le débogueur (gbd ou celui intégré à votre EDI) ou même valgrind (pour tout ce qui est problème de mémoire).
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  13. #13
    Membre expérimenté Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    625
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 625
    Points : 1 564
    Points
    1 564
    Par défaut
    Ce n'est pas dans tes deux boucles for que ton programme se plante en sortie, c'est dans
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SDL_FreeSurface(ombreActuelle);
    SDL_FreeSurface(plane);
    Comme ombreActuelle est une copie d'une adresse de ombre[x] et que plane est une copie d'une adresses de airplane[x], ET que celles-ci ont déjà été libérées dans les boucles for....
    On écrit "J'ai tort" ; "tord" est la conjugaison du verbre "tordre" à la 3ème personne de l'indicatif présent

  14. #14
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2012
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    Bonjour !

    Citation Envoyé par Kannagi Voir le message
    On s'enflamme toujours au début après quand on remarque un mur ça eteint notre flamme.


    J'ai compris le fait d'utiliser les pointeurs seulement quand la fonction doit pouvoir changer la valeur de la variable. D'ailleurs je l'ai laissé en pointeur seulement dans gestionClavier et le reste j'ai juste appeler les booleen de clavier et ça marche aussi bien

    Par contre que je mette ou pas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    *plane = *airplane[0];
    *ombreActuelle = *ombre[0];
    ou même que si je met tout dans des else if et la réinitialisation dans le else final, ça fait EXACTEMENT PAREIL.

    Du coup je suppose que le problème est dans le passage des paramètres...

    Ce n'est pas dans tes deux boucles for que ton programme se plante en sortie, c'est dans
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SDL_FreeSurface(ombreActuelle);
    SDL_FreeSurface(plane);
    Comme ombreActuelle est une copie d'une adresse de ombre[x] et que plane est une copie d'une adresses de airplane[x], ET que celles-ci ont déjà été libérées dans les boucles for....
    Justement si c'est une copie, ne faut t'il pas supprimer l'original et la copie puisque c'est stocké à différent endroit de la mémoire ?
    De plus si j'enlève ça ne change rien, par contre, si je n’appelle pas ma fonction affichage, le fait de quitter ne plante pas. Donc ça confirme ma théorie du fait que c'est dans le passage des paramètres de cette fonction qu'il y a le soucis... Pourtant c'est de la seule façon que mon debugger me permet de le faire :/


    LittleWhite, cette fonction permet justement de vérifier si les paramètres sont bien transmis ? Je ne comprends pas trop comment l'utiliser.

    PS: pour coder le tir tu vas souffrir
    J'ai déjà essayé, et j'ai réussis à tirer 1 missile ! Mais je pouvais en envoyer un seul car il rechargeais le même a chaque fois xD
    Après j'ai lu qu'il fallait faire ça avec les listes chaînées (pire que les pointeurs ) du coup j'ai essayé de faire ça maison avec un tableau... Sans succès ! C'est pour ça que je suis venu ici pour d'abord rendre mon code propre et pratique et ensuite pour demander une petite aide sur les listes chaînées et cette gestion des tirs.... MAIS chaque chose en son temps :/

  15. #15
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 860
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 860
    Points : 219 064
    Points
    219 064
    Billets dans le blog
    120
    Par défaut
    Pour la copie des SDL_Surface* et des pointeurs dans un cas général.
    Lorsque vous faites :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SDL_Surface* pS1 = IMG_Load(...); 
    SDL_Surface* pS2 = pS1;
    Seul les pointeurs sont copiés. Je m'expliquer. SDL_Surface est une structure. Un pointeur est une variable qui indique où lire les données.
    Lorsque l'on copie un pointeur, la structure n'est pas copié, seule son adresse est copiée (la flèche pointant sur la structure).
    Si je ne me fais pas clair, il faudra lire un cours

    Pour conclure, l'image en elle même n'est pas copiée, du coup, vous avez deux variables indiquant la même image.
    Si vous détruisez la première image, le deuxième pointeur ne sera plus valide car il pointera sur une image détruite (segfault).


    Pour les assertions, cela permet de vérifier entre autre, que les pointeurs ne sont pas NULL lorsqu'il sont passé à la fonction. Car un pointeur NULL n'est pas utilisable. Ainsi, si vous vérifiez avec les assertions, vous pouvez débogué plus rapidement le cas où vous passer NULL par inadvertance.
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  16. #16
    Expert éminent sénior
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 214
    Points : 10 140
    Points
    10 140
    Par défaut
    Si vous détruisez la première image, le deuxième pointeur ne sera plus valide car il pointera sur une image détruite (segfault).
    Detruire c'est assez vaste comme terme ,je préfère plutôt dire en fait quand on libère une mémoire ,et que tu pointe dessus , cette adresse ne fait plus partie du programme donc le système exploitation arrête ton programme ( un programme n'a pas le droit écrir/lire au delà de sa mémoire alloué).

    ou même que si je met tout dans des else if et la réinitialisation dans le else final, ça fait EXACTEMENT PAREIL.

    Du coup je suppose que le problème est dans le passage des paramètres...
    On fait je me demande quand tu fais *plane = *airplane[0]; est correct j'ai fait un test et j'ai bien je que je pensais.

    Quand on fait *plane = *airplane[0]; on pointe vers les valeurs , mais pas sur les adresses , donc il faut copier les adresse donc plane = airplane[0]; est correct mais cela modifiera adresse que pendant la fonction.

    Donc tu dois faire un double pointeur sur SDL_Surface **plane et puis écrire *plane = airplane[0];
    bon moi j'aurais pas fait cela trop de pointeur x)

    J'aurais faite que affichage appel SDL_BlitSurface en fonction des conditions ou de mettre des variables et après ces variable on affiche la bonne image.

    Pour le tir les liste chaîné sont pas nécessaire , enfin moi j'utilise un tableau , mais il faudra bien 'joué' dans le sens ou il faudra faire un tri correct,et garder la vitesse des tir , bref c'est surtout que tu vas souffrir parce que c'est un vrai casse tete.

  17. #17
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 860
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

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

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 860
    Points : 219 064
    Points
    219 064
    Billets dans le blog
    120
    Par défaut
    Je viens de me rendre compte d'un autre détail.
    Pour des SDL_Surface* et aussi dangereux, car la structure contient un pointeur sur les pixels. Ce pointeur est, comme je l'ai expliqué précédemment, copier tel quel, mais pas les données pointées. Ainsi, même faire comme cela, pour des SDL_Surface est faux.

    Je crois que la SDL possède une fonction spéciale pour la copie de SDL_Surface.

    La liste chainées permet le dynamisme. Seul problème c'est que la liste chainée va provoquer une série de malloc() / free() dans la boucle principale du jeu. Ce qui est fortement déconseillé (car les appels système sont lents).
    Du coup, je suis pour un tableau simple alloué dès le début et assez grand pour gérer les bullets (500 devrait suffire, je crois)
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  18. #18
    Expert éminent sénior
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 214
    Points : 10 140
    Points
    10 140
    Par défaut
    Citation Envoyé par LittleWhite Voir le message
    Je crois que la SDL possède une fonction spéciale pour la copie de SDL_Surface.
    Il veut copier les adresse pas la structure (et puis ça sera lourd comme procédé a mon avis).
    Donc comme je l'ai dit il faut faire un double pointeur , mais vu qu'il galère un peu sur les pointeurs , je lui conseiller appeler SDL_Blit directement dans sa fonction.

  19. #19
    Membre expérimenté Avatar de edgarjacobs
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2011
    Messages
    625
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 64
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Mai 2011
    Messages : 625
    Points : 1 564
    Points
    1 564
    Par défaut
    Comme ombreActuelle est une copie d'une adresse de ombre[x] et que plane est une copie d'une adresses de airplane[x], ET que celles-ci ont déjà été libérées dans les boucles for....
    Justement si c'est une copie, ne faut t'il pas supprimer l'original et la copie puisque c'est stocké à différent endroit de la mémoire ?
    Non, c'est une copie d'une adresse mémoire, pas une copie de ce qui se trouve à cette adresse.

    ombre[x] pointe sur une une zone mémoire. Cette zone mémoire est structurée dans le format donné par la structure SDL_Surface. Dans cette zone mémoire, se trouve une adresse, gérée par la SDL (n'entrons pas dans les détails), qui indique où sont stockés les bits composants l'image.

    Quand tu fais ombreActuelle=ombre[x], ombreActuelle pointe également sur cette même zone mémoire.

    Quand tu fais SDL_FreeSurface(ombre[x]), cette zone mémoire est détruite, l'adresse qui se trouvait dans cette zone mémoire et qui indiquait où se trouvaient les bits de ton image, est détruite également, ainsi que la zone mémoire où étaient stockés les bits de ton image.

    Par conséquent, quand SDL_FreeSurface(ombreActuelle) est exécutée à son tour, elle se retrouve avec des adresses aberrantes... et ton programme prend la voie express pour la sortie.

    Edgar.

    Pour les puristes, on remplacera à volonté détruite par libérée ou rendue au système
    On écrit "J'ai tort" ; "tord" est la conjugaison du verbre "tordre" à la 3ème personne de l'indicatif présent

  20. #20
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Février 2012
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 30
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2012
    Messages : 11
    Points : 5
    Points
    5
    Par défaut
    Bonjour à tous, j'espère que votre dimanche se passe bien vous

    Réveillé très tôt ce matin par une sale bestiole du type des arachnides, je n'ai pas vraiment pu me rendormir. (Je déteste ces petits trucs, c'est super mesquin ).
    Bref, soyons positif j'en ai profité pour bosser mon code, et bonne nouvelle, toutes mes fonctions marchent super bien. Je compile, aucune erreurs ni avertissements, le jeu se lance et je peux déplacer mon avion et les images changent bien en fonction des mouvements ! Merci pour tous vos messages qui m'ont vraiment aidés !

    gestionClavier(), gamePlay() et gestionAffichage().
    Mon main commence à être assez joli !

    J'ai voulu alors, continuer sur ma lancée de l'organisation de mon code et, j'ai voulu créer une fonction qui allait charger au début du programme toutes les images.

    Alors je vais la nommer loadImage().
    J'ai commencé et j'ai réussis quand même à faire un truc assez incroyable pour moi. Utiliser un double pointeur. (Bon ok, je pense que ça a fonctionner totalement par pur hasard mais pourtant dans ma tête c'était logique )

    Alors la voici cette fonction :
    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
     
    #include "ini.h"
     
    void loadImages(SDL_Surface ** background,SDL_Surface ** airplane[],SDL_Surface ** ombre[]){
     
        //On charge notre image de fond.
    	*background = IMG_Load("img/map3.jpg");
     
        //On charge les images de l'avion.
        *airplane[0] = IMG_Load("img/aviondefault.png"); //Par defaut
        *airplane[1] = IMG_Load("img/avionup.png"); //Quand on avance
        *airplane[2] = IMG_Load("img/avionright.png"); //Quand on tourne à droite
        *airplane[3] = IMG_Load("img/aviondown.png"); //Quand on recule
        *airplane[4] = IMG_Load("img/avionleft.png"); //Quand on tourne à gauche
        *airplane[5] = IMG_Load("img/aviondownleft.png"); //Quand on recule à gauche
        *airplane[6] = IMG_Load("img/aviondownright.png"); //Quand on recule à droite
     
        *ombre[0] = IMG_Load("img/aviondefaultombre.png"); //Par defaut
        *ombre[1] = IMG_Load("img/avionupombre.png"); //Quand on avance
        *ombre[2] = IMG_Load("img/avionrightombre.png"); //Quand on tourne à droite
        *ombre[3] = IMG_Load("img/aviondownombre.png"); //Quand on recule
        *ombre[4] = IMG_Load("img/avionleftombre.png"); //Quand on tourne à gauche
     
    }
    Le prototype :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    void loadImages(SDL_Surface ** background,SDL_Surface ** airplane[],SDL_Surface ** ombre[]);
    Et mon main (simplifié) :
    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
     
    int main(int argc, char *argv[])
    {	
    	/*VARIABLES LOCALES*/
    	SDL_Surface *airplane[7] = {NULL}, *ombre[5] = {NULL};
    	SDL_Surface *background = NULL *plane = NULL;
     
    	loadImages(&background,&airplane[],&ombre[]);
    	plane = airplane[0];
    	do
    	{	
    		//Le blitte de l'avion et de l'ombre se fait normalement dans la fonction gestionAffichage(), mais la c'est seulement pour tester.
    		SDL_BlitSurface(plane, NULL, screen, &positionAirplane);
     
    		SDL_BlitSurface(background, &camera, screen, &positionBackground);
    		SDL_Flip(screen);	
     
     
    	 }while(clavier.quit == 0);
     
    }
    Bon j'arrive à afficher le background sans problème
    C'est donc l'avion et son nombre que je n'arrive pas afficher.
    Et c'est sans doute dû au fait que ça soit des tableau...
    Et que les tableau, on ne les mets pas en paramètre n'importe comment.
    J'ai fais quelques recherches, il parait qu'il faut utiliser malloc.
    Et comme c'est pas super conseillé, j'attend votre avis.
    J'ai essayer de mon côté aussi, à défaut de passer par un tableau, de passer par une structure. Ce qui donnait quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    airplane->defaut = IMG_Load("img/aviondefault.png");
    etc..

    Sauf que ça n'a pas marché, car c'était peine perdu à mon avis :p
    Donc je suis revenu aux tableaux, mais bon. On va dire que ça ne marche pas mieux

Discussions similaires

  1. Réponses: 2
    Dernier message: 03/06/2012, 23h32
  2. Création d'une interface graphique de type carrousel
    Par bydavy dans le forum Composants graphiques
    Réponses: 11
    Dernier message: 09/03/2012, 13h58
  3. [PHP 5.4] Création d'une zone de texte type word
    Par toinou62 dans le forum Langage
    Réponses: 1
    Dernier message: 05/06/2009, 10h58
  4. [Lazarus] Création d'index multiples tables de type dBase
    Par ovni76 dans le forum Lazarus
    Réponses: 7
    Dernier message: 13/04/2009, 14h33
  5. Création d'une boite de dialogue type MessageBox
    Par kurkaine dans le forum C++Builder
    Réponses: 8
    Dernier message: 25/10/2006, 11h45

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