Tekemäni Editori ei jostain syystä lue näppäimiä.
Escapesta ei mene pois ohjelmasta eikä numeronäppäimillä ole vaikutusta.
listaan tähän koko koodin koska ei ole hajuakaan missä päin se vika luuraa.
/* Tomillan NS kenttäeditori EDIT: ei liity: (versio -> 0.0.5 0.1.0 =>toimivuutta 0.2.0 =>tiedoston hallintaa 0.3.0 =>Kuvien osoitteet ja määrien hallinta paremmaksi) */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include "SDL.h" //Tarpeelliset kirjastot haettu int taulu[12][16]={ {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1}, {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} };//Alustetaaan taulukko piirto kuntoon int numero = 0; // mitä objektia käytetään int H_x; // hiiren x ja y int H_y; int H_napit; // hiiren nappi int pois; // poistutaanko ohjelmasta void Hiiren_sijainti(void); //Funktio hakee hiiren sijainnin void Nappain_paino(void); //Funktio tekee näppäinpainallusten tarvitsemat toiminnot void Piirto(void); //Funktio huolehtii void Piirra(int objekti, int X, int Y); //Funktio huolehtii yksittäisen kuvan piirtämiseltä SDL_Surface *screen; // näytölle piirto pinta SDL_Surface *kuva; // Kuvalle piirto pinta int main(int argc, char *argv[]) //Main funktio->Näytön asetukset, pää looppi, muistin vapautus { Uint32 initflags = SDL_INIT_VIDEO; // näytön asettamisen tarkistusta varten Uint8 video_bpp = 32; // Värisyvyys = 32 bittinen Uint32 videoflags = SDL_SWSURFACE | SDL_FULLSCREEN | SDL_DOUBLEBUF; // lipukkeet: käytä_normaaliamuistia | Kokonäyttötila | kaksoispuskurointi if ( SDL_Init(initflags) < 0 ) { //tapahtuuko virhe fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError()); exit(1); } //Asetetaan näytön asetukset screen=SDL_SetVideoMode(1024,768, video_bpp, videoflags); //Tekee yhteensä 16x12 ruutuisen näytön (1 ruutu 64x64 px), värisyvyys, lataa lipukkeet if (screen == NULL) { //jos näyttö jää tyhjäksi tapahtui virhe ja keskeytetään ohjelma fprintf(stderr, "Couldn't set 640x480x%d video mode: %s\n", video_bpp, SDL_GetError()); SDL_Quit(); exit(2); } pois = 0; //asetetaan poistujamuuttuja nollaksi while ( !pois ) { //jatketaan kunnes halutaan poistua Hiiren_sijainti(); //Haetaan hiiren sijainti Nappain_paino(); //tee näppäinten edellyttämät toiminnot Piirto(); //piirrä SDL_Delay(500); //odota hetki ja jatketaan } SDL_FreeSurface(kuva); //puhditetaan pinnat ja SDL kirjasto SDL_FreeSurface(screen); SDL_Quit(); return(0); } void Hiiren_sijainti(void){ H_napit=SDL_GetMouseState(&H_x, &H_y); //lukee H_napit-muuttujaan painallettu nappi ja hiiren sijainti H_x ja H_y muuttujiin } void Nappain_paino(void){ Uint8* nappi; SDL_Event tapahtuma; // ennen näppäinten lukemista tulee lukea tapahtumat? SDL_PollEvent(&tapahtuma); if(H_napit == SDL_BUTTON(1)){taulu[(H_x/64)][(H_y/64)]=numero;} //jos hiirellä on painettu vasenta h näppäintä laitetaan taulukkoon hiiren kohtaan objektin numero nappi = SDL_GetKeyState(NULL); if ( nappi[SDLK_1] ) { numero = 1; } if ( nappi[SDLK_1] ) { numero = 1; } if ( nappi[SDLK_2] ) { numero = 2; } if ( nappi[SDLK_3] ) { numero = 3; } if ( nappi[SDLK_4] ) { numero = 4; } if ( nappi[SDLK_5] ) { numero = 5; } if ( nappi[SDLK_6] ) { numero = 6; } if ( nappi[SDLK_7] ) { numero = 7; } if ( nappi[SDLK_8] ) { numero = 8; } if ( nappi[SDLK_9] ) { numero = 9; } if ( nappi[SDLK_0] ) { numero = 0; } if ( nappi[SDLK_ESCAPE] ) { pois = 1; } } void Piirto(void){ //taulukon piirto for(int i=0; i<=11; i++) { for(int j=0; j<=15; j++) { Piirra(taulu[i][j], j*64, i*64);//käydään taulu läpi } } Piirra(numero, (H_x/64)*64, (H_y/64)*64); //jotta H_x olisi 64 jaollinen luku, SDL_Flip(screen); } void Piirra(int objekti, int X, int Y){ //kuvien piirto if(objekti == 0){kuva=SDL_LoadBMP("/NS/Kuvat/0.bmp"); } if(objekti == 1){kuva=SDL_LoadBMP("/NS/Kuvat/1.bmp"); } if(objekti == 2){kuva=SDL_LoadBMP("/NS/Kuvat/2.bmp"); } if(objekti == 3){kuva=SDL_LoadBMP("/NS/Kuvat/3.bmp"); } if(objekti == 4){kuva=SDL_LoadBMP("/NS/Kuvat/4.bmp"); } if(objekti == 5){kuva=SDL_LoadBMP("/NS/Kuvat/5.bmp"); } if(objekti == 6){kuva=SDL_LoadBMP("/NS/Kuvat/6.bmp"); } if(objekti == 7){kuva=SDL_LoadBMP("/NS/Kuvat/7.bmp"); } if(objekti == 8){kuva=SDL_LoadBMP("/NS/Kuvat/8.bmp"); } if(objekti == 9){kuva=SDL_LoadBMP("/NS/Kuvat/9.bmp"); } SDL_Rect alue; // mille alueellä näyttöä kuva piirretään alue.x = X; // koordinaatit alue.y = Y; SDL_BlitSurface(kuva, NULL, screen, &alue); }
[Offtopic]
Miksi tuolla ylhäällä lukee "0.2.0 =>tiedoston hallintaa ", minä en ainakaan näe yhtään tiedostonhallinta-funktioita tuolla koodissa... (Taidan olla sokea)...
Elleis se sitten tarkoita noita kuvien lataamista...
[/Offtopic]
Minulla tulee tuollaista virhettä ku yrittää kääntää...
main.c:126: error: ‘for’ loop initial declaration used outside C99 mode
main.c:128: error: ‘for’ loop initial declaration used outside C99 mode
Yritän selvittää mistä johtuu..-
EDIT: käänsin c++ kääntäjällä ja kääntyi nätisti...
Minulla ainakin lähtee esciä painamalla pois ohjelmasta...
Öh, anteeksi, jäi tuo versionkehityssuunnitelman runko sinne alkuun :(
Ensinnäkin onnittelut päänsärkyisestä koodin ulkonäöstä, mutta älä huoli, se paranee, kun ohjelmoi enemmän. :)
Tapahtumia ei tarvitse pumpata ennen näppäinten lukemista.
Alustat taulu-muuttujan muodolla taulu[y][x], mutta koodirivillä
if(H_napit == SDL_BUTTON(1)){taulu[(H_x/64)][(H_y/64)]=numero;}
käsittelet sitä muodossa taulu[x][y]. Tästä voi seurata mitä kummallisimpia seurauksia!
Sanoit: "Escapesta ei mene pois ohjelmasta eikä numeronäppäimillä ole vaikutusta", mutta en yhdy tähän väittämään. Eski toimi hienosti, ja näppäimistöllä sain valittua kuvat, jotka itse piirsin. Ongelmasi saattaa johtua väärin muotoillusta tiedostopolustasi. Olet kirjoittanut SDL_LoadBMP("/NS/Kuvat/9.bmp")
. Ota ensimmäinen vinoviiva polusta pois.
Lisäksi kutkuttaisi kertoa pari kikkaa, joilla voisit selventää ja parantaa koodiasi, mutta eivätköhän ne muotoudu sinulle automaattisesti, jos pysyttelet ohjelmoinnin parissa.
edit. niin ja tuo muistivuoto! Lataat kuvat uudestaan ja uudestaan jokaisella piirtokerralla. Niiden vapauttaminen ohjelman lopussa ei jeesaa kovin paljoa. :)
Koodi on ilmeisesti tätä kuuluisaa C/C++:aa eli melkein C:tä muttei aivan. C99:nä tuo mennee läpi (en jaksa kokeilla), GCC:n lippu -std=c99, jos vehkis91 haluaa kokeilla. Virhehän on aivan selvä, jos C:n perusteet ovat hallussa. C++ on sen verran vapaampaa, ettei tuollaista virhettä tule.
Suosittelen tapahtumien lukemista semanttisesti, eli jos et käytä niitä mihinkään, käske SDL_PumpEvents-funktiolla SDL:n hoitaa kaikki jonossa olevat, ja jos taas käytät, niin lue kaikki jonosta aina kerralla (while (SDL_PollEvent(...)) {hoida...}) äläkä vain yhtä ohjelman joka kierroksella.
Ohjelmasi vuotaa muistia aivan mielettömästi, lataat joka piirtokerralla kuvat uudestaan etkä vapauta kuin lopuksi sen yhden, johon kuva-osoitin sillä hetkellä osoittaa. 16x12 tilen tasolla tämä tarkoittaa, että joka piirtokerralla lataat ja hukkaat 192 kuvaa jo pelkän taustan takia. Ei ihme, jos mitään ei näy. Oletko edes varma, että ohjelma pääsee SDL_Flip-funktioon asti? Noin epäoptimaalisella toteutuksella jo piirto voi kestää pitkään. Lisää piirtofunktioon (sekä Piirto että Piirrä) debug-printtausta ja aseta pääohjelman silmukassa pois-muuttuja heti ykköseksi, jotta silmukka suoritetaan vain kerran. Debug-tulosteessa voit myös tarkistaa, että kuvaosoitin ei ole NULL. Ihmettele sitten lisää, kun tiedät, mitä ohjelma edes yrittää piirtää. Myös kuvapolkusi näyttävät varsin epäilyttävältä, et kai sentään juurihakemiston alla kuviasi pidä? Varmaan pitäisi ensimmäinen "/" poistaa jokaisesta. Tarkista aina dataa ladatessasi, että lataus onnistuu.
Tee fiksusti: lataa kuvat ohjelman alussa taulukkoon (SDL_Surface *kuvat[10]) ja vapauta kaikki kymmenen lopuksi. Ei tarvitse välillä latailla, ei vuoda muistia, ja koodiakin säästyy, kun voit kirjoittaa vain "kuvat[numero]" noiden kymmenen if-lauseen sijaan.
Minäkin piirsin itse kuvat, ja ne kuvat piirtyivät eri kohtiin kuin missä hiiri olim eli sulla on koordinaattien kanssa jokin ongelma...
Ja annan yhden vinkin ainakin käytä struct tai class.
ja sitten #include <string.h> -> #include <string>
ja sitten niiden headereiden jälkeen using sdl::string;
EDIT: Metabolix: Minulla ainakin piirtää ne kuvat, mutta väärään kohtaan, koska tuossa yhdessä vaiheessa nuo kordinaatit vaihtavat paikkaa.
vehkis91 kirjoitti:
ja sitten #include <string.h> -> #include <string>
Ei todellakaan. Nuo ovat kaksi täysin eri otsikkoa, voit tutustua asiaan vaikkapa Googlen avulla. Ensimmäinen sisältää C:n tekstin- ja muistinkäsittelyfunktioita.
vehkis91 kirjoitti:
EDIT: Metabolix: Minulla ainakin piirtää ne kuvat, mutta väärään kohtaan, koska tuossa yhdessä vaiheessa nuo kordinaatit vaihtavat paikkaa.
Missä kohti? Pikaisella silmäyksellä kaikki menee aivan loogisesti. Jos tarkoitat i:tä ja j:tä Piirto-funktiossa, katso toki vielä tarkemmin ja käy vilkaisemassa, miten päin se taulukko olikaan (eli y, x eikä x, y).
EN tarkoita, kun niitä, että aluksi oli y, x ja llopussa taas x,y, kun muutin niin alkoi pelaan ihan kunnolla.
Jaa sori tuosta stringistä, en c:tä ole pahemmin käyttänyt, joten...
Edit: siis tuo mitä tgunner kirjoitti.
Kiitos vastauksesta
Huomasit selvästi, että olen aloittelija ohjelmointipuolella. Pyrin jatkossa keskittymään tarkemmin koodin ulkonäköön, aloittelijamokailujen vähentämiseen ja koodin optimointiin.
For silmukat eivät aiheuttaneet Apple(PowerPC)/Xcode (tästä johtuen tulee olla /-merkki ennen kuvanpolkua) kääntäjällä mitään error herjaa. Näppäimillä ei ollut vaikutusta, nyt kuitenkin kun vaihdoin x ja y oikein, niin palikka kyllä seuraa hiiren liikkeitä mutta erittäin tahmeasti, aluksi nopeammin mutta noin sekunnin ajon jälkeen muuttuu tahmeeksi: hiiri liikkuu ja kuva tulee noin sekunnin viiveellä perässä.
Näppäimissä ei siis ollut mitään vikaa, ne toimivat kun jaksaa vaan pitää pohjassa n. sekunnin.
Onko koneesi uudehkompi kuin tämä n 2,5vuotta vanha ibook G4 apple?
Ehkä ajatus liikkuu huomenna nopeammin ja jatkan sitten debuggausta.
vehkis91 kirjoitti:
ja sitten #include <string.h> -> #include <string>
ja sitten niiden headereiden jälkeen using sdl::string;
Tarkoitat varmaankin std::string;. Muutenkin tuo vaihdos ei oikein tee mitä halusit, kuten Metabolix jo huomauttikin.
No en yhtään ihmettele, jos alkaa hidasteleen ku lataat joka kerta nuo kuvat uudelleen...
Jaa niin, [koordinaatit väärin] käsittelyssä eikä piirrossa. Minusta se silti piirtää aivan oikein mutta klikkaus käsitellään väärin. Tässä ohjelmassa ero ei ole niin konkreettinen, mutta esimerkiksi pienessä pelissä on jo hyvin olennaista, piirretäänkö ukkeli aivan väärään paikkaan vai liikkuuko se oikeastikin jostain syystä sinne. (Ensimmäinen on joskus paljon ikävämpi ongelma, koska se voi olla vaikeampi havaita, vaikka korjaaminen ehkä olisikin helpompaa.)
Edit. Itse aiheeseen vielä: Miksi XCode (tai Mac) aiheuttaa tuollaisen vaatimuksen tiedostopolkuun? Sen kerran, kun Macia käytin, käyttäjän kotihakemisto oli /Users-hakemiston alla, ja pitäisin järkevänä oman kotihakemiston käyttämistä.
Ohjelman hidastuminen luultavasti johtuu juuri mainituista muistivuodoista, ja muutenkin hitautta aiheuttaa tuo SDL_Delay, jolla käsket ohjelman odottaa aina puoli sekuntia, ja kuvien jatkuva latailu.
Juu sain toimimaan tuon täysin reaaliaikaisesti, kun tein tarvittavat muutokset.
Tässä pitäis olla kaikki tarvittavat muutokset.
Nuo muut voivat sanoa, jos teen jotain väärin...
PS. sain kääntymään c-kääntäjälläkin... :P
lataaKuvat():
void lataaKuva() //Laitat sitten sen protyypin ennen mainia. { //ja kutsut mainista tätä ennen sitä päälooppia. kuva[0]=SDL_LoadBMP("0.bmp"); kuva[1]=SDL_LoadBMP("1.bmp"); kuva[2]=SDL_LoadBMP("2.bmp"); kuva[3]=SDL_LoadBMP("3.bmp"); kuva[4]=SDL_LoadBMP("4.bmp"); kuva[5]=SDL_LoadBMP("5.bmp"); kuva[6]=SDL_LoadBMP("6.bmp"); kuva[7]=SDL_LoadBMP("7.bmp"); kuva[8]=SDL_LoadBMP("8.bmp"); kuva[9]=SDL_LoadBMP("9.bmp"); }
globaalit:
SDL_Surface *kuva; -> SDL_Surface *kuva[10];
main:
SDL_Delay(10); for(int i=0;i<10;i++) //Surfaseiden vapautus.. ONKO OIKEIN? { SDL_FreeSurface(kuva[i]); }
piirrä:
void Piirra(int objekti, int X, int Y){ //kuvien piirto SDL_Rect alue; // mille alueellä näyttöä kuva piirretään alue.x = X; // koordinaatit alue.y = Y; SDL_BlitSurface(kuva[objekti], NULL, screen, &alue); }
Pdän kuvat selkeyden vuoksi suoraan kovalevyn pohjalla. En tiedä miksi tulee se /-merkki siihen alkuun mutta ei toimi ilman.
Mulle on ihan sama mistä ne kuvat lataa.. Laita tuohon lataus funktioon se oikea polku ja kerro sitten toimiko se ohjelma.
Joo nyt toimii täysillä, kiitos avuista.
No hyvä. :D
Aihe on jo aika vanha, joten et voi enää vastata siihen.