Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: SDL: Ongelman punaisen kanssa

Sivun loppuun

Lahha [20.08.2006 19:28:28]

#

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++;
	}

}

Mazzimo [21.08.2006 18:54:57]

#

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).

Sisuaski [21.08.2006 18:58:13]

#

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);

Lahha [21.08.2006 19:48:45]

#

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.

Megant [21.08.2006 21:19:49]

#

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; }
    }
}

Lahha [21.08.2006 21:59:21]

#

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?

Megant [21.08.2006 22:44:40]

#

Oho, juu, kirjoistusvirhe sattunut :)

Lahha [22.08.2006 09:25:53]

#

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ä...


Sivun alkuun

Vastaus

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

Tietoa sivustosta