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