[SDL] Mon image ne s'affiche pas

Fermé
bed2 Messages postés 3 Date d'inscription jeudi 2 février 2023 Statut Membre Dernière intervention 3 février 2023 - 2 févr. 2023 à 01:45
 bed2 - 10 févr. 2023 à 16:45

Bonjour en suivant un tuto je rencontre un probleme mon image ne s affiche pas et je n'ai aucun message d'erreur

#include<stdio.h>
#include<stdlib.h>
#include<SDL/SDL.h>
#include<SDL/SDL_image.h>

SDL_Surface *ecran=NULL;

SDL_Event event={0};

SDL_Surface *paysage=NULL;
SDL_Rect paysage_rect={0,0,0,0};

Uint32 couleur=0;

int main(){

	int Largeur = 800;
	int Hauteur = 480;
	int run=1;
	int now=0;
	int ex=0;
	int periodefps=33;
	int dt=0;
	float delta_s=0;

	SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO);

	ecran=SDL_SetVideoMode(Largeur,Hauteur,32,SDL_HWSURFACE);
	SDL_WM_SetCaption("Jeux2",NULL);
	
	couleur=SDL_MapRGB(ecran->format,51,51,255);

	paysage=IMG_Load("mario.png");
	if(paysage == NULL){
		printf("rater");
	}
	SDL_GetClipRect(paysage,& paysage_rect);

	printf("x=%d, y=%d, w=%d, h=%d\n", paysage_rect.x, paysage_rect.y, paysage_rect.w, paysage_rect.h);

	while(run){

		now=SDL_GetTicks();
		dt=now -ex;

		if(dt > periodefps){

			delta_s=dt/1000.0;

//			printf("delta = %d\n", delta_s);

			SDL_FillRect(ecran,NULL,couleur);

			SDL_BlitSurface(paysage,NULL,ecran,& paysage_rect);

        	        SDL_Flip(ecran);

			SDL_PollEvent(& event);
			switch(event.type){

				case SDL_QUIT:
				run=0;
				break;

				case SDL_KEYDOWN:
				if (event.key.keysym.sym==SDLK_ESCAPE){

					run=0;
				}
				break;

				case SDL_KEYUP:
				break;

				default:
				break;
			}
			ex=now;
		}
		else{
			SDL_Delay(periodefps - dt);
		}
	}

	SDL_FreeSurface(paysage);

	SDL_Quit();

}
A voir également:

2 réponses

[Dal] Messages postés 6180 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 15 mai 2024 1 084
2 févr. 2023 à 21:05

Bonjour bed2,

Votre code source est pour une version 1.2 de la SDL.

Cette version a été rendue obsolète par le projet SDL qui ne la maintient plus depuis 2012.


SDL version 1.2.15 (historic)

SDL 1.2 has been superceded by SDL 2.0.

SDL 1.2 is no longer supported and no longer works on many modern systems, but the source code is available for historic purposes on GitHub

Y a-t-il une bonne raison pour que tu utilises cette bibliothèque au lieu de la SDL2 ?

Travailles tu sur un système d'exploitation ancien qui ne soit supporté que par la SDL 1.2 ?

1
bed2 Messages postés 3 Date d'inscription jeudi 2 février 2023 Statut Membre Dernière intervention 3 février 2023
3 févr. 2023 à 16:54

Non c un tuto que je suis met j ai trouver le probleme l endroit ou j executer mon fichier l'image etait pas au meme endroit donc il ne la trouver pas. Mais maintenant j ai une autre probleme quand je veux que mon personnage saute il saute puis reste bloquer en haut et j ai mis de me dire x pour et il me donne toujour un comme si je relacher la touche a l'infini voici le code :

                               case SDL_KEYUP:
127                                 if (event.key.keysym.sym==SDLK_SPACE)
128                                 {
129                                         printf("x= %d\n", x);
130                                         x = 1;
131                                         printf("erreur %s", SDL_GetError());
132                                 }
133                                 break;
134 
135                                 default:
136                                 break;
137                         }
138                         if (x == 1)
139                         {
140                                 if (plane_rect.y >= 200)
141                                 {
142                                         x = 0;
143                                         plane_rect.y = plane_rect.y - 20;
144                                 }
145                         }
146                         else
147                         {
148                                 if(plane_rect.y <= 199)
149                                 {
150                                         plane_rect.y = plane_rect.y + 10;
151                                 }
152                         }
1
bed2 Messages postés 3 Date d'inscription jeudi 2 février 2023 Statut Membre Dernière intervention 3 février 2023
3 févr. 2023 à 17:02

Et si je met event.key.keysym.sym==SDLK_SPACE dans keydown sa fonctionne temp que je n'atteint pas 200 sinon c le meme probleme x reste egale a 1

0
[Dal] Messages postés 6180 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 15 mai 2024 1 084 > bed2 Messages postés 3 Date d'inscription jeudi 2 février 2023 Statut Membre Dernière intervention 3 février 2023
Modifié le 7 févr. 2023 à 14:00

Salut bed2,

Tu postes un code partiel qui ne permet pas de comprendre ta boucle d'animation.

Si tu veux faire sauter ton personnage lorsque la barre d'espacement est pressée, tu devrais utiliser l'événement SDL_KEYDOWN, et vérifier que la touche pressée est bien SDLK_SPACE.

Si tu veux faire un saut où son personnage monte de 20 en 20 pixels jusqu'à atteindre une coordonnée verticale de 200 et le faire redescendre une fois qu'il a atteint 200, tu dois écrire le code manquant qui gère le saut en testant si le sommet du saut est atteint et, si c'est le cas, que les coordonnées verticales diminuent ensuite jusqu'à arriver à celle du "sol", et ce n'est que lorsque cela arrive que le saut est terminé.

Sinon, ta boucle a l'air de mélanger pas mal de choses et au lieu de x, tu pourrais utiliser une variable saut_en_cours plus parlante.

Elle pourrait ressembler à ceci :

  1. début boucle
  2. scanner les touches
  3. si espace est pressé et qu'on n'est pas déjà en train de sauter (saut_en_cours est faux) alors commencer à sauter et fixer saut_en_cours à vrai
  4. si saut_en_cours est vrai calculer les prochaines coordonnées du personnage qui saute en gérant l'ascension et la descente comme indiqué ci-dessus
  5. si saut_en_cours est vrai et qu'on a terminé de sauter, fixer saut_en_cours à faux
  6. afficher le personnage à ses coordonnées actuelles
  7. boucler sur 1

Tu verras aussi que tu as intérêt à faire une boucle concise qui sépare dans ton jeu ce qui est gestion des inputs, gestion des objets de la scène, et affichage de la scène, en les mettant dans des fonctions. Ta boucle fait alors moins une dizaine de lignes et tu y vois plus clair en répartissant les tâches à gérer par ton programme.

0
Bed2 > [Dal] Messages postés 6180 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 15 mai 2024
7 févr. 2023 à 16:41

Salut mon code n a pas plus changer que se qu il y avait au début  et je n ai pas d animation et mon problème c que x reste égale à 1. Quand j ai mis dans keydown quand il atteint 200 il reste bloquer en au car x = 1 alors qu il devrait être égale à 0 voilà mon problème. 

0
[Dal] Messages postés 6180 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 15 mai 2024 1 084 > Bed2
7 févr. 2023 à 18:18

Apparemment mes indications ne te suffisent pas pour résoudre ton problème :-)

Ce que tu as posté ici : https://forums.commentcamarche.net/forum/affich-37785791-sdl-mon-image-ne-s-affiche-pas#2 ne se trouve pas dans ton code de début.

Poste ton code actuel en entier s'il te plaît.

0
[Dal] Messages postés 6180 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 15 mai 2024 1 084
Modifié le 10 févr. 2023 à 14:33

Salut bed2,

Pour implémenter les points 2, 3, 4 et 5 de l'algorithme suivant :

  1. début boucle
  2. scanner les touches
  3. si espace est pressé et qu'on n'est pas déjà en train de sauter (saut_en_cours est faux) alors commencer à sauter et fixer saut_en_cours à vrai
  4. si saut_en_cours est vrai calculer les prochaines coordonnées du personnage qui saute en gérant l'ascension et la descente comme indiqué ci-dessus
  5. si saut_en_cours est vrai et qu'on a terminé de sauter, fixer saut_en_cours à faux
  6. afficher le personnage à ses coordonnées actuelles
  7. boucler sur 1

Je répartirais cela en deux fonctions :

void scanner_inputs(struct jeu * j) {
        SDL_PollEvent(&j->ecran.event);
        switch(j->ecran.event.type) {
        case SDL_QUIT:
                j->jeu_en_cours = 0;
        break;

        case SDL_KEYDOWN:
                if (j->ecran.event.key.keysym.sym==SDLK_ESCAPE) {
                        j->jeu_en_cours = 0;
                }
                if (j->ecran.event.key.keysym.sym==SDLK_SPACE &&
                                j->mario.saut_en_cours == PAS_DE_SAUT_EN_COURS) {
                        j->mario.saut_en_cours = ASCENSION_SAUT;
                }
        break;

        default:
        break;
        }
}

void gerer_elements_jeu(struct jeu * j) {
        if (j->mario.rect.x >= j->ecran.Largeur)
                j->mario.rect.x = 0;

        j->mario.rect.x += 15;

        if (j->mario.saut_en_cours) {
                if (j->mario.saut_en_cours == ASCENSION_SAUT) {
                        j->mario.rect.y -= 30;
                        if (j->mario.rect.y <= 200)
                                j->mario.saut_en_cours = DESCENTE_SAUT;
                } else if (j->mario.saut_en_cours == DESCENTE_SAUT) {
                        j->mario.rect.y += 30;
                        if (j->mario.rect.y > 380)
                                j->mario.saut_en_cours = PAS_DE_SAUT_EN_COURS;
                }
        }
}

Les éléments du jeu sont mis dans une struct jeu, qui est passée via son pointeur à ces fonctions, et des enum sont créés pour faciliter la compréhension des valeurs représentant les différents états du personnage.

enum type_deplacement { IMMOBILE, GAUCHE, DROITE };
enum phase_saut { PAS_DE_SAUT_EN_COURS, ASCENSION_SAUT, DESCENTE_SAUT };

struct ecran {
        char window_caption[256];
        int Largeur;
        int Hauteur;
        int periodefps;
        SDL_Event event;
        SDL_Surface * surf;
};

struct paysage {
        char file[256];
        SDL_Surface * surf;
        SDL_Rect rect;
};

struct mario {
        char file[256];
        SDL_Surface * surf;
        SDL_Rect rect;
        enum type_deplacement deplacement_en_cours;
        enum phase_saut saut_en_cours;
};

struct jeu {
        int jeu_en_cours;
        Uint32 couleur;
        struct ecran ecran;
        struct paysage paysage;
        struct mario mario;
};

En utilisant ces structures de données, ont peut créer des fonctions pour initialiser le jeu, initialiser le paysage, initialiser le personnage, et la boucle du jeu peut être rendue plus lisible, comme ceci :

int main(void) {
        int now=0;
        int ex=0;
        int dt=0;
        float delta_s=0;

        struct jeu j;

        init_jeu(&j, "Jeux2", 1600, 800, 33);
        init_paysage(&j, "./image/background.bmp");
        init_mario(&j, "./image/perso1.png", 100, 350);

        while (j.jeu_en_cours) {
                now = SDL_GetTicks();
                dt = now -ex;

                if (dt > j.ecran.periodefps) {
                        dessiner_ecran(&j);
                        scanner_inputs(&j);
                        gerer_elements_jeu(&j);

                        delta_s = dt / 1000.0;
                        ex = now;
                } else {
                        SDL_Delay(j.ecran.periodefps - dt);
                }
        }

        free_jeu(&j);
        SDL_Quit();
}

C'est juste un exemple basé sur ton code :-)

0
[Dal] Messages postés 6180 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 15 mai 2024 1 084
Modifié le 10 févr. 2023 à 14:36

et voilà le code complet suivant cette conception :

#include <stdio.h>
#include <stdlib.h>
#include <SDL.h>
#include <SDL_image.h>

enum type_deplacement { IMMOBILE, GAUCHE, DROITE };
enum phase_saut { PAS_DE_SAUT_EN_COURS, ASCENSION_SAUT, DESCENTE_SAUT };

struct ecran {
        char window_caption[256];
        int Largeur;
        int Hauteur;
        int periodefps;
        SDL_Event event;
        SDL_Surface * surf;
};

struct paysage {
        char file[256];
        SDL_Surface * surf;
        SDL_Rect rect;
};

struct mario {
        char file[256];
        SDL_Surface * surf;
        SDL_Rect rect;
        enum type_deplacement deplacement_en_cours;
        enum phase_saut saut_en_cours;
};

struct jeu {
        int jeu_en_cours;
        Uint32 couleur;
        struct ecran ecran;
        struct paysage paysage;
        struct mario mario;
};

void init_jeu(struct jeu * j, char * caption, int Largeur, int Hauteur, int fps) {
        j->jeu_en_cours = 1;
        j->couleur = 0;

        strcpy(j->ecran.window_caption, caption);
        j->ecran.Largeur = Largeur;
        j->ecran.Hauteur = Hauteur;
        j->ecran.periodefps = fps;

        SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO);
        const SDL_VideoInfo* pinfo = SDL_GetVideoInfo();
        int bpp = pinfo->vfmt->BitsPerPixel;

        j->ecran.surf = NULL;
        int ecran_w = pinfo->current_w;
        int ecran_h = pinfo->current_h;
        j->ecran.surf = SDL_SetVideoMode(j->ecran.Largeur, j->ecran.Hauteur,
                        bpp, SDL_HWSURFACE);
        printf("ecran_w=%d, ecran_h=%d, bpp=%d\n", ecran_w, ecran_h, bpp);
        j->couleur = SDL_MapRGB(j->ecran.surf->format, 51, 51, 255);

        SDL_WM_SetCaption(j->ecran.window_caption, NULL);
}

void free_jeu(struct jeu * j) {
        SDL_FreeSurface(j->mario.surf);
        SDL_FreeSurface(j->paysage.surf);
}

void init_paysage(struct jeu * j, char * file) {
        strcpy(j->paysage.file, file);

        j->paysage.surf = NULL;
        j->paysage.rect = (SDL_Rect){0, 0, 0, 0};

        SDL_Surface * tmp = NULL;
        tmp = IMG_Load(j->paysage.file);
        if (NULL == tmp) {
                printf("erreur init_paysage %s\n", SDL_GetError());
                exit(1);
        }
        j->paysage.surf = SDL_DisplayFormat(tmp); //DisplayFormatAlpha pour image avec du transparent
        SDL_FreeSurface(tmp);
        SDL_GetClipRect(j->paysage.surf, &j->paysage.rect);
        printf("x=%d, y=%d, w=%d, h=%d\n", j->paysage.rect.x, j->paysage.rect.y, 
                        j->paysage.rect.w, j->paysage.rect.h);
}

void free_paysage(struct jeu * j) {
        /* TODO */
        (void) j;
}

void init_mario(struct jeu * j, char * file, int start_x, int start_y) {
        strcpy(j->mario.file, file);
        j->mario.surf = NULL;
        j->mario.rect = (SDL_Rect){0, 0, 0, 0};

        SDL_Surface * tmp= IMG_Load(j->mario.file);
        if (NULL == tmp) {
                printf("erreur init_mario %s \n", SDL_GetError());
                exit(1);
        }
        j->mario.surf = SDL_DisplayFormatAlpha(tmp);

        SDL_FreeSurface(tmp);
        SDL_GetClipRect(j->mario.surf, &j->mario.rect);

        j->mario.rect.x = start_x;
        j->mario.rect.y = start_y;
        j->mario.deplacement_en_cours = IMMOBILE;
        j->mario.saut_en_cours = PAS_DE_SAUT_EN_COURS;
}

void dessiner_ecran(struct jeu * j) {
        SDL_FillRect(j->ecran.surf, NULL, j->couleur);
        SDL_BlitSurface(j->paysage.surf ,NULL, j->ecran.surf, &j->paysage.rect);
        SDL_BlitSurface(j->mario.surf, NULL, j->ecran.surf, &j->mario.rect);
        SDL_Flip(j->ecran.surf);
        printf("saut_en_cours = %d - mario.rect.x = %d - mario.rect.y = %d\n",
                        j->mario.saut_en_cours,
                        j->mario.rect.x, j->mario.rect.y);
}

void scanner_inputs(struct jeu * j) {
        SDL_PollEvent(&j->ecran.event);
        switch(j->ecran.event.type) {
        case SDL_QUIT:
                j->jeu_en_cours = 0;
        break;

        case SDL_KEYDOWN:
                if (j->ecran.event.key.keysym.sym==SDLK_ESCAPE) {
                        j->jeu_en_cours = 0;
                }
                if (j->ecran.event.key.keysym.sym==SDLK_SPACE &&
                                j->mario.saut_en_cours == PAS_DE_SAUT_EN_COURS) {
                        j->mario.saut_en_cours = ASCENSION_SAUT;
                }
        break;

        default:
        break;
        }
}

void gerer_elements_jeu(struct jeu * j) {
        if (j->mario.rect.x >= j->ecran.Largeur)
                j->mario.rect.x = 0;

        j->mario.rect.x += 15;

        if (j->mario.saut_en_cours) {
                if (j->mario.saut_en_cours == ASCENSION_SAUT) {
                        j->mario.rect.y -= 30;
                        if (j->mario.rect.y <= 200)
                                j->mario.saut_en_cours = DESCENTE_SAUT;
                } else if (j->mario.saut_en_cours == DESCENTE_SAUT) {
                        j->mario.rect.y += 30;
                        if (j->mario.rect.y > 380)
                                j->mario.saut_en_cours = PAS_DE_SAUT_EN_COURS;
                }
        }
}

int main(void) {
        int now=0;
        int ex=0;
        int dt=0;
        float delta_s=0;

        struct jeu j;

        init_jeu(&j, "Jeux2", 1600, 800, 33);
        init_paysage(&j, "./image/background.bmp");
        init_mario(&j, "./image/perso1.png", 100, 350);

        while (j.jeu_en_cours) {
                now = SDL_GetTicks();
                dt = now -ex;

                if (dt > j.ecran.periodefps) {
                        dessiner_ecran(&j);
                        scanner_inputs(&j);
                        gerer_elements_jeu(&j);

                        delta_s = dt / 1000.0;
                        ex = now;
                } else {
                        SDL_Delay(j.ecran.periodefps - dt);
                }
        }

        free_jeu(&j);
        SDL_Quit();
}

J'ai repris la position de départ que tu avais définie à 100, 350 pour ton personnage, mais elle ne fonctionne pas bien avec le pas d'incrémentation et la limite en hauteur du saut que tu avais définis. Il faudrait ajuster tout cela pour que cela soit cohérent dans la gestion du saut pour revenir sur la même valeur y en fin de saut.

0