Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C: Hidastusta liikuttamisessa

remontti-reiska [06.01.2005 18:28:13]

#

if (GetAsyncKeyState(38)){
angely++;
glTranslatef(0, 0, angely);
}
else
{
glTranslatef(0, 0, angely);
}

Ylhäällä siis neliön liikutuspätkä. Se on hieman liian nopeahko, eli miten saisin pienen hidastuksen tuohon?

Metabolix [07.01.2005 07:35:04]

#

Vastaus: Voit (kannattaa) käyttää kulmana float-muuttujaa ja lisätä siihen jotakin pienempää eli korvata ++:n vaikka += 0.1f:llä.

Ohjeita: Tuolla tavalla koodisi on täysin riippuvainen koneen nopeudesta, eli neliö pyörii vauhdikkaammin nopealla koneella. Yleensä pelien ja muiden tällaisten ohjelmien toiminnan pitäisi olla näennäisesti yhtä nopeaa koneesta riippumatta. Siksi on tapana, että tarkistat päälooppisi alussa, paljonko aikaa kierrokseen on kulunut, ja teet kaikki muutokset sen mukaan (eli esim. angley += KulunutAika * 0.1f. Aikaa voi mitata vaikkapa time.h:n clock-funktiolla:

double Ohjelman_Alusta_Kulunut_Aika_Sekunteina = (double)clock() / CLK_TCK; // CLK_TCK tai CLOCKS_PER_SEC

GetAsyncKeyState on tosi myös, jos näppäintä on painettu viimeisen tarkistuksen ja tämän välissä. Se, onko näppäin alhaalla nyt, lukee merkitsevimmässä bitissä (0x8000).

vihje: glTranslatef-funktion ei tarvitse olla if-lauseen sisällä, sehän suoritetaan joka tapauksessa. Riittää, jos sinulla on if-lauseessasi tuo muuttujan arvon muuttaminen:

if (GetAsyncKeyState(38)) angley++;

Ehdotus: Voisit lisätä kulman muuttumisen viereen tarkistuksen, että kulma pysyy 0 - 360 asteen rajoissa, eli poistaa kokonaiset kierrokset. Ohjelman toiminnan ei pitäisi häiriintyä, mutta tästä voi olla joskus hyötyä.

if (angley > 360) angley -= 360;

Huomautus: Eikös kulma ole angle eikä angel?

remontti-reiska [07.01.2005 11:14:57]

#

Jooh, kulma voi olla angle tai joku aivan muu. En yleensä siitä muuttujan nimestä niin paljon välitä.

remontti-reiska [07.01.2005 12:43:26]

#

Nyt tapahtuikin niin hassusti, että muokkausaika meni umpeen ja en tajunnut tuota sinun Ohje -osiosi ensimmäistä ohjetta. Viitsitkö kertoa pikkusen tarkemmin sen kohdan?

Metabolix [07.01.2005 21:44:35]

#

Siis, jos ohjelmasi on jotenkin näin:

while (true)
{
  // Jos on viestejä, käsitellään
  if (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
  {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }
  // Ei viestejä, suoritetaan ohjelmaa
  else
  {
    // Jos on nappi, nostetaan anglea
    if (GetAsyncKeyState(38))
      angley++;

    // Laitetaan translate
    glTranslatef(0, 0, angley);
  }
}

Kai teet sen jotenkin noin, PeekMessage-funktiolla?
Ja tietysti tuossa on muuta koodia, kuten piirtofunktio ja ne... mutta nyt pitäisi huomioida kulunut aika, joten lisätään koodiin muuttujia vaikka näin:
unsigned int Aika, Edellinen;
Sitten muutetaan else-kohta tällaiseksi:

else
{
  /* Muuttujat menevät nyt vähän hassusti, mutta
   * 'Edellinen' on siis clock-funktion viimekerran aika ja
   * Aika-muuttujaan lasketaan viime kerrasta tähän kulunut aika.
   * Ajat millisekunteina */
  Aika = Edellinen;
  Edellinen = (1000 * clock()) / CLK_TCK;
  Aika = Edellinen - Aika;

  // Jos on nappi, nostetaan anglea kuluneen ajan mukaan
  if (GetAsyncKeyState(38))
    angley += Aika * 0.1f; // 0.1f / millisekunti => 3,6 sek / kierros

  // Ja loput ihan samalla tavalla. Jos kyseessä olisi tyypin liikkuminen, niin liikemäärä pitäisi taas kertoa ajalla.
}

remontti-reiska [08.01.2005 10:43:49]

#

Jooh, nyt meni jakeluun. Kiitos taas.

Vastaus

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

Tietoa sivustosta