Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C: Aikaan perustuvan funktion ongelma

Sivun loppuun

verho88 [18.07.2006 16:17:13]

#

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

Sisuaski [18.07.2006 16:30:25]

#

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.

T.M. [18.07.2006 16:33:52]

#

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.

verho88 [18.07.2006 16:47:19]

#

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ä.

sooda [18.07.2006 16:59:29]

#

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.

T.M. [18.07.2006 22:29:26]

#

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.

Metabolix [18.07.2006 22:38:50]

#

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?

T.M. [18.07.2006 22:41:26]

#

Editoin jo sen kerroinjutun siitä pois ennen kuin vastasit, kun tajusin ettei se olisi ollut sama tulos. :)

Metabolix [18.07.2006 22:43:16]

#

Noh noh, eipäs sensuroida. Kyllä se siinä oli vielä minun vastaukseni lähdettyäkin. :)


Sivun alkuun

Vastaus

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

Tietoa sivustosta