Eli ongelmani on Liian nopea peli..
Vanhalla koneellani peli toimi ongelmattomasti, mutta uudessa koneessa onkin enemmän tehoa ja sitten tulikin mieleen se, että sinnehän pitää sinne koodiin tehdä, jotain että peli toimii yhtänopeasti kaikilla. Matopelin oppaassa on odotus funktio ja ajan otto funktio, mutta en ihan ymmärtänyt, että miten niitä käytetään?
Eli miten noita funktioita käytetään? Kaasua kun painaa auton nopeus muuttuu erittäin nopeasti ja auto menee kuin raketti pois kuvasta.
Tässä lähdekoodia tuosta
Kuten näkyy otin noita matopelin koodeja sinne ja niitä on siellä johonkin laitettu, mutta ei toimi oikein luultavasti. :P
Ps. Kiitos.
Minä olen tehnyt sen näin. Yritin kattella tuota sun koodia että miten tää integroituisi siihen mutta empä onnistunut.
Uint32 FramenAlku = 0; Uint32 FramenPituus = 1000 / FPS; while(1) { /*muu koodi*/ Uint32 KaytettyAika = SDL_GetTicks() - FramenAlku; if(KaytettyAika < FramenPituus) SDL_Delay( FramenPituus - KaytettyAika ); FramenAlku = SDL_GetTicks(); }
Lahhan ehdottama tapa on yleisesti ottaen huono: nopeudesta tulee epätarkka, ja hitaalla koneella peli pyörii hitaammin.
Matopelioppaassa kerrotaan tuosta hidastamisesta suunnilleen niin selkeästi, kuin vain suinkin on mahdollista, joten kannattaisi varmaan yrittää lukea se vielä muutaman kerran.
Miten saan FPS:n näkyviin? Ja miten voin tarkistaa toimiiko viritelmäni, kun minulla ei ole kahta konetta joilla testaisin asian.
Tulostat jonnekin laskurin tuloksen sekunnin ajan. Nollaat laskurin heti kun tulostus alkaa ja käynnistät laskurin uudestaan. Päivität tulostuksen sekunnin jälkeen. jne.
Tein muuttujan FPS ja tulostin sen pihalle (game.h tiedostossa PeliAlkaa funktiossa)
Se kuitenkin antaa arvoksi aina 0? Eli virhellinen varmaan, mutta en tiedä onko tämä edes FPS mittausta, enkä silti ole ihan varma saako tälläisellä systeemillä edes tarkistettua toimiiko peli kaikilla koneilla yhtänopeasti.
#include <iostream> #include <stdio.h> #include "SDL/SDL.h" #include <SDL/SDL_ttf.h> #include "data/draw.hpp" #include "data/game.h" int main(int argc, char* args[]) { bool pois=false; bool piirretty=false; float ajan_muutos = 0.02; Uint8* nappi; nappi = SDL_GetKeyState(NULL); Game::Download_StartGame(); while(pois==false) { int tulos = 0; bool loppu = false, piirretty = false; // Nollataan kello. float pelin_kello = Game::sekunnit(true); Game::FPS = Game::sekunnit(true); while (pelin_kello + ajan_muutos <= Game::sekunnit()) { pelin_kello += ajan_muutos; piirretty = false; } if (piirretty) { Game::odota(); } else { Game::PeliAlkaa(Game::rooma); piirretty = false; } SDL_PumpEvents(); if (Game::rooma == 1) { if(nappi[SDLK_ESCAPE]) { pois=true; } } } SDL_Quit(); return 0; }
Millainen on Game::sekunnit() ja millä tavalla se liittyy FPS:n laskemiseen? Eikös FPS ole frames per seconds eli pitäisi varmaan laskea piirrettyjen ruutujen määrä aikayksikköä kohden ja skaalata se joksikin fiksuksi.
mika132 kirjoitti:
Ja miten voin tarkistaa toimiiko viritelmäni
Lisää testiksi silmukkaan ylimääräinen SDL_Delay(30). Jos peli toimii tästä huolimatta yhtä nopeasti (mutta tietenkin nykivästi), olet tehnyt oikein.
Nykyisessä koodissasi on kaksi aivan idioottimaista virhettä, joista näkee, ettet vieläkään ymmärrä ohjelmoinnista oikein mitään, vaikka vastaukset lukevat suomeksi suoraan oppaassa.
Ihan oikeasti: Lopeta tuo pelin tekeminen ja opettele perusasiat. Et saa ikinä mitään aikaan, jos et ymmärrä tuollaisia yksinkertaisia asioita kuin muuttujien alustusten oikeaa paikkaa.
Noniin nyt kun sain vihdoin tallennetua tuon SDL_Delay(30) tuonne lähdekoodiin niin peli ei toiminut tökkivästi vaan hirveän hitaasti.
Eikä tästä kasasta varmaan peliä tulekkaan. Harjoitusta harjoitusta. Tällä hetkellä olen tehnyt hahmon liikkutamista esineiden keräämistä yms perusjuttuja nyt on auton liikuttaminen / pientä fysiikkaa vuorossa. (silti hahmon liikuttamisissa on sama ongelma tällä koneella liian nopeaa)
Takaisin asiaan..
Ja mitä tarkoitat? Eikös nollaus ole ulkopuolella. Ihan ensimmäisen whilen yläpuolella.
mika132 kirjoitti:
Ja mitä tarkoitat? Eikös nollaus ole ulkopuolella. Ihan ensimmäisen whilen yläpuolella.
En nyt tiedä, mitä nollausta tarkoitat, mutta ainakin nollaat muttujat tulos
ja pelin_kello
joka kierroksella ja käytät sekunnit
-funktiota väärin. Lisäksi koodissasi on edelleen virhe, josta mainitsin edellisen viestini kohdassa 2.
Nyt vihdoin taisin ymmärtää tuon perusteen.. Ei ollut ollenkaan huono idea tehdä itse tyhjästä pelimoottoria.. :)
Kuitenkin.. Nyt jos laitan ensimmäiseen while silmukkaan SDL_Delay(50); peli on hieman tökkivää.. Jos en laita mitään se on ihanteellisessa nopeudessa.. Tarkoittaako tämä, että nyt se toimii kaikilla koneilla yhtänopeasti? Vai pitääkö vielä testata jotenkin.. Jos täytyy miten sen voisi testata?
Tuon kommentin perusteella et kyllä ymmärtänyt perustetta. Pitäähän sinun tietää mitä silmukkasi tekevät.
Ehkä jotenkin näin:
float aika_ero; .. aika_ero = pelin_kello - Game::sekunnit(); while (aika_ero > 0) { SDL_Delay(aika_ero); // tai joku vakio esim 10 tuon aika_ero tilalla aika_ero = pelin_kello - Game::sekunnit(); } // Tämä if korjaa mahdollisen aikahyppäyksen jos esim alt+tab keskeyttää pääsilmukan if (aika_ero<-400) pelin_kello = Game::sekunnit(); pelin_kello += ajan_muutos;
mika132 kirjoitti:
Nyt jos laitan ensimmäiseen while silmukkaan SDL_Delay(50); peli on hieman tökkivää.. Jos en laita mitään se on ihanteellisessa nopeudessa.
Jos "tökkivä" tarkoittaa, että peli toimii samalla nopeudella mutta pätkivästi, olet onnistunut. Eli siis jos ukko juoksee saman samassa ajassa tai auto kiertää radan yhtä nopeasti tms.
Lisäsin kolmanteen matopelioppaaseen animaation, jossa näkyvät rinnakkain oikea ja väärä toiminta.
Aihe on jo aika vanha, joten et voi enää vastata siihen.