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

C++ Discussion :

[Tétris]Bug de code


Sujet :

C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2007
    Messages : 24
    Par défaut [Tétris]Bug de code
    Bonjour

    Je suis en train de coder mon propre tétris et je suis face à un drôle de problème.

    Lorsque le bloc arrive, il tombe normalement:


    Mais lorsqu'il a touché le "sol", une copie de ce bloc se place au milieu du jeu.
    (Je pense que le bloc est placé en Y avec les coordonnées de X).
    Voici une petite image montrant le problème:

    (Le carré du haut est l'intrus).

    Voici le code utilisé pour générer les coordonnées du bloc:
    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
    case 2:  //Case 2 == CARRE
    /*
    pos est de type SDL_Rect et est un tableau de 4 cases.  Il contient les coordonnées du bloc en train de tomber.
    */
            case 2:  //Carré
            if(carte[pos[2].x][pos[2].y+1] == 0 && carte[pos[3].x][pos[3].y+1] == 0
            && (pos[2].y+1) < NB_BLOCS_H){
                for(int i=0;i<4;i++){
                    pos[i].y++;
                }
            }
            if(pos[2].y+1 == NB_BLOCS_H || carte[pos[2].x][pos[2].y+1] != 0
            || carte[pos[3].x][pos[3].y+1] != 0){
                carte[x_1][y_1] = 4;
                carte[pos[1].x][pos[1].y] = 4;
                carte[pos[2].x][pos[2].y] = 4;
                carte[pos[3].x][pos[3].y] = 4;
                pos[0].x = -1;
                pos[0].y = -1;
                pos[1].x = -1;
                pos[1].y = -1;
                pos[2].x = -1;
                pos[2].y = -1;
                pos[3].x = -1;
                pos[3].y = -1;
                etat = true;
     
            }
            break;
    Voici le code qui colle les images à l'écran:
    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
    //Blittage du décor
        for(int i=0;i<NB_BLOCS_L;i++){
            for(int j=0;j<NB_BLOCS_H;j++){
                position.x = i*TAILLE_BLOC;
                position.y = j*TAILLE_BLOC;
                switch(carte[i][j]){
                    case 0:
                    SDL_BlitSurface(vide, NULL, ecran, &position);
                    break;
                    case 1://Ligne
                    SDL_BlitSurface(jaune, NULL, ecran, &position);
                    break;
                    case 2://Bloc
                    SDL_BlitSurface(rouge, NULL, ecran, &position);
                    break;
    //Pour l'instant, seul 2 "case" sont faits.
                }
               //Blittage du bloc en cours de descente
                for(int alpha=0;alpha<4;alpha++){
                    if(pos_piece[alpha].x == i && pos_piece[alpha].y == j){
                        position.x = i*TAILLE_BLOC;
                        position.y = j*TAILLE_BLOC;
                        SDL_BlitSurface(jaune, NULL, ecran, &position);
                    }
                }//Fin du "for"
            }
        }

    Ou est le problème?

    Merci d'avance.

  2. #2
    Rédacteur
    Avatar de darrylsite
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    1 299
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Juillet 2007
    Messages : 1 299
    Par défaut
    je crois qu' il sera un peu difficile de t' aider. Tu ne commentes meme pas le code incomplet que tu nous donnes. On ne peut pas vraiment deviner ce que tu veux que le programme faisse. Ni quelle methode tu utilisée pour construire le programme.
    switch(carte[i][j]){
    case 0:
    Le 0 signifie quoi ?

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2007
    Messages : 24
    Par défaut
    En fait, chaque bloc est un nombre de 1 à 7 (il y a 7 blocs). Les coordonnées de ce bloc sont stockées dans une variable de type SDL_Rect. (Dans la fonction, elle s'appelle "pos[]" et c'est un tableau de 4 (il y a 4 blocs dans chaque figure).

    Une fonction se charge donc de faire descendre le bloc et tout se passe parfaitement.

    Ensuite, si le bloc ne peut plus descendre (s'il est arrivé au bas de l'écran ou a touché un autre bloc), LE BLOC EST ECRIT DANS LA VARIABLE "carte" qui est un tableau de int.

    Dans la boucle principale, il suffit juste d'afficher le contenu de la varialbe carte
    (carte[i][j] est le numéro de la case parcourue par la boucle).
    Dans mon code, 0 vaut "vide", un fond vide est donc affiché.
    Suivant le nombre que c'est, un bloc d'une couleur X ou Y est "Blitté".

    Le problème est que lorsque le bloc s'arrête, il s'affiche correctement, mais un autre bloc intrus apparait ET RESTE QUOI QU'IL SE PASSE!!!
    (le carré supérieur du secont PrintScreen).

    Les fonctions de descente et d'affichange sont dans une classe nommée bloc.
    Voici l'entiereté de ma fonction "descente" (elle n'est pas terminée) qui se charge, si le bloc ne peut plus descendre, de le "fixer" dans la variable "carte".
    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
     
    bool bloc::descente(SDL_Rect *pos, int piece, int carte[][NB_BLOCS_L]){
        bool etat = false;
     
        switch(piece){
            case 1://Barre horizontale
            if(carte[pos[0].x][pos[0].y+1] == 0 && carte[pos[1].x][pos[1].y+1] == 0
            && carte[pos[2].x][pos[2].y+1] == 0 && carte[pos[3].x][pos[3].y+1] == 0
            && pos[0].y+1 < NB_BLOCS_H){
                for(int i=0;i<4;i++){
                    pos[i].y++;
                }
            }
            if(pos[0].y+1 == NB_BLOCS_H){
                for(int i=0;i<4;i++){
                    carte[pos[i].x][pos[i].y] = 1;
                }
                //Piochage d'un nouveau bloc
                etat = true;
            }
            break;
            case 2:  //Carré
            if(carte[pos[2].x][pos[2].y+1] == 0 && carte[pos[3].x][pos[3].y+1] == 0
            && (pos[2].y+1) < NB_BLOCS_H){
                for(int i=0;i<4;i++){
                    pos[i].y++;
                }
            }
            if(pos[2].y+1 == NB_BLOCS_H){
                for(int i=0;i<4;i++){
                    carte[pos[i].x][pos[i].y] = 2;
                }
                //Piochage d'un nouveau bloc
                etat = true;
            }
            break;
            case 3: //T
            if(carte[pos[0].x][pos[0].y+1] == 0 && carte[pos[2].x][pos[2].y+1] == 0
            && carte[pos[3].x][pos[3].y+1] == 0 && pos[3].y+1 < NB_BLOCS_H){
                for(int i=0;i<4;i++){
                    pos[i].y++;
                }
            }
            if(pos[3].y+1 == NB_BLOCS_H || carte[pos[3].x][pos[3].y+1] !=0
            || carte[pos[0].x][pos[0].y+1] != 0 || carte[pos[2].x][pos[2].y+1] != 0){
                for(int i=0;i<4;i++){
                    carte[pos[i].x][pos[i].y] = 3;
                }
                //Piochage d'un nouveau bloc
                etat = true;
            }
            break;
            case 4:
            if(carte[pos[2].x][pos[2].y+1] == 0 && carte[pos[3].x][pos[3].y+1] == 0
            && pos[3].y+1 < NB_BLOCS_H){
                for(int i=0;i<4;i++){
                    pos[i].y++;
                }
            }
            if(pos[2].y+1 == NB_BLOCS_H || carte[pos[2].x][pos[2].y+1] != 0
            || carte[pos[3].x][pos[3].y+1] != 0){
                for(int i=0;i<4;i++){
                    carte[pos[i].x][pos[i].y] = 4;
                }
                //Piochage d'un nouveau bloc
                etat = true;
            }
            break;
            case 5:
            if(carte[pos[2].x][pos[2].y+1] == 0 && carte[pos[3].x][pos[3].y+1] == 0
            && pos[3].y+1 < NB_BLOCS_H){
                for(int i=0;i<4;i++){
                    pos[i].y++;
                }
            }
            if(pos[2].y+1 == NB_BLOCS_H || carte[pos[2].x][pos[2].y+1] != 0
            || carte[pos[3].x][pos[3].y+1] != 0){
                for(int i=0;i<4;i++){
                    carte[pos[i].x][pos[i].y] = 5;
                }
                //Piochage d'un nouveau bloc
                etat = true;
            }
            break;
        }
     
     
     
        return etat;
    }
    La variable de type bool qui est renvoyée indique simplement s'il faut ou non sélectionner une nouvelle piece.
    -Le code n'est pas optimisé, j'ai trouvé un moyen plus rapide que 3 boucles pour "fixer" le bloc qui descend dans la varialbe "carte", mais je n'ai pas encore eu le temps de changer.


    Voici maintenant une partie de la fonction "jouer" qui se charger de gérer...tout le jeu
    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
     
    //Descente de la piece:(appel de la fonction descente donnée ci-dessus).
        forme_posee = piece.descente(pos_piece, piece, carte);
    /*
    pos_piece est le tableau de SDL_Rect contenant la position de la piece
    piece est le type de pièce qui est en train de descendre
    carte est le tableau de int contenant toute la carte du jeu
    */
     
     
        /*Blittage du menu(il n'est pas terminé et n'est qu'un simple morceau rouge!)*/
        SDL_FillRect(menu, NULL, SDL_MapRGB(ecran->format, 255, 0, 0));
        pos_menu.y = 0;
        pos_menu.x = (NB_BLOCS_L * TAILLE_BLOC);
        SDL_BlitSurface(menu, NULL, ecran, &pos_menu);
     
        /*Blittage du décor (double boucle pour parcourir toute l'étendu de la variable carte[NB_BLOCS_L][NB_BLOCS_H]*/
        for(int i=0;i<NB_BLOCS_L;i++){
            for(int j=0;j<NB_BLOCS_H;j++){
               //Création des différentes positions pour tous les blocs
                position.x = i*TAILLE_BLOC;
                position.y = j*TAILLE_BLOC;
     
               //Parcours de la carte et affichage de ce qu'elle contient
                switch(carte[i][j]){
                    case 0://Si la carte est vide
                    SDL_BlitSurface(vide, NULL, ecran, &position);
                    break;
     
                    //Les différents nombres servent à afficher différentes couleurs.
                    case 1:
                    SDL_BlitSurface(jaune, NULL, ecran, &position);
                    break;
                    case 2:
                    SDL_BlitSurface(rouge, NULL, ecran, &position);
                    break;
                    case 3:
                    SDL_BlitSurface(bleu, NULL, ecran, &position);
                    break;
                    case 4:
                    SDL_BlitSurface(vert, NULL, ecran, &position);
                    break;
                    case 5:
                    SDL_BlitSurface(mauve, NULL, ecran, &position);
                    break;
                }
     
     
                //Blittage de la pièce qui descend
                for(int alpha=0;alpha<4;alpha++){
                    if(pos_piece[alpha].x == i && pos_piece[alpha].y == j){
                        position.x = i*TAILLE_BLOC;
                        position.y = j*TAILLE_BLOC;
                        SDL_BlitSurface(jaune, NULL, ecran, &position);
                    }
                }//Fin du "for"
            }
        }
    Voilà, j'espère que je me suis bien exprimé

    Merci de votre aide.

    EDIT: le code qui place le bloc dans la variable "carte" a été quelque peu amélioré mais le problème reste le même.

  4. #4
    Membre expérimenté
    Profil pro
    Dev
    Inscrit en
    Décembre 2007
    Messages
    191
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations professionnelles :
    Activité : Dev

    Informations forums :
    Inscription : Décembre 2007
    Messages : 191
    Par défaut
    Le problème est que lorsque le bloc s'arrête, il s'affiche correctement, mais un autre bloc intrus apparait ET RESTE QUOI QU'IL SE PASSE!!!
    (le carré supérieur du secont PrintScreen).
    Est ce que le jeu interagit avec le bloc, c'est-à-dire est ce juste un affichage parasite ou peux tu poser les nouveaux blocs dessus ?

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2007
    Messages : 24
    Par défaut
    Les nouveaux blocs qui tombent se "fixent" sur ce bloc.
    Voici un petit shéma annoté qui explique las bugs:


    (J'ai tracé des lignes rouges pour que vous voyez bien la séparation des blocs.)

  6. #6
    Membre éprouvé
    Inscrit en
    Décembre 2006
    Messages
    103
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 103
    Par défaut
    Bonjour,
    ce que je ferai, c'est que je regarderai que la coordonnée de X pour savoir à quel endroit il est tombé, avec la détection de collision quand il tombe, puis je le fixerai dans une carte intermédiaire.
    Utilise plus le côté POO du C++, je te dirai de tout gérer les blocs dans une classe à eux, puis de faire une classe pour le jeu avec ses données personnelles, c'est ce que j'ai fait pour mon tétris (si je retrouve le code, je te le montre.).

    A plus.

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2007
    Messages : 24
    Par défaut
    J'ai découvert qqch de curieux:
    Voici les coordonnées des 4 blocs au moment où ils ont touché le "sol":
    8 29
    9 29
    10 29
    11 29
    et voici les coordonnées auxquelles ont été blittées des blocs:
    BLIT 8 29
    BLIT 9 9
    BLIT 9 29
    BLIT 10 9
    BLIT 10 29
    BLIT 11 9
    BLIT 11 29
    BLIT 12 9
    J'ai essayé de faire mon "case" le plus simple possible, mais je ne vois toujours pas pourquoi ça bugge.
    Revoici le "case" du bloc qui tombait à ce moment:
    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
    case 1: //Si c'est une barre:
                if(carte[pos[0].x][pos[0].y+1] == 0 && carte[pos[1].x][pos[1].y+1] == 0
            && carte[pos[2].x][pos[2].y+1] == 0 && carte[pos[3].x][pos[3].y+1] == 0
            && pos[0].y+1 < NB_BLOCS_H){
                for(int i=0;i<4;i++){
                    pos[i].y++;
                }
            }
            else{
               for(int i=0;i<4;i++)
                {
                    carte[pos[i].x][pos[i].y] = 1;
                pos[i].x=-1;
                pos[i].y=-1;
                }
     
               //Piochage d'un nouveau bloc
               forme = true;
            }
     
            break;
    @30barrett40:
    Que veux-tu dire par "une carte intermédiaire"?

  8. #8
    Membre expérimenté
    Profil pro
    Dev
    Inscrit en
    Décembre 2007
    Messages
    191
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations professionnelles :
    Activité : Dev

    Informations forums :
    Inscription : Décembre 2007
    Messages : 191
    Par défaut
    LEs résultats du débug que tu as fait (affichage des blits) sont intéressants : cela veut, je pense, surement dire que le problème est au moment ou la variable carte est écrite :

    Citation Envoyé par chindit Voir le message
    Ensuite, si le bloc ne peut plus descendre (s'il est arrivé au bas de l'écran ou a touché un autre bloc), LE BLOC EST ECRIT DANS LA VARIABLE "carte" qui est un tableau de int.

    où est la partie du code qui teste si cette variable :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    //Descente de la piece:(appel de la fonction descente donnée ci-dessus).
        forme_posee = piece.descente(pos_piece, piece, carte);
    est true ? (et donc je suppose que tu écris dans carte[][] à ce moment là).

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2007
    Messages : 24
    Par défaut
    La pièce qui tombe est écrite dans la variable carte dans le "case" de la fonction qui teste si le bloc peut encore descendre (cf message précédent pour le code).

    Depuis que j'ai posté le message précédent, la fonction ne renvoie plus la variable bool mais la modifie en tant que référence (ce qui ne change pas beaucoup).

    Voici la partie qui teste si la variable vaut "true" et qui sélectionne une nouvelle pièce. Mais je ne vois pas en quoi ce "if" pourrait être à l'origine du bug!
    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
    new_time = SDL_GetTicks();
        if(new_time - old_time > delai){
    //SI assez de temps s'est écoulé, activation des fonctions
     
        //Couleur de fond de l'écran == NOIR
        SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 0, 0, 0));
     
    	if(forme_posee){
    //Si on peut choisir une nouvelle pièce
            piece_future = piece.select_forme();
    //Sélection de la pièce
            forme_posee = false;
    //Mise à "false" de la variable de sélection
            piece.place_bloc(pos_piece, piece_future);
    //Préparation des coordonnées initiales du bloc
        }

  10. #10
    Membre éprouvé
    Inscrit en
    Décembre 2006
    Messages
    103
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 103
    Par défaut
    Au lieu d'utiliser une variable carte comme tu la définie, fais un tableau petit avec lors de la conversion pour l'image une constante correspondant à la largeur d'un bloc.

    Pour sélectionner un nouveau bloc, copie l'écran actuel dans une surface temporaire. Sinon, je ne vois pas pourquoi

Discussions similaires

  1. Bug en code C
    Par hred1 dans le forum C
    Réponses: 1
    Dernier message: 07/10/2011, 15h37
  2. Bug ie7 ? Code html pur qui fait prendre 100% de cpu à IE7
    Par Rakken dans le forum Mise en page CSS
    Réponses: 8
    Dernier message: 06/01/2009, 10h53
  3. Bug du code erreur 2051
    Par popof60 dans le forum VBA Access
    Réponses: 6
    Dernier message: 25/01/2008, 09h49

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