Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

25.06.2016, 16:51

sf::Event::mouseMove gibt falsche Werte bei sf::Event::mousePressed

Hey,

ich habe ein echt komischen Bug in SFML. Ich hole mir die Mausposition von dem sf::Event. Das funktioniert auch soweit ganz gut. Doch wenn ich jetzt eine Maustaste drücke, verändert sich der Wert von sf::Event::mouseMove;
Was vorher die Y-Koordinate war ist jetzt die X-Koordinate und die X-Koordinate ist jetzt 0.

C-/C++-Quelltext

1
2
3
4
5
6
while (_rw.pollEvent(_ev))  
{
        
   std::cout << "X: " << _ev.mouseMove.x << " | Y: " << _ev.mouseMove.y << "\n";
    
}



Solange ich mich mit der Maus bewege wird dort auch die richtige Mausposition ausgegeben. Aber sobald ich ein Maustaste klicke sieht das Ganze gleich direkt anders aus.
Hat da jemand eine Lösung ?


MfG
Sceiwen

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

2

25.06.2016, 16:53

ich habe ein echt komischen Bug in SFML.
Das ist ein Bug in Deinem Code, nicht in SFML.
Du prüfst nämlich überhaupt nicht auf den Typ des Events. Folglich kommen da allerlei verschiedene Events rein. Und bei denen sind die Werte für mouseMove natürlich mit unsinnigen Werten belegt. Fazit: Immer den Typ des Events prüfen, bevor man auf Attribute zugreift!
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

3

25.06.2016, 16:59

Ich habe wohl vergessen zu erwähnen, dass ich das in meinem Programm auch tue. Ich verwende Callbacks die auf die Events von sf::Event reagieren. Z.b habe eine Funktion namens "onWidgetMoved(sf::Event& ev)". Dort habe ich aber folglich das selbe Problem, obwohl ich den Typen vorher prüfe.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

4

25.06.2016, 17:26

Klingt unwahrscheinlich, ganz ehrlich. Du bist ja nicht der Einzige, der mit SFML arbeitet. Und solange Du keinen Code zeigst, solange können wir auch nur spekulieren. Da oben in den paar Zeilen Code machst Du jedenfalls keine Typ-Prüfung. Also entweder zeigst Du uns den relevanten Code oder wir raten einfach nur blind weiter ;)
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

5

25.06.2016, 17:44

Du hast vollkommen Recht dass es daran liegt das ich vorab den Typen prüfen muss. Der ganze Sinn der Sache ist es, dass ich mit der Maus ein sf::RectangleShape bewegen kann. Das Problem hierbei ist, dass ich vorher prüfen muss ob es geklickt wurde um dort dann die Mausposition zwischenzuspeichern um dann danach zu prüfen ob die Maus bewegt wurde.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    void Window::onTitlebarMoved(sf::Event & ev) //Wird aufgerufen wenn die Titlebar bewegt wurde
    {
        static sf::Vector2f olddifference;
        sf::Vector2f difference = _localClickPos - this->globalToLocal(ev.mouseMove.x, ev.mouseMove.y); //Bin mir nicht sicher ob die Rechnung funktioniert. Berechne hier nur die Differenz
                                                                                                                //zwischen der aktuellen Position und der Position aus dem letztem Frame. 

        std::cout <<"DiffX: "<< _localClickPos.x << " | DiffY: " << _localClickPos.y << "\n";

        this->setPosition(sf::Vector2f(this->getPosition() + (difference - olddifference))); //Hier versuche ich dann das Fenster mit der Maus zu bewegen. Sollte so klappen, hoffentlich... ^^
        olddifference = difference;
    }
    void Window::onTitlebarPressed(sf::Event & ev) //Wird aufgerufen wenn die Titlebar geklickt wurde.
    {
        _localClickPos = this->globalToLocal(ev.mouseMove.x, ev.mouseMove.y); //Die Mausposition zwischenspeichern. (Vorher in den lokalen Space umwandeln)
    }


Das Problem ist hier dann halt nur dass ich pro Klick auf die Titlebar die Mausposition zwischenspeichern will, aber es nicht kann.

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

6

25.06.2016, 17:49

Auch in dem Code ist keine Prüfung. Du sagst das ganze wird als Callback genutzt. Dann zeig mal den Code davon. Wie verbindest du das ganze und stellst sicher dass es sich um ein MouseMove Event handelt.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

7

25.06.2016, 17:57

Window Klasse

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
        /////////////////////////////////////////////////////////////////////////////////////
    Window::Window(float width, float height, int titlebarheight)
        : WidgetContainer(width, height)
        , _contenGroup(width, width - titlebarheight)
        , _titlebar(width, titlebarheight)
    {
        WidgetContainer::add(&_titlebar);
        WidgetContainer::add(&_contenGroup);

                //Hier füge ich den Events die Callbacks hinzu.
        this->addEventListener(sf::Event::MouseButtonReleased, std::bind(&Window::onWidgetReleased, this, std::placeholders::_1));
        this->addEventListener(sf::Event::MouseButtonPressed, std::bind(&Window::onWidgetPressed, this, std::placeholders::_1));
        this->addEventListener(sf::Event::MouseEntered, std::bind(&Window::onWidgetEntered, this, std::placeholders::_1));
        this->addEventListener(sf::Event::MouseLeft, std::bind(&Window::onWidgetLeft, this, std::placeholders::_1));
        _titlebar._closebutton.addEventListener(sf::Event::MouseButtonPressed, std::bind(&Window::onButtonPressed, this, std::placeholders::_1));
        _titlebar.addEventListener(sf::Event::MouseMoved, std::bind(&Window::onTitlebarMoved, this, std::placeholders::_1));
        _titlebar.addEventListener(sf::Event::MouseButtonPressed, std::bind(&Window::onTitlebarPressed, this, std::placeholders::_1));

        _contenGroup.setPosition(sf::Vector2f(0, titlebarheight));

        _shape.setSize(sf::Vector2f(width, height));
        this->setType(WidgetType::Window);
    }
    /////////////////////////////////////////////////////////////////////////////////////
    void Window::update()
    {
        WidgetContainer::update();
    }
    /////////////////////////////////////////////////////////////////////////////////////
    void Window::setColor(sf::Color color)
    {
        _shape.setFillColor(color);
    }
    /////////////////////////////////////////////////////////////////////////////////////
    void Window::add(Widget* widget, std::string id)
    {
        _contenGroup.add(widget, id);
    }
    /////////////////////////////////////////////////////////////////////////////////////
    void Window::draw(sf::RenderTarget & target, sf::RenderStates states) const
    {
        target.draw(_shape, states);

        WidgetContainer::draw(target, states);
    }
    /////////////////////////////////////////////////////////////////////////////////////
    void Window::onButtonPressed(sf::Event & ev)
    {
        removeAllWidgets();
        this->getParent()->removeWidget(this);
    }
    /////////////////////////////////////////////////////////////////////////////////////
    void Window::onTitlebarMoved(sf::Event & ev)
    {
            static sf::Vector2f olddifference;
            sf::Vector2f difference = _localClickPos - this->globalToLocal(ev.mouseMove.x, ev.mouseMove.y);

            std::cout <<"DiffX: "<< _localClickPos.x << " | DiffY: " << _localClickPos.y << "\n";

            //this->setPosition(sf::Vector2f(this->getPosition() + (difference - olddifference)));
            olddifference = difference;
    }
    void Window::onTitlebarPressed(sf::Event & ev)
    {
        _localClickPos = this->globalToLocal(ev.mouseMove.x, ev.mouseMove.y);
    }
    /////////////////////////////////////////////////////////////////////////////////////
    void Window::onWidgetReleased(sf::Event & ev)
    {
        this->setClicked(false);
    }
    /////////////////////////////////////////////////////////////////////////////////////
    void Window::onWidgetPressed(sf::Event & ev)
    {
        this->setClicked(true);
    }
    /////////////////////////////////////////////////////////////////////////////////////
    void Window::onWidgetEntered(sf::Event & ev)
    {
        this->setHovered(true);
    }
    /////////////////////////////////////////////////////////////////////////////////////
    void Window::onWidgetLeft(sf::Event & ev)
    {
        this->setHovered(false);
    }
    /////////////////////////////////////////////////////////////////////////////////////


Das Überprüfen der Events:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
        Gui::Gui()
        : WidgetContainer(0, 0)
        , _currentMouseOverWidget(nullptr)
        , _currentClickedWidget(nullptr)
    {}
    void Gui::update()
    {
        WidgetContainer::update();
    }
    void Gui::handle(sf::Event ev)
    {   
                //Hier werden die Events auf den Typen geprüft. Je nachdem welches Event stattgefunden hat, wird die entsprechende Callback aufgerufen.
        if (ev.type == sf::Event::MouseMoved)
        {
            _onMouseMoved(ev);
        }
        if (ev.type == sf::Event::MouseButtonPressed)
        {
            _onMousePressed(ev);
            //std::cout << ev.mouseMove.x << " | " << ev.mouseMove.y <<  "\n";
        }
        if (ev.type == sf::Event::MouseButtonReleased)
        {
            _onMouseReleased(ev);
        }
    }
    void Gui::_onMouseMoved(sf::Event ev)
    {
        Widget* w = this->getObjectsUnderPoint(ev.mouseMove.x, ev.mouseMove.y);

        if (_currentMouseOverWidget != nullptr && _currentMouseOverWidget->getClicked())
        {
            _currentMouseOverWidget->dispatchEvent(ev); //Hier wird eine Callback Funktion aufgerufen die dem Event zugeordnet ist
        }

        if (_currentMouseOverWidget != w)
        {
            if (_currentMouseOverWidget != nullptr)
            {
                ev.type = sf::Event::MouseLeft;
                _currentMouseOverWidget->dispatchEvent(ev); //Hier wird eine Callback Funktion aufgerufen die dem Event zugeordnet ist
            }

            _currentMouseOverWidget = w;

            if (_currentMouseOverWidget != nullptr)
            {
                ev.type = sf::Event::MouseEntered;
                _currentMouseOverWidget->dispatchEvent(ev); //Hier wird eine Callback Funktion aufgerufen die dem Event zugeordnet ist
            }
        }
    }

    void Gui::_onMousePressed(sf::Event ev)
    {
        _currentClickedWidget = _currentMouseOverWidget;

        if (_currentClickedWidget != nullptr)
        {
            _currentMouseOverWidget->dispatchEvent(ev); //Hier wird eine Callback Funktion aufgerufen die dem Event zugeordnet ist
        }
    }

    void Gui::_onMouseReleased(sf::Event ev)
    {
        if (_currentMouseOverWidget == _currentClickedWidget)
        {
            if (_currentMouseOverWidget != nullptr)
            {
                _currentMouseOverWidget->dispatchEvent(ev); //Hier wird eine Callback Funktion aufgerufen die dem Event zugeordnet ist
            }
        }

        if (_currentClickedWidget != nullptr)
        {
            _currentClickedWidget->dispatchEvent(ev); //Hier wird eine Callback Funktion aufgerufen die dem Event zugeordnet ist
            _currentClickedWidget = nullptr;
        }
    }

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Sceiwen« (25.06.2016, 18:45)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

8

25.06.2016, 18:16

sf::Event::MouseButtonPressed passt nicht zu Event::mouseMove::x. Genau das wertest Du aber bei onTitlebarPressed aus. Also folglich die falschen Event-Properties. Du brauchst da Event::mouseButton.
Siehe auch: http://www.sfml-dev.org/documentation/2.…f9ff2cdf606481f
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

9

25.06.2016, 18:33

Vielen Dank, genau dass brauchte ich.
Ich würde aber gerne nochmal fragen wie man es realisieren könnte das ich das Fenster mit der Maus bewegen kann. Ich kriege es einfach nicht hin. Aktueller Stand (wie im Code) ist dass er sich zwar mit der Maus bewegt, aber irgendwie epileptische Anfälle hat ^^

10

25.06.2016, 19:25

Habe es selber lösen können.
Vielen Dank nochmal.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
    void Window::onTitlebarMoved(sf::Event & ev)
    {
        sf::Vector2f difference = _localClickPos - this->getPosition();
        this->setPosition(sf::Vector2f(this->globalToLocal(ev.mouseMove.x, ev.mouseMove.y) - difference));
    }
    void Window::onTitlebarPressed(sf::Event & ev)
    {
        _localClickPos = this->globalToLocal(ev.mouseButton.x, ev.mouseButton.y);
    }

Werbeanzeige