• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Nie działają jednocześnie dwa bloki kodu "while (window->pollEvent(event))" ustawione pod sobą - C++ SFML 2.4

Aruba Cloud VPS - 50% taniej przez 3 miesiące!
0 głosów
706 wizyt
pytanie zadane 10 lipca 2018 w C i C++ przez DarkEliat Bywalec (2,810 p.)

Witam.

Pracuję nad kodem Drag&Drop (Moje poprzednie pytanie: https://forum.pasja-informatyki.pl/346053/nie-dziala-kod-zlap-przeciagnij-pusc-c-sfml jeśli ktoś ma jakiś inny pomysł jak rozwiązać ten problem będę wdzięczny za odpowiedź).

Próbuję użyć Eventów w dwóch miejscach w kodzie, ale jak się okazuje działa tylko ten ustawiony na samym początku pętli głównej gry.

Taki zapis dział, ale nijak nie mi jest pomocny:

while (window->isOpen() && gameInfo->state == GameInfo::GAME)
		{
			sf::Event event;
			while (window->pollEvent(event))
			{
				if (event.type == Event::KeyPressed && event.key.code == Keyboard::Escape)
					window->close();
				if (event.type == Event::Closed)
					window->close();
				if (event.type == Event::LostFocus)
					paused = true;

				switch (event.type)
				{
					case Event::MouseButtonPressed:
						if (event.mouseButton.button == Mouse::Left)
						{
							cout << "START ";
						}
						break;

					case Event::MouseButtonReleased:
						if (event.mouseButton.button == Mouse::Left)
						{
							cout << "STOP ";
						}
						break;
					}
			}
// ...

Co ciekawe taki zapis nie działa (poprawnie wykonuje się tylko pierwsza pętla pollEvent):

while (window->isOpen() && gameInfo->state == GameInfo::GAME)
		{
			sf::Event event1;
			while (window->pollEvent(event1))
			{
				switch (event1.type)
				{

				case Event::MouseButtonPressed:
					if (event1.mouseButton.button == Mouse::Left)
					{
						cout << "START ";
					}
					break;

				case Event::MouseButtonReleased:
					if (event1.mouseButton.button == Mouse::Left)
					{
						cout << "STOP ";
					}
					break;
				}
			}

			sf::Event event;
			while (window->pollEvent(event))
			{
				if (event.type == Event::KeyPressed && event.key.code == Keyboard::Escape)
					window->close();
				if (event.type == Event::Closed)
					window->close();
				if (event.type == Event::LostFocus)
					paused = true;

				
			}
// ...

Co jeszcze ciekawsze taki zapis działa, ale także jest totalnie bezużyteczny, ponieważ blokuje wykonywanie całego programu:

while (window->isOpen() && gameInfo->state == GameInfo::GAME)
		{
			sf::Event event1;
			while (window->pollEvent(event1))
			{
				switch (event1.type)
				{

				case Event::MouseButtonPressed:
					if (event1.mouseButton.button == Mouse::Left)
					{
						cout << "START ";
					}
					break;

				case Event::MouseButtonReleased:
					if (event1.mouseButton.button == Mouse::Left)
					{
						cout << "STOP ";
					}
					break;
				}
			}

			while (window->isOpen() && gameInfo->state == GameInfo::GAME)
			{
				sf::Event event;
				while (window->pollEvent(event))
				{
					if (event.type == Event::KeyPressed && event.key.code == Keyboard::Escape)
						window->close();
					if (event.type == Event::Closed)
						window->close();
					if (event.type == Event::LostFocus)
						paused = true;


				}
			}
// ...

Jest mi to w stanie ktoś wytłumaczyć? Byłbym bardzo wdzięczny za radę jak korzystać z kilku pętli "while (window->pollEvent(event))" na raz. Dodam jeszcze, że ta druga będzie się znajdowała w innym pliku.

Pozdrawiam.

1 odpowiedź

0 głosów
odpowiedź 10 lipca 2018 przez adrian17 Mentor (351,140 p.)

Co ciekawe taki zapis nie działa (poprawnie wykonuje się tylko pierwsza pętla pollEvent):

Co ma sens - ten kod nie ma prawa działać.

            sf::Event event1;
            while (window->pollEvent(event1))

Pierwsza pętla wywołuje się tak długo, jak (while) są jeszcze jakieś nieobsłużone eventy. pollEvent() ściąga je z wewnętrznej kolejki eventów i przekazuje Tobie. Po zakończeniu tej pętli...

            sf::Event event2;
            while (window->pollEvent(event2))

Nie ma już żadnych nieobsłużonych eventów (dlatego poprzednia pętla while się skończyła), więc pollEvent() nie przekaże ani jednego eventu, więc ta pętla nie wykona się ani razu.

Byłbym bardzo wdzięczny za radę jak korzystać z kilku pętli "while (window->pollEvent(event))"

Musisz mieć jedno centralne miejsce wyciągające eventy (choć niekoniecznie w jednym przez całość działania programu) - te eventy możesz przekazywać i obsługiwać gdziekolwiek chcesz. Może być na przykład coś w stylu

while (window->pollEvent(event))
{
	ui->handleEvent(event);
	world->handleEvent(event);
	playerEntity->handleEvent(event);
    // etc etc
}

 

komentarz 10 lipca 2018 przez DarkEliat Bywalec (2,810 p.)
Czyli chcesz mi powiedzieć, że dwa obiekty Event mogą przetrzymywać dwa różne zdarzenia?
komentarz 10 lipca 2018 przez adrian17 Mentor (351,140 p.)
Nie rozumiem pytania. Mówię, że drugie pollEvent() nic nie robi.
komentarz 10 lipca 2018 przez DarkEliat Bywalec (2,810 p.)
Bo napisałeś, że je można przekazywać, stąd moja myśl, że jeśli gdzieś je wyślę, a za ten czas wydarzy się kolejne zdarzenie, to tamto wysłane dalej będzie miało informację o starym zdarzeniu?

Masz jakiś pomysł jak to okodować?

Ewentualnie jeśli miałbyś pomysł jak rozwiązać problem z pytania do którego dałem link, to zdarzenia byłyby zbędne. Dlatego proszę spojrzyj na nie w wolnej chwili bo to blokuje moje prace.
komentarz 10 lipca 2018 przez adrian17 Mentor (351,140 p.)

Przekombinowujesz.

W oknie zbiera się kolejka zdarzeń. Przez te kilka milisekund które spędzasz na wyświetlaniu rzeczy lub robieniu jakiejś innej logiki, mogło na przykład przyjść kilka zdarzeń ruchu myszy.

window->pollEvent(event);

Wywołanie pollEvent() ściąga zdarzenie z kolejki do Twojej zmiennej `event`. `event` zawiera teraz informacje o tym zdarzeniu.

Jeśli nie ma żadnych zdarzeń w kolejce, pollEvent() nic nie robi i zwraca false.

Czy w tym widzisz coś konfudującego?

Ewentualnie jeśli miałbyś pomysł jak rozwiązać problem z pytania do którego dałem link, to zdarzenia byłyby zbędne. Dlatego proszę spojrzyj na nie w wolnej chwili bo to blokuje moje prace.

To pytanie sprzed 3 miesięcy, na które dostałeś rozsądnie wyglądającą odpowiedź. Nie rozumiem tez, co to pytanie ma do "kilku pętli pollEvent".

komentarz 10 lipca 2018 przez DarkEliat Bywalec (2,810 p.)
To w sumie prawda odnośnie tej odpowiedzi, ale musiałem przebudować ten kod. Mnie też się wydawało, że jest dobry (może jest, ale ja mogę nie potrafić go użyć). Ten kod od użytkownika j23 musiałem umieścić w osobnym pliku (klasie), a później okazało się, że takie rozwiązanie nie działa. Właśnie dlatego potrzebuję 2 pętli.

Albo zrobię to po swojemu jak było w tym pytaniu (tam nie używałem eventów), tylko ktoś musi mi wskazać błąd.
komentarz 10 lipca 2018 przez adrian17 Mentor (351,140 p.)

Chodzi o drag&drop, tak? Ogólna idea tamtego kodu j23 jest dobra, napisałem coś własnego podstawowego od ręki i wydaje się działać:

https://puu.sh/AUbdE/a652ed181b.mp4

#include <SFML/Graphics.hpp>
int main()
{
    sf::RenderWindow window(sf::VideoMode(800, 600), "SFML window");

    sf::RectangleShape rect({50, 50});
    rect.setPosition(100, 100);

    sf::Vector2i pos;
    bool dragging = false;

    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            switch (event.type) {
                case sf::Event::Closed:
                    window.close();
                    break;
                case sf::Event::MouseButtonPressed:
                    if(event.mouseButton.button == sf::Mouse::Left) {
                        pos = sf::Vector2i(event.mouseButton.x, event.mouseButton.y);
                        if (rect.getGlobalBounds().contains(pos.x, pos.y))
                            dragging = true;
                    }
                    break;
                case sf::Event::MouseButtonReleased:
                    if(event.mouseButton.button == sf::Mouse::Left) {
                        dragging = false;
                    }
                    break;
                case sf::Event::MouseMoved:
                    if(dragging)  {
                        sf::Vector2i pos2(event.mouseMove.x, event.mouseMove.y);
                        sf::Vector2i move = pos2 - pos;
                        rect.move(move.x, move.y);
                        pos = pos2;
                    }
                    break;
            }
        }
        window.clear();
        window.draw(rect);
        window.display();
    }
}

 

komentarz 11 lipca 2018 przez DarkEliat Bywalec (2,810 p.)
Dziękuję za pomoc! Teraz tylko będę musiał przebudować ten kod by działał pod talię (klasa Deck). Boję się, że znów wyniknie jakaś głupia anomalia, podobna do tego co opisałem w tamtym pytaniu (przesuwalność tylko jednej obiektu).

Pozdrawiam.

Podobne pytania

0 głosów
1 odpowiedź 248 wizyt
pytanie zadane 22 marca 2018 w C i C++ przez Perseusz Bywalec (2,190 p.)
+2 głosów
1 odpowiedź 143 wizyt
pytanie zadane 10 kwietnia w C# przez roger10 Nowicjusz (180 p.)
0 głosów
1 odpowiedź 729 wizyt

93,189 zapytań

142,204 odpowiedzi

322,029 komentarzy

62,517 pasjonatów

Advent of Code 2024

Top 15 użytkowników

  1. 2817p. - dia-Chann
  2. 2769p. - Łukasz Piwowar
  3. 2759p. - Łukasz Eckert
  4. 2738p. - CC PL
  5. 2704p. - Tomasz Bielak
  6. 2678p. - Łukasz Siedlecki
  7. 2666p. - rucin93
  8. 2485p. - Marcin Putra
  9. 2418p. - Michal Drewniak
  10. 2367p. - Adrian Wieprzkowicz
  11. 2317p. - Mikbac
  12. 2239p. - Michał Telesz
  13. 2156p. - Anonim 3619784
  14. 1733p. - rafalszastok
  15. 1628p. - Dominik Łempicki (kapitan)
Szczegóły i pełne wyniki

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Wprowadzenie do ITsec, tom 1 Wprowadzenie do ITsec, tom 2

Można już zamawiać dwa tomy książek o ITsec pt. "Wprowadzenie do bezpieczeństwa IT" - mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy aż 15% zniżki! Dziękujemy ekipie Sekuraka za fajny rabat dla naszej Społeczności!

...