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

Auteur Sujet: Move vue lorsque le bouton G de la souris est appuyé et la souris deplacée  (Lu 2856 fois)

0 Membres et 1 Invité sur ce sujet

Rick_Cplusplus

  • Newbie
  • *
  • Messages: 34
    • Voir le profil
    • E-mail
Bonjour la comunauté,

J'ai un petit souci avec ce code (j'ai essayé de le rendre minimal) :

#include <iostream>
#include <math.h>
#include <vector>
#include <SFML/Graphics.hpp>

class Hexagone
{
    public:
        Hexagone(unsigned int, unsigned int, double);

        unsigned int q; // no ligne
        unsigned int r; // rang dans la ligne

        double m_rayon; // rayon de l'hexagone

        sf::ConvexShape polygon; // drawable representant l'hexagone

    private:

};


Hexagone::Hexagone(unsigned int q = 0, unsigned int r = 0, double rayon = 0): q(q), r(r), m_rayon(rayon), polygon(6)
{

    const double PI = 3.14159265358979323846;
    double theta(0);

    // parametrage du polygone
    for(unsigned int i(0); i<6; i++)
    {
        theta = (60 * i + 30)* PI / 180;
        polygon.setPoint(i, sf::Vector2f(m_rayon * cos(theta), m_rayon * sin(theta)));
    }
    polygon.setOutlineColor(sf::Color::Black);
    polygon.setOutlineThickness(-2);
    if(r%2 == 0) polygon.setFillColor(sf::Color::Blue);
    else polygon.setFillColor(sf::Color::Green);
}

class Carte
{
    public:
        Carte(unsigned int, unsigned int);

        void dessine(sf::RenderWindow &); // dessine les hexagones (dessine la carte)

        unsigned int m_nbhex; // nombre d'hexagones par ligne
        unsigned int m_nblg; // nombre de lignes

        unsigned int m_lx; // taille X du mode fenetre pour affichage de la carte
        unsigned int m_ly; // taille Y du mode fenetre pour affichage de la carte
        double m_r; // rayon des hexagones calculé en fonction de la fenêtre

        double m_ech; // echelle d'affichage

        std::vector <Hexagone*> listHex; // conteneur des pointeurs vers les hex

    private:

};

Carte::Carte(unsigned int nblg, unsigned nbhex): m_nbhex(nbhex), m_nblg(nblg), m_lx(0), m_ly(0), m_r(0), m_ech(1), listHex{}
{
    //recuperation du mode fenetre de la carte
    std::vector<sf::VideoMode> modes = sf::VideoMode::getFullscreenModes();

    // choix du mode le plus grand apres le mode full screen
    sf::VideoMode mode = modes[1];

    m_lx = mode.width;
    m_ly = mode.height;

    // determination du rayon des hex svt taille fenetre
    double rx = m_lx / (sqrt(3) * (nbhex + .5));
    double ry = m_ly / (1.5 * (nblg - 1) + 2);
    m_r = rx;
    if (ry < rx) m_r = ry;

    // instantiation des hexagones
    for(unsigned int i(0); i<m_nblg; i++)
    {
        for(unsigned int j(0); j<m_nbhex; j++)
        {
            Hexagone *hex = new Hexagone(i, j, m_r);
            listHex.push_back(hex);
        }
    }

    //definition de la taille de la fenetre
    m_lx = nbhex * m_r * sqrt(3) + m_r * sqrt(3) / 2;
    m_ly = m_r * (2 + 1.5 * (nblg - 1));
}


void Carte::dessine(sf::RenderWindow &fenetre)
{
    double offset(0);

    for(unsigned int i(0); i < listHex.size(); i++)
    {
        if(listHex[i] -> q % 2 == 0) offset = sqrt(3) * m_r;
        else offset = sqrt(3) * m_r / 2;
        listHex[i] -> polygon.setPosition(((sqrt(3) * m_r * listHex[i] -> r) + offset), ((1.5 * m_r * listHex[i] -> q) + m_r));

        fenetre.draw(listHex[i] -> polygon);
    }
    return;
}


int main()
{
    // instantiation Carte
    unsigned nbhex = 50;
    unsigned int nblg = 20;
    Carte *carte = new Carte(nblg, nbhex);

    // creation fenetre
    bool pleinEcran = false;
    sf::RenderWindow fenetre;
    auto style = (pleinEcran ? sf::Style::Fullscreen : sf::Style::Default);
    fenetre.create({carte -> m_lx, carte -> m_ly, 32}, "Carte", style);

    // creation de la vue et de son viewport
    sf::View view1 = fenetre.getDefaultView();
    view1.setViewport(sf::FloatRect(0,0,.9,1));
    fenetre.setView(view1);

    sf::Vector2i prevMouse(0 , 0);

    bool leftButtonPressed(false);
    bool leftButtonReleased(true);

    while(fenetre.isOpen())
    {
        // memorisation position souris en début de frame
        prevMouse = sf::Mouse::getPosition(fenetre);

        // gestion des evenements
        sf::Event event;
        while (fenetre.pollEvent(event))
        {
            // detection et fermeture fenetre
            if (event.type == sf::Event::Closed)
            {
                fenetre.close();
            }

            // detection click button gauche
            if (event.type == sf::Event::MouseButtonPressed)
            {
                if (event.mouseButton.button == sf::Mouse::Left)
                {
                    leftButtonPressed = true;
                    leftButtonReleased = false;
                }
            }

            // detection de-click button gauche
            if (event.type == sf::Event::MouseButtonReleased)
            {
                if (event.mouseButton.button == sf::Mouse::Left)
                {
                    leftButtonPressed = false;
                    leftButtonReleased = true;
                }
            }

            // Ici il a du code pour zoomer / dé zoomer qui fonctionne bien donc je l'ai enlevé...
            {
            // code qui fonctionne...
            }

            // si bouton gauche maintenu, deplacement vue
            if(event.type == sf::Event::MouseMoved && leftButtonPressed)
            {
                sf::Vector2f dpl(prevMouse.x - event.mouseMove.x, prevMouse.y - event.mouseMove.y); // <- ici dpl vaut (0, 0) et je ne comprend pas pourquoi...
                view1.move(dpl);
            }

        }
        //effacement
        fenetre.clear(sf::Color::Black);

        //MaJ vue
        fenetre.setView(view1);

        //dessin
        carte -> dessine(fenetre);

        //affichage
        fenetre.display();
    }
    return 0;
}
 

Les 2 classes (les attributs "public" ne le resteront pas à terme bien sûr  ;)) sont opérantes et ne font pas parti de mon pb, je ne les ai laissées que pour l’exhaustivité du code.

Ce que je n'arrive pas à comprendre, c'est pourquoi le vecteur dpl vaut (0, 0) (voir commentaire dans le main) alors que la souris a bougée...
Une piste à me suggérer ?

Si mon approche est incorrecte, existe t-il une meilleure façon de procéder pour déplacer la vue d'un vecteur correspondant au mouvement de la souris entre 2 frames lorsque le bouton gauche de la souris est maintenu appuyé entre ces 2 frames ?

Rick.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re: Move vue lorsque le bouton G de la souris est appuyé et la souris deplacée
« Réponse #1 le: Septembre 12, 2019, 10:42:50 am »
Parce que prevMouse est identique à ce que tu vas récupérer dans Event::MouseMoved, de toute évidence. Un "vrai" prevMouse serait mis à jour dans Event::MouseMoved, juste après avoir utilisé les coordonnées.

Sinon j'aime bien leftButtonPressed et leftButtonReleased. Tu ne crois pas qu'il y a un truc qui sert légèrement à rien là-dedans ? ;)
Laurent Gomila - SFML developer

Rick_Cplusplus

  • Newbie
  • *
  • Messages: 34
    • Voir le profil
    • E-mail
Re: Move vue lorsque le bouton G de la souris est appuyé et la souris deplacée
« Réponse #2 le: Septembre 12, 2019, 03:57:59 pm »
Parce que prevMouse est identique à ce que tu vas récupérer dans Event::MouseMoved, de toute évidence.
Certes, c'est ce que me disait le debugger mais cela causait mon désaroi...

Un "vrai" prevMouse serait mis à jour dans Event::MouseMoved, juste après avoir utilisé les coordonnées.
Ah Il s'agit donc d'un mauvais positionnement de prevMouv dans le code...  ::)

Sinon j'aime bien leftButtonPressed et leftButtonReleased. Tu ne crois pas qu'il y a un truc qui sert légèrement à rien là-dedans ? ;)
Si,si, mais qd je suis perdu je tente des trucs fous pour voir ; l'espoir fait coder... ;D

Quoi qu'il en soit, j'ai pu venir à bout de ce Pb grace à Toi. Merci encore pour ce soutien efficace et rapide. :)
Rick.