Pelissäni on semmonen pikku bugi, että jos sen ajaa hitaammalla koneella, päähenkilö hyppää matalemmalle. Tässä pätkä fysiikasta:
t = aikaväli jokaisen framen välillä. 0.01s-0.03s luokkaa.
v_y = päähahmon kiihtyvyys. negatiivinen luku -> alaspäin.
update_time = aika ohjelman käynnistyksestä siihe, kun viimeksi oltiin tässä funktiossa.
y = ukon y koordinaatti. -merkkinen alaspäin.
t=(double)clock()/1000.0-(double)update_time; v_y-=t; y+=v_y; update_time=clock()/1000.0;
Huomautus: clock()/1000.0; palauttaa double arvon, koska luvussa 1000 on desimaali piste.
Jos laitan ohjelman main funktioon rivin SDL_Delay(20);, pääukko hyppää matalammalle. Johtuuko tämä näistä seikoista: ?
- t:n arvo on eri, koska ohjelmalla kestää pidempään, yhden framen tekemiseen
-clock()/1000.0; palauttaa _pääosin_ vain kahden desimaalin tarkkuudella ajan.
Minusta tuntuu, että nämä kaksi yhdessä tekee tämän bugin.
hypyn korkeus ero on n. 1/5.
Mikä muu OpenGL/SDL/muu aikafunktio palauttaisi kolmen desimaalin tarkkuudella?
Olisi tyhmää, jos peli olisi helpompi todella nopealla prosessorilla.
Älä tosiaan käytä clockia ajan mittaamiseen. Ainakin minulla se palauttaa käytetyn prosessoriajan, joka on aivan väärä asia. SDL:ssä on SDL_GetTicks. En ole kokeillut, osaako se kunnollisen tarkkuuden Windowsissa. Jos ei, niin katso viestini täältä. Ohjelmaasi vielä epätarkentaa se, että kutsut moneen kertaan tuota clockia, ja siinäkin välissä on ehtinyt tapahtua. Tässä parempi tapa:
Kulunut_Aika = SDL_GetTicks() - Vanha_aika; Vanha_Aika += Kulunut_Aika; // Joka on siis luonnollisesti sama kuin SDL_GetTicks() äsken.
Jos tarkkuus on huono, niin tällä saa sitä tarkennettua, vaikka pätkiminen toisaalta vähän lisääntyy:
Uusi_Aika = SDL_GetTicks(); while (Uusi_Aika == SDL_GetTicks()); // Odotamme, että arvo muuttuu Uusi_Aika = SDL_GetTicks(); // Otamme sen uudestaan, jolloin se on "juuri eikä melkein". Kulunut_Aika = Uusi_Aika - Vanha_aika; // Lasketaan kulunut aika Vanha_Aika = Uusi_Aika; // Ja se on nyt historiaa ;)
Liikkuminen pitää laittaa joiltakin osin jonkinlaiseen for-silmukkaan.
for (i = 0; i < Kulunut_Aika; i++)
Mitä enemmän on silmukassa, sitä parempi lopputulos. Ainakin nopeuden ja sijainnin muutokset pitää laittaa sinne. Eli liikut ikään kuin millisekuntin kerrallaan. Sijainnin voi laskea vaikka muuttujaan tuleva_sijainti, niin voi sitten vasta silmukan ulkopuolella laskea törmäykset. Tämä ei tietenkään oikein toimi, jos kimpoaminen halutaan mukaan.
Jos on oletettavaa, että pelisi on kaikin puolin kevyt piirtämistä lukuunottamatta, voit laittaa kaiken paitsi piirtämisen tuollaiseen for-silmukkaan, jolloin pääset parhaaseen tulokseen. Muutenkin tämä kaikki kannattaa laittaa ainakin jonkin kokoiseen silmukkaan, vaikka enintään 25ms kerralla. Riippuu toki pelin toteutuksesta, mutta ilman tätä saattaa toisinaan tapahtua hieman kummia, kun joku liikkuu kohdasta, jossa oikeastaan onkin jo jotakin tiellä.
Käytän piirtämiseen enimmäkseen OpenGL, joten se ei hirveän raskas ole prosessorille. SDL:llää käytän myös, mutta aika vähän sen hitauden vuoksi.
SDL_GetTicks() näytti palauttavan tarkempia arvoja, mutta sama ongelma oli vieläkin. Pitää tutustua noihin muihin laskutapoihin.
Noissa laskukaavoissa on se ongelma, että et ota aikaa kunnolla huomioon laskettaessa nopeuden ja paikan muutosta.
dt = (aika - vanhaaika) * sopiva skaalaus; vy -= g*dt; y += vy*dt; //tästä puuttui ajalla kertominen
Kiitos paljon, FooBat!! vika oli juuri tuossa! nyt se toimii millä tahansa delaylla samallailla! :)
Aihe on jo aika vanha, joten et voi enää vastata siihen.