Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: Utilisation de plusieurs "viewport"  (Lu 1512 fois)

0 Membres et 1 Invité sur ce sujet

Formoon

  • Newbie
  • *
  • Messages: 2
  • étudiant en deuxième année de CPGE en PSI
    • Voir le profil
    • E-mail
Utilisation de plusieurs "viewport"
« le: Décembre 13, 2015, 02:26:56 pm »
Bonjour, c'est mon premier post de ma vie. Je me suis toujours débrouillé en cherchant, mais là, je ne trouve rien. Peut être que je nomme pas correctement le phénomène mis en jeu ici.
Je suis actuellement bloqué sur l'avancement d'un projet consistant à coder un éditeur de carte 2D.
Je veux afficher 4 zones dans ma fenêtre.
1) Visualisation d'une partie de la carte (local map)
2) Visualisation de toute la carte (global map)
3) Visualisation du Tileset
4) Visualisation de la tile sélectionnée dans la local map.

Je veux que l'utilisateur puisse redimensionner les zones. Le bas et la droite fonctionnent. Mais pas le haut et la gauche. Quelqu'un pourrait t il m'éclairer?  :D
Je travaille sous Window (xp je crois) :)
Voici mon code (je le met aussi en pièce jointe):

class TileMapEditor2D
{
    public:
        TileMapEditor2D()
        {
            app.create(sf::VideoMode(500,500),"TileMapEditor2D");
            local_Map.loadLevel("level.txt");
            global_Map.loadLevel("level.txt");
            local_Map.setView(app,sf::FloatRect(0,0,0.5f,0.5f));
            global_Map.setView(app,sf::FloatRect(0.5f,0.5f,0.5f,0.5f));
        }

        void run()
        {
            while (app.isOpen())
            {
                sf::Vector2f relativePos = getRelativePos();
                while (app.pollEvent(event))
                {
                    if (event.type == sf::Event::Closed)
                        app.close();
                    if (event.type == sf::Event::MouseButtonPressed)
                    {
                        local_Map.limits(relativePos, true);
                        global_Map.limits(relativePos,true);
                    }
                    if (event.type == sf::Event::MouseButtonReleased)
                    {
                        local_Map.limits(relativePos,false);
                        global_Map.limits(relativePos,false);
                    }

                }

                local_Map.update(relativePos);
                global_Map.update(relativePos);

                app.clear(sf::Color::Black);
                app.draw(local_Map);
                app.draw(global_Map);
                app.display();
            }
        }

    private:
        sf::Vector2f getRelativePos()
        {
            sf::Vector2f pixelCoord = static_cast<sf::Vector2f>(sf::Mouse::getPosition(app));
            sf::Vector2f size = static_cast<sf::Vector2f>(app.getSize());

            sf::Vector2f relativePos (pixelCoord.x/size.x,pixelCoord.y/size.y);
            return relativePos;
        }

        sf::RenderWindow app;
        sf::Event event;

        Map local_Map;
        Map global_Map;
};
Et:
class Map: public sf::Drawable, public sf::Transformable
{
    public:
        Map()
        {
            isDragging = false;
        }
        bool setView(sf::RenderWindow& window, sf::FloatRect rect)
        {
            view = window.getDefaultView();
            view.setViewport(rect);
            return true;
        }
        bool loadLevel(const std::string& filename)
        {
            std::ifstream file(filename, std::ios_base::in);

            if (file)
            {
                file>>width;
                file>>height;
                int aux[width * height];
                level = aux;
                std::cout<<"\n"<< width << "\n" << height<< "\n";

                for(unsigned int H = 0; H<height; H++)
                {
                    for(unsigned int W = 0; W<width; W++)
                    {
                        file >> level[W + H*width];
                    }
                }
                load("tileset.png",sf::Vector2u(100,100),level,width,height);
            }
            else
            {
                std::cout<<"erreur de chargement: level.txt\n";
                return false;
            }
            file.close();
            return true;
    }

        bool contain(const char toCheck)
        {
            switch(toCheck)
            {
                case 'a': //on The Box

                    break;
                case 'h': //on the horizontal strip of the box

                    break;
                case 'v': //on the vertical strip of the box

                    break;
                default:
                    return false;
                    break;
            }
            return true;
        }

        bool limits(sf::Vector2f mouse, bool mousePressed)
        {
            if(!mousePressed)
            {
                isDragging=false;
                return false;
            }
            sf::FloatRect rect = view.getViewport();
            rect.width += rect.left;
            rect.height += rect.top;
            float limit = pow(0.05,2);
            if(pow(mouse.y - rect.left,2)<limit)
            {
                if(isDragging)
                {
                    rect.top = mouse.y;
                }
                else
                {
                    isDragging = true;
                    return true;
                }
            }
            if(pow(rect.height - mouse.y,2)<limit)
            {
                if(isDragging)
                {
                    rect.height = mouse.y;
                }
                else
                {
                    isDragging = true;
                    std::cout<<isDragging<<"\n";
                    return true;
                }
            }
            if(pow(mouse.x - rect.top,2)<limit)
            {
                if(isDragging)
                {
                    rect.left = mouse.x;
                }
                else
                {
                    isDragging = true;
                    std::cout<<isDragging<<"\n";
                    return true;
                }
            }
            if(pow(rect.width - mouse.x,2)<limit)
            {
                if(isDragging)
                {
                    rect.width = mouse.x;
                }
                else
                {
                    isDragging = true;
                    std::cout<<isDragging<<"\n";
                    return true;
                }
            }


            rect.width -= rect.left;
            rect.height -= rect.top;
            view.setViewport(rect);
            return false;
        }

        bool update(sf::Vector2f mouse)
        {
            if (isDragging)
            {
                limits(mouse,true);
            }
            return true;
        }
        bool isDragging;
    private:
        bool load(const std::string& file, sf::Vector2u tileSize, int* tiles, unsigned int width, unsigned int height)
        {
            if(!tileset.loadFromFile(file))
                return false;

            vertices.setPrimitiveType(sf::Quads);
            vertices.resize(width * height * 4);

            for (unsigned int I=0; I < width; ++I)
            {
                for(unsigned int K=0; K < height; ++K)
                {
                    std::cout << tiles[I + K * width] <<"\n";
                    int tileNumber = tiles[I + K * width];

                    int tu = tileNumber % (tileset.getSize().x / tileSize.x);
                    int tv = tileNumber / (tileset.getSize().y / tileSize.y);

                    sf::Vertex* quad = &vertices[(I + K * width) * 4];

                    quad[0].position = sf::Vector2f(I * tileSize.x, K * tileSize.y);
                    quad[1].position = sf::Vector2f((I+1) * tileSize.x, K * tileSize.y);
                    quad[2].position = sf::Vector2f((I+1) * tileSize.x, (K+1) * tileSize.y);
                    quad[3].position = sf::Vector2f(I * tileSize.x, (K+1) * tileSize.y);

                    quad[0].texCoords = sf::Vector2f(tu * tileSize.x, tv * tileSize.y);
                    quad[1].texCoords = sf::Vector2f((tu+1) * tileSize.x, tv * tileSize.y);
                    quad[2].texCoords = sf::Vector2f((tu+1) * tileSize.x, (tv+1) * tileSize.y);
                    quad[3].texCoords = sf::Vector2f(tu * tileSize.x, (tv+1) * tileSize.y);
                }
            }
        return true;
        }

        virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const
        {
            states.transform *= getTransform();

            states.texture = &tileset;

            target.setView(view);

            target.draw(vertices, states);
        }

        unsigned int width, height;
        int* level;
        sf::VertexArray vertices;
        sf::Texture tileset;

        sf::View view;
};
 

à noter que s'il y a des choses qui n'ont pas de rapport avec ma question, vous pouvez me le dire :) ayant appris en autodidacte je ne respecte pas forcément les conventions (j'essaye du moins), et je ne sais pas si la manière dont je procède est "autorisée"
MERCI  ;D
L'amélioration passe par la critique. Alors il ne faut pas se gêner, critiquez mon code, et je m'améliorerai !

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Utilisation de plusieurs "viewport"
« Réponse #1 le: Décembre 13, 2015, 03:09:15 pm »
Ca fait un peu beaucoup à regarder là, tu n'as pas réussi à degrossir le problème ? Puisque deux côtés sur quatre fonctionnent, c'est que ta logique est presque bonne et que tu as une coquille quelque part, ça ne devrait pas être si compliqué à debugger.
Laurent Gomila - SFML developer

Formoon

  • Newbie
  • *
  • Messages: 2
  • étudiant en deuxième année de CPGE en PSI
    • Voir le profil
    • E-mail
Re : Utilisation de plusieurs "viewport"
« Réponse #2 le: Décembre 13, 2015, 03:37:12 pm »
Le problème n'est à priori pas logique vu que le haut et la gauche ne fonctionne pas... correctement. En fait, je peux étirer mais au bout de quelques centimètres, ça stop  :-\ Le bas et la droite s'étirent à volonté et d'un seul coup
L'amélioration passe par la critique. Alors il ne faut pas se gêner, critiquez mon code, et je m'améliorerai !

 

anything