UpiPang Blog
Minden az időzítésen múlik
A játékokban az időzítés meglehetősen fontos kérdés, azon egyszerű oknál fogva, hogy a számítógép teljesítménye igencsak eltérő. Mégis igazán jó lenne, ha (a lehetőségekhez képest) a játék egyforma sebességgel futna minden gépen. Erre szolgál az időzítő.
Az UpiPang eddig egy (meglehetősen egyszerű) időzítőt használt: minden képkockánál megnézte, hogy hányszor tíz milliszekundum telt el, és ennyivel léptette előre a műsort. Egy egészen gyors gépnél persze lehet, hogy még nem telt el egy centiszekundum sem (mert ennél gyorsabban kiszámította és kirajzolta a következő képkockát), ilyenkor egy kicsit még vártunk.
Vagyis, a játék belül centiszekundumonként lépett előre. Ha (a rajzolás lassúsága miatt) két képkocka között több centiszekundum is eltelt volna, akkor annyival többel léptetett előre mindent, és csak a két-három-sok előrelépéssel később rajzolt ki mindent. Így elérhető volt, hogy lassabb gépen is (némi szaggatottság árán) azonos tempóban történjenek az események.
Ez így majdnem jó is volt.
A dolog szépséghibája a kerekítés volt: ha ugyanis a jelenlegi gépen mondjuk 13ms volt egy teljes kirajzolás, akkor is 10ms-ot haladt előre a játék, a maradék 3ms-ot pedig elfelejtette. Nos, örömmel tudatom, hogy írtam egy szép, új GameTimer-t, ami a töredék időket megfelelően görgeti. Az elején le kell nullázni (ResetTimer), utána pedig nincs más feladat, mind minden léptetés és rajzolás után megkérdezni tőle, hogy hány tick is telt el (GetAdvances).
A trükk benne mindössze annyi, hogy a kezdő idő mellett (FirstTick) eltárolom azt is, hogy összesen hány lépés (TotalAdvances) történt összesen.
Íme a kód, tanulságképpen:
##########################################################################
package GameTimer;
##########################################################################
use vars qw($FirstTick $TotalAdvances);
sub ResetTimer {
$FirstTick = $::App->ticks;
$TotalAdvances = 0;
}
sub GetAdvances {
my ($ticks, $advance);
$ticks = $::App->ticks;
$advance = int(($ticks - $FirstTick) / 10) - $TotalAdvances;
$TotalAdvances += $advance;
return $advance;
}
És végül, az első screenshot, ami játék közben készült! (Ha rákattintasz, nagyobban is megnézheted.)

Hozzászólások
0