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

Le problème exposé dans ce sujet a été résolu.

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

+0 -0

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
+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.

+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 !

+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.

+1 -0

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 )

Bonjour s’il vous plait j’ai un soucis.

Lorsque j’ouvre mon program SDL2 avec l’invite de commande (avec SDL_QUIT mise comme evenement) elle reste bien allume jusqu’a se que je la ferme. Or lorsque je part l’ouvrire dan le dossier bin elle fait juste un flash et s’eteint .

Bonjour @Kamgaotso, essaye de créer ton propre sujet pour ta question. Aussi, donne un exemple de code source.

D’ici, je comprends vite fait le problème mais pas le pourquoi. Avec le code ça sera plus claire.

Mais surtout crée ton propre sujet.

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

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