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; }
SDL_image.dll puuttuu zipistä
Ja muistetaanpa lopuksi tuhota se kuva, SDL_FreeSurface(ukko);
Jostain olen kuullut, että SDL_FreeSurfacea ei tarvitsisi käyttää, koska SDL_Quit(); tekee sen, mutta laitetaan nyt Metabolixin mieliksi :)
Zippi on korjattu.
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ä! :)
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.
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.
zipistä puuttuu myös sdl.dll
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.
Zippi on korjattu jälleen kerran, tosin pitäishän nyt SDL.dll olla kaikilla :/ (tai sitten ei)
Näkyy pelkkää mustaa, missäköhän vika?
ukko.png ei varmaan löydy, katsoitko stderr ja/tai stdout tiedoston? Käänsitkö ite vai käytitkö käännettyä?
Minullakin näkyy pelkkää mustaa ja käytin valmiiksi käännettyä.
hmm, outoa, sanooto stdout tai stderr mitään?
Ei sano minulla ainankaan.
Err, outoa. Kokeile kääntää ite.
Onko tuo tarkoitettu toimimaan win vai linux alustalla?
win, vaikka kyllä pitäisi toimi suoraan linuxillakin (Ei mitään ihmeellisiä kirjastoja)
Joo mulla oli sama juttu ku Cc:llä eli mustaa näkyy ja käytin valmiiksi käännettyä...
Joo mulla oli sama juttu ku Cc:llä eli mustaa näkyy ja käytin valmiiksi käännettyä..
Taitaapi johtua siitä, kun paketista puuttuu zlib.dll:llä
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
Mulla toi herjaa ku yritän kääntää koodia: painovoima.cpp:112: warning: converting to `int' from `float'?
miten saisin tuon pois?
?
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.. ;)
Aihe on jo aika vanha, joten et voi enää vastata siihen.