Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C: Framerate

Sivun loppuun

Tumpelo [08.02.2006 22:02:48]

#

Elikkä minä teen erästä peliä, ja se kaipaisi nyt jotain kunnon framerate systeemiä, tähän mennessä olen vain tehnyt neekerinkengät eli laittanut kisaloopin loppuun SDL_Delay(15); Tämä ei liene kuitenkaan tehokas tapa, eikä varsinkaan vakaa ja järjestelmäriippumaton. Joten kuinkas tämä tehdään ammattimaisesti?

Tzaeru [09.02.2006 13:46:41]

#

SDL:llä on muuten kiva funktio fsp:n rajoittamiseen, FPSmanager. Tässähän tämä:

        // Rajoita framea:
	// Alusta framin hallintafunkkari:
	FPSmanager fpsm;
	SDL_initFramerate(&fpsm);
	SDL_setFramerate(&fpsm, 60); // 60 framea sekunnissa

	// Kutsutaan FrameLimitteri:
	SDL_framerateDelay(&fpsm);

Deewiant [09.02.2006 13:55:52]

#

"Ammattimaisesti" homma kuitenkin tehdään niin, että katsotaan, kauanko aikaa on mennyt edellisen framen piirtämisestä ja sitten lasketaan kaikki pelin fysiikka yms sen ajan mukaan. FPS voi olla mikä vaan, mutta kaikki tapahtuu yhtä nopeasti koneesta riippumatta.

Metabolix [09.02.2006 18:19:41]

#

Ja mitä sitten tehdään, kun peli ei pyöri tuolla 60:llä framella? Eli ei mitään FPS:n purkkasäätöä, vaan tuo Deewiantin mainitsema tapa.

Mahdollisimman tarkalla tavalla:

for (i = 0; i < KulunutAika; ++i)
{
  Nopeus += Kiihtyvyys;
  Sijainti += Nopeus;
}

Tai nopeammin:

Nopeus += Kiihtyvyys * KulunutAika;
Sijainti += Nopeus * KulunutAika;

Tai sitten jollakin hienommalla tavalla. Konstit on monet.

Deewiant [09.02.2006 18:22:40]

#

Miten tuo for-looppi on tarkempi kuin kertolasku? Ainahan tuosta tulee sama tulos, ellei sitten tule jotain overflowta, jolloin kummankin tavan tuottama tulos on pielessä.

Tumpelo [09.02.2006 18:28:54]

#

Metabolix kirjoitti:

Ja mitä sitten tehdään, kun peli ei pyöri tuolla 60:llä framella? Eli ei mitään FPS:n purkkasäätöä, vaan tuo Deewiantin mainitsema tapa.

Mahdollisimman tarkalla tavalla:

for (i = 0; i < KulunutAika; ++i)
{
  Nopeus += Kiihtyvyys;
  Sijainti += Nopeus;
}

Tai nopeammin:

Nopeus += Kiihtyvyys * KulunutAika;
Sijainti += Nopeus * KulunutAika;

Tai sitten jollakin hienommalla tavalla. Konstit on monet.

Nyt en täysin ymmärtänyt... Mikä tuossa on tuo KulunutAika?

Deewiant [09.02.2006 19:19:05]

#

Tumpelo kirjoitti:

Mikä tuossa on tuo KulunutAika?

Tämäntyylisesti:

int main() {
	while (pelataan)
		loop();
}

void loop() {
	int aikaNyt = katoKellosta();

	int kulunutAika = edellinenAika - aikaNyt;

	ynnääNopeusJaSijainti(kulunutAika);

	edellinenAika = aikaNyt;
}

Tumpelo [09.02.2006 19:22:09]

#

No kuinkas tuo aika sitten katsotaan?

Metabolix [09.02.2006 19:47:54]

#

Hakua saa käyttää.

Uint32 KulunutAika, VanhaAika;

// Aika aluksi (Vai lupasikohan SDL, että se on nolla? Anyway...)
VanhaAika = SDL_GetTicks();

// Pääsilmukkasi, mikä lie onkaan
while (1) {
  KulunutAika = SDL_GetTicks() - VanhaAika;
  VanhaAika += KulunutAika;

  // Kaikki muu koodi tänne
}

Tumpelo [09.02.2006 20:08:19]

#

Ah, nyt selkeni. Vaikuttaa kätevälle, pitää viikonloppuna soveltaa koodissa kun aivot juoksevat sitten paremmin...

Deewiant [09.02.2006 21:43:22]

#

Metabolix kirjoitti:

// Aika aluksi (Vai lupasikohan SDL, että se on nolla? Anyway...)

SDL_GetTicks() palauttaa SDL:n alustuksesta (vai ohjelman käynnistyksestä?) kuluneen ajan millisekunteina. Todennäköisesti se siis ei ole nolla.

Ja koska se on 32-bittinen etumerkitön kokonaisluku, se overflowaa vajaan 50 päivän päästä, eli softan käyttötarkoituksesta riippuen kannattaa olla tarkkana.

Metabolix [09.02.2006 23:07:38]

#

Ah, mutta overflowlla ei ole tässä tapauksessa mitään merkitystä, koska framen pituus tulee laskettua oikein siitä huolimatta. Ongelmia tulee vasta, jos yhden framen pituus venyy sinne 49,7 vuorokauden yli.

Nollalla tarkoitin juuri sitä, että onko tuo mahdollisesti SDL_n alustuksen jälkeen nolla. Mutta toki tuo kuuluu joka tapauksessa poimia juuri ennen pääsilmukkaa, koska sitä ennen on kuitenkin jo latailtu tiedostoista jotakin. Minusta on myös hyvä asettaa se kohdalleen aina, kun jotakin mahdollisesti pitkäkestoista tapahtuu (esimerkiksi tason lataaminen tiedostosta).


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta