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 Jean B . Évalué à 3.
[^] # Re: Commence par utiliser une Paste
Posté par lmg . Évalué à 1.
Voila voila :) : http://friendpaste.com/7IEnuOZ75mK7RAcEDOvjke
Mais pas moyen de trouver comment éditer mon premier message...
[^] # Re: Commence par utiliser une Paste
Posté par Jean B . Évalué à 2.
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 lmg . Évalué à 1.
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 Jean B . Évalué à 2.
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 Jean B . Évalué à 2.
serpent->w
qui provoque le segfault.
[^] # Re: Commence par utiliser une Paste
Posté par Jean B . Évalué à 2.
http://friendpaste.com/7IEnuOZ75mK7RAcEDOvjke L133
Par contre il y en a une autre plus loin.
[^] # Re: Commence par utiliser une Paste
Posté par lmg . Évalué à 1.
[^] # Re: Commence par utiliser une Paste
Posté par Jean B . Évalué à 2.
Ça m'apprendras a chercher des erreurs de dèv sans essayer de comprendre le but du code.
Donc chez moi ça segfault tout simplement car SDL_LoadBMP("serpent.bmp"); renvoie un pointeur nil, vu que je n'ai pas le .bmp.
[^] # Re: Commence par utiliser une Paste
Posté par lmg . Évalué à 1.
Mais sinon, pas d'autres commentaires plus généraux?
[^] # Re: Commence par utiliser une Paste
Posté par lmg . Évalué à 1.
Il me reste toujours le problème du plantage à la collision, et puis vous pouvez toujours poster pour donner des commentaires sur mon code (il doit être très perfectible, car je débute).
[^] # Re: Commence par utiliser une Paste
Posté par Le Pnume . Évalué à 1.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.