[SDL 2] Problème lors de l'actualisation de l'interface

L’auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Bonjour à tous, j’essaye de réaliser un jeu de dames en C, cela me permet de découvrir le SDL 2 grâce au magnifique tuto disponible sur ce site.

Cependant j’ai un comportement super bizarre que je n’arrive pas à identifier/ déboguer. Il s’agit manifestement d’une mauvaise manip du SDL mais je ne parviens pas à mettre le doigt dessus, et je ne sais pas trop quoi rechercher puisque je débute l’IHM.

C’est sûrement un truc tout con mais je préfère comprendre mon erreur plutôt que de try hard pour la trouver et bêtement la corriger.

Merci pour votre aide :)

Voici la fonction belliqueuse :

void drawGame(SDL_Renderer *renderer, struct piece whitePieces[], struct piece blackPieces[], int nbPieces, int boardSize) {
    SDL_Color yellow = {255, 240, 140, 0};

    setWindowColor(renderer, yellow);
    drawboard(renderer, boardSize);  // Le programme plante lorsqu'il doit dessiner le plateau de jeu pour la deuxième fois

    drawPieces(renderer, whitePieces, nbPieces, WHITE);
    drawPieces(renderer, blackPieces, nbPieces, BLACK);

    SDL_RenderPresent(renderer);
}

Dessine les pions :

void drawPieces(SDL_Renderer *renderer, struct piece pieces[], int nbPieces, int color){
    SDL_Rect imageParams = {0, 0, 0, 0};
    SDL_Rect pieceParams = {0, 0, 0, 0};
    SDL_Texture *pieceImage = NULL;

    if(color == WHITE){
        pieceImage = loadImage("assets/whitePiece.bmp", renderer);
    }
    else {
        pieceImage = loadImage("assets/blackPiece.bmp", renderer);
    }

    SDL_QueryTexture(pieceImage, NULL, NULL, &imageParams.w, &imageParams.h);

    for(int i=0; i<nbPieces; i++) {

        pieceParams.w = imageParams.w/10 + pieces[i].width;
        pieceParams.h = imageParams.h/15 + pieces[i].height;
        pieceParams.x = (((pieceParams.w + SPACING_WIDTH) * pieces[i].posX) - OFFSET_WIDTH);
        pieceParams.y = (((pieceParams.h + SPACING_HEIGHT) * pieces[i].posY) - OFFSET_HEIGHT);

        pieces[i].posY = pieceParams.y;
        pieces[i].posX = pieceParams.x;

        SDL_RenderCopy(renderer, pieceImage, NULL, &pieceParams);
        SDL_SetRenderTarget(renderer, pieceImage);
    }


    if(NULL != pieceImage)
        SDL_DestroyTexture(pieceImage);
}

Dessine le plateau de jeu :

void drawboard(SDL_Renderer *renderer, int size){
    int nbSquare = (size * size);
    SDL_Rect damierWhite[nbSquare/2];
    SDL_Rect damierBlack[nbSquare/2];
    int posX=0; int posY=0; int idxW = 0; int idxB = 0;

    for(int i = 0; i<nbSquare; i++){
        if(((i + posY) % 2) == 0){
            damierBlack[idxB].w = 60;
            damierBlack[idxB].h = 60;
            damierBlack[idxB].x = 10 + posX*60;
            damierBlack[idxB].y = 10 + posY*60;
            idxB++;
        }
        else{
            damierWhite[idxW].w = 60;
            damierWhite[idxW].h = 60;
            damierWhite[idxW].x = 10 + posX*60;
            damierWhite[idxW].y = 10 + posY*60;
            idxW++;
        }
        if(posX == size-1){
            posX = 0;
            posY++;
        }
        else{
            posX++;
        }
    }
    SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
    SDL_RenderFillRects(renderer, damierBlack, nbSquare/2);
    SDL_SetRenderDrawColor(renderer, 100, 100, 100, 255);
    SDL_RenderFillRects(renderer, damierWhite, nbSquare/2);
}

Et voilà comment elle est innocemment appelée :

drawGame(renderer, whitePieces, blackPieces, nbPieces, boardSize);
SDL_Delay(5000);
drawGame(renderer, whitePieces, blackPieces, nbPieces, boardSize);

Et voila le resultat lors du premier appel, puis du second. Avec dans la console : Process returned 1 (0x1) Image utilisateur Image utilisateur

Édité par Boruwaka

+0 -0

Bon je connais pas SDL, mais as-tu tenté les mesure de débogage classique (débogueur, print (plus sale, mais peut être utile quand même), …) ça pourrait déjà te permettre de localiser la ligne qui pose problème.

+0 -0
Auteur du sujet

Yes, il s’agit de la ligne 5 de drawGame(), lorsque le programme doit dessiner sur l’écran après cette fonction, cela dessine en bleu et fait planter la suite du programme.

Plus précisément, il s’agit du fait de dessiner le damier, d’abord les blancs (bleu clair) et ensuite les noirs (bleu foncé), je ne vois vraiment pas ce qui peut coincer :honte:

Captures à l’appui :

image.png
image.png
image.png
image.png

Édité par Boruwaka

+0 -0

Salut @Boruwaka,

Tu peux poster le code complet (peut-être sur un git pour que ce soit plus simple). Il y a quelques petits soucis dans le code et certaines simplifications possibles. Par exemple tu charges les images des pièces à chaque fois que tu appelles la fonction ; c’est plus simple de les charger une seule fois au début. Pariel ta fonction pour dessiner le damier est plutôt compliquée.

Assez des salamis, je passe au jambon — Je fais un carnage si ce car nage car je nage, moi, Karnaj ! — Le comble pour un professeur de mathématique ? Mourir dans l’exercice de ses fonctions.

+0 -0

Pas mal de chose qui ne vont pas dans ton code.

En premier, je dirais que SDL_RenderPresent n’est pas correcte. Normalement, tu l’appeles qu’une seule fois. Ça, c’est certainement la source de tes problèmes de couleurs.

Le deuxième point, c’est le calcul des coordonnées des pièces. La première fois, ça va mais ensuite rien ne va plus.

    for(int i=0; i<nbPieces; i++) {

        pieceParams.w = imageParams.w/10 + pieces[i].width;
        pieceParams.h = imageParams.h/15 + pieces[i].height;
        pieceParams.x = (((pieceParams.w + SPACING_WIDTH) * pieces[i].posX) - OFFSET_WIDTH);
        pieceParams.y = (((pieceParams.h + SPACING_HEIGHT) * pieces[i].posY) - OFFSET_HEIGHT);

        pieces[i].posY = pieceParams.y;
        pieces[i].posX = pieceParams.x;

        SDL_RenderCopy(renderer, pieceImage, NULL, &pieceParams);
        SDL_SetRenderTarget(renderer, pieceImage);
    }

Ici, je ne comprend rien à ton calcul. Que fais SetRenderTarget ? Tu ne souhaites pas modifier piecesImage alors ne l’utilise pas. Pourquoi tu modifies posX et posY ? C’est pas censé être la position sur le damier et pas sur le rendu ? Si oui, alors tu n’as pas besoin de modifier ces valeurs. Une bonne méthode est de rendre constant pieces.

Bref, tu mélanges beaucoup de choses j’ai l’impression !

Édité par ache

ache.one                 🦹         👾                                🦊

+2 -0

Pour compléter ce que dit @ache, tu dois séparer la logique du jeu de l’affichage. Tu devrais pouvoir écrire ton programme consolecet juste changer les endroits où tu gères les entrées sorties.

Dans le brouillon du tuto SDL, on a un peu un exemple avec un morpion.

Édité par Karnaj

Assez des salamis, je passe au jambon — Je fais un carnage si ce car nage car je nage, moi, Karnaj ! — Le comble pour un professeur de mathématique ? Mourir dans l’exercice de ses fonctions.

+1 -0
Auteur du sujet

Merci à tous de votre aide :)

En premier, je dirais que SDL_RenderPresent n’est pas correcte. Normalement, tu l’appeles qu’une seule fois. Ça, c’est certainement la source de tes problèmes de couleurs.

ache

Je ne pensais pas que l’appeler plusieurs fois à la suite pouvait poser soucis, merci pour l’info.

Le deuxième point, c’est le calcul des coordonnées des pièces. La première fois, ça va mais ensuite rien ne va plus. Ici, je ne comprend rien à ton calcul. Que fais SetRenderTarget ? Tu ne souhaites pas modifier piecesImage alors ne l’utilise pas. Pourquoi tu modifies posX et posY ? C’est pas censé être la position sur le damier et pas sur le rendu ?

ache

Oui j’ai mélangé posX, posY avec les calculs de rendu pour déterminer quand je suis au dessus de tel ou tel pièce :honte:

Tu dois séparer la logique du jeu de l’affichage. Tu devrais pouvoir écrire ton programme console et juste changer les endroits où tu gères les entrées sorties. Dans le brouillon du tuto SDL, on a un peu un exemple avec un morpion.

Karnaj

Merci de m’avoir fait découvrir ce tuto, j’aimerai le réaliser à l’occasion. J’ai séparé le code en mettant la "logique" dans le main, le "rendering" dans un fichier à part et les #define ainsi que la déclaration de la structure, encore à part.

Pour conclure : Après avoir réorganisé le code, testé chaque retour de fonction SDL/interne, créé un fichier d’erreur pour pouvoir fprintf() dedans, changé l’algo pour ne pas mélanger la position d’une pièce et sa position sur le rendu.. Mon problème de couleur s’est résolu de lui même :ange: . Je pense que c’était en rapport avec le fait de réinitialiser l’image à chaque fois qui posait soucis.

Merci de votre aide à tous :)

(A force de pratique, j’apprécie de plus en plus le SDL, c’est normal docteur ? :B )

+1 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte