cs_snake57
Messages postés204Date d'inscriptionvendredi 19 novembre 2004StatutMembreDernière intervention 1 novembre 2011
-
4 mars 2009 à 19:41
cs_snake57
Messages postés204Date d'inscriptionvendredi 19 novembre 2004StatutMembreDernière intervention 1 novembre 2011
-
14 mars 2009 à 21:10
Bonjour, j'ai un petit problème avec un prog que je suis entrain de faire.
C'est la première fois que j'utilse la SDL et les pointeurs donc je galère un peu.
Voici mon code :
const int tailleCarre=20; // Taille d'un carré en pixel.
const int nbrCarreLigneTotal=22; // Nombre de carré composant la hauteur du plateau.
const int nbrCarreColonneTotal=11; // Nombre de carré composant la largeur du plateau.
const int tailleEcranLargeur=800; // Taille de la largeur de la fenêtre de jeu (en pixel).
const int tailleEcranHauteur=600; // Taille de la hauteur de la fenêtre de jeu (en pixel).
const int tailleEspaceCarre=1; // Taille de l'espace entre les différents carré (en pixel).
SDL_Surface *ecran = NULL; // Le pointeur qui va stocker la surface de l'écran.
SDL_Surface *carre = NULL; // Les formes sont composées de plusieurs carrés mis cote a cote.
SDL_Rect *positionCarre = NULL;
SDL_Event event; // La variable contenant l'évènement
int continuer=1; //Variable qui permettra de sortir du programme dès qu'elle passera a 0.
int i,j;
SDL_Init(SDL_INIT_VIDEO);
ecran = SDL_SetVideoMode(tailleEcranLargeur, tailleEcranHauteur, 32, SDL_HWSURFACE| SDL_DOUBLEBUF); // On ouvre une fenêtre, SDL_HWSURFACE : les données seront chargées dans la mémoire vidéo, mode double buffering.
if (ecran == NULL) // Si l'ouverture a échoué, on écrit l'erreur et on arrête.
{
fprintf(stderr, "Impossible de charger le mode vidéo : %s\n", SDL_GetError());
exit(EXIT_FAILURE);
}
SDL_WM_SetCaption("Tetris", NULL); // Mettre "Tetris" comme nom de la fenêtre.
carre = (SDL_Surface*) malloc(nbrCarreLigneTotal * nbrCarreColonneTotal * sizeof(SDL_Surface));
if (carre == NULL) // On vérifie si l'allocation a marché ou pas
{
exit(EXIT_FAILURE); // On arrête tout
}
positionCarre =(SDL_Rect*) malloc(nbrCarreLigneTotal * nbrCarreColonneTotal * sizeof(SDL_Rect));
if (positionCarre == NULL) // On vérifie si l'allocation a marché ou pas
{
exit(EXIT_FAILURE); // On arrête tout
}
for (i=0; i<nbrCarreLigneTotal; i++) // création des carrés, mise encouleur des carres de bord, définition de l'emplacement des carrés.
{
for (j=0; j<nbrCarreColonneTotal; j++)
{
carre+i*nbrCarreColonneTotal+j = SDL_CreateRGBSurface(SDL_HWSURFACE, tailleCarre, tailleCarre, 32, 0, 0, 0, 0); // On creer les carré.
SDL_FillRect(carre+i*nbrCarreColonneTotal+j, NULL, SDL_MapRGB(ecran->format, 128, 128, 128)); // On choisit la couleur de fond des carré.
positionCarre+i*nbrCarreColonneTotal+j->x = j*tailleCarre+j*tailleEspaceCarre;
positionCarre+i*nbrCarreColonneTotal+j->y = i*tailleCarre+i*tailleEspaceCarre;
}
}
Enfait j'ai 3 erreurs de compil dans ma double boucle for:
la première est au niveau du SDL_CreateRGBSurface, le compilo me dit "error: non-lvalue in assignment".
les deux autres sont sur les deux dernieres ligne des boucles for, le compilo me dis "error: base operand of `->' is not a pointer".
Pour la première je vois pas trop ce que c'est le pb, les autres je pense que c'est a cause des pointeurs mais je vois pas quoi faire.
Le soucis que tu as c'est que la tu écris un peu nimporte où en mémoire (un pointeur représente une adresse de la mémoire) et même si le programme passait la compilation tu aurais surement une erreur fatale au lancement.
Sinon pour résoudre ton probleme tu peut utiliser des tableau de pointeur pour carre et positionCarre.
Il faudrait que tu arrives à ce genre de ligne :
au lieu de "positionCarre+i*nbrCarreColonneTotal+j->x" tu devrais avoir un truc du genre "positionCarre[i*nbrCarreColonneTotal+j]->x"
The_Snail
Messages postés21Date d'inscriptionmardi 18 janvier 2005StatutMembreDernière intervention 6 mars 2009 5 mars 2009 à 16:53
Salut,
Après modif ça donne un truc du genre :
#include "sdl.h"
#include <stdio.h>
int main(int argc, char** argv)
{
const int tailleCarre=20;
const int nbrCarreLigneTotal=22;
const int nbrCarreColonneTotal=11;
const int tailleEcranLargeur=800;
const int tailleEcranHauteur=600;
const int tailleEspaceCarre=1;
SDL_Surface *ecran;
SDL_Surface *carre[nbrCarreColonneTotal][nbrCarreLigneTotal]; // on utilise un tableau à 2 entrées
SDL_Rect positionCarre[nbrCarreColonneTotal][nbrCarreLigneTotal]; // idem
SDL_Event event;
int continuer=1;
int i,j;
printf("Creation de la fenetre\n");
ecran = SDL_SetVideoMode(tailleEcranLargeur, tailleEcranHauteur, 16, SDL_HWSURFACE|SDL_DOUBLEBUF);
if (ecran == NULL)
{
fprintf(stderr, "Impossible de charger le mode vidéo : %s\n", SDL_GetError());
exit(EXIT_FAILURE);
}
SDL_WM_SetCaption("Tetris", NULL);
printf("Creation de la grille\n");
for (i = 0; i < nbrCarreColonneTotal; i++) // i colonne
{
for (j = 0; j < nbrCarreLigneTotal; j++) // j ligne
{
carre[i][j] = SDL_CreateRGBSurface(SDL_HWSURFACE, tailleCarre, tailleCarre, 32, 0, 0, 0, 0); // On creer les carré.
printf("ajout couleur\n");
SDL_FillRect(carre[i][j], NULL, SDL_MapRGB(ecran->format, 128, 128, 128)); // On choisit la couleur de fond des carré.
positionCarre[i][j].x = i*tailleCarre+i*tailleEspaceCarre; // position x du carre
positionCarre[i][j].y = j*tailleCarre+j*tailleEspaceCarre; // position y du carre
}
}
printf("Boucle principale\n");
while(continuer == 1)
{
while (SDL_PollEvent(&event))
{
// check for messages
switch (event.type)
{
// exit if the window is closed
case SDL_QUIT:
continuer = 0;
break;
// check for keypresses
case SDL_KEYDOWN:
{
// exit if ESCAPE is pressed
if (event.key.keysym.sym == SDLK_ESCAPE)
continuer = 0;
break;
}
} // end switch
}
cs_snake57
Messages postés204Date d'inscriptionvendredi 19 novembre 2004StatutMembreDernière intervention 1 novembre 2011 5 mars 2009 à 19:30
oui the_snail cela fonctionne, mais plus tard j'aurais besoin de passer mon tableau "carre" et "positioncarre" a des fonctions.
Si elle sont déclaré de la sorte est ce que c'est possible?
SDL_Surface *carre[nbrCarreColonneTotal][nbrCarreLigneTotal]; // on utilise un tableau à 2 entrées
SDL_Rect positionCarre[nbrCarreColonneTotal][nbrCarreLigneTotal]; // idem
Si c'est possible tu peux juste me donner un exemple de ce que sa donnerais si par ex je voulais mettre cette partie dans une fonction :
for (i = 0; i < nbrCarreColonneTotal; i++) // i colonne
{
for (j = 0; j < nbrCarreLigneTotal; j++) // j ligne
{
carre[i][j] = SDL_CreateRGBSurface(SDL_HWSURFACE, tailleCarre, tailleCarre, 32, 0, 0, 0, 0); // On creer les carré.
printf("ajout couleur\n");
SDL_FillRect(carre[i][j], NULL, SDL_MapRGB(ecran->format, 128, 128, 128)); // On choisit la couleur de fond des carré.
positionCarre[i][j].x = i*tailleCarre+i*tailleEspaceCarre; // position x du carre
positionCarre[i][j].y = j*tailleCarre+j*tailleEspaceCarre; // position y du carre
}
}
Voila si tu avais le temps pour me montrer sa, sa serait sympa ;)
The_Snail
Messages postés21Date d'inscriptionmardi 18 janvier 2005StatutMembreDernière intervention 6 mars 2009 6 mars 2009 à 17:09
Salut,
Oui il est possible de passer des tableaux en paramètre à des fonctions et c'est très simple. Voici ce que ça donne (sur le code précédent j'avais inversé les indice de tableau par rapport à toi donc je les ai remis comme toi mais ça change rien à leur utilisation) :
int main(int argc, char** argv)
{
const int tailleEcranLargeur = 800; // Taille de la largeur de la fenêtre de jeu (en pixel).
const int tailleEcranHauteur = 600; // Taille de la hauteur de la fenêtre de jeu (en pixel).
SDL_Surface *ecran; // Le pointeur qui va stocker la surface de l'écran.
SDL_Surface *carre[nbrCarreLigneTotal][nbrCarreColonneTotal]; // Les formes sont composées de plusieurs carrés mis cote a cote.
SDL_Rect positionCarre[nbrCarreLigneTotal][nbrCarreColonneTotal];
SDL_Event event; // La variable contenant l'évènement
int continuer=1; //Variable qui permettra de sortir du programme dès qu'elle passera a 0.
printf("Creation de la fenetre\n");
ecran = SDL_SetVideoMode(tailleEcranLargeur, tailleEcranHauteur, 16, SDL_HWSURFACE|SDL_DOUBLEBUF); // On ouvre une fenêtre, SDL_HWSURFACE : les données seront chargées dans la mémoire vidéo, mode double buffering.
if (ecran == NULL) // Si l'ouverture a échoué, on écrit l'erreur et on arrête.
{
fprintf(stderr, "Impossible de charger le mode vidéo : %s\n", SDL_GetError());
exit(EXIT_FAILURE);
}
SDL_WM_SetCaption("Tetris", NULL); // Mettre "Tetris" comme nom de la fenêtre.
printf("Creation de la grille\n");
createMap(carre, positionCarre, ecran);
printf("Boucle principale\n");
while(continuer == 1)
{
while (SDL_PollEvent(&event))
{
// check for messages
switch (event.type)
{
// exit if the window is closed
case SDL_QUIT:
continuer = 0;
break;
// check for keypresses
case SDL_KEYDOWN:
{
// exit if ESCAPE is pressed
if (event.key.keysym.sym == SDLK_ESCAPE)
continuer = 0;
break;
}
} // end switch
}
// Affichage des carres
drawSquare(ecran, carre, positionCarre);
SDL_Flip(ecran);
}
return 0;
}
int drawSquare(SDL_Surface* ecran, SDL_Surface* carre[][nbrCarreColonneTotal], SDL_Rect positionCarre[][nbrCarreColonneTotal])
{
int i, j;
for (i = 0; i < nbrCarreLigneTotal; i++)
{
for (j = 0; j < nbrCarreColonneTotal; j++)
{
if((SDL_BlitSurface(carre[i][j], 0, ecran, &positionCarre[i][j]) == -1))
{
fprintf(stderr, "Erreur avec SDL_BlitSurface : %s\n",SDL_GetError());
return -1;
}
}
}
return 0;
}
void createMap(SDL_Surface* carre[][nbrCarreColonneTotal], SDL_Rect positionCarre[][nbrCarreColonneTotal], SDL_Surface* ecran)
{
int i, j;
for (i = 0; i < nbrCarreLigneTotal; i++) // création des carrés, mise encouleur des carres de bord, définition de l'emplacement des carrés.
{
for (j = 0; j < nbrCarreColonneTotal; j++)
{
carre[i][j] = SDL_CreateRGBSurface(SDL_HWSURFACE, tailleCarre, tailleCarre, 32, 0, 0, 0, 0); // On creer les carré.
SDL_FillRect(carre[i][j], NULL, SDL_MapRGB(ecran->format, 128, 128, 128)); // On choisit la couleur de fond des carré.
positionCarre[i][j].x = j*tailleCarre+j*tailleEspaceCarre;
positionCarre[i][j].y = i*tailleCarre+i*tailleEspaceCarre;
}
}
}
Alors pour commencer j'ai supprimer quelques unes de tes variable constantes pour les mettre en "define" puisque qu'elle n'ont pas lieu d'être modifiés dans le programme.
Pour le passage de tableau en argument d'une fonction, tu n'est pas obligé de mettre la taille du premier indice mais pour les autres la taille est obligatoire. De plus lorsque tu écris "SDL_Surface* carre[][nbrCarreColonneTotal]", nbrCarreColonneTotal ne doit pas être une variable d'où l'interet de le mettre en define.
Vous n’avez pas trouvé la réponse que vous recherchez ?
cs_snake57
Messages postés204Date d'inscriptionvendredi 19 novembre 2004StatutMembreDernière intervention 1 novembre 2011 6 mars 2009 à 20:37
ok, mais moi je voulais placer les fonctions dans des fichers différents pas dans le main.
En faisant comme tu as dis je suis obligé de déclarer "#define nbrCarreColonneTotal 11" a chaque que je fais un fichier avec une fonction qui prend SDL_Surface* carre[][nbrCarreColonneTotal] en paramètre.
Je trouve pas sa super pratique.
Y'aurais pas moyen d'avoir une fonction qui prend en paramètre l'adresse du premier carré "SDL_Surface* carre" et qui calcul les adresse des carrés suivant en utilisant les variables des boucles?
Pour ensuite utiliser cette adresse calculé dans le SDL_FillRect?
cs_snake57
Messages postés204Date d'inscriptionvendredi 19 novembre 2004StatutMembreDernière intervention 1 novembre 2011 6 mars 2009 à 20:41
En clair sa donnerais un truc du genre la:
void modifCouleur(int nbrLigne, int nbrColonne, SDL_Surface *carre, SDL_Surface *ecran)
{
int i, j;
for (i = 0; i < nbrLigne; i++)
{
for (j = 0; j < nbrColonne; j++)
{
carre=carre+i*nbrColonne+j;
SDL_FillRect(carre, NULL, SDL_MapRGB(ecran->format, 128, 128, 128)); // On choisit la couleur de fond des carré.
}
}
}
La la compil passe mais le prog plante :((( et c'est justement en truc dans le genre la que je voudrais faire.
// Definition des constantes
#define nbrCarreColonneTotal 11
#define nbrCarreLigneTotal 22
#endif
// Fin du fichier constantes.h
et ce fichier tu l'inclus dans tous tes ficiers C qui ont besoin des constantes avec cette ligne
#include "constantes.h"
Si cette methode ne te plais pas, le seul moyen que je vois, c'est d'utiliser des pointeurs double et triple à la place des tableaux et d'allouer la memoire dynamiquement et la dans la fonction tu as juste à passer par les pointeur mais c'est assez galère je trouve. Ca rajoute pas mal de code (allocation mémoire et libération de la memoire allouée) et il est préférable de bien manipuler les pointeurs pour ça.