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

SFML problem z funkcją Sleep();

0 głosów
1,081 wizyt
pytanie zadane 9 października 2015 w C i C++ przez sofnir Gaduła (4,690 p.)

Hej, mam problem z funkcją Sleep() w SFMLu Najlepiej będzie mi wstawić kod i opisać co się dzieję:

if (moves < 2)
						{
							change_color(random_numbers, cards, i, j);
							moves++;
							if (moves == 1)
							{
								first_pick[0] = i;
								first_pick[1] = j;
								first_pick[2] = random_numbers[i][j];
							}
							else if (moves == 2)
							{
								second_pick[0] = i;
								second_pick[1] = j;
								second_pick[2] = random_numbers[i][j];
								if (first_pick[2] == second_pick[2]) std::cout << "brawo" << std::endl;
								else
								{
									Sleep(1000);
									std::cout << "kiepsko";
								}
							}	
						}

Teraz opiszę mój problem, dlaczego std::cout << "kiepsko"; wykonuje się w tym samym czasie co funkcja change color? Gdy dochodzę do momentu, w którym ma się wykonać std::cout<< "kiepsko", wówczas funkcja change_color czeka 1 sekundę i dopiero wykonuje się równocześnie z coutem. Powinna najpierw wykonać się funkcja change_color, a następnie po 1 sekundzie wypisanie "kiepsko" na ekran. Dlaczego tak się nie dzieję? 

1 odpowiedź

+1 głos
odpowiedź 9 października 2015 przez furas Maniak (53,800 p.)
wybrane 12 października 2015 przez sofnir
 
Najlepsza
A co dokładnie wykonuje ta funkcja change_color() ?

Programy GUI w kodzie wykonują pętle (zwaną często "mainloop"), w której wykonują kolejno (w jednym wątku) takie rzeczy jak pobieranie danych o stanie klawiatury i myszy, obsługa różnych zdarzeń i widgetów itd. Dzięki temu, że każda rzecz wykonuje coś krótkiego i pętla wykonuje się powiedzmy 60 razy na sekundę (w grach określane jako FPS - Frames Per Seconds) więc wygląda to jakby całość odbywała się wielowątkowo - jakby jedne rzeczy wykonywały sie niezależnie od drugich.

Może być tak, że change_color zmienia jakąś zmienną odnośnie koloru okna/widgetu ale odrysowanie tego okna/widgetu (i spowodowanie, że obiekt zmieni kolor) następuje w specjalnej funkcji, która wywoływana jest po `Sleep()` więc dopiero wtedy widać efekt użycia funkcji change_color.

Nie należy używac Sleep bo to zatrzymuje wykonywnie wszystkich funkcji w programie.

Gdybyś ustawił Sleep na coś większego to pewnie by się okazało, że nie tylko kolor się nie zmienia ale program nie reaguje na myszkę i klawiaturę.

Jeśli w programie mają się wykonywać funkcje długortwałe to należy je robić w osobnym wątku. Innym sposobem jest dodanie zmiennej z czasem określającym kiedy ma się wykonać dana rzecz i co sprawdzanie czy już czas to wykonać.

Trzeba to po prostu tak skonstruować, żeby "mainloop" nie było zatrzymywane.
komentarz 10 października 2015 przez sofnir Gaduła (4,690 p.)
Bardzo dziękuję za odpowiedź, to mi wiele wyjaśnia i jest bardzo logiczne. Robię grę w pary (memory game). Załóżmy, że gracz odkrywa pierwszą kartę, następnie odkrywa drugą i nie udało mu się trafić. Zanim karty się odwrócą (będzie widoczny rewers) gracz musi zobaczyć obrazek drugiej karty, żeby go zapamiętać. Zamiast funkcji Sleep muszę wywołać start odliczania jakiegoś zegara i w pętli głownej zrobić ifa, który będzie sprawdzał, czy zegarek ma na liczniku określoną wartość (może lepiej czy przekroczył jakąś wartość) i wtedy wywołać zamierzoną funkcję, zatrzymać i wyzerować zegar. Przy okazji będzie trzeba zadbać o to, żeby użytkownik nie mógł w tym czasie odkrywać kolejnych kart. Dobrze kombinuję?
komentarz 10 października 2015 przez furas Maniak (53,800 p.)

Możesz pobrać aktualny czas, dodać ilość sekund na "spanie" i zapamiętać w zmiennej. Potem w każdym przejściu pętli pobierasz aktualny czas i porównujesz z zapamiętanym aby określić czy "spanie" już można zakończyć. 

Dodatkowo wykorzystuje się zmienną opisującą stan gry np. stan = spanie/pauza/wyswietlanie_menu lub rozbite na samodzielne zmienne spanie = true/false, pauza = true/false, wyswietlanie_menu = true/false, animacja_karty = true/false i na podstawie tego typu zmiennych można w różnych miejscach podejmować decyzję czy w danym przejściu pętli wolno kartę odkrywać (lub robić inne rzeczy)

komentarz 12 października 2015 przez sofnir Gaduła (4,690 p.)

Mam jeszcze takie pytanie, bo mam problem z klasą Clock. Nie wiem jak ona się zachowuje. Mam przykładowo

sf::Time time;
sf::Clock clock;
time = clock.getElapsedTime + sf::seconds(10.f);

i później nie wiem jak to przyrównać w tej głównej pętli


if(clock.getElapsedTime >= time) std::cout<<"it works"<<std::endl;

i właśnie to mi nie działa, mam prośbę, mógłbyś mi powiedzieć co robię źle?

 

komentarz 13 października 2015 przez furas Maniak (53,800 p.)

Nie mam pojęcia jak się zachowuje ale trzeba zacząć od sprawdzonej metody - więcej wypisywania danych zmiennych itp. aby przekomać się co zmienne zawierają. Dodaj więc może w kodzie

sf::Time time;
sf::Clock clock;
time = clock.getElapsedTime + sf::seconds(10.f);

std::cout << clock.getElapsedTime << endl;
std::cout << time << endl;
std::cout << (clock.getElapsedTime >= time) << endl;

---

EDIT:

`clock.getElapsetTime` jest funkcją czyli musi zawierać nawiasy () aby zwróciło czas. Inaczej może zwracać adres pamięci pod którym się znajduje ta funkcja (wskaźnik do funkcji) czyli wartość która może być bardzo duża - dużo większa niż 10 sekund :).

Wydaje mi, że użycie powinno wyglądać coś w tym stylu
 

// utworzenie zmiennej do porównania
sf::Time time = sf::second(10.f);

// stworzenie zegara i wystartowanie odliczania czasu od zera
sf::Clock clock;

// sprawdzenie czy mineło 10 sekund
if(clock.getElapsedTime() >= time) 

// wystartowanie odliczania ponownie od zera
clock.restart()

http://szymonsiarkiewicz.pl/poradniki/sfml-kurs-podstawowy/obslugiwanie-czasu-w-sfml/

---

Wydaje mi się, że autor podanej strony Szymon Siarkiewicz rzucił mi sie w oczy na tym forum. Avatar z tamtej strony też chyba widziałem na tym forum.

Podobne pytania

0 głosów
2 odpowiedzi 568 wizyt
pytanie zadane 28 sierpnia 2016 w C i C++ przez Kosmaty205 Początkujący (340 p.)
0 głosów
2 odpowiedzi 1,473 wizyt
+2 głosów
5 odpowiedzi 811 wizyt
pytanie zadane 18 października 2015 w C i C++ przez patryk16 Obywatel (1,080 p.)

93,731 zapytań

142,668 odpowiedzi

323,286 komentarzy

63,290 pasjonatów

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

Twierdza Linux. Bezpieczeństwo dla dociekliwych

Aby uzyskać rabat -10%, użyjcie kodu pasja-linux, wpisując go w specjalne pole w koszyku.

...