Précédent   Forum du club des développeurs et IT Pro > Applications > Développement 2D, 3D et Jeux > API graphiques > SDL
SDL Forum d'entraide sur l'API SDL. Avant de poster -> FAQ SDL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 01/04/2012, 15h22   #1
Menudelux
Invité de passage
 
Homme Alexis
Étudiant
Inscription : avril 2012
Messages : 8
Détails du profil
Informations personnelles :
Nom : Homme Alexis
Âge : 17
Localisation : France

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : avril 2012
Messages : 8
Points : 2
Points : 2
Par défaut Détection collisions Sokoban like

Bonjour à tous,

Me voila en plein apprentissage du C et de la SDL. Je suis actuellement en train de coder un petit Mario Sokoban afin de pratiquer. Mais je rencontre un petit problème que je n'arrive pas du tout à résoudre depuis deux jours déjà. Le problème peut vous paraître tout simple, mais sachez que je suis un jeune débutant. ^^

Pour vous présenter mon problème, partons du fait que j'ai seulement deux fichiers : « jeu.c » et son équivalent en header, « jeu.h » (que je trouve inutile de présenter dans ce post).

Voila donc mon fichier "jeu.c". Je vous l'accorde, c'est un peu le bazar mais je pense qu'apprendre à coder proprement vient avec l’expérience.

Code :
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
#include <stdlib.h>
#include <stdio.h>
#include <SDL/SDL.h>
#include <SDL_image.h>
#include "jeu.h"
#include "constantes.h"
 
long MAP[NOMBREY_BLOC][NOMBREX_BLOC] = {0};
long VALIDATION = 0, BLOC_OBJECTIF = 0;
 
void jeu(SDL_Surface *ecran)
{
    personnage(ecran);
}
 
void generer_map(SDL_Surface *ecran, long *initialiser)
{
    long i, j;
 
    SDL_Surface *caisse = NULL, *caisse_ok = NULL, *mur = NULL, *objectif = NULL;
    mur = IMG_Load("sprites_mario_sokoban/mur.jpg");
    caisse = IMG_Load("sprites_mario_sokoban/caisse.jpg");
    caisse_ok = IMG_Load("sprites_mario_sokoban/caisse_ok.jpg");
    objectif = IMG_Load("sprites_mario_sokoban/objectif.png");
 
    SDL_Rect position_bloc;
 
    if(*initialiser)
    {
        *initialiser = initialiser_map(MAP);
    }
 
    for(i=0; i<NOMBREY_BLOC;i++)
    {
        for(j=0; j<NOMBREX_BLOC;j++)
        {
            if(MAP[i][j] == 1)
            {
                  position_bloc.x = j*34;
                  position_bloc.y = i*34;
 
                  SDL_BlitSurface(mur, NULL, ecran, &position_bloc);
            }
            else if(MAP[i][j] == 2)
            {
                  position_bloc.x = j*34;
                  position_bloc.y = i*34;
 
                  SDL_BlitSurface(caisse, NULL, ecran, &position_bloc);
            }
            else if(MAP[i][j] == 3)
            {
                  position_bloc.x = j*34;
                  position_bloc.y = i*34;
 
                  SDL_BlitSurface(objectif, NULL, ecran, &position_bloc);
            }
            else if(MAP[i][j] == 4)
            {
                  position_bloc.x = j*34;
                  position_bloc.y = i*34;
 
                  SDL_BlitSurface(caisse_ok, NULL, ecran, &position_bloc);
            }
        }
    }
 
    SDL_FreeSurface(caisse);
    SDL_FreeSurface(mur);
    SDL_FreeSurface(caisse_ok);
    SDL_FreeSurface(objectif);
}
 
long initialiser_map(long MAP[][NOMBREX_BLOC])
{
    long i, j;
 
    MAP[2][4] = 1;
    MAP[4][6] = 2;
    MAP[7][10] = 2;
    MAP[8][10] = 3;
    MAP[2][6] = 3;
 
    for(i=0; i<NOMBREY_BLOC;i++)
    {
        for(j=0;j<NOMBREX_BLOC;j++)
        {
            if(MAP[i][j] == 3)
            {
                BLOC_OBJECTIF++;
            }
        }
    }
 
 
    return 0;
}
 
void personnage(SDL_Surface *ecran)
{
    long choix_continuer = 1;
    long initialiser = 1;
    SDL_Event event;
    SDL_Surface *mario = NULL;
    mario = IMG_Load("sprites_mario_sokoban/mario_bas.gif");
    SDL_Rect position_mario;
 
    position_mario.x = 100;
    position_mario.y = 100;
 
    SDL_EnableKeyRepeat(10, 10);
 
    while(choix_continuer)
    {
        SDL_WaitEvent(&event);
        switch(event.type)
        {
            case SDL_QUIT:
                choix_continuer = 0;
                break;
            case SDL_KEYDOWN:
                switch(event.key.keysym.sym)
                {
                    case SDLK_UP:
                        mario = IMG_Load("sprites_mario_sokoban/mario_haut.gif");
                        deplacer_joueur(&position_mario, HAUT);
                        break;
                    case SDLK_DOWN:
                        mario = IMG_Load("sprites_mario_sokoban/mario_bas.gif");
                        deplacer_joueur(&position_mario, BAS);
                        break;
                    case SDLK_LEFT:
                        mario = IMG_Load("sprites_mario_sokoban/mario_gauche.gif");
                        deplacer_joueur(&position_mario, GAUCHE);
                        break;
                    case SDLK_RIGHT:
                        deplacer_joueur(&position_mario, DROITE);
                        mario = IMG_Load("sprites_mario_sokoban/mario_droite.gif");
                        break;
                }
                break;
        }
 
    SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));
    generer_map(ecran, &initialiser);
    SDL_BlitSurface(mario, NULL, ecran, &position_mario);
    gagner(&choix_continuer);
    SDL_Flip(ecran);
    }
 
    SDL_FreeSurface(mario);
}
 
void deplacer_joueur(SDL_Rect *position_joueur, long orientation)
{
    long detecteur_collision = 1;
    long positionX_futur_joueur = 0;
    long positionY_futur_joueur = 0;
 
    if(orientation == HAUT)
    {
        positionY_futur_joueur = position_joueur->y - 1;
        positionX_futur_joueur = position_joueur->x;
 
        collision(&detecteur_collision, positionX_futur_joueur, positionY_futur_joueur, HAUT);
 
        if(detecteur_collision)
        {
            position_joueur->y--;
        }
        else{}
    }
    else if(orientation == BAS)
    {
        positionY_futur_joueur = position_joueur->y + 1;
        positionX_futur_joueur = position_joueur->x;
 
        collision(&detecteur_collision, positionX_futur_joueur, positionY_futur_joueur, BAS);
 
        if(detecteur_collision)
        {
            position_joueur->y++;
        }
        else{}
    }
    else if(orientation == GAUCHE)
    {
        positionX_futur_joueur = position_joueur->x - 1;
        positionY_futur_joueur = position_joueur->y;
 
        collision(&detecteur_collision, positionX_futur_joueur, positionY_futur_joueur, GAUCHE);
 
        if(detecteur_collision)
        {
            position_joueur->x--;
        }
        else{}
    }
    else if(orientation == DROITE)
    {
        positionX_futur_joueur = position_joueur->x + 1;
        positionY_futur_joueur = position_joueur->y;
 
        collision(&detecteur_collision, positionX_futur_joueur, positionY_futur_joueur, DROITE);
 
        if(detecteur_collision)
        {
            position_joueur->x++;
        }
        else{}
    }
}
 
void collision(long *detecteur_collision, long positionX_futur_joueur, long positionY_futur_joueur, long orientation)
{
 
    long i,j;
    SDL_Rect position_bloc;
    position_bloc.x = 0, position_bloc.y = 0;
 
    for(i=0; i<NOMBREY_BLOC;i++)
    {
        for(j=0; j<NOMBREX_BLOC;j++)
        {
            if(MAP[i][j] == 1 || MAP[i][j] == 4 )
            {
                position_bloc.x = j*34;
                position_bloc.y = i*34;
 
                if(positionX_futur_joueur + 20 < position_bloc.x || positionX_futur_joueur + 5 > position_bloc.x +34 || positionY_futur_joueur + 30 < position_bloc.y || positionY_futur_joueur > position_bloc.y + 34)
                {
                    *detecteur_collision = 1;
                }
                else
                {
                    *detecteur_collision = 0;
                }
            }
            else if(MAP[i][j] == 2)
            {
                position_bloc.x = j*34;
                position_bloc.y = i*34;
 
                if(positionX_futur_joueur + 20 < position_bloc.x || positionX_futur_joueur + 5 > position_bloc.x +34 || positionY_futur_joueur + 30 < position_bloc.y || positionY_futur_joueur > position_bloc.y + 34)
                {}
                else
                {
                    if(orientation == HAUT)
                    {
                        if(MAP[i-1][j] == 0)
                        {
                            MAP[i][j] = 0;
                            MAP[i-1][j] = 2;
                        }
                        else if(MAP[i-1][j] == 3)
                        {
                            MAP[i][j] = 0;
                            MAP[i-1][j] = 4;
                            VALIDATION++;
                        }
                        else
                        {
                            *detecteur_collision = 0;
                        }
                    }
                    if(orientation == BAS)
                    {
                        if(MAP[i+1][j] == 0)
                        {
                            MAP[i][j] = 0;
                            MAP[i+1][j] = 2;
 
                        }
                        else if(MAP[i+1][j] == 3)
                        {
                            MAP[i][j] = 0;
                            MAP[i+1][j] = 4;
                            VALIDATION++;
                        }
                        else
                        {
                            *detecteur_collision = 0;
                        }
                    }
                    if(orientation == GAUCHE)
                    {
                        if(MAP[i][j-1] == 0)
                        {
                            MAP[i][j] = 0;
                            MAP[i][j-1] = 2;
                        }
                        else if(MAP[i][j-1] == 3)
                        {
                            MAP[i][j] = 0;
                            MAP[i][j-1] = 4;
                            VALIDATION++;
                        }
                        else
                        {
                            *detecteur_collision = 0;
                        }
                    }
                    if(orientation == DROITE)
                    {
                        if(MAP[i][j+1] == 0)
                        {
                            MAP[i][j] = 0;
                            MAP[i][j+1] = 2;
                        }
                        else if(MAP[i][j+1] == 3)
                        {
                            MAP[i][j] = 0;
                            MAP[i][j+1] = 4;
                            VALIDATION++;
                        }
                        else
                        {
                            *detecteur_collision = 0;
                        }
                    }
                }
            }
        }
    }
}
 
void gagner(long *choix_continuer)
{
    if(VALIDATION == BLOC_OBJECTIF)
    {
        *choix_continuer = 0;
    }
}
Avec ce code, ma gestion des collisions du personnage avec les murs marche très bien, les poussages de la caisse dans les parties vides de la map ainsi que dans les cases objectifs marchent très bien.

Mais cela coince lorsque mon personnage pousse la caisse et que celle ci est bloquée par un mur derrière. Ma caisse est stoppée net par le mur, mais mon personnage, si je continue à appuyer sur les flèches directionnelles, rentre dans la caisse. Or, je veux que lorsque la caisse est en contact avec un mur, il soit stoppé lui aussi mais par la caisse.
Quelques screens pour bien comprendre le problème :



Ci-dessus le personnage est bloqué dès la caisse et ne peut plus pousser dans la direction du mur (cas que je voudrais obtenir mais que j'ai dans les cas où orientation == HAUT et orientation == DROITE).



Ci-dessus, le personnage n'est pas bloqué par la caisse et lui rentre dedans, il ne peut pas pousser dans la direction du mur aussi. (Cas que j'ai lorsque orientation == BAS et orientation == GAUCHE).

Voila le bout de code que je soupçonne de planter:

Code :
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
else if(MAP[i][j] == 2)
            {
                position_bloc.x = j*34;
                position_bloc.y = i*34;
 
                if(positionX_futur_joueur + 20 < position_bloc.x || positionX_futur_joueur + 5 > position_bloc.x +34 || positionY_futur_joueur + 30 < position_bloc.y || positionY_futur_joueur > position_bloc.y + 34)
                {}
                else
                {
                    if(orientation == HAUT)
                    {
                        if(MAP[i-1][j] == 0)
                        {
                            MAP[i][j] = 0;
                            MAP[i-1][j] = 2;
                        }
                        else if(MAP[i-1][j] == 3)
                        {
                            MAP[i][j] = 0;
                            MAP[i-1][j] = 4;
                            VALIDATION++;
                        }
                        else
                        {
                            *detecteur_collision = 0;
                        }
                    }
                    if(orientation == BAS)
                    {
                        if(MAP[i+1][j] == 0)
                        {
                            MAP[i][j] = 0;
                            MAP[i+1][j] = 2;
 
                        }
                        else if(MAP[i+1][j] == 3)
                        {
                            MAP[i][j] = 0;
                            MAP[i+1][j] = 4;
                            VALIDATION++;
                        }
                        else
                        {
                            *detecteur_collision = 0;
                        }
                    }
                    if(orientation == GAUCHE)
                    {
                        if(MAP[i][j-1] == 0)
                        {
                            MAP[i][j] = 0;
                            MAP[i][j-1] = 2;
                        }
                        else if(MAP[i][j-1] == 3)
                        {
                            MAP[i][j] = 0;
                            MAP[i][j-1] = 4;
                            VALIDATION++;
                        }
                        else
                        {
                            *detecteur_collision = 0;
                        }
                    }
                    if(orientation == DROITE)
                    {
                        if(MAP[i][j+1] == 0)
                        {
                            MAP[i][j] = 0;
                            MAP[i][j+1] = 2;
                        }
                        else if(MAP[i][j+1] == 3)
                        {
                            MAP[i][j] = 0;
                            MAP[i][j+1] = 4;
                            VALIDATION++;
                        }
                        else
                        {
                            *detecteur_collision = 0;
                        }
                    }
                }
Mes 4 « else » sont censés bloquer le mouvement du personnage afin qu'il ne puisse rentrer dans la caisse si celle-ci est stoppée par un mur, (*detecteur_collision = 0. Mais ce code ne marche que lorsque la caisse est bloquée par la gauche ou par le bas contre un mur, c'est à dire quand orientation == DROITE et orientation == HAUT. Pourtant, j'ai mis le même code dans orientation == BAS et orientation == GAUCHE.

Je voudrais ainsi obtenir le résultat des cas quand orientation == DROITE et orientation == HAUT pour les deux autres orientations, c'est à dire quand orientation == BAS et orientation == GAUCHE.

Merci d'avance pour votre aide.
Menudelux est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 01/04/2012, 20h56   #2
Obsidian
Modérateur
 
Avatar de Obsidian
 
Homme
Chercheur d'emploi
Inscription : septembre 2007
Messages : 4 614
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 36
Localisation : France, Essonne (Île de France)

Informations professionnelles :
Activité : Chercheur d'emploi
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : septembre 2007
Messages : 4 614
Points : 11 078
Points : 11 078
Bonjour,

Pour un débutant, c'est un projet déjà remarquablement abouti. Bravo !

Tu as déjà commencé à factoriser les opérations que tu auras à répéter fréquemment, en les déportant dans des fonctions qui leur sont propres. C'est bien. Cela dit, tes fonctions ne sont pour le moment que des procédures impératives, dans le sens où elles sont toutes de types void.

En s'arrangeant pour qu'elles renvoient un booléen permettant d'indiquer si l'opération s'est bien passée ou pas, tu pourrais plus facilement mettre en place des séquences d'opérations, voire même t'arranger pour les appeler récursivement : en l'occurence, ce serait la fonction déplace_joueur() qui appelerait elle-même une fonction deplace_caisse() le cas échéant, et qui renverrait toute de suite false sans déplacer le joueur si deplace_caisse() renvoie false elle aussi.

L'avantage, c'est que tu passerais tes coordonnées x et y en argument de fonction, et que tu pourrais les rappeler autant de fois que tu le veux en faisant les modifications (« ± 1 ») sur tes paramètres, donc sans avoir à modifier les variables initiales.
Obsidian est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 01/04/2012, 21h59   #3
Menudelux
Invité de passage
 
Homme Alexis
Étudiant
Inscription : avril 2012
Messages : 8
Détails du profil
Informations personnelles :
Nom : Homme Alexis
Âge : 17
Localisation : France

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : avril 2012
Messages : 8
Points : 2
Points : 2
Yes merci de l'aide mais je n'ai pas pu appliquer entièrement ta méthode proposée, voila mon nouveau code:

Code :
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
void deplacer_joueur(SDL_Rect *position_joueur, long orientation)
{
    long detecteur_collision = 1;
    long detecteur_caisse = 1;
    long positionX_futur_joueur = 0;
    long positionY_futur_joueur = 0;
 
    if(orientation == HAUT)
    {
        positionY_futur_joueur = position_joueur->y - 1;
        positionX_futur_joueur = position_joueur->x;
 
        deplacer_caisse(&detecteur_caisse, positionX_futur_joueur, positionY_futur_joueur, HAUT);
 
        collision(&detecteur_collision, positionX_futur_joueur, positionY_futur_joueur, HAUT);
 
        if(detecteur_collision && detecteur_caisse)
        {
            position_joueur->y--;
        }
        else{}
    }
    else if(orientation == BAS)
    {
        positionY_futur_joueur = position_joueur->y + 1;
        positionX_futur_joueur = position_joueur->x;
 
        deplacer_caisse(&detecteur_caisse, positionX_futur_joueur, positionY_futur_joueur, BAS);
 
        collision(&detecteur_collision, positionX_futur_joueur, positionY_futur_joueur, BAS);
 
        if(detecteur_collision && detecteur_caisse)
        {
            position_joueur->y++;
        }
        else{}
    }
    else if(orientation == GAUCHE)
    {
        positionX_futur_joueur = position_joueur->x - 1;
        positionY_futur_joueur = position_joueur->y;
 
        deplacer_caisse(&detecteur_caisse, positionX_futur_joueur, positionY_futur_joueur, GAUCHE);
 
        collision(&detecteur_collision, positionX_futur_joueur, positionY_futur_joueur, GAUCHE);
 
        if(detecteur_collision && detecteur_caisse)
        {
            position_joueur->x--;
        }
        else{}
    }
    else if(orientation == DROITE)
    {
        positionX_futur_joueur = position_joueur->x + 1;
        positionY_futur_joueur = position_joueur->y;
 
        deplacer_caisse(&detecteur_caisse, positionX_futur_joueur, positionY_futur_joueur, DROITE);
 
        collision(&detecteur_collision, positionX_futur_joueur, positionY_futur_joueur, DROITE);
 
        if(detecteur_collision && detecteur_caisse)
        {
            position_joueur->x++;
        }
        else{}
    }
}
 
void collision(long *detecteur_collision, long positionX_futur_joueur, long positionY_futur_joueur, long orientation)
{
 
    long i,j;
    SDL_Rect position_bloc;
    position_bloc.x = 0, position_bloc.y = 0;
 
    for(i=0; i<NOMBREY_BLOC;i++)
    {
        for(j=0; j<NOMBREX_BLOC;j++)
        {
            if(MAP[i][j] == 1 || MAP[i][j] == 4 )
            {
                position_bloc.x = j*34;
                position_bloc.y = i*34;
 
                if(positionX_futur_joueur + 20 < position_bloc.x || positionX_futur_joueur + 5 > position_bloc.x +34 || positionY_futur_joueur + 30 < position_bloc.y || positionY_futur_joueur > position_bloc.y + 34)
                {
                    *detecteur_collision = 1;
                }
                else
                {
                    *detecteur_collision = 0;
                }
            }
 
        }
    }
}
 
void deplacer_caisse(long *detecteur_caisse, long positionX_futur_joueur, long positionY_futur_joueur, long orientation)
{
    long i,j;
    SDL_Rect position_caisse;
    position_caisse.x = 0, position_caisse.y = 0;
 
    for(i=0; i<NOMBREY_BLOC;i++)
    {
        for(j=0; j<NOMBREX_BLOC;j++)
        {
            if(MAP[i][j] == 2)
            {
                position_caisse.x = j*34;
                position_caisse.y = i*34;
 
                if(positionX_futur_joueur + 20 < position_caisse.x || positionX_futur_joueur + 5 > position_caisse.x +34 || positionY_futur_joueur + 30 < position_caisse.y || positionY_futur_joueur > position_caisse.y + 34)
                {}
                else
                {
                    if(orientation == HAUT)
                    {
                        if(MAP[i-1][j] == 0)
                        {
                            MAP[i][j] = 0;
                            MAP[i-1][j] = 2;
                        }
                        else if(MAP[i-1][j] == 3)
                        {
                            MAP[i][j] = 0;
                            MAP[i-1][j] = 4;
                            VALIDATION++;
                        }
                        else
                        {
                            *detecteur_caisse = 0;
                        }
                    }
                    if(orientation == BAS)
                    {
                        if(MAP[i+1][j] == 0)
                        {
                            MAP[i][j] = 0;
                            MAP[i+1][j] = 2;
 
                        }
                        else if(MAP[i+1][j] == 3)
                        {
                            MAP[i][j] = 0;
                            MAP[i+1][j] = 4;
                            VALIDATION++;
                        }
                        else
                        {
                            *detecteur_caisse = 0;
                        }
                    }
                    if(orientation == GAUCHE)
                    {
                        if(MAP[i][j-1] == 0)
                        {
                            MAP[i][j] = 0;
                            MAP[i][j-1] = 2;
                        }
                        else if(MAP[i][j-1] == 3)
                        {
                            MAP[i][j] = 0;
                            MAP[i][j-1] = 4;
                            VALIDATION++;
                        }
                        else
                        {
                            *detecteur_caisse = 0;
                        }
                    }
                    if(orientation == DROITE)
                    {
                        if(MAP[i][j+1] == 0)
                        {
                            MAP[i][j] = 0;
                            MAP[i][j+1] = 2;
                        }
                        else if(MAP[i][j+1] == 3)
                        {
                            MAP[i][j] = 0;
                            MAP[i][j+1] = 4;
                            VALIDATION++;
                        }
                        else
                        {
                            *detecteur_caisse = 0;
                        }
                    }
                }
            }
        }
    }
}
 
void gagner(long *choix_continuer)
{
    if(VALIDATION == BLOC_OBJECTIF)
    {
        *choix_continuer = 0;
    }
}
Comme tu le vois j'ai suivis ton conseil de faire une nouvelle fonction, mais toujours une fonction void

En effet voila le code que j'avais fait au début en suivant ta méthode entièrement:

Code :
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
void deplacer_joueur(SDL_Rect *position_joueur, long orientation)
{
    long detecteur_collision = 1;
    long detecteur_caisse = 1;
    long positionX_futur_joueur = 0;
    long positionY_futur_joueur = 0;
 
    if(orientation == HAUT)
    {
        positionY_futur_joueur = position_joueur->y - 1;
        positionX_futur_joueur = position_joueur->x;
 
        detecteur_caisse = deplacer_caisse(&detecteur_caisse, positionX_futur_joueur, positionY_futur_joueur, HAUT);
 
        collision(&detecteur_collision, positionX_futur_joueur, positionY_futur_joueur, HAUT);
 
        if(detecteur_collision && detecteur_caisse)
        {
            position_joueur->y--;
        }
        else{}
    }
    else if(orientation == BAS)
    {
        positionY_futur_joueur = position_joueur->y + 1;
        positionX_futur_joueur = position_joueur->x;
 
        detecteur_caisse = deplacer_caisse(&detecteur_caisse, positionX_futur_joueur, positionY_futur_joueur, BAS);
 
        collision(&detecteur_collision, positionX_futur_joueur, positionY_futur_joueur, BAS);
 
        if(detecteur_collision && detecteur_caisse)
        {
            position_joueur->y++;
        }
        else{}
    }
    else if(orientation == GAUCHE)
    {
        positionX_futur_joueur = position_joueur->x - 1;
        positionY_futur_joueur = position_joueur->y;
 
        detecteur_caisse = deplacer_caisse(&detecteur_caisse, positionX_futur_joueur, positionY_futur_joueur, GAUCHE);
 
        collision(&detecteur_collision, positionX_futur_joueur, positionY_futur_joueur, GAUCHE);
 
        if(detecteur_collision && detecteur_caisse)
        {
            position_joueur->x--;
        }
        else{}
    }
    else if(orientation == DROITE)
    {
        positionX_futur_joueur = position_joueur->x + 1;
        positionY_futur_joueur = position_joueur->y;
 
        detecteur_caisse = deplacer_caisse(&detecteur_caisse, positionX_futur_joueur, positionY_futur_joueur, DROITE);
 
        collision(&detecteur_collision, positionX_futur_joueur, positionY_futur_joueur, DROITE);
 
        if(detecteur_collision && detecteur_caisse)
        {
            position_joueur->x++;
        }
        else{}
    }
}
 
void collision(long *detecteur_collision, long positionX_futur_joueur, long positionY_futur_joueur, long orientation)
{
 
    long i,j;
    SDL_Rect position_bloc;
    position_bloc.x = 0, position_bloc.y = 0;
 
    for(i=0; i<NOMBREY_BLOC;i++)
    {
        for(j=0; j<NOMBREX_BLOC;j++)
        {
            if(MAP[i][j] == 1 || MAP[i][j] == 4 )
            {
                position_bloc.x = j*34;
                position_bloc.y = i*34;
 
                if(positionX_futur_joueur + 20 < position_bloc.x || positionX_futur_joueur + 5 > position_bloc.x +34 || positionY_futur_joueur + 30 < position_bloc.y || positionY_futur_joueur > position_bloc.y + 34)
                {
                    *detecteur_collision = 1;
                }
                else
                {
                    *detecteur_collision = 0;
                }
            }
 
        }
    }
}
 
long deplacer_caisse(long *detecteur_caisse, long positionX_futur_joueur, long positionY_futur_joueur, long orientation)
{
    long i,j;
    SDL_Rect position_caisse;
    position_caisse.x = 0, position_caisse.y = 0;
 
    for(i=0; i<NOMBREY_BLOC;i++)
    {
        for(j=0; j<NOMBREX_BLOC;j++)
        {
            if(MAP[i][j] == 2)
            {
                position_caisse.x = j*34;
                position_caisse.y = i*34;
 
                if(positionX_futur_joueur + 20 < position_caisse.x || positionX_futur_joueur + 5 > position_caisse.x +34 || positionY_futur_joueur + 30 < position_caisse.y || positionY_futur_joueur > position_caisse.y + 34)
                {
                   *detecteur_caisse = 1;
                   return 1;
                }
                else
                {
                    if(orientation == HAUT)
                    {
                        if(MAP[i-1][j] == 0)
                        {
                            MAP[i][j] = 0;
                            MAP[i-1][j] = 2;
                        }
                        else if(MAP[i-1][j] == 3)
                        {
                            MAP[i][j] = 0;
                            MAP[i-1][j] = 4;
                            VALIDATION++;
                        }
                        else
                        {
                            return 0;
                        }
                    }
                    if(orientation == BAS)
                    {
                        if(MAP[i+1][j] == 0)
                        {
                            MAP[i][j] = 0;
                            MAP[i+1][j] = 2;
 
                        }
                        else if(MAP[i+1][j] == 3)
                        {
                            MAP[i][j] = 0;
                            MAP[i+1][j] = 4;
                            VALIDATION++;
                        }
                        else
                        {
                            return 0;
                        }
                    }
                    if(orientation == GAUCHE)
                    {
                        if(MAP[i][j-1] == 0)
                        {
                            MAP[i][j] = 0;
                            MAP[i][j-1] = 2;
                        }
                        else if(MAP[i][j-1] == 3)
                        {
                            MAP[i][j] = 0;
                            MAP[i][j-1] = 4;
                            VALIDATION++;
                        }
                        else
                        {
                            return 0;
                        }
                    }
                    if(orientation == DROITE)
                    {
                        if(MAP[i][j+1] == 0)
                        {
                            MAP[i][j] = 0;
                            MAP[i][j+1] = 2;
                        }
                        else if(MAP[i][j+1] == 3)
                        {
                            MAP[i][j] = 0;
                            MAP[i][j+1] = 4;
                            VALIDATION++;
                        }
                        else
                        {
                            return 0;
                        }
                    }
                }
            }
        }
    }
}
Je coince avec ces lignes:

Code :
1
2
3
4
5
if(positionX_futur_joueur + 20 < position_caisse.x || positionX_futur_joueur + 5 > position_caisse.x +34 || positionY_futur_joueur + 30 < position_caisse.y || positionY_futur_joueur > position_caisse.y + 34)
                {
                   *detecteur_caisse = 1;
                   return 1;
                }
Voila si je ne le fais pas à l'aide d'un pointeur ma fonction déplacer_caisse ne saura géré que le déplacement d'une caisse. Aurais tu une solution afin que je le fasse avec un return et non un pointeur ? (j'abuse peut être trop des pointeurs^^).

Après je vois pas tellement l'utilité d'un return a part pour tester si la fonction s'est bien exécutée, comme tu nous le dis plus haut.
D'ailleurs je vais modifier mon code source afin de vérifier si certaines de mes fonctions se sont bien passées.

Sinon j'aurais une autre question, voila mon problème résolut, mais maintenant y'a un truc qui me gène... C'est de n'avoir pas compris pourquoi mon code en début de sujet ne marchait pas

Cordialement Menudelux.
Menudelux est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 02/04/2012, 03h13   #4
Obsidian
Modérateur
 
Avatar de Obsidian
 
Homme
Chercheur d'emploi
Inscription : septembre 2007
Messages : 4 614
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 36
Localisation : France, Essonne (Île de France)

Informations professionnelles :
Activité : Chercheur d'emploi
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : septembre 2007
Messages : 4 614
Points : 11 078
Points : 11 078
Pourquoi renvoyer le résultat de « collision » via un pointeur plutôt que par le retour de la fonction elle-même ? Si tu la fais renvoyer un booléen, tu peux écrire ensuite :

Code :
1
2
3
4
5
6
7
8
if (collision())
{
    /* Rester sur place */
}
else
{
    /* Se déplacer */
}
À part cela, je te conseille déjà d'utiliser une énumération pour désigner les éléments de ta carte, plutôt que des chiffres en dur, et d'y ajouter le joueur proprement dit :

Code :
    enum element { vide=0, mur=1, caisse, objectif, caisse_ok, joueur };
Je te conseille également de faire la même chose pour les directions :

Code :
    enum direction { HAUT=1, DROITE, BAS, GAUCHE };
Ensuite, tu fais une fonction « déplacer » pouvant potentiellement échouer, donc renvoyant un booléen, et prenant trois arguments : les coordonnées x et y de l'élément de la carte à déplacer, et un paramètre enum direction indiquant dans quel sens il faut se déplacer.

À ce stade, dans le corps de ta fonction, tu commences par définir deux variables « dx » et « dy » en fonction de la direction. Ces variables pouvant toutes deux valoir +1, 0 ou -1. L'avantage est qu'il s'agit de variables locales. Elles ne modifieront donc pas les coordonnées originales.

De là, tu poses plusieurs postulats :
  • Les seules pièces pouvant être déplacées sont : le joueur et les caisses ;
  • Une caisse ne peut être déplacée que si sa destination est « vide » ou « objectif » ;
  • Un joueur ne peut être déplacée que si sa destination est « vide » ou « caisse » ET que cette caisse peut être déplacée d'abord.

Et pour honorer ce dernier point, rien n'empêche ta fonction « déplacer » de se rappeler elle-même en cours de procédure pour déplacer la caisse, puis finir de déplacer le joueur si ça s'est bien passé.

Après il faudra faire attention à différentes choses, comme le fait de ne pas remplacer une case « objectif » par du vide en passant dessus, et autres petites formalités.

Citation:
Envoyé par Menudelux Voir le message
Sinon j'aurais une autre question, voila mon problème résolut, mais maintenant y'a un truc qui me gène... C'est de n'avoir pas compris pourquoi mon code en début de sujet ne marchait pas
Il faudrait que je prenne le temps de le lire en détail pour voir à quelle ligne ça coince mais, en même temps, il est un peu tard et c'est à toi de le faire : le déboguage fait partie intégrante du métier du développeur, et le travail d'enquête peut être très stimulant en soi.
Obsidian est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 15/04/2012, 01h40   #5
Menudelux
Invité de passage
 
Homme Alexis
Étudiant
Inscription : avril 2012
Messages : 8
Détails du profil
Informations personnelles :
Nom : Homme Alexis
Âge : 17
Localisation : France

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : avril 2012
Messages : 8
Points : 2
Points : 2
Désolé pour mon absence je n'avais plus de pc sous la main.

J'ai décidé de tout refaire afin de faire un code performant et à la fois propre.
Je suis donc entrain de suivre tes conseils, pardon si je vais te faire répéter mais je n'arrive pas du tout à comprendre comment tu me conseilles de former ma fonction déplacer.

Citation:
Il faudrait que je prenne le temps de le lire en détail pour voir à quelle ligne ça coince mais, en même temps, il est un peu tard et c'est à toi de le faire : le déboguage fait partie intégrante du métier du développeur, et le travail d'enquête peut être très stimulant en soi.
J'ai tenté de le déboguer avant de poster ce sujet, mais je n'y suis pas arrivé :s

Merci d'avance.
Menudelux est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/04/2012, 02h18   #6
Obsidian
Modérateur
 
Avatar de Obsidian
 
Homme
Chercheur d'emploi
Inscription : septembre 2007
Messages : 4 614
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 36
Localisation : France, Essonne (Île de France)

Informations professionnelles :
Activité : Chercheur d'emploi
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : septembre 2007
Messages : 4 614
Points : 11 078
Points : 11 078
Citation:
Envoyé par Menudelux Voir le message
pardon si je vais te faire répéter mais je n'arrive pas du tout à comprendre comment tu me conseilles de former ma fonction deplacer.
L'idée est de faire une fonction « deplacer() » qui déplace un objet, quel qu'il soit, sur la carte à condition que ce soit possible. Et pour cela, elle prend trois arguments : x, y et un code indiquant dans quel direction on souhaite faire le déplacement (x et y étant les coordonnées sur la carte de l'objet à déplacer).

En retour, cette fonction renvoie 1 si l'objet a bien été déplacé et 0 si elle n'a pas pu le faire.

Dans les faits, la fonction vérifie si l'objet aux coordonnées indiquées est soit le joueur, soit une caisse (bien placée ou pas). Si ce n'est pas le cas, on sort en renvoyant 0 tout de suite car tout autre objet (les murs, donc) est inamovible.

Si c'est une caisse, il faut que sa destination soit vide ou soit un des points de stockage à atteindre ;

Si c'est le joueur, il faut que sa destination soit vide, un point de stockage ou soit une caisse que l'on peut déplacer. Et pour vérifier ce dernier point le cas échéant, il suffit de rappeler récursivement « déplacer() » alors qu'on est encore dedans, en passant les coordonnées de la caisse. Si cet appel-là renvoie 0, la caisse ne peut être déplacée et le joueur non plus, par conséquent. On ressort donc en renvoyant 0 également, en cascade.

Mais si l'appel a renvoyé 1, alors non seulement la caisse peut être déplacée mais elle vient de l'être ! Il n'y plus qu'à déplacer le joueur qui est désormais face au vide et à renvoyer 1 également, en cascade, pour signifier à la fonction principale que le déplacement des deux éléments s'est bien passé.
Obsidian est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 22/04/2012, 21h11   #7
Menudelux
Invité de passage
 
Homme Alexis
Étudiant
Inscription : avril 2012
Messages : 8
Détails du profil
Informations personnelles :
Nom : Homme Alexis
Âge : 17
Localisation : France

Informations professionnelles :
Activité : Étudiant

Informations forums :
Inscription : avril 2012
Messages : 8
Points : 2
Points : 2
Merci bien pour l'aide Obsidian.
Je pense avoir compris, je pars donc direct recoder mon mario sokoban en entier
Menudelux est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Cette discussion est résolue.
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 06h23.


 
 
 
 
Partenaires

Hébergement Web