Partage
  • Partager sur Facebook
  • Partager sur Twitter

Problème multiples draw en SFML

Sujet résolu
    21 septembre 2017 à 11:46:59

    Salut les zéros!

    J'ai aujourd'hui besoin de l'aide de ce précieux forum, je n'ai malheureusement pas pu résoudre mon problème moi même ce coup-ci ^^.

    Je suis en train de développer un énième jeu en SFML (un flappy bird like) que je voudrais une fois terminé, le porter sur android. J'utilise l'IDE qtcreator. 

    Mais je suis tomber sur un os, je développe ce projet sur un nouveau pc (un Asus ROG G552VW-CN448T, i7-6700HQ, 8go de RAM, GTX 960m). Et je rencontre le problème suivant: si je dessine 5 objets dans la fenêtre de rendu tout va bien, le jeu est fluide et marche niquel. Par contre si je rajoute un 6e objet c'est le drame, l'écran devient tout noir et rien n’apparaît, mais le plus étrange c'est que je peux supprimer n'importe lequel de mes 6 draws et ça remarche, il ne veux juste pas afficher plus de 5 draws. 

    En plus mon code marche sur mon PC fixe (i5 4670k, 16go de RAM et une GTX 970)...

    J'ai vérifié mon utilisation CPU et l'utilisation RAM de mon jeu, ils ne sont même pas élevés (40mo d'utilisé et 0.3% de CPU en général).

    Voilà, j'ai vraiment besoin de votre aide sur ce coup...

    Merci d'avance

    Hugo

    Lien github du projet:

    https://github.com/hbollon/Flappy_Bird

    Code de mon fichier main:

    #include <iostream>
    #include <time.h>
    #include "player.h"
    #include "game.h"
    #include "ground.h"
    #include "pipedown.h"
    #include "pipeup.h"
    #include <SFML/Graphics.hpp>
    #include <SFML/Window.hpp>
    #include <SFML/System.hpp>
    
    int i=0;
    
    int main()
    {
        sf::RenderWindow game(sf::VideoMode(1920, 1080), "Flappy Bird", sf::Style::Fullscreen);
    
        game.setFramerateLimit(60);
        game.setKeyRepeatEnabled(false);
    
        player bird;
        PipeUp pipeU;
        PipeDown pipeD;
        ground ground1(-500);
        ground ground2(1420);
    
        loadTextures();
    
        sf::Vector2f center(bird.getX() + 700, bird.getY() + 530);
        sf::Vector2f size (1920,1080);
        sf::View vue (center, size);
    
        while (game.isOpen())
        {
            if (i>6)
            {
            bird.animation();
            i=0;
            }
            i++;
    
            sf::Event event;
    
            while (game.pollEvent(event))
            {
                if (event.type == sf::Event::Closed)
                    game.close();
    
                if (event.type == sf::Event::KeyPressed)
                    if(event.key.code == sf::Keyboard::Escape)
                        game.close();
                if (event.type == sf::Event::KeyPressed)
                {
                    if (event.key.code == sf::Keyboard::Space)
                    {
                        bird.jump();
                    }
                }
            }
    
            bird.gravity();
            s_background.setPosition(back_X += 4, back_Y);
    
            if (counter >= 480)
            {
                counter = 0;
                switch (testGround)
                {
                case 0:
                    ground1.moveGround();
                    testGround++;
                    break;
                case 1:
                    ground2.moveGround();
                    testGround = 0;
                    break;
                default:
                    break;
                }
             }
    
            if (counterT >= 100)
            {
                counterT = 0;
                random = 0;
                srand(time(NULL));
                random = (rand() % (MAX - MIN + 1)) + MIN;
            }
    
            counter++;
            counterT++;
    
            game.clear();
    
            game.draw(s_background);
            game.draw(ground1.getSpriteGround());
            game.draw(ground2.getSpriteGround());
            game.draw(pipeU.getSpritePipeUp());
            game.draw(pipeD.getSpritePipeDown());
            game.draw(bird.getSprite());
    
            vue.setCenter(center);
            game.setView(vue);
            bird.getPosition();
    
            center.x = bird.getX() + 700;
    
            game.display();
        }
    
        return 0;
    }
    
    void loadTextures()
    {
        if (!t_background.loadFromFile("background.png"))
        {
            std::cout << "Error when loading background.png" << std::endl;
        }
        else
        {
            std::cout << "Loading background.png successful" << std::endl;
        }
    
        s_background.setTexture(t_background);
        s_background.setPosition(back_X, back_Y);
    }
    



    -
    Edité par hbollon 21 septembre 2017 à 11:49:51

    • Partager sur Facebook
    • Partager sur Twitter

    Projet en cours : Site/Blog professionnel
    A venir: Fondation d'une auto-entreprise de e-commerce et création d'une plateforme web avec Laravel et l'api Bagisto.
    GitHub : https://github.com/hbollon 
    Sites : Parrainage Boursorama , (à venir ^^)

      21 septembre 2017 à 15:36:44

      Sur le point purement fonctionnel, sans avoir testé, il ne me semble pas y avoir de problèmes avec ton code.

      Peut être un problème de texture mal initialisé, ou un truc dans un état indéterminé qui traine ?

      Sinon, tu as pas mal de problèmes niveau conception et langage dans ton code:

      • Pas d'utilisation de srand et rand, on utilise l'entête <random> en c++
      • Pas de variables globales, il te faut virer tout ce que tu as dans Game.h
      • Ton .pro est assez mal écrit :
      • INCLUDEPATH += C:/SFML/include
        DEPENDPATH += C:/SFML/include
        /// tu n'as pas besoin de l'indiquer plusieurs fois
        
        win32:CONFIG(release, debug|release): LIBS += -LC:/SFML/lib/ -lsfml-audio-
        else:win32:CONFIG(debug, debug|release): LIBS += -LC:/SFML/lib/ -lsfml-audio-d
        
        ///Tu peut tout simplement remplacer ces lignes par quelque chose comme ca
        
        CONFIG(release, debug|release): LIBS += -lsfml-graphics-s \
                                                -lsfml-window-s \
                                                -lsfml-audio-s \
                                                -lsfml-system-s 
        
        CONFIG(debug, debug|release): LIBS +=   -lsfml-graphics-s-d \
                                                -lsfml-window-s-d \
                                                -lsfml-audio-s-d \
                                                -lsfml-system-s-d 
        
      • Pourquoi ceci ?
      • void player::getPosition()
        {
            m_X = s_bird.getPosition().x;
            m_Y = s_bird.getPosition().y;
        }
        
        int player::getX() const
        {
            return m_X;
        }
        
        int player::getY() const
        {
            return m_Y;
        }
        
        // Tu peut tout simplement virer ton getPosition et faire les recupération directe des données de tes sprites (de plus ces positions sont des flottants)
        int player::getX() const
        {
            return s_bird.getPosition().x;
        }
      • Tes classes pipeup, pipedown et ground sont très similaire, a quelques données prêt, tu peu facilement faire une classe générique commune, et spécifier ce que tu veut comme donnée a travers le constructeur
      • Pour ton git, tu n'as pas besoin d'envoyer les dossier de build. Tu peut le rajouter dans ton gitignore

      -
      Edité par n!co69 21 septembre 2017 à 15:38:24

      • Partager sur Facebook
      • Partager sur Twitter
      "Tout devrait être rendu aussi simple que possible, mais pas plus." A.Einstein
        21 septembre 2017 à 15:43:52

        Salut,

        Juste une petite question au passage :  pourquoi tester deux fois coup sur coup if (event.type == sf::Event::KeyPressed) dans ta boucle?

        Pourquoi ne pas le faire en une seule fois, étant donné que si escape est enfoncée, elle prendra d'office le pas sur tous les autres?

        Ainsi, les lignes

                    if (event.type == sf::Event::KeyPressed)
                        if(event.key.code == sf::Keyboard::Escape)
                            game.close();
                    if (event.type == sf::Event::KeyPressed)
                    {
                        if (event.key.code == sf::Keyboard::Space)
                        {
                            bird.jump();
                        }
                    }

        pourraient tout aussi bien prendre la forme de

                    if (event.type == sf::Event::KeyPressed)
                        if(event.key.code == sf::Keyboard::Escape)
                            game.close();
                        else if (event.key.code == sf::Keyboard::Space)
                            bird.jump();
                    }

        voire meme

        if (event.type == sf::Event::KeyPressed){
            switch(event.key.code){
                case sf::Keyboard::Escape :
                    game.close();
                    break;
                case event.key.code == sf::Keyboard::Space :
                    bird.jump();
                default : // juste pour éviter l'avertissement
            }
        }

        (qui facilitera sans doute les chose le jour où tu voudra ajouter des actions)cela ne changerait rien à l'exécution ;)

        EDIT: cela ne résoudra surement en rien ton problème, mais garder un code simple et clean est ton premier devoir, ne serait-ce que pour te permettre de t'y retrouver plus facilement ;)

        -
        Edité par koala01 21 septembre 2017 à 15:52:28

        • Partager sur Facebook
        • Partager sur Twitter
        Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs  à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
          21 septembre 2017 à 18:27:02

          Bonsoir à vous deux et merci pour vos réponses :)

          Merci pour vos idées/conseils, je vais appliqué tout ça dés que je peux et je vous tiendrai au courant!

          J'ai pas mal de travail ce soir (je suis en L1 MIST), mais si j'ai le temps j’essaierai de modifier tout ça pour ce soir.

          EDIT: MERCI BEAUCOUP!!!!

          J'ai appliqué tout ce que vous m'avez dit (sauf fusion de mes trois classes, je le ferai quand j'aurai un peu plus de temps), et il s'avère que le problème venait de mon getPosition, qui en plus était une erreur débile....

          En tout cas merci à vous deux!

          @n!co69 si tu pouvais juste m'expliquer la façon de faire des random en c++, j'ai chercher vite fait et j'ai trouvé que la bonne vielle technique des srand, et rien avec la lib <random>...

          Dernière chose, tout mes projet SFML sur mes deux PC souffrent de stuttering ( de ce style : https://en.sfml-dev.org/forums/index.php?topic=16449.0), de ce que j'ai pu trouvé ça peut venir de l'optimisation threadée nVidia mais je l'ai désactivé sans succés alors si quelqu'un a une idée je suis preneur ^^

          -
          Edité par hbollon 21 septembre 2017 à 19:02:46

          • Partager sur Facebook
          • Partager sur Twitter

          Projet en cours : Site/Blog professionnel
          A venir: Fondation d'une auto-entreprise de e-commerce et création d'une plateforme web avec Laravel et l'api Bagisto.
          GitHub : https://github.com/hbollon 
          Sites : Parrainage Boursorama , (à venir ^^)

            21 septembre 2017 à 21:12:34

            http://www.cplusplus.com/reference/random/uniform_int_distribution/

            Tu as un petit exemple ici.

            En gros il te faut 2 choses:

            • Un générateur aléatoire qui génère des séries de grand nombres (tu as par exemple std::mt19937 ou encore std::default_random_engine)
            • Une distribution, qui transforme le grand nombre généré en une valeur exploitable (std::uniform_int_distribution, std::discrete_distribution).

            Tu as sur la gauche de la page précédente tous les générateurs et distributions dispo dans le standard.

            • Partager sur Facebook
            • Partager sur Twitter
            "Tout devrait être rendu aussi simple que possible, mais pas plus." A.Einstein
              23 septembre 2017 à 19:13:08

              Merci! Ça marche impec' ! :)

              J'attends de voir si j'ai des retours sur mon problème de stuttering et je passe ce sujet en résolu.

              • Partager sur Facebook
              • Partager sur Twitter

              Projet en cours : Site/Blog professionnel
              A venir: Fondation d'une auto-entreprise de e-commerce et création d'une plateforme web avec Laravel et l'api Bagisto.
              GitHub : https://github.com/hbollon 
              Sites : Parrainage Boursorama , (à venir ^^)

              Problème multiples draw en SFML

              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
              • Editeur
              • Markdown