Teen tässä pientä harjottelu projektia, mut ny ois kaks pientä onglemaa.
Ongelmat:
1- Kun ampuu peli jää jökkiin. Tiedän miksi sillä aikaa kun ammus on näytöllä ei voi tehä mitään mutta se jää senki jälken jökkii.
2- Nyt kun lisäsin ääniä niin kun yrittää käynnistää pelin se valittaa :"Proseduurin aloitus kohtaa SDL_Error ei löydy dynaamisesti linkitettävästä kirjastosta SDL.dll"
Nappulat
Nuolista -Liikkuu
1,2 ja 3 -Vaihtaa alusta
Välilyönti -Ampuu
ESC -Lopettaa
Tolla ois viimesin toimiva versio.(Ei ääniä eikä ampumista)
http://www.freewebs.com/lahha/Peli.sfx.exe
#include <SDL/SDL.h> // sisällytetään SDL:n otsikkotiedostot #pragma comment(lib, "SDLmain.lib") // otetaan SDL:n LIB-tiedostot mukaan. Kun nämä rivit ovat ohjelman alussa, #pragma comment(lib, "SDL.lib") // sinun ei tarvitse lisätä LIB-tiedostoja "käsin" #pragma comment(lib, "SDL_mixer.lib") // #pragma-rivit toimivat VAIN Visual c++:alla! gcc:llä parametri -lSDL ajaa saman asian void PiirraKuva(SDL_Surface *kuva, SDL_Surface *naytto, int x, int y); // aliohjelma, joka piirtää kuvan void PiirraAmmus(SDL_Surface *tausta, SDL_Surface *kuva, SDL_Surface *ammus, SDL_Surface *naytto, int x, int y); // Piirtää ammuksen int main(int argc, char *argv[]) { /******************************************** * alustetaan SDL:n video-ominaisuudet. ********************************************/ if( SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO) < 0 ) // jos paluuarvo on pienempi kuin 0, tapahtui virhe { fprintf(stderr, "SDL:n alustus ei onnistunut: %s\n", SDL_GetError()); //virheestä tiedot tiedostoon SDL_Quit(); return 0; // lopetetaan ohjelma } // open 44.1KHz, signed 16bit, system byte order, // stereo audio, using 1024 byte chunks if(Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 1024) < 0) { printf("Mix_OpenAudio: %s\n", Mix_GetError()); return 0; } // vaihdetaan ikkunan nimi (näkyy tehtäväpalkissa) SDL_WM_SetCaption("KatiskaGame", NULL); // SDL on nyt alustettu virheettömästi. /********************************************* * muut valmistelut *********************************************/ SDL_Surface * naytto = new SDL_Surface; // näkyvä pinta SDL_Surface * kuva = new SDL_Surface; // pinta laatikolle SDL_Surface * tausta = new SDL_Surface; // pinta taustalle SDL_Surface * ammus = new SDL_Surface; // pinta ammukselle Mix_Chunk *aani; // vaihdetaan resoluutio naytto = SDL_SetVideoMode(1024, 768, 32, SDL_HWSURFACE|SDL_FULLSCREEN|SDL_DOUBLEBUF); // ladataan bittikartat kuva = SDL_LoadBMP("Art\\1.bmp"); tausta = SDL_LoadBMP("Art\\tausta.bmp"); ammus = SDL_LoadBMP("Art\\ammus.bmp"); int lootax=400; int lootay=600; // laatikon koordinaatit Uint8* nappi; // näppäimet SDL_Event tapahtuma; // tapahtumat int hiiri,x,y; // hiiren tila bool pois=false; aani=Mix_LoadWAV_RW(SDL_RWFromFile("Sound\\M1.ogg", "rb"), 0); // olemme jo ladanneet äänitiedoston if(Mix_PlayChannel(0, aani, -1)==-1) {fprintf(stderr, "Virhe : %s ", Mix_GetError());} // virhe /********************************************* * pääsilmukka *********************************************/ while(pois==false) { // poistutaanko SDL_PollEvent(&tapahtuma); if ( tapahtuma.type == SDL_QUIT ) { pois = true; } //poistumistapahtuma if ( tapahtuma.type == SDL_KEYDOWN ) { if ( tapahtuma.key.keysym.sym == SDLK_ESCAPE ) { pois = true; } // näinkin voi lukea näppäimiä } // liikutetaan laatikkoa nappi = SDL_GetKeyState(NULL); if ( nappi[SDLK_UP] ) { lootay -= 1; } if ( nappi[SDLK_DOWN] ) { lootay += 1; } if ( nappi[SDLK_LEFT] ) { lootax -= 1; } if ( nappi[SDLK_RIGHT] ) { lootax += 1; } if ( nappi[SDLK_1] ) { kuva = SDL_LoadBMP("Art\\1.bmp"); } if ( nappi[SDLK_2] ) { kuva = SDL_LoadBMP("Art\\2.bmp"); } if ( nappi[SDLK_3] ) { kuva = SDL_LoadBMP("Art\\3.bmp"); } if ( nappi[SDLK_SPACE] ) { PiirraAmmus(tausta, kuva, ammus, naytto, lootax, lootay); } hiiri=SDL_GetMouseState(&x,&y); // luetaan nappien tila if(hiiri & SDL_BUTTON(1)) // ykkösnappi pohjassa pois=true; SDL_SetColorKey(kuva, SDL_SRCCOLORKEY, SDL_MapRGB(kuva->format,0,0,0));//Läpinäkyvyys PiirraKuva(tausta, naytto, 0, 0); // piirretään tausta PiirraKuva(kuva, naytto, lootax,lootay); // piirretään alus // nyt kuva on piirretty, mutta koska käytämme kaksoispuskurointia, kuva ei näy vielä // siksi tarvitsemme SDL_Flip()-funktiota SDL_Flip(naytto); } delete tausta; // vapautetaan muisti tausta = 0; // varmuuden vuoksi delete kuva; // vapautetaan muisti kuva = 0; // varmuuden vuoksi delete ammus; // vapautetaan muisti ammus = 0; // varmuuden vuoksi delete tausta; // vapautetaan muisti naytto = 0; // varmuuden vuoksi Mix_FreeChunk(aani); aani = NULL; //varmuuden vuoksi SDL_Quit(); // "suljetaan" SDL return 0; } /********************************** * Aliohjelma bittikartan piirtämiseen * Parametreina osoitin kuvan pintaan (lähteeseen), osoitin näyttöpintaan (kohteeseen) sekä koordinaatit, mihin * kohtaan kohdepintaa kuva piirretään **********************************/ void PiirraKuva(SDL_Surface *kuva, SDL_Surface *naytto, int x, int y) { if ( kuva == NULL ) { fprintf(stderr, "Kuvannäyttö ei onnistunu: %s\n", SDL_GetError()); return; } // mihin näytöllä SDL_Rect alue; alue.x = x; alue.y = y; // näytölle SDL_BlitSurface(kuva, NULL, naytto, &alue); // koska toinen parametri on NULL, piirretään koko kuva } void PiirraAmmus(SDL_Surface *tausta, SDL_Surface *kuva, SDL_Surface *ammus, SDL_Surface *naytto, int x, int y) { SDL_Rect alue; int yy=y; if ( ammus == NULL ) { fprintf(stderr, "Kuvannäyttö ei onnistunu: %s\n", SDL_GetError()); return; } y -=20; while(y != 0) { y -= 4; alue.x = x; alue.y = y; // näytölle PiirraKuva(tausta, naytto, 0, 0); // piirretään tausta PiirraKuva(kuva, naytto, x,yy); // piirretään alus SDL_BlitSurface(ammus, NULL, naytto, &alue); SDL_Flip(naytto); SDL_Delay(5); } }
1. Ongelmasi on tuo PiirraAmmus, se nimittäin pyörii tietyn ajan ja blokkii muun pelin siksi aikaa.
Ammuksen piirtämistä ei kannatat ehdä tuolla tavalla. Parempi tapa on pitää jossain muistissa näytöllä olevat ammukset, ja sitten joka kerta kun pääsilmukka suoritetaan niin ammuksia liikutetaan ja ne piirretään uudestaan (ja samalla voidaan tarkistaa törmääkö ammus seinään/toiseen pelaajaan jne).
2. Ääniä varten sinun tulee ainakin sisällyttää SDL_Mixerin otsikkotiedostot: #include <SDL/SDL_mixer.h>. Ilman sitä koodi ei varmaankaan käänny?
Lopuksi vielä eräs juttu koodistasi:
SDL_Surface * naytto = new SDL_Surface; // näkyvä pinta SDL_Surface * kuva = new SDL_Surface; // pinta laatikolle SDL_Surface * tausta = new SDL_Surface; // pinta taustalle SDL_Surface * ammus = new SDL_Surface; // pinta ammukselle // vaihdetaan resoluutio naytto = SDL_SetVideoMode(1024, 768, 32, SDL_HWSURFACE|SDL_FULLSCREEN|SDL_DOUBLEBUF); // ladataan bittikartat kuva = SDL_LoadBMP("Art\\1.bmp"); tausta = SDL_LoadBMP("Art\\tausta.bmp"); ammus = SDL_LoadBMP("Art\\ammus.bmp");
Vaikka kuinka hienosti muistat vapauttaa new:llä varaamaasi muistia lopussa, niin tuossa kohtaa ohjelma vuotaa muistia. Aluksi varaat SDL_Surfacelle muistia new:llä, mutta SDL_SetVideoMode ja SDL_LoadBMP hoitavat itse muistin varaamisen ja palauttavat osoittimen jo varattuun muistiin. Niinpä aluksi new:llä varaamasi muisti jää varatuksi, mutta mikään osoitin ei osoita siihen.
Ongelmasi varmaankin on se, että PiirraAmmus-funktion y ei ikinä päädy nollaksi, jos se ei aluksi satu olemaan jaollinen neljällä. Laitapa siis silmukka pyörimään niin kauan, kuin y on suurempi kuin nolla.
Toiseen kysymykseen suosittelisin uudemman SDL.DLL:n hankkimista.
Heikin sanoihin muistinkäsittelystä lisäisin, että SDL:n funktioiden palauttamat pinnat pitää vapauttaa SDL_FreeSurface-funktiolla. Ainoa poikkeus on näyttöpinta, jonka SDL vapauttaa itse.
SDL_Surface *ruutu; SDL_Surface *kuva; ruutu = SDL_SetVideoMode(640, 480, 32, 0); kuva = SDL_LoadBMP("kuva.bmp"); SDL_FreeSurface(kuva); // Kuvat pitää aina vapauttaa.
Kiitti nyt toimii muuten paitsi että ääniä ei kuulu ja tulee tää "Virhe : Tried to play a NULL chunk"
Eli toisin sanoen äänen lataaminen ei ole onnistunut. Uskaltaisin väittää, että Mix_LoadWav_RW-funktio ei osaa ladata kuin WAV-formaattia, kuten nimestäkin voi päätellä. Sitä paitsi tuossakin on taas muistivuodon paikka. Avaa ensin tiedosto, sitten käytä sitä ja lopuksi sulje se!
SDL_RWops * tiedosto = SDL_RWFromFile("joku.wav", "rb"); if (!tiedosto) {perror("Tiedosto ei auennut!\n"); exit(1);} Mix_Chunk * aani = Mix_LoadWav_RW(tiedosto, 0); if (!aani) {perror("Lataus ei onnistunut!\n"); exit(1);} SDL_RWClose(tiedosto); Mix_FreeChunk(aani);
En saanu noita toimii. En edes .wav tiedostolla. Jos joku viittis nii vois laittaa sen tohon mun ohjelmaan ja sit jos joku vois tehä ees esimerkin miten toi ammuksen piirtäminen kannattais tehä.
Ohjelma voi laata tolta. Tän hetkisessä koodis ei oo mitää merkintöjä äänestä, mut sisältää ääni tiedostot. paketti sisältää koodin.
Aihe on jo aika vanha, joten et voi enää vastata siihen.