Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Nopea peli

Sivun loppuun

mika132 [02.11.2010 15:16:01]

#

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.

Lahha [02.11.2010 16:00:35]

#

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();
}

Metabolix [02.11.2010 16:04:25]

#

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.

mika132 [02.11.2010 16:36:46]

#

Miten saan FPS:n näkyviin? Ja miten voin tarkistaa toimiiko viritelmäni, kun minulla ei ole kahta konetta joilla testaisin asian.

tässä silti tuo koodi (main.cpp)

Jokotai [02.11.2010 16:58:50]

#

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.

mika132 [02.11.2010 18:58:35]

#

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;
}

Teuro [02.11.2010 19:03:16]

#

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.

Metabolix [02.11.2010 21:12:29]

#

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.

  1. Nollaat pelin kellon ja sekuntilaskurin joka kierroksella. Eikö järki (tai opas) sano, että tämä pitäisi tehdä while-silmukan ulkopuolella? Muutenhan kello on joka kierroksen alussa nollassa.
  2. Pelin toiminta tapahtuu jossain aivan väärässä paikassa. Toiminnan (liikkumisen ym.) pitäisi tapahtua sisemmässä while-silmukassa, jossa päivitetään pelin kelloa. Game::PeliAlkaa-funktion kohdalla ei saa muuttaa mitään tietoja, vaan siellä saa pelkästään piirtää.

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.

mika132 [11.11.2010 19:34:11]

#

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.

Koodi

Metabolix [11.11.2010 23:00:04]

#

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.

mika132 [14.11.2010 13:51:15]

#

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?

User137 [14.11.2010 15:04:42]

#

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;

Metabolix [14.11.2010 16:33:17]

#

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.


Sivun alkuun

Vastaus

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

Tietoa sivustosta