Vanhaan topicikiin ei vastattu ja se painui hieman alas, joten päätin kysäistä uudestaan. Olen testannut jo kaksi päivää tätä miten sen saisi korjattua, mutta ei niin ei.
Kun kuulin, että goto on huono koodaus vaihtoehto muutin sitä, mutta tuhoisin seurauksin. :O
Pistin "valinta" muuttujan. Eli tarkistetaan jos valinta muuttuja on jotain tiettyä niin mennään pisteeseen jotain.
Ongelma:
Painan oikeaan kohtaa ykkösnapilla. Mitään ei tapahdu. Painan kolmoshiiren nappia ihan missä vain (sulkee pelin) niin katsoppas kuva välähtää taustalla joka piti tulla jo aikaisemmin. Pistin SDL_delayn(5000); ja kyllä haluaman ikuva tulee siihen. Okei yritys kaksi: En painanut lainkaan taloa, mutta painoin suoraan kolmosta. Peli sammui ilman viivettä. Ja kolmas yritys painoin kuvaa ykköshiirellä ja sitten painoin kolmosta niin kuva tuli taas viideksi sekuntiksi. Miksei se tule aikaisemmin?
if valinta jälkeinen tapahtuma on alapuolella ja niiden alla nuo nappula sörsselit. =)
if (valinta==1) { SDL_FreeSurface(kuva); SDL_FreeSurface(talo_1); SDL_FreeSurface(talo_2); SDL_Surface *Tausta; Tausta=SDL_LoadBMP("grafiikat/tausta.bmp"); PiirraKuvaTausta(Tausta, naytto); TTF_Init(); SDL_Surface *teksti; SDL_Surface *teksti2; TTF_Font *font = NULL; SDL_Color textcolor = {255, 0, 0}; font = TTF_OpenFont("courbd.ttf", 20); int c=50; char mjono[10]; sprintf(mjono, "%i", c); teksti = TTF_RenderText_Blended(font, mjono, textcolor); teksti2 = TTF_RenderText_Blended(font, "Rahaa: ", textcolor); SDL_Rect alue_tekstille; alue_tekstille.x = 200; alue_tekstille.y = 200; SDL_Rect alue_tekstille2; alue_tekstille2.x = 120; alue_tekstille2.y = 200; SDL_BlitSurface(teksti, NULL, naytto, &alue_tekstille); SDL_BlitSurface(teksti2, NULL, naytto, &alue_tekstille2); SDL_Flip(naytto); SDL_Delay(5000); }
void TarkastaOnkoPisteSuorakulmiossa(int hiiren_x, int hiiren_y, int taloKuvanX, int taloKuvanY, int taloKuvanLeveys, int taloKuvanKorkeus) { int talon_viimeinen_X = taloKuvanX + taloKuvanLeveys; int talon_viimeinen_y = taloKuvanY + taloKuvanKorkeus; if ((hiiren_x >= taloKuvanX) && (hiiren_x <= talon_viimeinen_X)) { if ((hiiren_y >= taloKuvanY) && (hiiren_y <= talon_viimeinen_y)) { valinta = 1; } } } hiiri=SDL_GetMouseState(&hiiren_x,&hiiren_y); if (SDL_GetMouseState(&hiiren_x, &hiiren_y) & SDL_BUTTON(1)) { TarkastaOnkoPisteSuorakulmiossa(hiiren_x, hiiren_y, taloKuvanX, taloKuvanY, taloKuvanLeveys, taloKuvanKorkeus); } if(hiiri & SDL_BUTTON(3)) pois=true; //koodia muutama rivi ja sitten SDL_Flip(naytto);
Voisitko laittaa sitä koodia vähän enemmän näkyville?
Kuvat pitäisi ladata ohjelman alussa ja vapauttaa lopussa, ellei ole jotain hyvää syytä vapautella kuvia kesken kaiken.
TTF_Init(); kannattaisi myös kutsua tuota funktiota ohjelman alussa.
Ja luulen, että flippaat tuossa taustakuvan sen sun kuvas päälle, joten siksi et ehdi nähdä sitä kuvaasi, ku vain sen 5sec.
Sori ku tuli taas vaihteeks vähän epäselvää tekstiä, mutt toivottavasti ymmärsit jotain.
Edit: eli piirtojärestyksen pitäisi olla:
1.piirrä tausta 2.piirrä muut kamat 3.ja sitten lopuksi flipataan.
en nää sun pääsilmukkaasi mutt luulen ett on jotenki näin
1.jos painettu nappia, niin piirrä kuva flipataan tässä väliss. 2.jos painettu toista nappia, niin lopeta 3.piirrä tausta 4.flippaa näytölle.
eli jos on jotenkin noin, niin vaihda se taustan piirto tonne ensimmäiseksi, sitten poista se flippaus tolta funtiosta, koska sitä ei tarvitse tehdä kuin pääsilmukan lopussa.
JEE taas epäselvää tekstiä.
Juu ymmärsin jotenkin. Mites tälläinen:
string team_name = "Hehe"; char name[10]; sprintf(name, "%s", team_name);
Eli mitä laitan tuohon sprintf keskelle? %s tulee vain (null) teksti ja %i tulee nolla koitin myös %c mutta tuli pelkkää tyhjää. Mikä on oikea?
En C++:aa erityisemmin osaa, mutta sprintf on C-kirjaston funktio eikä siten ymmärrä string-olioita. Muotoilujono "%s" vaatii osoittimen char-taulukkoon, ja string-oliolta sellaisen saa googlen mukaan c_str()-metodilla. Eli:
string team_name = "Hehe"; char name[10]; sprintf(name, "%s", team_name.c_str());
Juu noin se pitäisi toimia kuten hunajavohveli sanoi, mutta tarvitseeko sen olla välttämättä char[] -tyyppiä? Jos ei niin tälläinen hoitaisi homman vähän simppelimmin:
string team_name = "Hehe"; string name (team_name);
Kiitos. =)
teksti = TTF_RenderText_Blended(font, "Huomenna tulee \n uusi lehmä", textcolor);
Miksi tuo tyypillinen \n rivinvaihto ei toimi tuossa? :O
Koska SDL_ttf ei tue rivinvaihtoja tekstissä.
Eli sun pitää tehdä näin:
rivi1 = TTF_RenderText_Blended(font, "Huomenna tulee", textcolor); rivi2 = TTF_RenderText_Blended(font, "uusi lehmä", textcolor);
Sitten vaan sopivasti tuon rivi2 koordinaatit, ettet piirrä niitä päällekkäin.
Ajattelin vain, että olisiko nopeampaa tapaa, kun tuota tahtia koodi menee aivan mössöksi. : <
lisäksi nappuloiden kanssa onkelmia.
SDL_PollEvent(&tapahtuma); while(SDL_PollEvent(&tapahtuma)) { if (tapahtuma.key.keysym.sym == SDLK_1) { rahaa++; SDL_BlitSurface(teksti6, NULL, naytto, &alue_tekstille6); SDL_Flip(naytto); } }
Tuo koodi ei tee mitään.
Teet vaikka jonkun oman funktion, mikä osaa rivitää tekstin tms.
Edit: lukaseppas tuo: https://www.ohjelmointiputka.net/oppaat/opas.
Niin selviää, ett miten niitä nappeja käsitellään.
laitetaan nyt pieni esimerkki
Tässä tapauksessa kun painaa ruksia ikkunan kulmasta tai painaa esc nappia, niin pääsilmukka loppuu. Tosta sun pitäis jo osata muokata toimiva versio.
Tämä siis suoraan yhdestä projektistani, joten toimivuus on varma.
//ennen pääsilmukkaa Uint8* button; //Pääsilmukass while( SDL_PollEvent( &event ) ) { //Jos painetaan ruksia if( event.type == SDL_QUIT ) { running = false; } if (this->button[SDLK_ESCAPE]) //Lopetus { running = false; } }
Juu nyt toimii. Evotin vähän. :DD
Yksi ongelma kuitenkin. Niinkuin näette ylempää iffissä on koodi:
rahaa++;
se ei kuitenkaan lisää rahaa yhtään, joten mistä johtuu päivitys moka tms? :O
Näytäppäs vähän sitä koodias.
Ennen kuin esittelen sitä niin putsaan sitä hieman (nimittäin pari ominaisuutta ja toista sataa riviä koodia. : <
Mikä olisi SDL:ssä hyvä tapa vaihtaa ns. Huonetta? :O
Ai niinkuin pelissä? 1. huoneesta 2. huoneeseen?
Varmaan teet jonkin kohdan 1. huoneeseen, mikä kertoo enginelle, että pitää ladata 2. huone.
Kun 2.huone on ladattu engine siirtää pelaajan 1.huoneesta 2.huoneen aloituskoordinaatteihin.
Niin mutta tarkoitan, että miten? case, if goto?
No vaikka.
//pääsilmukass //Tämä siis kentän maali if(pelaajaX == maaliX && pelaajaY == maaliY) //tee jotain
ok. Taisin saadakkin tuollaisen luotua on vain pieni ongelma. =)
En tiedä tarkkaan miten C++ suorittaa koodia. Vetääkö se sen kerran loppuun ja antaa olla. Eli tällöin mikä funktio jättää tietyn kohdan päälle mitä C++ suorittaa koko ajan. Katsos tällä hetkellä on kaksi eri huonetta. Kun painaa taloa 1 pitäisi päästä toiseen huoneeseen, mutta ei pääse ja luulen, että vika on siinä, että pää funktio:
int main(int argc, char *argv[])
ei ala uudestaan jonka takia peli ei osaa ottaa huonetta kaksi näkyviin. Eli miten aloitan koko funktion uudestaan tai jätän tuo huone välin päälle jollain silmukalla?
Siis kaikkien pelien pohjana on jonkinlainen pääsilmukka, jota sitten rullataan eestakas. Pääsilmukassa tapahtuu kaikki pelin mekaniikka. esim. pelaajan liikutus, kaikkien objektien piirto ja ...
Eli tuo minun int main on pääsilmukka koska se oli valmiina siinä aloittaessani uuden projektin. No miksi sitten tuo ei toimi. (nyt tulee monta riviä koodia, mutta tärkeää on vain ne ominaisuudet siellä.)
Ei vaan sen on main funktio. Sun pääsilmukka on tämä:
while(pois==false) { 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; } }
Ei millään pahalla, mutta koodisi on sen näköistä, että kannattais tutustua vaikka putkan c++ oppaaseen...
Lyhyesti vastattuna: int main ei ole pääsilmukka, eikä silmukka ylipäätänsäkään. Pääsilmukkasi on while(pois==false), minkä sisällä ei tehdä mitään muuta kuin tutkitaan ESCin painallusta.
Pidemmästi vastattuna:
Opettele debuggerin käyttöä ja steppaamaan koodiasi. Voit tehdä samaa ihan paperillakin(/ruudullakin) käymällä koodin suoritusta mielessäsi läpi rivi riviltä. Nyt kun ohjelmaa menee läpi rivi riviltä, niin paljastuu tälläinen rakenne:
1. Alusta SDL
2. Piirrä huone 0
3. Looppaa tyhjää pääsilmukkaa tekemättä mitään kunnes painetaan ESC
4. Lue hiiren tila ja tarkasta paikka
5. Poistu ohjelmasta välittömästi tarkastusten jälkeen
Matalammalla tasolla en alkanut koodia tutkimaan, mutta jo ylemmällä tasolla näkee selvästi missä pahimmat loogiset virheet.
Tapoja tehdä huonesiirtymä on yhtä paljon kun ohjelmoijiakin. En osaa sanoa onko varinaisesti universaalia parasta tapaa olemassakaan, mutta esim. tilakoneisiin perustuva ratkaisu on toimiva. Peli voi olla esim. PELAA tilassa tasolla 1 ja sopivan ehdon täytyttyä se siirtyy tilaan SEURAAVA_TASO, jolloin ladataan seuraava taso ja tila päivitetään PELAA tilaan tasolla 2. Tiloja on helppo lisätä jälkikäteenkin (kuten PAUSE, MENU, DEBUG yms.) ja niiden muokkaus yhteisen tilakäsittelijän kautta on aika helppoa.
EDIT. Taas Vehkis ehti ensin :p
JES! :D
Kiitos! Sain tuon huone systeemin toimimaan. Tiesin koko ajan vian, mutta en tajunnut sitä kunnolla ja sitten tajusin ja kysyin asiasta täällä. Eli vika miksi huone ei vaihtunut oli Pääloopin väärä paikka. :P
Aihe on jo aika vanha, joten et voi enää vastata siihen.