Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: C++: Painovoima

Sivun loppuun

ZcMander [07.06.2006 12:03:11]

#

Ajattelinpa tehdä pienen painovoimaesimerkin, koska ei oikein millään kielellä ollut sopivaa koodivinkkiä.

Periaatehan tässä on se, että normaalisti painovoima vetää kuvaa alaspäin tietyn määrän verran, mutta jos kuva on maassa kiinni, se ei vedäkkään, muutenhan se menisi näytön ulkopuolelle.

Kun hypätään, asetetaan tuo maaginen veto negatiivisen puolelle, eli se vetää ylöspäin, jos tätä ei rajoitettaisiin se menisi näytön yli jälleen kerran, sen takia on jokin, melko pieni arvo, joka vähennetään tuosta "vedosta", kunnes se saapuu normaalille, positiiviselle puolelle.

Huomaa, että SDL_Image-kirjastoa ei tarvi, jos IMG_Load-funktion korvaa, esim. SDL_LoadBMP

Exe ja muut tarvittavat tiedostot (ei lähdekoodia) löytyy osoitteesta: http://shell.nullcore.org/~zcmander/muuta/painovoima.zip

EDIT: Lisättiin SDL_FreeSurface(ukko);

#include <cstdlib>
#include <iostream>
#include <SDL.h>
#include <SDL_image.h> //Tätä ei tarvi, jos korvaa IMG_Load jollain toisella

#define NAYTONLEVEYS 1280
#define NAYTONKORKEUS 1024


#define PITKAHYPPYVOIMA -11 //Pitkan hypyn voima
#define LAHTOVOIMA -5 //Normaalin hypyn voima

#define ALASTULOVOIMA 5 //Normaali veto, koska 0 on näytön yläreuna, se on positiivinen
#define LISAYSVOIMA 0.1 //Paljon vähennetaan joka kierroksella, jos ollaan ilmassa

#define KUVA "ukko.png" //Kuvan nimi ja polku josta kuva ladataan


#define MAA NAYTONKORKEUS-150 //Kuva saa olla maksimissaan 150pikseliä korkea

using namespace std;

//Piirtää kuvan näytölle
void PiirraKuva(SDL_Surface *kuva, SDL_Surface *naytto, int x, int y)
{
  SDL_Rect alue;
  alue.x = x;
  alue.y = y;
  SDL_BlitSurface(kuva, NULL, naytto, &alue); //Itse piirtotapahtuma
}

int main ( int argc, char** argv )
{
    float nopeusy = ALASTULOVOIMA; //Ei tarvi pääsilmukassa tehdä tätä

    int paikkax = NAYTONLEVEYS/2; //Keskelle näyttöä
    int paikkay = MAA; //Ollaan valmiiksi maassa kiinni !HUOM! jos muutat tätä, niin aseta maassa = false
    bool maassa = true; //Asetetaan myös, että ollaan maassa kiinni


    //Alustetaan SDL
    if ( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
        cout << "SDL ei voitu alustaa: " <<  SDL_GetError() << endl;
        return 1;
    }

    //Asetetaan näyttötila
    SDL_Surface* screen = SDL_SetVideoMode(NAYTONLEVEYS, NAYTONKORKEUS, 32, SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_FULLSCREEN);

    //Tarkistetaan onnistuiko
    if (!screen) {
        cout << "Ei voitu asettaa näyttötilaa " << NAYTONLEVEYS << "x" << NAYTONKORKEUS << endl;
        return 1;
    }

    //Testikuvan nimi ja sen lataus, jos tästä vaihtaa IMG_Load-funktion johonkin muuhun esim. SDL_LoadBMP, niin SDL_Imagea ei tavi
    SDL_Surface *ukko = IMG_Load(KUVA);

    SDL_Event tapahtuma; //Tätä tarvitaan näppäimistön kuuntelemiseen

    bool pois = false; //Poistutaanko ohjelmasta

    while (!pois)
    {
        SDL_PollEvent(&tapahtuma); //Haetaan tapahtumia
        switch (tapahtuma.type)
        {
            case SDL_QUIT: //Kun painetaan ruksia, joka ei ole mahdollista kokoruututilassa
                pois = true;
                break;

            //Näppäinpainallukset
            case SDL_KEYDOWN:
                switch (tapahtuma.key.keysym.sym) {
                    case SDLK_ESCAPE: //Jos painettiin esciä
                        pois = true;
                        break;

                    case SDLK_UP: //Ylösnuoli
                        if (maassa == true) { //Vain jos ollaan maassa voidaan hypätä
                            nopeusy = LAHTOVOIMA; //Koska 0 kohta on näytön yläreunassa niin pitää vähentää
                            maassa = false; //Ei olla enään maassa kiini
                        }
                        break;

                    case SDLK_LEFT: //Siirrytään 3pixeliä vasemmalle
                        paikkax -= 3;
                        break;

                    case SDLK_RIGHT: //Siirrytään 3pixeliä oikealle
                        paikkax += 3;
                        break;

                    case SDLK_SPACE: //Tehdää "pitkähyppy" (longjump)
                        if (maassa == true) { //Vain maasta voi hypätä
                            nopeusy = PITKAHYPPYVOIMA; //Käytetään pitkänhypyn voimaa
                            maassa = false; //Ei olla enään maassa
                        }
                        break;
                }
                break;
        }//switch (tapahtuma.type)

        //Jos nopeus pystysuunnassa on pienempi kuin pitäisi
        if (nopeusy < ALASTULOVOIMA)
            nopeusy += LISAYSVOIMA; //niin lisätään nopeuteeen tietynverran lisää, että loppuenlopuksi saapaan nopeusy == ALASTULOVOIMA

        if (nopeusy > ALASTULOVOIMA) //jos se satuu menemään yli niin korjataan
            nopeusy = ALASTULOVOIMA;

        if (!maassa) { //Jos ei olla maassa, niin vain silloin lisätään paikkayhyn nopeusy, tämä if ei ole välttämätön, koska seuraavassa iffissä korjataan, jos tätä iffiä ei ole
            paikkay += (int)nopeusy;
        }

        //Ei mennä alle maan, ja jos sattuu menemään, niin korjataan, samalla asetetaan, että ollaan maassa kiinni
        if (paikkay >= MAA) {
            paikkay = MAA; //Korjaus
            maassa = true; //Asetetaan, että ollaan maassa kiinni
        }

        SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 0, 0, 0)); //Tyhjennetään ruuutu, ei tarvi SDL_gfx
        PiirraKuva(ukko, screen, paikkax, paikkay); //Piirretään kuva oikeaan paikkaan
        SDL_Flip(screen);//Päivitetään ruutu

    } //Päälooppi

    SDL_FreeSurface(ukko); //Vapauttaa ukko-kuvan muistista
    SDL_Quit();
    return 0;
}

T.M. [08.06.2006 19:47:10]

#

SDL_image.dll puuttuu zipistä

Metabolix [09.06.2006 00:45:45]

#

Ja muistetaanpa lopuksi tuhota se kuva, SDL_FreeSurface(ukko);

ZcMander [09.06.2006 11:35:48]

#

Jostain olen kuullut, että SDL_FreeSurfacea ei tarvitsisi käyttää, koska SDL_Quit(); tekee sen, mutta laitetaan nyt Metabolixin mieliksi :)

Zippi on korjattu.

tgunner [09.06.2006 14:43:08]

#

Vähän hidas, mutta ihan toimiva ja opettavainen esimerkki painovoimasta. Olisit sentään voinut läpinäkyväistää tuon punaisen taustan ukolta käyttäen SDL_SetColorKey:tä! :)

Meitsi [09.06.2006 16:05:27]

#

lainaus:

Vähän hidas, mutta ihan toimiva ja opettavainen esimerkki painovoimasta. Olisit sentään voinut läpinäkyväistää tuon punaisen taustan ukolta käyttäen SDL_SetColorKey:tä! :)

...tai käyttämällä alpha-blendattua PNG:tä kun kerta tuossa sdl_image kirjastoa käytetään jo muutenkin.

ZcMander [09.06.2006 22:52:49]

#

Tuon kuvan voi vaihtaa, tuo on vain esimerkkikuva, ei ollut edes tarkoitus ottaa taustaa pois, värjäsin vain gimppillä testikuvaksi, joka sitten jäi.

temu92 [10.06.2006 01:33:24]

#

zipistä puuttuu myös sdl.dll

Metabolix [10.06.2006 10:11:22]

#

lainaus:

Jostain olen kuullut, että SDL_FreeSurfacea ei tarvitsisi käyttää, koska SDL_Quit(); tekee sen

Olet kuullut väärin. Tuo on yleinen harhaluulo, mutta jokainen voi halutessaan käydä toteamassa SDL:n lähdekoodista, että noin ei ole. Voisi tehdä hyvää useimmille käyttää täyttä DEBUG-käännöstä SDL:stä, niin se lopussa kertoisi vapauttamatta jääneiden pintojen määrän.

ZcMander [10.06.2006 12:03:21]

#

Zippi on korjattu jälleen kerran, tosin pitäishän nyt SDL.dll olla kaikilla :/ (tai sitten ei)

T.M. [10.06.2006 17:02:33]

#

Näkyy pelkkää mustaa, missäköhän vika?

ZcMander [10.06.2006 17:05:20]

#

ukko.png ei varmaan löydy, katsoitko stderr ja/tai stdout tiedoston? Käänsitkö ite vai käytitkö käännettyä?

Cc [11.06.2006 13:13:32]

#

Minullakin näkyy pelkkää mustaa ja käytin valmiiksi käännettyä.

ZcMander [11.06.2006 13:15:37]

#

hmm, outoa, sanooto stdout tai stderr mitään?

Cc [11.06.2006 13:26:09]

#

Ei sano minulla ainankaan.

ZcMander [11.06.2006 19:42:24]

#

Err, outoa. Kokeile kääntää ite.

Cc [11.06.2006 22:37:31]

#

Onko tuo tarkoitettu toimimaan win vai linux alustalla?

ZcMander [13.06.2006 10:13:16]

#

win, vaikka kyllä pitäisi toimi suoraan linuxillakin (Ei mitään ihmeellisiä kirjastoja)

tesmu [13.06.2006 15:45:28]

#

Joo mulla oli sama juttu ku Cc:llä eli mustaa näkyy ja käytin valmiiksi käännettyä...

tkok [04.07.2006 13:19:15]

#

Joo mulla oli sama juttu ku Cc:llä eli mustaa näkyy ja käytin valmiiksi käännettyä..

ZcMander [27.08.2006 13:20:23]

#

Taitaapi johtua siitä, kun paketista puuttuu zlib.dll:llä

pienipoika [22.05.2008 14:26:42]

#

hoho. onpa aina aikamoista säätöä noitten dll tiedostojen kanssa :P käyttäsitte linuxia ja hyvää pakettihallintaa joka hoitaa ite riippuvuudet. apt on ihku <3

vehkis91 [16.06.2008 14:33:49]

#

Mulla toi herjaa ku yritän kääntää koodia: painovoima.cpp:112: warning: converting to `int' from `float'?

miten saisin tuon pois?

vehkis91 [20.06.2008 15:22:31]

#

?

Pampi [22.10.2008 02:44:23]

#

Juu, ei käänny mullakaan Dev-C++. Herjaa myös tuota "warning: converting to `int' from `float'?" ja muutenkin joutui korjaamaan itse tuota koodia jonkin verran.. ;)


Sivun alkuun

Vastaus

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

Tietoa sivustosta