Bonjour à tous, dans l'optique de développer un jeu (qui est déjà bien avancé), je dois afficher des menus de sélections de façon successives (par exemple : écran-titre > choisir niveau > niveau 01 > difficulté) comme dans les jeux professionnels quoi.
Voilà alors ma méthode habituel fonctionne bien lors du jeu, mais lorsque je quitte (SDL_Quit ou l'appui sur la touche echap), on dirait que le jeu remonte en arrière dans les niveaux, et j'ai des grosses fuites de mémoires quand je mets la fonction DeleteWindow() qui a pourtant le rôle de la vider des différents sons et images. Donc en regardant, j'ai mis un seul DeleteWindow() à l'écran titre (le premier menu) et ça résout le problème, mais j'aimerai un code plus propre, et surtout plus stable.
Voici ma façon de faire actuelle, je copie cette boucle pour chaque menu, en changeant l'affichage et la gestion de l'appui sur Espace pour accéder au sous menu suivant :
par exemple le menu suivant sera EventsChoice() :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80 void Window::EventsTitle() { //Boucle Principal menu = 0; menuGameOver = 0; //Tant que l'utilisateur n'a pas quitter while (continuer) { while (SDL_PollEvent(&event) ) { switch(event.type) { case SDL_QUIT : continuer = 0; break; case SDL_KEYDOWN : if(event.key.keysym.sym == SDLK_ESCAPE) continuer = 0; if(menu > 0) { if(event.key.keysym.sym == SDLK_UP) { FSOUND_PlaySound(FSOUND_FREE, menuSound); menu--; } } if(menu < 2) { if(event.key.keysym.sym == SDLK_DOWN) { menu++; FSOUND_PlaySound(FSOUND_FREE, menuSound); } } if(event.key.keysym.sym == SDLK_SPACE) { FSOUND_PlaySound(FSOUND_FREE, valideSound); if(menu == 0) { EventsChoice(); } if(menu == 2) continuer = 0; } break; } } tempsActuel = SDL_GetTicks(); if (tempsActuel - tempsPrecedent > FPS) { SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255)); SDL_BlitSurface(Title[menu], 0, SDL_GetVideoSurface(), &posTitle); heroTitle->Draw(); SDL_Flip(ecran); tempsPrecedent = tempsActuel; } else // Si ça fait moins de 30ms depuis le dernier tour de boucle, on endort le programme le temps qu'il faut { SDL_Delay(FPS - (tempsActuel - tempsPrecedent)); } } DeleteWindow(); }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85 void Window::EventsChoice() { //Boucle Principal menu = 0; //Tant que l'utilisateur n'a pas quitter while (continuer) { while (SDL_PollEvent(&event) ) { switch(event.type) { case SDL_QUIT : continuer = 0; break; case SDL_KEYDOWN : if(event.key.keysym.sym == SDLK_ESCAPE) continuer = 0; if(menu > 0) { if(event.key.keysym.sym == SDLK_LEFT) { FSOUND_PlaySound(FSOUND_FREE, menuSound); menu--; } } if(menu < 1) { if(event.key.keysym.sym == SDLK_RIGHT) {FSOUND_PlaySound(FSOUND_FREE, menuSound); menu++;} } if(event.key.keysym.sym == SDLK_SPACE) { FSOUND_PlaySound(FSOUND_FREE, valideSound); if(menu == 1) { SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255)); SDL_BlitSurface(ready, 0, SDL_GetVideoSurface(), &posready); SDL_Flip(ecran); SDL_Delay(1000); InitGame(1); } if(menu == 0) { SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255)); SDL_BlitSurface(ready, 0, SDL_GetVideoSurface(), &posready); SDL_Flip(ecran); SDL_Delay(1000); InitGame(0); } } break; } } tempsActuel = SDL_GetTicks(); if (tempsActuel - tempsPrecedent > FPS) { SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255)); SDL_BlitSurface(Choice[menu], 0, SDL_GetVideoSurface(), &posTitle); heroTitle->Draw(); SDL_Flip(ecran); tempsPrecedent = tempsActuel; } else // Si ça fait moins de 30ms depuis le dernier tour de boucle, on endort le programme le temps qu'il faut { SDL_Delay(FPS - (tempsActuel - tempsPrecedent)); } } }
et voici ma fonction deleteWindow qui pose tant de problème, tout semble pourtant être dans les règles :
Il arrive même que le debugger situe la fuite de mémoire... dans le constructeur !!!
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 void Window::DeleteWindow() { FSOUND_Sample_Free(valideSound); FSOUND_Sample_Free(menuSound); FSOUND_Sample_Free(bonusSound); FSOUND_Sample_Free(degat); FSOUND_Stream_Close(musique); FSOUND_Close(); SDL_FreeSurface(Title[0]); SDL_FreeSurface(Title[1]); SDL_FreeSurface(GameOver[0]); SDL_FreeSurface(GameOver[1]); if(player != NULL) player->Free(); if(lvl[lvl.size()-1] != NULL) lvl[lvl.size()-1]->Free(); SDL_FreeSurface(ecran); SDL_Quit(); }
En mettant l'erreur sur un "FSOUND_Close()" à la dernière parenthèse...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62 Window::Window() { stade = 2; float w = 720; float h = 480; FSOUND_Init(44100, 32, 0); SDL_Init(SDL_INIT_VIDEO | SDL_DOUBLEBUF); SDL_WM_SetCaption("PATCHWORK Hero",NULL); ecran = SDL_SetVideoMode(w, h, 32, SDL_HWSURFACE); Title[0] = IMG_Load("Title/ecran-titre-01.png"); Title[1] = IMG_Load("Title/ecran-titre-02.png"); Title[2] = IMG_Load("Title/ecran-titre-03.png"); GameOver[0] = IMG_Load("Title/game-over-01.png"); GameOver[1] = IMG_Load("Title/game-over-02.png"); Choice[0] = IMG_Load("Title/choix-01.png"); Choice[1] = IMG_Load("Title/choix-02.png"); degatImg = IMG_Load("Enemies/degat.png"); heroTitle = new PictureAnimated("Title/hero.imga", 0.35); ready = IMG_Load("Title/ready.png"); posTitle.x = 0; posTitle.y = 0; menu = 0; menuGameOver = 0; posready.x = 0; posready.y = 0; /*if(musiquestop == false) { musique = FSOUND_Stream_Open("Music/Fond.mp3", FSOUND_LOOP_NORMAL, 0, 0); FSOUND_Stream_Play(FSOUND_FREE, musique); FSOUND_Stream_SetLoopCount(musique, -1); }*/ bonusSound = FSOUND_Sample_Load(FSOUND_FREE, "Music/bonus.mp3", 0, 0, 0); degat = FSOUND_Sample_Load(FSOUND_FREE, "Music/degat.mp3", 0, 0, 0); menuSound = FSOUND_Sample_Load(FSOUND_FREE, "Music/menu.mp3", 0, 0, 0); valideSound = FSOUND_Sample_Load(FSOUND_FREE, "Music/valide.mp3", 0, 0, 0); SDL_ShowCursor(SDL_DISABLE); lastlevel = 0; OpenStory(); }
J'avoue que j'ai vraiment du mal à comprendre et j'aurai vraiment besoin de votre aide pour ce problème !!!
Comment feriez vous pour afficher les menus ? Comment régler ce problème ?
Merci d'avance !
Partager