Mulla on koodissa sellainen looppi joka pyörii maksimissaan 100 kertaa sekunnissa. Kaiken järjen mukaan siihen pitäisi saada aikaan perustuva funktio, joka muuttaa tietyn muuttujan arvoa enintään 100 kertaa sekunnissa. Mutta huomasinpa omaksi huvikseni, että se vaihtuu vain kerran sekunnissa. Kaikki muu toimii nopeammin. Testasin vielä frapsilla, niin FPS:t oli noin 70.
Tarkoitus siis on, että ukko hyppää ja sen y-koordinaatti vaihtuu aikaan perustuvan funktion mukaan.
Tässä siis koodi:
if ((GetAsyncKeyState('Q')) && (!jump)) // Jos ei hypätä ja painetaan Q:ta { jump=TRUE; // Hyppy päälle y_speed=1.0; // Hypyn nopeus alussa jump_start_y=my_y; // Korkeus alussa jump_start=GetTickCount(); // Hypyn alkuaika } if (jump) // Jos siis hypätään { jump_end=GetTickCount(); // Tämän hetkinen aika jump_time=(jump_end-jump_start)/1000; // Kuinka kauan on hypätty? (sekunteina) // Tämä menee siis fysiikan lakien mukaan. Tasaisesti muuttuvan nopeuden kaavalla my_y=gravitaatio*(jump_time*jump_time)+y_speed*jump_time+jump_start_y; if (my_y<0) // ja jos ollaan painuttu "maan" alle { jump=FALSE; // Eipä hypätä enää my_y=0; // Ja nostetaan maan pinnalle } }
Muuttujista vielä, että:
my_y, jump_time, y_speed ja gravitation ovat float-muuttujia, vaikka sillä ei ole vaikutusta asiaan vaikka olisivat long doubleja.
Kummastuttaa siis, kun my_y vaihtuu vain sekunnin välein.
mod.edit: ne kooditagit
Uskoisin tämän rivin olevan ongelmasi ydin:
jump_time=(jump_end-jump_start)/1000;
Mikäli jump_end ja jump_start ovat kokonaislukuja, on myös lausekkeen arvona kokonaisluku, joka muunnetaan floatiksi vasta, kun se tallennetaan jump_timeen (jolloin kaikki sekuntia pienemmät osat on jo hukattu).
Mikäli vika on nyt tässä kohtaa, pitäisi luvun 1000 muuntaminen muotoon 1000.0f auttaa.
my_y=gravitaatio*(jump_time*jump_time)+y_speed*jump_time+jump_start_y;
Ehkä kannattaa miettiä miten tuon kaavan saa toteutettua ilman kertolaskuja ja ilman sekunteihin perustuvaa aikaa.
Eli lisää jokaiseen objektiin painovoima (yk+=voima; y+=yk), ja kun sä hyppäät, niin se tippuu myöskin alas tuon painoivoiman takia. Ei siis tarvitse tietää missä kohdassa aikaa äijä on, vaan joka frame lisäät äijään sen painovoiman vaikutuksen, jolloin ukko hyppää ja tippuu painovoiman vaikutuksen alaisena.
Muutin tuon muotoon 1000.0f ja nyt toimii. Kiitos Sisuaskille. T.M.:lle vain sitä, että jos teen sen niin miten sanoit gravitaation voimakkuus riippuu silloin koneen tehoista. :) Vaikka tuskinpa nykykoneilla eroa huomaisi, mutta vanhemmilla kyllä.
Tuon TM:n jutun voisi hoitaa vaikka suoritettavaksi n kertaa sekunnissa, eikä kerran joka frame, niin ihan tasaisesti rullaisi silloin. Harvoin mitään tuollaista laitetaankaan mitenkään ilman nopeushallintaa.
Häh. Jos sä reaaliaikasen haluat siitä, niin se pitää laskea joka freimi.
Ja tuo on nopein mahdollinen tapa minkä esitin. Jos muutama pluslasku per freimi hidastaa konetta, niin aika hidas kone saa olla. Jopa miljoonia pluslaskuja voidaan suorittaa sulavasti, yksi ei tunnu missään.
T.M. varmaankin osaa kertoa, mihin se nopeuskerroin sitten perustuu ellei kuluneeseen aikaan? Ja T.M. varmaankin myös tietää, että eivät ne kertolaskutkaan hitaita ole, se on historiaa se. Eikä tuolla tavalla tule aivan sama lopputuloskaan, ei se kelpaa silloin. Kaikkein nopeinta olisi poistaa koko kiihtyvyysominaisuus ja tehdä hypyistä vakionopeuksisia ja -korkuisia, miksei sitten niin saman tien?
Editoin jo sen kerroinjutun siitä pois ennen kuin vastasit, kun tajusin ettei se olisi ollut sama tulos. :)
Noh noh, eipäs sensuroida. Kyllä se siinä oli vielä minun vastaukseni lähdettyäkin. :)
Aihe on jo aika vanha, joten et voi enää vastata siihen.