Rebonjour a vous tous, vous m'avez conseillé d'utilisé les listes chainées pour mon problème de queue.
J'ai décidé de vous écoutez, et oui c'est rare^^.
Seulement voila, j'ai un problème pour l'initialisation.
Voici mon fichier qui inclut les 2 typedef ainsi que la fonction d'initialisation
typedef struct Element Element;
struct Element
{
SDL_Rect positionQueue;
Element *suivant
};
typedef struct Liste Liste;
struct Liste
{
Element *premier;
};
Liste *initialisation()
{
Liste *liste = malloc(sizeof(*liste));
Element *element = malloc(sizeof(*element));
if(liste == NULL || element == NULL)
exit(EXIT_FAILURE);
element->positionQueue = 0;
element->suivant = NULL;
liste->premier = element;
return liste;
}
J'ai une erreur a la ligne
element->positionQueue = 0;^^
http://cpp-rendering.io : Vous trouverez tout ce dont vous avez besoin sur Vulkan / OpenGL et le rendu 3D !
Tout dépend du comment tu l'utilise. Et puis ce n'est pas uniquement pour des piles infinies de données qu'on utilise les listes.
Pour un jeu de ce genre, j'aurais vu les choses dans l'architecture suivante :
- une liste appelé serpent.
- chaque partie du serpent connait sa position, sa vitesse de déplacement, sa direction (si elle bouge), pourquoi pas le chemin de l'image qui sera chargée, la référence de la partie en amont et en aval...
- dans mon main je n'aurais que quelques fonction qui concidèrent complètement transparent le fait de connaitre le type de l'objet en question sur l'écran et qui se contentent simplement de :
- rafraichir les positions (en fonction des vitesse, des direction et des positions).
- mettre à jour l'affichage.
Je ne vais pas citer toute l'architecture mais le principe est là
chaque partie du serpent connait sa position, sa vitesse de déplacement, sa direction (si elle bouge), pourquoi pas le chemin de l'image qui sera chargée, la référence de la partie en amont et en aval...
Tout ce traitement est inutile, je pense.
Pourquoi à tout prix vouloir déplacer le corps alors qu'il est immobile?
Seul la tête et la queue, sont dynamiques.
Sinon voila, j'ai creer mes fonctions ajouter en tete qui a l'air de fonctionner, et supprimer en fin, mais j'ai un problème, je ne suis pas sur de ma méthode^^
void ajouterEnTete(Liste *liste, SDL_Rect position)
{
Element *nouveau = malloc(sizeof(*nouveau));
if(liste == NULL || nouveau == NULL)
exit(EXIT_FAILURE);
nouveau->positionQueue.x = position.x;
nouveau->positionQueue.y = position.y;// on modifie
nouveau->suivant = liste->premier;
liste->premier = nouveau;//element prend la place de premier
}
void supprimerEnFin(Liste *liste, SDL_Rect position)
{
if(liste == NULL)
exit(EXIT_FAILURE);
Element *elementADepiler;
if(elementADepiler->suivant == NULL)// si l'element suivant pointe sur null alors c'est le dernier donc on le vire
{
free(elementADepiler);
}
while(elementADepiler->suivant != NULL);// on parcours jusque element a depiler soit le dernier et on le supprimme
free(elementADepiler);
}
http://cpp-rendering.io : Vous trouverez tout ce dont vous avez besoin sur Vulkan / OpenGL et le rendu 3D !
Tout ce traitement est inutile, je pense.
Pourquoi à tous pris vouloir déplacer le corps alors qu'il est immobile?
Seul la tête et la queue, sont dynamiques.
Quand tu as affaire à un virage tu es bien obliger de faire bouger le corp de ton serpent de façon "non-uniforme", je veux dire par là que tu auras une partie qui va continuer à avancer dans l'ancienne direction jusqu'à arriver à la position de la tête quand on a changé de direction, ce qui t'impose de découper ton serpent en éléments unitaires.
Si tu regardes bien un jeu de snake, tu remarque que les déplacements se font case par case.
Le déplacement se fait uniquement en effaçant la queue et en plaçant la tête au bon endroit.
Tu n'as pas à t'occuper du virage.
Comment "Mapper" ta fenêtre est une autre question C'est bien évidemment ce qu'il y a de plus simple à faire, mais ça ne dispense pas le fait qu'on ait besoin de connaitre la vitesse et la position (que ce soit en pixel ou rapporter à l'echelle de la map de la fenêtre) .
J'ai pas compris comment utiliser les listes chainées pour ma queue
Si tu n'es pas à l'aise avec les listes je pense que ce ne sera pas forcément bénéfique pour toi d'utiliser cette méthode. Sinon je te conseille de faire quelques exercices qui se rapportent aux listes chainnées avant de continuer ton code.
Autrement demande à GurneyH s'il veut bien développer son idée pour toi (vu qu'il a l'aire d'être contre cette méthode).
Bas j'ai essayer avec un tableau, mais ca ne marche pas^^, donc j'ai appris les listes chainées^^, je sais a peu pres les utilisés, mais je ne sais pas si mes fonctions sont bonnes déja, et comment utiliser les position pour la queue, si tu veux m'aider pour les tableauxs, il faut répondre sur mon ancien poste^^
http://cpp-rendering.io : Vous trouverez tout ce dont vous avez besoin sur Vulkan / OpenGL et le rendu 3D !
Je veux bien sinon regarde ce code, et dit moi ce qui ne fonctionne pas s'il te plait.
for(v=0; v<taille; v++)// on commence une boucle
{
if(snakeActu == snake[DROITE])
{
if(v == 0)// si v = 0 on place le premier tronceau
{
positionQueue[v].x = (positionJoueur.x - 1) * TAILLE_CASE;//si a droite on place le premier morceau
positionQueue[v].y = (positionJoueur.y) * TAILLE_CASE;
}
else// si c superieur a 0
{
positionQueue[v].x = positionQueue[v-1].x - 1;//position queue prend la place x - 1 de l'autre
positionQueue[v].y = positionQueue[v-1].y;
}
}
else if(snakeActu == snake[GAUCHE])//si a gauche on place le premier morceau
{
if(v==0)
{
positionQueue[v].x = (positionJoueur.x + 1) * TAILLE_CASE;
positionQueue[v].y = (positionJoueur.y) * TAILLE_CASE;
}
else
{
positionQueue[v].x = positionQueue[v-1].x + 1;
positionQueue[v].y = positionQueue[v-1].y;
}
}
else if(snakeActu == snake[HAUT])//si en haut on place le premier morceau
{
if(v==0)
{
positionQueue[v].x = (positionJoueur.x) * TAILLE_CASE;
positionQueue[v].y = (positionJoueur.y + 1) * TAILLE_CASE;
}
else
{
positionQueue[v].x = positionQueue[v-1].x;
positionQueue[v].y = positionQueue[v-1].y + 1;
}
}
else if(snakeActu == snake[BAS])//si en bas on place le premier morceau
{
if(v==0)
{
positionQueue[v].x = (positionJoueur.x) * TAILLE_CASE;
positionQueue[v].y = (positionJoueur.y - 1) * TAILLE_CASE;
}
else
{
positionQueue[v].x = positionQueue[v-1].x;
positionQueue[v].y = positionQueue[v-1].y - 1;
}
}
}
http://cpp-rendering.io : Vous trouverez tout ce dont vous avez besoin sur Vulkan / OpenGL et le rendu 3D !
#include <sdl/sdl.h>
#include <time.h>
/* Dimensions de la grille de jeu */
#define W 50
#define H 50
/* Taille maximale du serpent */
#define MAX_LEN (W * H)
/* Taille en pixel d'un morceau du serpent */
#define NODE_SIZE 10
/* Nombre de directions */
#define N_DIR 4
/* Une structure pour stocker les coordonnées de la tête de la queue */
typedef struct pos
{
int lin, col;
} Pos;
typedef struct snake
{
/* direction actuelle */
int dir;
/* indice de la tête et de la queue dans notre tableau */
int hd, tl;
/* file implémentée sous forme de tableau */
Pos nodes[MAX_LEN];
/* Indique si le snake grandit ou pas */
SDL_bool grow;
/* Le sanke est mort ? */
SDL_bool dead;
} Snake;
/* Contenu possbile pour une case de la grille */
enum {EMPTY, SNAKE, APPLE};
/* Directions possibles, pour clarifier la gestion des touches */
enum {UP, RIGHT, DOWN, LEFT};
void Snake_init( Snake *snk, int ( *grd )[W] );
SDL_bool Snake_alive( Snake *snk, int ( *grd )[W] );
void Snake_move( Snake *snk, int ( *grd )[W] );
void Game_init( Snake *snk, int ( *grd )[W] );
void Game_newApple( int ( *grd )[W] );
void Game_display( int ( *grd )[W] );
/* Game --------------------------------------------------------------------- */
void Game_init( Snake *snk, int ( *grd )[W] )
{
Snake_init( snk, grd );
Game_newApple( grd );
}
/* Place une pomme dans la grille en prenant garde de na pas la
* placer sur le serpent.
* La méthode est très laide...
*/
void Game_newApple( int ( *grd )[W] )
{
int lin, col;
do
{
lin = rand() % H;
col = rand() % W;
} while( grd[lin][col] != EMPTY );
grd[lin][col] = APPLE;
}
/* On affiche simplement le contenu de la grille à l'ecran */
void Game_display( int ( *grd )[W] )
{
int lin, col;
SDL_Surface *screen = SDL_GetVideoSurface();
SDL_FillRect( screen, NULL, 0 );
for( lin = 0; lin < H; lin++ )
{
for( col = 0; col < W; col++ )
{
if( grd[lin][col] != EMPTY )
{
SDL_Rect dst;
dst.x = NODE_SIZE * col + 1;
dst.y = NODE_SIZE * lin + 1;
dst.w = NODE_SIZE - 1;
dst.h = NODE_SIZE - 1;
if( grd[lin][col] == SNAKE )
SDL_FillRect( screen, &dst, SDL_MapRGB( screen->format, 255, 255, 255 ) );
if( grd[lin][col] == APPLE )
SDL_FillRect( screen, &dst, SDL_MapRGB( screen->format, 255, 0, 0 ) );
}
}
}
}
/* Snake -------------------------------------------------------------------- */
/* On initialise tous les champs de notre structure */
void Snake_init( Snake *snk, int ( *grd )[W] )
{
Pos startPos;
/* Au début du jeu, bah la tête c'est la queue ! */
snk->hd = 0;
snk->tl = 0;
snk->dead = SDL_FALSE;
snk->grow = SDL_FALSE;
/* Le milieu de l'ecran */
startPos.lin = H / 2;
startPos.col = W / 2;
/* On place la tête dans la grille */
grd[startPos.lin][startPos.col] = SNAKE;
/* On renseigne les coordonnées de la tête */
snk->nodes[snk->hd] = startPos;
/* On choisi une direction au hasard */
snk->dir = rand() % N_DIR;
}
/* On teste si tête du snake est dans les limites de la grille et qu'il ne
* se mange pas.
*/
SDL_bool Snake_alive( Snake *snk, int ( *grd )[W] )
{
int lin = snk->nodes[snk->hd].lin;
int col = snk->nodes[snk->hd].col;
return lin >= 0 && lin < H
&& col >= 0 && col < W
&& grd[lin][col] != SNAKE;
}
/* Déplacement du serpent */
void Snake_move( Snake *snk, int ( *grd )[W] )
{
/* Nos 4 directions
* Chaque direction est représentée par un couple lin, col
*/
static const Pos dir[N_DIR] = {{ -1, 0}, {0, 1}, {1, 0}, {0, -1}};
/* Position actuelle de la tête */
Pos hdPos = snk->nodes[snk->hd];
/* Position actulle de la queue */
Pos tlPos = snk->nodes[snk->tl];
if( !snk->grow )
{
/* Le serpent ne grandit pas
* on efface l'ancienne queue */
grd[tlPos.lin][tlPos.col] = EMPTY;
/* On avance dans la file circulaire
* % MAX_LEN pour resté dans l'intervalle [0, MAX_LEN[ */
snk->tl = ( snk->tl + 1 ) % MAX_LEN;
}
else
{
/* Le serpent grandit, la queue reste en place */
/* il ne grandira pas 2 fois de suite */
snk->grow = SDL_FALSE;
}
/* On avance la tête, dans la file circulaire */
snk->hd = ( snk->hd + 1 ) % MAX_LEN;
/* On calcule la nouvelle position de la tête */
hdPos.lin += dir[snk->dir].lin;
hdPos.col += dir[snk->dir].col;
snk->nodes[snk->hd] = hdPos;
if ( Snake_alive( snk, grd ) )
{
/* La nouvelle position de la tête est valide */
if( grd[hdPos.lin][hdPos.col] == APPLE )
{
/* On a mangé une pomme */
/* Le serpent grandira au tour prochain */
snk->grow = SDL_TRUE;
/* On place une nouvelle pomme */
Game_newApple( grd );
}
/* On place un morceau de serpent au coordonnées de la nouvelle tête
* dans la grille
*/
grd[hdPos.lin][hdPos.col] = SNAKE;
}
else
{
/* La case n'est pas valide
* -> couic le snake
*/
snk->dead = SDL_TRUE;
}
}
int main( int argc, char *argv[] )
{
SDL_Surface *screen;
Uint8 *keys;
Snake snake;
static int grid[H][W];
if( SDL_Init( SDL_INIT_VIDEO ) < 0 )
{
fprintf( stderr, "%s\n", SDL_GetError() );
exit ( EXIT_FAILURE );
}
screen = SDL_SetVideoMode( W * NODE_SIZE, H * NODE_SIZE, 32, SDL_SWSURFACE );
if( screen == NULL )
{
fprintf( stderr, "%s\n", SDL_GetError() );
exit ( EXIT_FAILURE );
}
srand( ( unsigned )time( NULL ) );
keys = SDL_GetKeyState( NULL );
Game_init( &snake, grid );
while( !SDL_QuitRequested() && !snake.dead )
{
SDL_PumpEvents();
if( keys[SDLK_LEFT] )
snake.dir = LEFT;
else if( keys[SDLK_RIGHT] )
snake.dir = RIGHT;
else if( keys[SDLK_UP] )
snake.dir = UP;
else if( keys[SDLK_DOWN] )
snake.dir = DOWN;
Snake_move( &snake, grid );
Game_display( grid );
/* La flemme de faire une gestion de fps */
SDL_Delay( 40 );
SDL_Flip( screen );
}
/* Pour éviter un warning */
(void)argc;
(void)argv;
SDL_Quit();
return EXIT_SUCCESS;
}
J'ai tenté de commenter les points plus ou moins obscurs.
qnope: je regarderais pour ton problème.
Beaucoup de répétitions tout de même.
Sans vouloir t'offencer, je trouve que tu n'es pas très clair dans tes codes^^ car la j'ai rien compris, meme si j'ai un petit niveau, je ne comprend rien a ton code^^
http://cpp-rendering.io : Vous trouverez tout ce dont vous avez besoin sur Vulkan / OpenGL et le rendu 3D !
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
Objectif Zéro Bug - le test logiciel professionnel | L'électronique de zéro | Tableaux & pointeurs | Pointeurs sur fonctions | Lecture/écriture binaire
Tu initialises tout d'un coup à 0 (ou a NULL pour les pointeurs).
Objectif Zéro Bug - le test logiciel professionnel | L'électronique de zéro | Tableaux & pointeurs | Pointeurs sur fonctions | Lecture/écriture binaire
Objectif Zéro Bug - le test logiciel professionnel | L'électronique de zéro | Tableaux & pointeurs | Pointeurs sur fonctions | Lecture/écriture binaire
Objectif Zéro Bug - le test logiciel professionnel | L'électronique de zéro | Tableaux & pointeurs | Pointeurs sur fonctions | Lecture/écriture binaire
Objectif Zéro Bug - le test logiciel professionnel | L'électronique de zéro | Tableaux & pointeurs | Pointeurs sur fonctions | Lecture/écriture binaire
Objectif Zéro Bug - le test logiciel professionnel | L'électronique de zéro | Tableaux & pointeurs | Pointeurs sur fonctions | Lecture/écriture binaire