IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SDL Discussion :

Détection collisions Sokoban like


Sujet :

SDL

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2012
    Messages : 13
    Points : 14
    Points
    14
    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 : 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
    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 : 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
    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.

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 370
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 370
    Points : 23 625
    Points
    23 625
    Par défaut
    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.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2012
    Messages : 13
    Points : 14
    Points
    14
    Par défaut
    Yes merci de l'aide mais je n'ai pas pu appliquer entièrement ta méthode proposée, voila mon nouveau code:

    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
    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 : 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
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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.

  4. #4
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 370
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 370
    Points : 23 625
    Points
    23 625
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
        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 : Sélectionner tout - Visualiser dans une fenêtre à part
        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.

  5. #5
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2012
    Messages : 13
    Points : 14
    Points
    14
    Par défaut
    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.

    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.

  6. #6
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 370
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 370
    Points : 23 625
    Points
    23 625
    Par défaut
    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é.

  7. #7
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Avril 2012
    Messages
    13
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2012
    Messages : 13
    Points : 14
    Points
    14
    Par défaut
    Merci bien pour l'aide Obsidian.
    Je pense avoir compris, je pars donc direct recoder mon mario sokoban en entier

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 11/02/2014, 21h44
  2. détection collision rayon triangle par shader
    Par dark poulpo dans le forum OpenGL
    Réponses: 8
    Dernier message: 06/02/2013, 02h23
  3. [FLASH MX PRO] Détection des collisions
    Par Invité dans le forum Flash
    Réponses: 10
    Dernier message: 07/03/2006, 18h20
  4. [Optimisation]Détection de collisions, boucles imbriquées
    Par Rafy dans le forum Algorithmes et structures de données
    Réponses: 1
    Dernier message: 05/03/2006, 18h42
  5. Réponses: 4
    Dernier message: 25/09/2004, 09h58

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo