Herní návrhový vzor Rozdělení snímku
Z CHWiki
Obsah |
Účel
Zpřesnění fyzikálních výpočtů
Jiné názvy
Nejsou známy
Motivace
Při numerických výpočtech fyziky nestačí provádět jeden výpočet každý snímek, protože příliš dlouhý časový krok způsobuje něpřesnosti jako prolínání objektů nebo průchod objektů skrz sebe bez kolize. Proto se měří časový interval od posledního snímku a pokud je příliš velký, provede se několik výpočtů.
Použití
Vzor Rozdělení snímku použijeme, pokud chceme ve hře implementovat přesnou fyziku. Jeden výpočet za sekundu stačí jen pro úplně základní detekci kolizí.
Důsledky
V důsledku několika fyzikálních výpočtů každý snímek je hra náročnější na výpočetní výkon počítače. Na druhou stranu dosáhneme funkční a vcelku stabilní fyzikální simulace.
Implementace
Implementace je vcelku snadná, stačí v každém snímku vypočítat časový krok a v případě potřeby provést opakovaně výpočet, viz příklad.
Příklad
Téměř kompletní implementace měření časového intervalu a rozdělení snímku v jazyce C++:
// tato konstanta urcuje maximalni mozny interval mezi dvema fyzikalnimi
// vypocty v milisekundach
const float maxDelta = 30;
// do teto promenne se uklada aktualni cas v milisekundach
float now;
// tato promenna slouzi k uchovani casu posledniho snimku
float lastTime = 0;
void doPhysicsInTime(float time) {
// tato funkce spocita stav objektu v case time
// alternativou je posilat jen cas uplynuly od posledniho vypoctu
}
void Update() {
// kolik casu uplynulo od posledniho update
float deltaTime = now - lastTime;
// vzdy delame alespon 1 vypocet
int iterations = 1;
// pokud uplynulo vice casu nez je maximum
if (deltaTime > maxDelta)
// vypocitame pocet opakovani vypoctu
iterations = (int)(deltaTime / maxDelta) + 1;
// vypocitame interval mezi jednotlivymi opakovani vypoctu
float iterDelta = deltaTime / iterations;
for (int i = 0; i < iterations; i++) {
// vypocitame cas vypoctu i-teho opakovani
float newNow = lastTime + (i + 1) * iterDelta;
// spustime vypocet fyziky v dobe newNow
doPhysicsInTime(newNow);
}
// zapamatujeme si aktualni cas pro vypocet rozdilu v dalsim snimku
lastTime = now;
}
Známá použití
Všechny fyzikální enginy - ODE,...
