Eli kun tuossa minu pelissäni viholliset menevät punaisen alarunan yli niin se jää valkoiseksi eikä palaa punaiseksi. Ja myöskin alkukuvassa olemva musta teksti jää näkyviin peli taustaan.
http://www.freewebs.com/lahha/Peli.zip n. 165kt
source viel täs. Olen yrittäny komentoidda ja kirjoittaa selkeeä koodia, mutta toi komeentoiminen ei ainakana vielä ole oikein iskostunut selkärankaan.
/*******************************************************\
| |
| The Katiska Game v1.0 |
| |
| (c)Mika Katajamäki |
| |
| 20.8.06 -- 16:15 |
\*******************************************************/
#include <SDL/SDL.h> // sisällytetään SDL:n otsikkotiedostot
#include <stdlib.h>
#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
class Ammus
{
public:
int x;
int y;
};
class Vihollinen
{
public:
int x;
int y;
};
void PiirraKuva(SDL_Surface *kuva, SDL_Surface *naytto, int x, int y); // aliohjelma, joka piirtää kuvan
void PiirraAmmukset(SDL_Surface *kuva, SDL_Surface *naytto, Ammus Ammukset[80]); // piirtää ammukset
void PiirräVihut(SDL_Surface *kuva, SDL_Surface *naytto, Vihollinen Viholliset[80]); // piirtää vihut
void LaskeAmmustenSijainti(Ammus Ammukset[80]); // laskee ammusten liikkeen ja sijainnin
void LaskeVihujenSijainti(Vihollinen Viholliset[80]); // laskee avihujen liikkeen ja sijainnin
int ArvoVihuja(int kohta, Vihollinen Viholliset[80]);
int TarkistaOsumat(Ammus Ammukset[80], Vihollinen Viholliset[80], int score);
void AlustaAmmukset(Ammus Ammukset[80]);
void AlustaVihut(Vihollinen Viholliset[80]);
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)
//{
// fprintf(stderr, "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
*********************************************/
Ammus Ammukset[80]; // oliot ammuksille
int AmmuksenNumero=0; // apuluku ammuksien piirtämiseen
Vihollinen Viholliset[80]; // oliot vihuille
int VihollisenNumero=0; // apuluku vihollisten piirtämiseen
int ToinenApuLuku=0;
SDL_Surface * naytto; // näkyvä pinta
SDL_Surface * kuva; // pinta laatikolle
SDL_Surface * tausta; // pinta taustalle
SDL_Surface * ammus; // pinta ammukselle
SDL_Surface * vihu;
// 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\\alku.bmp");
ammus = SDL_LoadBMP("Art\\ammus.bmp");
vihu = SDL_LoadBMP("Art\\e1.bmp");
// aluksen kordinaatit
int lootax=400;
int lootay=600;
Uint8* nappi; // näppäimet
SDL_Event tapahtuma; // tapahtumat
int hiiri,x,y; // hiiren tila
int score=0; // Pisteet
bool pois=false;
/*********************************************
* Alkutekstit
*********************************************/
PiirraKuva(tausta, naytto, 0, 0);
SDL_Flip(naytto);
SDL_Delay(3500);
tausta = SDL_LoadBMP("Art\\tausta.bmp");
AlustaAmmukset(Ammukset);
AlustaVihut(Viholliset);
/*********************************************
* 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 -= 4; }
if ( nappi[SDLK_DOWN] ) { lootay += 4; }
if ( nappi[SDLK_LEFT] ) { lootax -= 4; }
if ( nappi[SDLK_RIGHT] ) { lootax += 4; }
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] ) // ampuminen. valitaan ammus ja asetetaan sen kordinaatit
{
Ammukset[AmmuksenNumero].y = lootay;
Ammukset[AmmuksenNumero].x = lootax;
Ammukset[AmmuksenNumero].y -= 28;
AmmuksenNumero++;
if( AmmuksenNumero == 80 ) { AmmuksenNumero = 0; }
SDL_Delay(10);
}
if (ToinenApuLuku == 40)
{
VihollisenNumero=ArvoVihuja(VihollisenNumero, Viholliset);
ToinenApuLuku = 0;
}
LaskeAmmustenSijainti(Ammukset);
LaskeVihujenSijainti(Viholliset);
score = TarkistaOsumat(Ammukset, Viholliset, score);
//Kentän rajat
if (lootax < 5) { lootax += 3; }
if (lootax > 1000) { lootax -= 3; }
if (lootay < 5) { lootay += 3; }
if (lootay > 690) { lootay -= 3; }
hiiri=SDL_GetMouseState(&x,&y); // luetaan nappien tila
if(hiiri & SDL_BUTTON(1)) // ykkösnappi pohjassa
pois=true;
//Piiretään kaikki kuvat
PiirraKuva(tausta, naytto, 0, 0); // piirretään tausta
PiirraKuva(kuva, naytto, lootax, lootay); // piirretään alus
PiirräVihut(vihu, naytto, Viholliset); // piirretään vihut
PiirraAmmukset(ammus, naytto, Ammukset); // piirretään ammukset
// nyt kuva on piirretty, mutta koska käytämme kaksoispuskurointia, kuva ei näy vielä
// siksi tarvitsemme SDL_Flip()-funktiota
SDL_Flip(naytto);
ToinenApuLuku++;
}
fprintf(stdout, "Pisteitä: %d\n", score); //Tallennetaan pisteet stdout teidostoon
score /= 5000;
fprintf(stdout, "Tappoja: %d", score); //Tallennetaan pisteet stdout teidostoon
SDL_FreeSurface(kuva);
SDL_FreeSurface(tausta);
SDL_FreeSurface(ammus);
SDL_Quit(); // "suljetaan" SDL
return 0;
}
/**********************************
* Aliohjelmat bittikarttojen piirtämiseen
* Parametreina osoitin kuvan pintaan (lähteeseen), osoitin näyttöpintaan (kohteeseen) sekä koordinaatit,
* siihen kohtaan mihin kohtaan kohdepintaa kuva piirretään
**********************************/
void PiirraKuva(SDL_Surface *kuva, SDL_Surface *naytto, int x, int y)
{
SDL_SetColorKey(kuva, SDL_SRCCOLORKEY, SDL_MapRGB(kuva->format,0,0,0));//Läpinäkyvyys
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 PiirraAmmukset(SDL_Surface *kuva, SDL_Surface *naytto, Ammus Ammukset[80])
{
int AmmuksenNumero=0; // apuluku ammuksien piirtämiseen
SDL_Rect alue;
SDL_SetColorKey(kuva, SDL_SRCCOLORKEY, SDL_MapRGB(kuva->format,0,0,0));//Läpinäkyvyys
if ( kuva == NULL )
{
fprintf(stderr, "Ammuksen piirto ei onnistunu: %s\n", SDL_GetError());
return;
}
while (AmmuksenNumero < 80)
{
// mihin näytöllä
alue.x = Ammukset[AmmuksenNumero].x;
alue.y = Ammukset[AmmuksenNumero].y;
// näytölle
SDL_BlitSurface(kuva, NULL, naytto, &alue); // koska toinen parametri on NULL, piirretään koko kuva
AmmuksenNumero++;
}
}
void PiirräVihut(SDL_Surface *kuva, SDL_Surface *naytto, Vihollinen Viholliset[80])
{
int VihuNumero=0; // apuluku vihujen piirtämiseen
SDL_Rect alue;
SDL_SetColorKey(kuva, SDL_SRCCOLORKEY, SDL_MapRGB(kuva->format,0,0,0));//Läpinäkyvyys
if ( kuva == NULL )
{
fprintf(stderr, "Vihollisen piirto ei onnistunu: %s\n", SDL_GetError());
return;
}
while (VihuNumero < 80)
{
// mihin näytöllä
alue.x = Viholliset[VihuNumero].x;
alue.y = Viholliset[VihuNumero].y;
// näytölle
SDL_BlitSurface(kuva, NULL, naytto, &alue); // koska toinen parametri on NULL, piirretään koko kuva
VihuNumero++;
}
}
/*********************************
* Funktiot jotka laskee ammusten ja vihujen sijainteja
*********************************/
void LaskeAmmustenSijainti(Ammus Ammukset[80])
{
int ApuLuku=0;
while (ApuLuku < 80)
{
if( Ammukset[ApuLuku].y >= -50 ){ Ammukset[ApuLuku].y -= 8; }
ApuLuku++;
}
}
void LaskeVihujenSijainti(Vihollinen Viholliset[80])
{
int VihuNumero=0; // apuluku vihujen piirtämiseen
int Luku=0;
while (VihuNumero < 80)
{
Luku = 1 + (rand()%10);
Viholliset[VihuNumero].y += 2;
// Sit vähän sivuttais liikettä
if ( Luku == 1 ) { Viholliset[VihuNumero].x += 2; }
if ( Luku == 2 ) { Viholliset[VihuNumero].x += 2; }
if ( Luku == 3 ) { Viholliset[VihuNumero].x -= 2; }
if ( Luku == 4 ) { Viholliset[VihuNumero].x -= 2; }
if ( Luku == 5 ) { Viholliset[VihuNumero].x += 4; }
if ( Luku == 6 ) { Viholliset[VihuNumero].x += 4; }
if ( Luku == 7 ) { Viholliset[VihuNumero].x -= 4; }
if ( Luku == 8 ) { Viholliset[VihuNumero].x -= 4; }
VihuNumero++;
}
}
//Sit viel joku joka arpoo uudet vihut.
//sen jälkeen se mikä kattoo osumat
// ehkä jotain muut kivaa
// nii ja sit vihut ja ammukset opitää alusta niin
//et ne ei näy alus ruudulla
int ArvoVihuja(int kohta, Vihollinen Viholliset[80])
{
//int loppu = kohta + 3;
//while (kohta !=loppu) { kohta++; }
Viholliset[kohta].x = 200;
Viholliset[kohta].y = -45;
kohta++;
if(kohta == 80) { kohta = 0; }
Viholliset[kohta].x = 500;
Viholliset[kohta].y = -45;
kohta++;
if(kohta == 80) { kohta = 0; }
Viholliset[kohta].x = 700;
Viholliset[kohta].y = -45;
kohta++;
if(kohta == 80) { kohta = 0; }
return kohta;
}
int TarkistaOsumat(Ammus Ammukset[80], Vihollinen Viholliset[80], int score)
{
int Luku1=0;
int Luku2=0;
int VX;
int VX2;
int VY;
int VY2;
while (Luku2 < 80)
{
while (Luku1 < 80)
{
VY = Viholliset[Luku1].y + 30;
VY2 = Viholliset[Luku1].y + 10;
VX = Viholliset[Luku1].x + 10;
VX2 = Viholliset[Luku1].x + 30;
if (Ammukset[Luku2].x > VX && Ammukset[Luku2].x < VX2 && Ammukset[Luku2].y < VY && Ammukset[Luku2].y > VY2 )
{
Viholliset[Luku1].x = - 2000;
Ammukset[Luku2].x = -4000;
score += 5000;
}
Luku1++;
}
Luku1=0;
Luku2++;
}
return score;
}
void AlustaAmmukset(Ammus Ammukset[80])
{
int ApuLuku=0;
while (ApuLuku < 80)
{
Ammukset[ApuLuku].y = -4000;
ApuLuku++;
}
}
void AlustaVihut(Vihollinen Viholliset[80])
{
int VihuNumero=0;
while (VihuNumero < 80)
{
Viholliset[VihuNumero].y = -2000;
VihuNumero++;
}
}Koodi on selkeää, siitä plussaa! Itse asiassa noin pitkästä koodista ei saisi mitään selvää, jossei se olisi selkeää...
Mutta asiaan: en saa peliä jostain syystä ladatuksi, mutta oletan vian olevan siinä, ettet "päivitä" ruutua kertaakaan. Päivittämisellä tarkoitan lähinnä vanhan moskan pyyhkimistä ennen seuraavien piirtoa. Tämä tapahtuu käytännössä SDL_FillRect()-funktiolla. Tämä funktio tyhjentää halutun pinnan halutulla värillä, yleensä mustalla. Siispä näyttö tulisi päivittää esimerkiksi näin:
SDL_Flip( screenSurface ); SDL_FillRect( screenSurface, &screenSurface->clip_rect, SDL_MapRGB(screenSurface->format, 0, 0, 0));
Lisäksi uskoisin, että haluat päivittää taustalla olevan kuvan. Tämän vuoksi sinun täytyy piirtää taustakuva (tausta.bmp) joka loopinkierto uudestaan ennen muiden kuvien piirtoa (siis juuri while(pois==false) -kohdan jälkeen).
Ongelmasi johtuu siitä, että taustakuvasta asetetaan PiirraKuva-funktiossa musta läpinäkyväksi, eli mustat kohdat jätetään piirtämättä, eikä ruutua tyhjennetä missään kohtaa.
Tämä on korjattu helposti esim. Tyhjentämällä ruutu aina ennen sen piirtoa, eli lisäämällä kutsu SDL_FillRect(naytto, 0, 0); ennen pääsilmukan kuvienpiirtoa.
Toinen tapa on, ettet käytä PiirraKuva-funktiotasi tässä kohtaa, vaan korvaat pääsilmukan kutsun PiirraKuva(tausta, naytto, 0, 0); vaikka suoralla kutsulla SDL:lle, eli SDL_BlitSurface(tausta, 0, naytto, 0);
No olipas tyhmä moka.
Jos joku voisi viel vähän heittää idean alkua että miten tuota ampumista voisi rajoittaa että se ei vedä kokoajan tuollaista kauheen sarjaa.
Suosittelen ottamaan tuon SDL_Delayn pois tuolta ammuksen ampumisesta, ja laittamaan sen ruudun päivittämisen jälkeen.
Mutta tuosta ammuksen rajoittamisesta.
No, laitanpa suoraan vain koodia :)
Uint32 aika; //aika jolloin ammuttiin viimeksi
if ( nappi[SDLK_SPACE] ) // ampuminen. valitaan ammus ja asetetaan sen kordinaatit
{
if ( SDL_GetTicks() - aika < 1000) //tarkistetaan aika, 1000 on ammusten välillä tarvittava aika millisekunteina, eli ammuksia voisi nyt ampua kerran sekunnissa
{
aika = SDL_GetTicks();
Ammukset[AmmuksenNumero].y = lootay;
Ammukset[AmmuksenNumero].x = lootax;
Ammukset[AmmuksenNumero].y -= 28;
AmmuksenNumero++;
if( AmmuksenNumero == 80 )
{ AmmuksenNumero = 0; }
}
}Toi ei ihan toiminu mut keksin vian itte
Tossa on virhe
if ( SDL_GetTicks() - aika < 1000)
Toi < pitäs olla >
Mut Kiitti avust.
EDIT. yks pikku juttu viel ois. Mite .exeen saa oman kuvakkeen?
Oho, juu, kirjoistusvirhe sattunut :)
Mazzimo kirjoitti:
Mutta asiaan: en saa peliä jostain syystä ladatuksi.
Joo ittekkin huomasin ettei se lataa sitä kun klikkaa vaan pitää ottaa Tallenna kohde nimellä...
Aihe on jo aika vanha, joten et voi enää vastata siihen.