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

Auteur Sujet: [SFML 2.1] Position de la souris en retard?  (Lu 8812 fois)

0 Membres et 3 Invités sur ce sujet

Raitosan

  • Full Member
  • ***
  • Messages: 221
    • Voir le profil
    • E-mail
[SFML 2.1] Position de la souris en retard?
« le: Septembre 08, 2014, 10:57:36 pm »
Bonjour,

Je suis sous Ubuntu 14.04.

J'affiche une image pour remplacer le curseur de la souris(que je cache donc). Le problème, c'est que sf::Mouse::getPosition(window) a l'air d'être en retard...

En effet, je trouvais que mon curseur n'était pas fluide, j'ai donc rafficher le curseur du système pour voir la différence, et en effet, mon image traînais toujours derrière mon curseur... J'ai trouver ça bizarre et j'ai d'abord penser que ça venais de mon application qui devait avoir des problèmes d'optimisation, puis j'ai créer un nouveau projet et j'ai tester ce code:

 #include <iostream>
#include <SFML/System.hpp>
#include <SFML/Graphics.hpp>

using namespace std;

int main()
{
    sf::Texture m_mouse_texture;
    m_mouse_texture.loadFromFile("cursor.png");
    sf::Sprite m_mouse_sprite;
    m_mouse_sprite.setTexture(m_mouse_texture);
    m_mouse_sprite.setTextureRect(sf::IntRect(0,0,30,30));

    sf::RenderWindow window(sf::VideoMode(800, 600), "My window");

    // on fait tourner le programme jusqu'à ce que la fenêtre soit fermée
    while (window.isOpen())
    {
        // on inspecte tous les évènements de la fenêtre qui ont été émis depuis la précédente itération
        sf::Event event;
        while (window.pollEvent(event))
        {
            // évènement "fermeture demandée" : on ferme la fenêtre
            if (event.type == sf::Event::Closed)
                window.close();
        }

        window.clear(sf::Color(255,255,255));
        m_mouse_sprite.setPosition(sf::Mouse::getPosition(window).x,sf::Mouse::getPosition(window).y);
        window.draw(m_mouse_sprite);
        window.display();
    }

    return 0;
}

Et toujours le même problème. Quelqu'un aurait une idée pour résoudre ce problème?

Merci d'avance!

TheKingArthur

  • Invité
Re : [SFML 2.1] Position de la souris en retard?
« Réponse #1 le: Septembre 09, 2014, 11:24:26 pm »
Peut-être que c'est trop lourd de récupérer la position de la souris à chaque boucle.

Raitosan

  • Full Member
  • ***
  • Messages: 221
    • Voir le profil
    • E-mail
Re : [SFML 2.1] Position de la souris en retard?
« Réponse #2 le: Septembre 10, 2014, 09:23:28 am »
Pour provoquer un tel ralentissement, avec un code aussi basique que ça? Je ne pense pas. De plus l'application tourne à 60fps sans soucis, donc ce n'est pas un problème de ralentissement. C'est plutôt comme si la fonction pour récupérer la position de la souris n'actualisais celle-ci que de temps en temps. D'où le retard entre mon curseur et mon image...

Edit: Je tiens à préciser qu'on obtient le même problème en utilisant l'event MouseMoved.
« Modifié: Septembre 10, 2014, 09:52:39 am par Raitosan »

CINEfilHD77

  • Newbie
  • *
  • Messages: 38
    • Voir le profil
Re : [SFML 2.1] Position de la souris en retard?
« Réponse #3 le: Septembre 11, 2014, 10:30:41 am »
Minuscule amélioration :
Au lieu d'appeler la fonction getPosition de la souris deux fois, pour x et pour y, crée une variable avant ta boucle et remplie-la à chaque tour. Ensuite, tu envoies les composantes x et y de cette variable au setPosition de ton image. Comme ça tu calcule une bonne fois pour toute les coordonnées, au lieu de le faire deux fois.

Raitosan

  • Full Member
  • ***
  • Messages: 221
    • Voir le profil
    • E-mail
Re : [SFML 2.1] Position de la souris en retard?
« Réponse #4 le: Septembre 11, 2014, 10:31:58 pm »
Toujours le même problème :/

Avec MouseMoved mon code donne ça:
#include <SFML/Graphics.hpp>

int main()
{
    // création de la fenêtre
    sf::RenderWindow window(sf::VideoMode(800, 600), "My window");

    sf::Texture m_mouse_texture;
    m_mouse_texture.loadFromFile("cursor.png");
    sf::Sprite m_mouse_sprite;
    m_mouse_sprite.setTexture(m_mouse_texture);
    m_mouse_sprite.setTextureRect(sf::IntRect(0,0,30,30));

    int mouse_x = 0;
    int mouse_y = 0;

    // on fait tourner le programme tant que la fenêtre n'a pas été fermée
    while (window.isOpen())
    {
        // on traite tous les évènements de la fenêtre qui ont été générés depuis la dernière itération de la boucle
        sf::Event event;
        while (window.pollEvent(event))
        {
            // fermeture de la fenêtre lorsque l'utilisateur le souhaite
            if (event.type == sf::Event::Closed)
                window.close();
            if (event.type == sf::Event::MouseMoved)
            {
                mouse_x = event.mouseMove.x;
                mouse_y = event.mouseMove.y;
            }
        }

        // effacement de la fenêtre en noir
        window.clear(sf::Color::Black);

        m_mouse_sprite.setPosition(mouse_x,mouse_y);
        window.draw(m_mouse_sprite);

        // fin de la frame courante, affichage de tout ce qu'on a dessiné
        window.display();
    }

    return 0;
}
 

Et toujours le même problème :/

G.

  • Hero Member
  • *****
  • Messages: 1593
    • Voir le profil
Re : [SFML 2.1] Position de la souris en retard?
« Réponse #5 le: Septembre 11, 2014, 10:49:29 pm »
Pas le choix, le temps que tu dessines ton sprite le vrai curseur géré par l'OS est déjà ailleurs.
Y'a des méthodes pour modifier le curseur directement avec des méthodes spécifiques à l'OS, mais je ne les connais pas. Y'a eu des discussions à ce sujet (avec du code il me semble) sur le forum anglais.

Raitosan

  • Full Member
  • ***
  • Messages: 221
    • Voir le profil
    • E-mail
Re : [SFML 2.1] Position de la souris en retard?
« Réponse #6 le: Septembre 12, 2014, 01:00:11 am »
C'est bizarre car je n'ai pas ce problème sous un autre pc sous windows(pc moins puissant qui plus est) et je n'avais aucun problème à l'époque sous ubuntu avec la SFML 1.6 :/
On ne peux pas dire que ce problème soit vraiment gênant, mais ça donne l'impression que l'application rame, alors que pas du tout >_<

De plus, il me semblais que sf::Mouse::getPosition faisait directement appel à l'os pour connaitre la position du curseur. Avec une application qui tourne à 60fps et le fait qu'on récupère la position de la souris à chaque frame, ça nous donne 60 déplacements du sprite possible pour suivre le curseur. Donc en théorie, on ne devrais pas voir un aussi gros décalage entre les deux :/

TheKingArthur

  • Invité
Re : [SFML 2.1] Position de la souris en retard?
« Réponse #7 le: Septembre 12, 2014, 11:42:00 pm »
C'est peut-être un problème avec ubuntu. Ou c'est juste comme disai G. que l'affichage du sprite est long.

CINEfilHD77

  • Newbie
  • *
  • Messages: 38
    • Voir le profil
Re : [SFML 2.1] Position de la souris en retard?
« Réponse #8 le: Septembre 13, 2014, 12:51:13 pm »
Essaie ça :

sf::Vector2i mouse_pos;

// on fait tourner le programme tant que la fenêtre n'a pas été fermée
while (window.isOpen())
{
        // on traite tous les évènements de la fenêtre qui ont été générés depuis la dernière itération de la boucle
        sf::Event event;
        while (window.pollEvent(event))
        {
                // fermeture de la fenêtre lorsque l'utilisateur le souhaite
                if (event.type == sf::Event::Closed)
                        window.close();
        }

        // effacement de la fenêtre en noir
        window.clear(sf::Color::Black);

        // C'est peut-être mieux de prendre la pos de la souris après le clear
        mouse_pos = sf::Mouse::getPosition(window);
       
        // ça je suis pas sur, mais ça permettrait de placer le curseur de l'OS sur ta pos enregistrée :
        sf::Mouse::setPosition(mouse_pos);

        m_mouse_sprite.setPosition(mouse_pos.x, mouse_pos.y);
        window.draw(m_mouse_sprite);

        // fin de la frame courante, affichage de tout ce qu'on a dessiné
        window.display();
}
 

Raitosan

  • Full Member
  • ***
  • Messages: 221
    • Voir le profil
    • E-mail
Re : [SFML 2.1] Position de la souris en retard?
« Réponse #9 le: Septembre 13, 2014, 01:23:10 pm »
Merci pour votre aide mais le problème persiste :/
Le fait de redonner la position de l'image au curseur fait que la souris est bloquée dans le coin gauche de l'écran. Et c'est tout à fait normal. En fait, mouse_pos = sf::Mouse::getPosition(window); vaut, au début du programme 0,0. Juste après avoir récupérer ces valeurs, on repositionne directement la souris à cet emplacement sans qu'elle ait u le temps de bouger entre deux. Du coup, elle reste coincée dans le coin haut gauche de l'écran. Bien sur, on aurait le même résultat pour n'importe qu'elle autre valeur.

TheKingArthur, j'y ai réfléchis, et j'ai modifier l'image de mon sprite pour ne contenir que le curseur. L'image est donc un simple carrer de 30x30. J'ai retenter, et j'ai toujours le même problème.

Je pense en effet que ça vient d'ubuntu, mais apparemment je ne suis pas le seul à avoir le problème :/
« Modifié: Septembre 13, 2014, 02:18:45 pm par Raitosan »

CINEfilHD77

  • Newbie
  • *
  • Messages: 38
    • Voir le profil
Re : [SFML 2.1] Position de la souris en retard?
« Réponse #10 le: Septembre 13, 2014, 02:41:24 pm »
J'ai vérifié sur Windows, il y a aussi un décalage, mais très léger, c'est peut-être du à un changement de contexte pour la récupération de la position de la souris via l'OS, entre l'enregistrement des coordonnées, l'effaçage de la fenêtre, et l'affichage du sprite... Quoiqu'il-en-soit, je pense pas que tu puisses y remédier, sauf si Laurent n'est pas de mon avis, et si le décalage n'est que de quelques pixels, ça sera pas trop gênant, généralement quand on clique c'est pas à la volée :)

Raitosan

  • Full Member
  • ***
  • Messages: 221
    • Voir le profil
    • E-mail
Re : [SFML 2.1] Position de la souris en retard?
« Réponse #11 le: Septembre 13, 2014, 02:45:29 pm »
Il y a à peu près deux ans, j'ai créer la base d'un éditeur de map iso avec la sfml 1.6 sous windows. J'ai encore le programme et je l'ai tester. Et j'ai 0 décalage entre mon curseur et le sprite de ma souris :/

CINEfilHD77

  • Newbie
  • *
  • Messages: 38
    • Voir le profil
Je viens de voir qu'on peut modifier le titre de son message !!! :O
« Réponse #12 le: Septembre 13, 2014, 03:13:21 pm »
Il y a peut-être une solution, mais par contre je suis désolé, j'ai pas le temps de te donner un code.
Je t'explique :
- Tu replaces à chaque tour de boucle ton curseur au centre de ta fenêtre.
- Dès que tu récupères un event correspondant à un mouvement de souris, tu calcules le vecteur, la distance, enfin un truc comme ça, je pense que tu vas comprendre, entre la nouvelle position et le centre de la fenêtre.
- Tu déplaces ton sprite selon ce vecteur.

(En gros ton sprite ne suit plus directement le curseur, il ne fait que respecter son mouvement)

Ça devrait améliorer tout ça :)
« Modifié: Septembre 13, 2014, 03:15:04 pm par CINEfilHD77 »

Raitosan

  • Full Member
  • ***
  • Messages: 221
    • Voir le profil
    • E-mail
Re : [SFML 2.1] Position de la souris en retard?
« Réponse #13 le: Septembre 13, 2014, 04:50:08 pm »
ça m'a l'air de fonctionner, mais ça ne donne pas trop l'impression d'être fluide :/

#include <iostream>
#include <SFML/Graphics.hpp>

using namespace std;

int main()
{
    // création de la fenêtre
    sf::RenderWindow window(sf::VideoMode(800, 600), "My window");
    window.setMouseCursorVisible(false);

    sf::Texture m_mouse_texture;
    m_mouse_texture.loadFromFile("cursor.png");
    sf::Sprite m_mouse_sprite;
    m_mouse_sprite.setTexture(m_mouse_texture);
    m_mouse_sprite.setPosition(0,0);

    sf::Vector2i mouse_pos;
    // on fait tourner le programme tant que la fenêtre n'a pas été fermée
    while (window.isOpen())
    {
        // on traite tous les évènements de la fenêtre qui ont été générés depuis la dernière itération de la boucle
        sf::Event event;
        while (window.pollEvent(event))
        {
            // fermeture de la fenêtre lorsque l'utilisateur le souhaite
            if (event.type == sf::Event::Closed)
                window.close();
            if (event.type == sf::Event::MouseMoved)
            {
                mouse_pos.x = event.mouseMove.x-400; // -400 et -300 car le curseur est centrer dans la fenêtre.
                mouse_pos.y = event.mouseMove.y-300; // Cela permet d'avoir directement les distances du vecteur
            }
        }

        m_mouse_sprite.move(mouse_pos.x,mouse_pos.y);

        // effacement de la fenêtre en noir
        window.clear(sf::Color::Black);

        window.draw(m_mouse_sprite);

        // fin de la frame courante, affichage de tout ce qu'on a dessiné
        window.display();

        sf::Mouse::setPosition(sf::Vector2i(window.getPosition().x+400,window.getPosition().y+300)); // Pour centrer le curseur dans la fenêtre
    }

    return 0;
}

sf::Mouse::setPosition n'est pas trop gourmand?

Edit: J'ai essayer dans mon programme principale, et c'est juste une horreur :/ Le sprite ne se déplace que de temps en temps, et j'ai aussi remarquer que MouseMoved vallait toujours true.
A mon avis, le fait d'utiliser sf::Mouse::setPosition met MouseMoved à true(ce qui serait compréhensible)
« Modifié: Septembre 13, 2014, 05:16:41 pm par Raitosan »

CINEfilHD77

  • Newbie
  • *
  • Messages: 38
    • Voir le profil
Re : [SFML 2.1] Position de la souris en retard?
« Réponse #14 le: Septembre 13, 2014, 05:23:04 pm »
C'est possible. Au pire, au lieu de passer par les event, tu stockes la position précédente de la souris, et si la position en cours est différente, tu calcules la différence, le vecteur machin, et tu fais la même chose... :)