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.