Forum Programmation.c Snake en SDL

Posté par  .
Étiquettes : aucune
0
25
juin
2009

Bonjour à tous,

Pourriez vous me donner vos avis et conseils sur le code suivant? C'est le début d'un snake en SDL.

Et de plus deux petites questions:
-Tout d'abord concernant l'affichage d'une image lors de la collision, le programme plante.
-Ensuite sur le fait que si j'execute le binaire compilé par codeblocks en dehors de cet IDE, il me sort une belle erreur de segmentation.

Voila voila, place au code source. Désolé pour le manque de commentaires, je me ferais un plaisir de commenter toute partie difficilement compréhensible. (j'ai du rajouter des espaces sur les inclusions)


#include < stdio.h >
#include < stdlib.h >
#include < DL.h >
#include "main.h"
#include < string.h >
#define TAILLEMAX 2000
enum {BAS, DROITE, HAUT, GAUCHE};

int main(int argc, char* argv[])
{
SDL_Surface *ecran, *serpent, *boum, *tete[4];
char titre[20] = "Snake";

demarreSdl(&ecran, titre);

initialise(ecran, &serpent, &boum, tete);

evenements(ecran, serpent, boum, tete);

fermeSdl(serpent, boum);
return 0;
}

void demarreSdl(SDL_Surface **ecran, char titre[])
{
if(SDL_Init(SDL_INIT_VIDEO) == -1)
{
fprintf(stderr, "Erreur d'initialisation de la SDL : %s\n", SDL_GetError()); // Ecriture de l'erreur
exit(EXIT_FAILURE); // On quitte le programme
}
SDL_WM_SetIcon(SDL_LoadBMP("ico.bmp"), NULL);
*ecran = SDL_SetVideoMode(640, 480, 32, SDL_HWSURFACE | SDL_RESIZABLE | SDL_DOUBLEBUF);
if(*ecran == NULL)
{
fprintf(stderr, "Impossible de charger le mode vidéo: %s\n", SDL_GetError());
}
SDL_WM_SetCaption(titre, NULL);
SDL_EnableKeyRepeat(1, 1);
}

void fermeSdl(SDL_Surface *serpent, SDL_Surface *boum)
{
SDL_FreeSurface(serpent);
SDL_FreeSurface(boum);
SDL_Quit();
}

void evenements(SDL_Surface *ecran, SDL_Surface *serpent, SDL_Surface *boum, SDL_Surface *tete[])
{
int continuer =1, direction=BAS, taille=5, i=0;
SDL_Event evenement;
SDL_Rect positionSerpent[TAILLEMAX];
initialiseSerpent(positionSerpent, serpent, ecran, taille);
i=100;
while (continuer)
{
SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 2, 100, 40));

blitteSerpent(serpent, ecran, positionSerpent, taille, direction, tete);
SDL_Flip(ecran);

if(i==100)
{
decalePositions(positionSerpent, taille);
avanceSerpent(serpent, positionSerpent, direction);
i=0;
}
else
{
i++;
}

if(SDL_PollEvent(&evenement))
{
switch(evenement.type)
{
case SDL_KEYDOWN:
switch(evenement.key.keysym.sym)
{
case SDLK_RIGHT:
if(direction != GAUCHE)
direction = DROITE;
break;
case SDLK_LEFT:
if(direction != DROITE)
direction = GAUCHE;
break;
case SDLK_UP:
if(direction != BAS)
direction = HAUT;
break;
case SDLK_DOWN:
if(direction != HAUT)
direction = BAS;
break;
case SDLK_PLUS:
case SDLK_p:
if(taille
taille++;
break;
case SDLK_MINUS:
case SDLK_m:
if(taille>0)
taille--;
break;
case SDLK_ESCAPE:
continuer = 0;
break;
default:
break;
}
break;
case SDL_QUIT:
continuer =0;
break;
default: break;
}
}

if(cogne(positionSerpent, ecran, taille))
{
perdu(boum, ecran, positionSerpent);
continuer =0;
}
}
}

void initialise(SDL_Surface *ecran, SDL_Surface **serpent, SDL_Surface **boum, SDL_Surface *tete[])
{
int i=0;
char nom[10];
SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 2, 100, 40));
*serpent = SDL_LoadBMP("serpent.bmp");
*boum = SDL_LoadBMP("boum.bmp");
for(i=0; i
{
sprintf(nom, "tete%d.bmp", i);
tete[i]= SDL_LoadBMP(nom);
}
}

void initialiseSerpent(SDL_Rect positionSerpent[], SDL_Surface *serpent, SDL_Surface *ecran, int taille)
{
int i=0;
for(i=0; i
{
positionSerpent[i].x = ((ecran->w)/2)-((serpent->w)/2);
positionSerpent[i].y = ((ecran->h/2)-(serpent->h/2));
}
}

void blitteSerpent(SDL_Surface *serpent, SDL_Surface *ecran, SDL_Rect positionSerpent[], int taille, int direction, SDL_Surface *tete[])
{
int i;
SDL_Rect positionTete;
positionTete.x = positionSerpent[0].x;
positionTete.y = positionSerpent[0].y;
switch(direction)
{
case BAS:
positionTete.x = positionSerpent[0].x+tete[0]->w-serpent->w;
SDL_BlitSurface(tete[0], NULL, ecran, &positionTete);
break;
case DROITE:
positionTete.y = positionSerpent[0].y+tete[1]->h-serpent->h;
SDL_BlitSurface(tete[1], NULL, ecran, &positionTete);
break;
case HAUT:
positionTete.y = positionSerpent[0].y-tete[2]->h+serpent->h;
SDL_BlitSurface(tete[2], NULL, ecran, &positionTete);
break;
case GAUCHE:
positionTete.x = positionSerpent[0].x-tete[3]->w+serpent->w;
SDL_BlitSurface(tete[3], NULL, ecran, &positionTete);
break;
}
for(i=1; i
{
SDL_BlitSurface(serpent, NULL, ecran, &positionSerpent[i]);
}
}

void decalePositions(SDL_Rect positionSerpent[], int taille)
{
int i;
for(i=1; i
{
positionSerpent[TAILLEMAX-i].x = positionSerpent[TAILLEMAX-i-1].x;
positionSerpent[TAILLEMAX-i].y = positionSerpent[TAILLEMAX-i-1].y;
}
}

void avanceSerpent(SDL_Surface *serpent, SDL_Rect positionSerpent[], int direction)
{
switch(direction)
{
case BAS:
positionSerpent[0].y+=serpent->h+1;
break;
case DROITE:
positionSerpent[0].x+=serpent->w+1;
break;
case HAUT:
positionSerpent[0].y-=serpent->h+1;
break;
case GAUCHE:
positionSerpent[0].x-=serpent->w+1;
break;
}
}

int cogne(SDL_Rect positionSerpent[], SDL_Surface *ecran, int taille)
{
if(positionSerpent[0].x = ecran->w || positionSerpent[0].y= ecran->h)
{
return 1;
}
else if(surSerpent(positionSerpent, taille))
{
return 1;
}
else
{
return 0;
}
}

int surSerpent(SDL_Rect positionSerpent[], int taille)
{
int resultat=0, i;
for(i=1; i
{
if(positionSerpent[0].x == positionSerpent[i].x && positionSerpent[0].y == positionSerpent[i].y)
{
resultat = 1;
}
}
return resultat;
}

void perdu(SDL_Surface *boum, SDL_Surface *ecran, SDL_Rect positionSerpent[])
{
SDL_Rect position;
printf("Out !!%d\n", positionSerpent[0].x);
position.x=ecran->w/2-boum->w/2;
position.y=ecran->h/2-boum->h/2;
printf("%d, %d:%d", SDL_BlitSurface(boum, NULL, ecran, &position), position.x, position.y);
}
  • # Commence par utiliser une Paste

    Posté par  . Évalué à 3.

    • [^] # Re: Commence par utiliser une Paste

      Posté par  . Évalué à 1.

      Volontiers !

      Voila voila :) : http://friendpaste.com/7IEnuOZ75mK7RAcEDOvjke

      Mais pas moyen de trouver comment éditer mon premier message...
      • [^] # Re: Commence par utiliser une Paste

        Posté par  . Évalué à 2.

        Bon déjà j'ai perdu pas mal de temps a déclarer les entêtes de tes fonctions pour que ça compile. Comment à tu put compiler sans ça d'ailleurs ???

        Ensuite tu fait un include de main.c. WTF ?

        Et enfin pour ton erreur de segmentation. (si jamais tu ne sait pas ce que c'est les deux premières lignes de Erreur_de_segmentation te l'expliqueront)
        http://friendpaste.com/1Mp0rKqgCePj2hXLYDysoh
        J'ai placé deux puts(), je te laisse tirer les conclusions sur l'emplacement de l'erreur.


        Sinon pour les conseils etc plus généraux j'ai pas vraiment eu le temps de lire en détail ton code, donc j'ai pas grand chose a dire si ce n'est que je suis partisant du code en anglais. Mais je pense pas que c'est le genre de commentaires que tu attend.
        • [^] # Re: Commence par utiliser une Paste

          Posté par  . Évalué à 1.

          Merci d'y avoir jeté un œil!

          En fait je fais un include de main.H, et c'est ici que se trouvent mes entetes, qui m'encombraient un peu. Désolé de ne pas l'avoir précisé. (Voici une paste avec ce fichier http://friendpaste.com/7RSkBGZYHt4MeUQgA1W4kc qui corespond avec ce que tu as marqué.)

          D'autre part, si si, je sais très bien ce que c'est qu'une erreur de segmentation mais je ne m'explique pas qu'elle n'arrive que en dehors de codeblocks... Je ne vois d'ailleurs pas ce que tu reproche à ma boucle for :)

          Le code en anglais... Why not ! je le modifierais peut-être....
          • [^] # Re: Commence par utiliser une Paste

            Posté par  . Évalué à 2.

            D'autre part, si si, je sais très bien ce que c'est qu'une erreur de segmentation mais je ne m'explique pas qu'elle n'arrive que en dehors de codeblocks...
            C'est effectivement curieux. Je n'ai pas d'explication a te proposer. Peut tu récupérer les arguments de compilation de codeblock ?

            Je ne vois d'ailleurs pas ce que tu reproche à ma boucle for :)
            Moi rien ;). Par contre comme l'attestent mes deux puts c'est bien dans cette boucle que se trouve ton segfault.

            Donc pour une raison qui m'est encore inconnue quand tu/je compile sans codeblocks le tableau "positionSerpent" n'est pas correctement alloué, d'ou le segfault.

            Maintenant je suis pas spécialement un expert ès C/SDL donc c'est peut être une erreur fréquente.
          • [^] # Re: Commence par utiliser une Paste

            Posté par  . Évalué à 1.

            c'est juste un Heisenbug [[http://fr.wikipedia.org/wiki/Heisenbug]]

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.