Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Auton ohjaus

mika132 [04.01.2011 23:21:17]

#

Eli autoni ohjaus alkoi yhtäkkiä oikkuilemaan.

1. Pienessä vauhdissa auto menee sivuttain ja suuremmassa eteenpäin kuten pitää. Lisäksi auto menee lujempaa huomattavasti kun auto on tikkusuorassa.

2. Auto ei kulje kuten pitäisi. Auton kiihtyvyys lasketaan auton tehojen mukaan kuten voi päätellä alla olevasta funktiosta. eli jos tehot ovat 52hp kiihtyvyys on 0.52 ja huippunopeus siis 5.2, mutta auto ei liiku ellen tee erillistä double muuttujaa kiihtyvyydelle vielä liikutus funktioon sisälle.

3. Auto ei myöskään liiku ennen kuin vauhti on 1. Jos muutan kohdan:

x_oma+=std::cos(kulma_oma) * nopeus_oma;
y_oma+=std::sin(kulma_oma) * nopeus_oma;

tälläiseksi:

x_oma+=std::sin(kulma_oma) * nopeus_oma;
y_oma+=std::cos(kulma_oma) * nopeus_oma;

Niin auto kulkee vaikkei nopeus vielä olisikaan 1 vaan 0.jotain, mutta tuon muutoksen jälkeen auto liikkuu täysin eritavalla radalla muutenkin.

namespace Game {
    std::vector <Cars::OmatAutot> Autot;
    std::vector <Cars::KaikkiOsat> Osat;
    static const float ajan_muutos = 0.02;
    static float nopeus_oma=0;
    static float kiihtyy_oma=0;
}
void Game::Liikuta() {
        Uint8* nappi;
        nappi = SDL_GetKeyState(NULL);
        std::vector<Cars::OmatAutot>::iterator autoo = Autot.begin();
        while(autoo != Game::Autot.end()){
            cout << "Omistaja = " << autoo->omistaja << endl;
            if (autoo->omistaja == 1) {
                kiihtyy_oma = autoo->tehot / 100;
                max_nopeus_oma = autoo->tehot/10;
            } else {

            }
            cout << "kiihtyvyys_oma = " << kiihtyy_oma << endl;
            autoo++;
        }
        if (nappi[SDLK_LEFT]) {
            if (nopeus_oma >= 0.01 && nopeus_oma <= 2) {
                kulma_oma-=0.08;
                auton_kulma_oma+=0.08;
            }
            if (nopeus_oma >= 2 && nopeus_oma <= 4) {
                kulma_oma-=0.06;
                auton_kulma_oma+=0.06;
            }
            if (nopeus_oma >= 4 && nopeus_oma <= 10) {
                kulma_oma-=0.04;
                auton_kulma_oma+=0.04;
            }

        }
        if (nappi[SDLK_RIGHT]) {
            if (nopeus_oma >= 0.01 && nopeus_oma <= 2) {
                kulma_oma+=0.08;
                auton_kulma_oma-=0.08;
            }
            if (nopeus_oma >= 2 && nopeus_oma <= 4) {
                kulma_oma+=0.06;
                auton_kulma_oma-=0.06;
            }
            if (nopeus_oma >= 4 && nopeus_oma <= 10) {
                kulma_oma+=0.04;
                auton_kulma_oma-=0.04;
            }
        }
        if (nappi[SDLK_DOWN]) {
            nopeus_oma-=0.08;
        }
        if (nappi[SDLK_UP]) {
            if (nopeus_oma <= max_nopeus_oma) {
                nopeus_oma+=kiihtyy_oma; //0.05
            }
        } else {
            if (nopeus_oma >= 0.05) {
                nopeus_oma-=0.02;
            }
            else if (nopeus_oma <= 0.05) {
                nopeus_oma=0;
            }
        }
        SDL_FreeSurface(Tekstit::text_19);
        Tekstit::text_19 = Tekstit::LoadText(" ", true, nopeus_oma, Fontit::font2, 255, 0, 0);
        x_oma+=std::cos(kulma_oma) * nopeus_oma;
        y_oma+=std::sin(kulma_oma) * nopeus_oma;
}

siellä on kaksi eri kulman muutos muuttujaa, koska koitin sillä, että x akseli lasketaan sininillä ja y cosinillaja muokkasin niin, että auto muuttaisi suutaansa päinvastoin menosuuntaan ja se toimi osittain.


Ps. Yritin selittää mahdollisimman yksinkertaisesti. Toivottavasti ymmärrätte mitä haen takaa.

Grez [04.01.2011 23:35:50]

#

Missään ei näy muuttujien x_oma ja y_oma tietotyyppiä. Kai nekin on float eikä esim. int? Mielestäni kaksi mainitsemistasi ongelmista (ei liikettä ennen nopeutta 1 ja nopeampi nopeus tikkusuorassa) voisi johtua tuosta.

Sitten kysymyksissä puhut vauhdista ja koodissa on muuttujia joiden nimissä esiintyy nopeus. Tarkoitatko näillä samaa vai eri asiaa?

Sinänsä vauhti on oikea fysikaalinen termi puhuttaessa nopeuden itseisarvosta, eli esim. 50 km/h on nimenomaan vauhti. Sitten kun tiedetään myös suunta, on kyseessä nopeus. Esim. 50km/h pohjoisen suuntaan olisi nopeus. Valitettavaa, että teille laitetuista liikkumisnopeuden rajoituksista puhutaan nopeusrajoituksina, eikä vauhtirajoituksina, joka lienee yksi syy miksi nuo sekoitetaan.

Metabolix [04.01.2011 23:55:40]

#

mika132 kirjoitti:

Pienessä vauhdissa auto menee sivuttain ja suuremmassa eteenpäin kuten pitää.

Mitään tähän liittyvää virhettä ei näy tuossa koodissa. Oletko ihan varma asiasta? Oletko kokeillut, minne auto liikkuu, jos kiihdytät kääntymättä ollenkaan? Ovatko x_oma ja y_oma varmasti liukulukuja?

mika132 kirjoitti:

Lisäksi auto menee lujempaa huomattavasti kun auto on tikkusuorassa.

Kuulostaa siltä, että olet taas tunaroinut siinä ajanmittauksessa, josta on puhuttu ehkä noin 123456 kertaa. Etsi ne vanhat keskustelut (ja tietenkin matopeliopas) ja tarkista vielä kerran, että tuota Liikuta-funktiota kutsutaan yhtä monta kertaa sekunnissa auton asennosta riippumatta.

mika132 kirjoitti:

Auto ei liiku ellen tee erillistä double muuttujaa kiihtyvyydelle vielä liikutus funktioon sisälle.

Tarkista, mitkä ovat liikkeeseen liittyvien muuttujien (x_oma, y_oma, kulma_oma, nopeus_oma, max_nopeus_oma, kiihtyy_oma) arvot tuon funktion lopussa, mitkä niistä toimivat oikein ja mitkä toimivat väärin.

Muuttuja auton_kulma_oma on turha, koska auton_kulma_oma == -kulma_oma.

Funktion nappiosuudet (eli kaiken while-silmukasta SDL_FreeSurfaceen) voisi hoitaa huomattavasti helpomminkin:

double kulman_muutos = 0;
if (nappi[SDLK_RIGHT]) kulman_muutos += 1;
if (nappi[SDLK_LEFT]) kulman_muutos -= 1;

if (nopeus_oma < 0.01) kulman_muutos = 0;
else if (nopeus_oma < 2) kulman_muutos *= 0.08;
else if (nopeus_oma < 4) kulman_muutos *= 0.06;
else if (nopeus_oma < 10) kulman_muutos *= 0.04;
else kulman_muutos = 0;

kulma_oma += kulman_muutos * 0.08;

double nopeuden_muutos = 0;
if (nappi[SDLK_UP]) nopeuden_muutos += kiihtyy_oma;
if (nappi[SDLK_DOWN]) nopeuden_muutos -= 0.08;
if (!nappi[SDLK_UP] && !nappi[SDLK_DOWN]) nopeuden_muutos -= 0.02;

nopeus_oma += nopeuden_muutos;
if (nopeus_oma < 0) nopeus_oma = 0;
if (nopeus_oma > max_nopeus_oma) nopeus_oma = max_nopeus_oma;

mika132 [05.01.2011 10:43:14]

#

Kiitoksia. =)

Tein tässä eilen parisen tunita ja tänään ehtinyt jo parisen tunita väsäämään tekoäly moottoria.

Kehitin moottoria missä ei ollut pisteitä eikä mitään vaan tekoäly tarkisti kuinka pitkällä reunat ovat autosta (totaalisella if sodalla) ja koska käännetään.

Noh ongelma tuli tänään mieleen kun piirtelin tuota toimintaa paperille, että jos tekoäly lähtee 20pikseliä enemmän sivummalta sen ajolinja tulee menemään täysin mönkään ja pahasti.

Kiintopiste ideahan olisi ihan hyvä, mutta kiintopiste ideassa auto tekee sitä kuuluisaa "nykimis" liikettä. eli kääntää keulan yhtäkkiä pisteestä A pisteeseen B, johon en osaa tehdä korjausta.

kaantymis_pisteX = Racer::KuskinAlyX(Racer_ajotaito[0], Racer_hermot[0], Kurvi);
kaantymis_pisteY = Racer::KuskinAlyY(Racer_ajotaito[0], Racer_hermot[0], Kurvi);
x_jana = (Racers_x[0] - kaantymis_pisteX);
y_jana = (Racers_y[0] - kaantymis_pisteY);
auton_kulma_racer[0] = std::atan2((double)y_jana, (double)x_jana);

if (hypot(y_jana, x_jana) <= 40) {
    Kurvi+=1;
    RacersKurvi[0]=true;
    kaantymis_pisteX = Racer::KuskinAlyX(Racer_ajotaito[0], Racer_hermot[0], Kurvi);
    kaantymis_pisteY = Racer::KuskinAlyY(Racer_ajotaito[0], Racer_hermot[0], Kurvi);
    x_jana = (Racers_x[0] - kaantymis_pisteX);
    y_jana = (Racers_y[0] - kaantymis_pisteY);
} else {
    RacersKurvi[0]=false;
}
if (TimeLeftSpeed() == 0) {
    if (RacersUlkonaVaara[0] == true) {
        if (Racers[0] >= 0.8) {
            Racers[0]-=0.20;
        }
    }else if (RacersKurvi[0] == true) {
        if (Racers[0] >= 0.8) {
            Racers[0]-=0.40;
        }
    } else {
        if (Racers[0] >= 2) {
            Racers[0]=2;
        } else {
            Racers[0]+=0.32;
        }
    }
}
Racers_x[0]-=std::cos(auton_kulma_racer[0]) * Racers[0];
Racers_y[0]-=std::sin(auton_kulma_racer[0]) * Racers[0];

Kääntymispiste funktioita en usko, että tarvitsee laittaa, koska ne ovat vain funktioita joista palautetaan tietty arvo.

Vastaus

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

Tietoa sivustosta