Partage
  • Partager sur Facebook
  • Partager sur Twitter

probleme d'affichage dans une boucle avec la SFML

Sujet résolu
    8 août 2023 à 9:07:17

    Bonjour a tous, je suis en C++ avec la bibliotheque SFML je cherche a faire une map en 2D pour mon project cette map est dans une class World dont voicie la definition 
    #ifndef WORLD_H_INCLUDED
    #define WORLD_H_INCLUDED
    
    #include <SFML/Graphics.hpp>
    #include "PerlinNoise.h"
    #include "Brandom.h"
    #include <vector>
    
    class World
    {
    public:
        World(int& sizeX, int& sizeY, float seed, sf::Vector2i& positionCamera, int& blockSize, sf::RenderWindow& window);
        ~World();
        int getWorld(int const& x, int const& y) const;
        void draw(sf::Vector2i& positionCamera, unsigned int blockSize,int size);
    
    protected:
        void createWorld(int& blockSize);
        sf::RectangleShape colorBiome(int biome,sf::RectangleShape& pixel);
        int creationBiome(int & x,int & y, PerlinNoise& perlinNoise);
    
        const float W_seed;
        const int W_sizeX;
        const int W_sizeY;
        double W_scale = 1.5;
        int W_octaves = 4;
        double W_persistence = 0.30;
        sf::RenderWindow& W_window;
        std::vector<std::vector<int>> W_Monde;
        std::vector< std::vector<sf::RectangleShape>> W_Blocks;
    };
    
    #endif // WORLD_H_INCLUDED

    j'innitialise ma carte avec World Monde(WIDTHSCREEN, HEIGHTSCREEN, seed(), positionCamera, blockSize, window);

    World::World(int& sizeX, int& sizeY, float seed, sf::Vector2i& positionCamera, int& blockSize, sf::RenderWindow& window) : W_seed(seed), W_sizeX(sizeX), W_sizeY(sizeX), W_Monde(std::vector<std::vector<int>>(0, std::vector<int>())), W_Blocks(0, std::vector<sf::RectangleShape>()),W_window(window)
    {
        createWorld(blockSize);
    }
    
    World::~World()
    {
    
    }
    
    void World::createWorld(int& blockSize)
    {
        PerlinNoise perlinNoise(W_seed);
    
        int facteur = W_sizeY / 20;
    
        sf::RectangleShape rect;
        sf::RectangleShape chargement;
        chargement.setPosition(sf::Vector2f(W_sizeX / 4, W_sizeY / 2));
        rect.setPosition(sf::Vector2f(W_sizeX / 4 - 1, W_sizeY / 2 - 1));
        rect.setSize(sf::Vector2f(W_sizeX / 2 + 2, 17));
    
        std::vector<int> row(W_sizeX);
        std::vector<sf::RectangleShape> rowB(W_sizeX);
    
        for (int y = 0; y < W_sizeY + 1; ++y)
        {
            for (int x = 0; x < W_sizeX; ++x)
            {
                int biome = creationBiome(x, y, perlinNoise);
                row[x] = biome;
    
                sf::RectangleShape& pixel = rowB[x];
                pixel.setPosition(x * blockSize, y * blockSize);
                pixel.setSize(sf::Vector2f(blockSize, blockSize));
                colorBiome(biome, pixel);
            }
    
            W_Monde.push_back(row);
            W_Blocks.push_back(rowB);
    
            if (y % 10 == 0)
            {
                chargement.setSize(sf::Vector2f(y * ((W_sizeX / W_sizeY) / 2), 15.0f));
                chargement.setFillColor(sf::Color(y * 225 / W_sizeY, 0, 225 - y * 225 / W_sizeY));
    
                W_window.clear(sf::Color(225 - y * 225 / W_sizeY, 0, y * 225 / W_sizeY));
                W_window.draw(rect);
    
                // Dessinez la barre de chargement après W_window.clear() et avant W_window.display()
                W_window.draw(chargement);
    
                W_window.display();
            }
        }
    
        W_window.clear(sf::Color(225,175,0));
        W_window.display();
    }
    

    le code en soit fonctionne la carte est bien genere cependant cet partie de createWorld n'affiche pas la barre de chargement, la fenetre est bien clear avec la nouvelle couleur 

    sf::RectangleShape rect;
        sf::RectangleShape chargement;
        chargement.setPosition(sf::Vector2f(W_sizeX / 4, W_sizeY / 2));
        rect.setPosition(sf::Vector2f(W_sizeX / 4 - 1, W_sizeY / 2 - 1));
        rect.setSize(sf::Vector2f(W_sizeX / 2 + 2, 17));
    if (y % 10 == 0)
            {
                chargement.setSize(sf::Vector2f(y * ((W_sizeX / W_sizeY) / 2), 15.0f));
                chargement.setFillColor(sf::Color(y * 225 / W_sizeY, 0, 225 - y * 225 / W_sizeY));
    
                W_window.clear(sf::Color(225 - y * 225 / W_sizeY, 0, y * 225 / W_sizeY));
                W_window.draw(rect);
    
                // Dessinez la barre de chargement après W_window.clear() et avant W_window.display()
                W_window.draw(chargement);
    
                W_window.display();
            }
    d'avance merci à tous ceux qui etudierons mon cas

    -
    Edité par MathéoBrument 8 août 2023 à 14:05:17

    • Partager sur Facebook
    • Partager sur Twitter
      8 août 2023 à 16:44:14

      chargement.setSize(sf::Vector2f(y * ((W_sizeX / W_sizeY) / 2), 15.0f));



      d'où tu sors ta formule ??

      voici une barre faite vite fait avec quelques commentaire.

      j'utilise ma class timer pour simuler ton traitement

      #include <SFML/Graphics/RenderWindow.hpp>
      #include <SFML/Graphics/RectangleShape.hpp>
      
      #include "timer/timer.hpp"
      
      int main()
      {
          sf::RenderWindow window(sf::VideoMode(800, 800), "Test divers", sf::Style::Close);
      
          sf::RectangleShape rect;                                                // background de la barre de prgression
          rect.setPosition(100, 100);
          rect.setSize(sf::Vector2f(500, 50));                                    // pour une barre de progression de 500 * 50
          rect.setFillColor(sf::Color::Blue);
      
          sf::RectangleShape progerssBar;                                         // le barre de progression
          progerssBar.setPosition(100, 100);
          progerssBar.setSize(sf::Vector2f(0, 50));
          progerssBar.setFillColor(sf::Color::Cyan);
      
          mylib::Timer timer(5);                                                  // par pas de 50ms
          timer.startTimer();                                                     // c'est parti
      
          int W_sizeY{1000};                                                      // notre monde fait 1000 de haut
          int pas{10};                                                            // barre progresse tous les 10
          int progress{(W_sizeY / 100) / pas};                                    // faire avancer notre barre. tout les 10 la barre augmente de x %. 100% étant 1000
                                                                                  // 1% de progression  = 1000 / 100 = 100 donc 10 pixel = 10 / 100 = 10% de 1% donc 0.1% de progression total
          int progressBarWidth{0};
      
          for(int y = 0; y < W_sizeY + 1; ++y) {                                  // ta construction
              while(!timer.isTimeElapsed()) {                                     // simulons ton traitement de chargement
                  sf::sleep(sf::milliseconds(1));
              }
              timer.restartTimer();
              if(y % pas == 0) {
                  progressBarWidth += progress;
                  progerssBar.setSize(sf::Vector2f(progressBarWidth * 5, 50));    // * 5 car 500 = 5 * 100
              }
              window.clear();
              window.draw(rect);
              window.draw(progerssBar);
              window.display();
          }
      }



      -
      Edité par Djarkan 8 août 2023 à 16:48:31

      • Partager sur Facebook
      • Partager sur Twitter
        8 août 2023 à 19:00:00

        Salut,

        Malheureusement, il va te falloir revoir ta conception.
        Une classe World qui:
        1) Se construit.
        2) Nettoie l'écran (mince, on peut rien afficher avant le monde).
        2) S'affiche.
        3) Affiche une barre de progression.
        Cela fait 4 responsabilités, soit … 3 de trop.
        En clair, elle viole le SRP (Single-responsibility principle - Wikipedia).

        Il sera plus sage d'avoir:
        Une classe qui construit le monde (WolrdBuilder par exemple), et renvoie une classe World.
        La classe World soit équipée d'une fonction Display a qui tu fournira une référence vers la fenêtre. La classe World n'a pas besoin de connaitre le fenêtre en permanence, si cette dernière change, tu fais quoi ?
        Ou rendre la classe World affichable (en héritant de sf::Drawable et sf::Transformable), en toute logique, c'est la fenêtre qui affiche.
        La barre de progression doit être gérée ailleurs, il faudra prévoir un moyen de connaitre l'étant de la progression de génération du monde (DP observer peut être ?)

        • Partager sur Facebook
        • Partager sur Twitter

        probleme d'affichage dans une boucle avec la 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