Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Tempo gry powinno być stałe, a zależy od użycia procesora

Ostatnio zmodyfikowano 2014-04-19 22:21
Autor Wiadomość
czosnek17
Temat założony przez niniejszego użytkownika
Tempo gry powinno być stałe, a zależy od użycia procesora
» 2014-04-18 16:06:23
Próbuję sprawić, aby gra działała z tą samą prędkością na różnych komputerach.
C/C++
sf::Clock clock;
float co_ile_przebieg = 0.022f; //45 przebiegów na sekundę

sf::Clock clock_fps;
float sec = 1;
int fps = 0;
clock_fps.restart();


clock.restart();
while( okno.isOpen() )
{
   
    if( clock.getElapsedTime().asSeconds() > co_ile_przebieg )
    {
        clock.restart();
       
        if( clock_fps.getElapsedTime().asSeconds() > sec )
        {
            cout << "FPS  " << fps << endl;
            fps = 0;
            clock_fps.restart();
        }
       
        if( clock_fps.getElapsedTime().asSeconds() < sec )
             fps++;
       
       
        //tutaj funkcje gry
       
    }
    Sleep( 1 ); //w celu zmniejszenia użycia procesora
}
Jak widać działanie jest proste: jeżeli minął czas 0.022 s, wykonujemy kod gry, jeżeli nie to czekamy.
W grze mam odpowiednią ilość fps (43-44) z użyciem procesora < "0"% a więc bardzo małem.
Co jest dziwne?
Jeżeli obciążę procesor do 60% fps spada do ok 35. Dlaczego? Przecież cpu nie jest cały zajęty więc ilość fps powinna się utrzymać. Fps skaczą od 43-44 gdy ja nie obciążam specjalnie procesora, a robią to jakieś programy w tle. Jednak jest to niewielkie bo tylko 1 fps przy użyciu < 4%.
Może to coś w kodzie jest źle, a ja tego nie widzę? Wszystkie pomiary robiłem w menu głównym gry, na pewno to nie jest wina jego kodu.
P-108328
MrPoxipol
» 2014-04-18 16:23:40
Ustaw stały framerate, albo włącz synchronizacje pionową.
P-108329
czosnek17
Temat założony przez niniejszego użytkownika
» 2014-04-18 16:27:38
Vsync mam włączone, a framerate jest na max 45. Chodzi o to że spada dużo poniżej tej wartości, a nie powinno (procesor nie jest cały zajęty).
P-108330
MrPoxipol
» 2014-04-18 16:28:55
To po co jeszcze wywołujesz Sleep()? I to jeszcze z taką śmieszną wartością.

Wystarczy, że ustawisz sam limit klatek (najlepiej na 60). Możesz to zrobić funkcją z SFML, lub sleepem (sf::sleep(sf::milliseconds(1000/60)).
P-108331
czosnek17
Temat założony przez niniejszego użytkownika
» 2014-04-18 16:44:06
To po co jeszcze wywołujesz Sleep()? I to jeszcze z taką śmieszną wartością.
Sleep( 1 ); //w celu zmniejszenia użycia procesora
Po co gra ma żreć ~100%, gdy tego nie trzeba?

Ustawienie limitu fps funkcją sfml nic nie dało, nie o to tutaj chodzi. Sleepa nie używam, bo jest niedokładny. Problem nie jest w tym, że mam za dużo kratek.
To
if( clock.getElapsedTime().asSeconds() > co_ile_przebieg )
 robi, że nie będę miał więcej niż 45 fps(chodzi o przebiegi pętli a nie częstotliwość odświeżania ekranu).

Chodzi o to, że wartość zmiennej fps zmniejsza się z wzrostem użycia procesora, ale procesor nie jest cały zajęty.
P-108334
pekfos
» 2014-04-18 17:21:50
Chodzi o to, że wartość zmiennej fps zmniejsza się z wzrostem użycia procesora, ale procesor nie jest cały zajęty.
Bo to normalne? Wywal sleepy, wywal ograniczenia. Jeśli gra nie wyrabia, to nie dobijaj jej tymi śmiesznymi sposobami na.. no właśnie, co ty tu niby próbujesz osiągnąć? Najlepiej (najprościej) zastosuj pętlę czasu rzeczywistego i ciągnij z procesora ile fabryka dała. Na jednym komputerze będzie 1000 fps, na innym 50, ale gra będzie działać w obu przypadkach dobrze.

Po co gra ma żreć ~100%, gdy tego nie trzeba?
A dlaczego nie? Jak ktoś gra w grę, to liczy się wydajność gry. Sleep(1) to śmieszne i naiwne rozwiązanie. Naiwne, bo chyba myślisz, że to zatrzyma program na dokładnie 1 milisekundę. Te wywołanie może równie dobrze zatrzymać program na 100 ms.
P-108339
czosnek17
Temat założony przez niniejszego użytkownika
» 2014-04-19 14:28:29
Zrobiłem mały test i już wiem czemu tak się dzieje, ale to i tak dziwne, a nawet głupie.
C/C++
//w pętli
sf::Clock cl;
cl.restart();

sf::sleep( sf::microseconds( 1100 ) );
if( cl.getElapsedTime().asMicroseconds() > 3000 )
{
    cout << cl.getElapsedTime().asMicroseconds() << endl;
   
}
Gdy użycie procesora jest ok 50%, czas sleepa pochodzi do 10k mikrosekund(wtf), więc z niego nie mogę dalej korzystać.
Pętli czasu rzeczywistego nie robię, bo chcę, żeby wszystko w grze działo się z tą samą szybkością niezależnie od komputera.
Problem w tym, że gdy całkowicie wywalę sleep gra bierze cały procesor dla siebie, a wtedy gdy inne programy będą chciały coś zrobić, gra zacznie zamulać. Ogólnie lepiej jest bez sleepa. Chyba będę szukał dokładniejszych funkcji.
P-108370
pekfos
» 2014-04-19 16:59:21
Pętli czasu rzeczywistego nie robię, bo chcę, żeby wszystko w grze działo się z tą samą szybkością niezależnie od komputera.
Hm? Właśnie po to jest ta pętla.
P-108382
« 1 » 2
  Strona 1 z 2 Następna strona