[SFML] Timer oraz przekazywanie elemntów vector do stosu

0

Witam,
Chciałbym obsłuzyć zegar w applikacji opratej o sfml tak aby po kilku sekundach wykonał daną czynność, jak mogę to zrobić?
Mam obiekty klasy Koło, wszytskie zapisane w konetnerze vector, chce losowe wybrane elementy z vectora przypisać do stosu. Zarówno stos jak i vector maja ten sam typ clase Koło.
Czy losuje element 1-100 (elementy vector) i przypisuje do
nazwa_stosu.push(Vector[i]);
nastepnie wywołuje metodę
SetPosition nazwa_stosu.top().SetPosition
Jednak to nie działa, gdyz po próbie narysowania tego elemntu zwraca mi błąd.
Jak mogę przypsiac jedne elemnt do drugiego i czy po przypisaniu vectora do stosu , moge usunąc element z vectora przez wywowłanie destructora a elemnt stosu nadan mi pozostanie ?

0

Aby wywołać coś po określonej ilości czasu musisz zrobić to ręcznie w głównej pętli programu, tj.:

sf::Clock eventClock;
...
while( renderWindow.pollEvent(event) ){
    if( eventClock.getElapsedTime() >= sf::Time::seconds(10) ){
        //tutaj obsługa zdarzenia
        eventClock.restart();
    }  
}

Kod w miejscu komentarza będzie wykonywany co minimum 10 sekund. Dlaczego minimum? Wyobraźmy sobie, że jesteśmy w przebiegu pętli nr X. Zegar zliczył 9.90s, warunek nie wykonuje się, główna pętla wykonuje się normalnie dalej (gdzie jest jakaś logika, rendering, itd.) i zajęło to 250ms. Wykonywanie wraca do początku pętli i na liczniku mamy 10.15s. ;)
Powyższy przykład jest trochę na wyrost, bo w normalnych warunkach delta czasu (czas wykonania głównej pętli) nie powinna przekroczyć 40ms (co daje 25 FPS), ale jeśli to zdarzenie ma się uruchamiać regularnie z czasem błąd będzie narastał. Jeśli chcesz wywołać zdarzenie tylko raz, powyższe rozwiązanie wystarczy.

Inaczej lepiej przechowywać czas w osobnej zmiennej:

sf::Clock deltaClock;
sf::Time myEventTimer;
...
while( renderWindow.pollEvent(event) ){
    myEventTimer += deltaClock.restart();
    if( myEventTimer >= sf::Time::seconds(10) ){
        myEventTimer -= sf::Time::seconds(10);
        //tutaj obsługa zdarzenia
    }  
}

Powyższy kod nie gubi nadwyżek czasu. Do tego jeśli interwał ma być bardzo mały (rzędu kilku/kilkudziesięciu ms) możesz zamienić if na while, dzięki czemu zdarzenie będzie odpalane wielokrotnie w czasie jednej klatki.

Z projektowego punktu widzenia takie timery najlepiej zaimplementować za pomocą jakiejś prostej klasy Timer, przypisywanych do nich callbacków (np. przez std::function) oraz kolejki/listy aktywnych timerów obsługiwanych w głównej pętli (albo jeszcze lepiej: jakiegoś menadżera z metodami addTimer/removeTimer).

Natomiast opis Twojego problemu z wektorem i stosem jest niejasny i nie rozumiem, o co Ci chodzi. Jaki błąd Ci zwraca? W tych kontenerach przechowujesz obiekty Koło, czy wskaźniki do nich?

0

Wiec tak jesli chodzi o Timer mam problem z second(10) nie rozpoznaje tego poprawa na asSecond(10) tez wyrzucial blad. Ogolnie chce wylowoac poruszajace sie kule z kontenera vector , losownaie nastąpi po kilknastu sekundach.

<code class="cpp">vector < Ball > ball(49, Ball(win));
	vector < TextBall > tekst(49, TextBall(win));
std::stack < Ball > wylosowane;

....

while (win.isOpen())
	{
		licznik++;

...
if (licznik > 60)
		{

			cout << "cos";
			losuj = (std::rand() % 47) + 1;
			wylosowane.push(ball[losuj]);
			wylosowane.push(ball[losuj+1]);
		wylosowane.top().SetPozition(650, 100);
		}
		wylosowane.top().SetPozition(650, 100);
		wylosowane.top().Draw();

Chciałem zrobić tak aby kule po losownaiu trafialy do konetenera stack, a nastepnie mógł je wyswietlic obok głownego pola, oraz być może także usunąc wylosowana kule z maszyny losującej

0
while (win.isOpen())
    {
        licznik++;

W ten sposób zliczasz ilość wyrenderowanych klatek, nie czas. Nawet jeśli ustawisz stałe FPS nie masz gwarancji, że upłynęła żądana ilość czasu (program przymuli i zamiast 60 FPS akurat może być 20 - timer się odpali po 3s zamiast 1, albo sterownik/system wymusi vsync).

Co do konstruowania czasu: mój błąd, powinno być samo seconds(10) (to luźna funkcja, nie metoda sf::Time), dokumentacja jest tu trochę myląca na szybki rzut oka. ;) ( http://www.sfml-dev.org/documentation/2.0/classsf_1_1Time.php#af9fc40a6c0e687e3430da1cf296385b1 )

Nadal nie wiem, w czym masz konkretnie tkwi Twój problem z tymi kulami? :)

0

W jaki sposób mogę wykonać 6 zdrzarzeń w odstępnie 5 sekund?

1 użytkowników online, w tym zalogowanych: 0, gości: 1