nahoy Skrevet 27. november 2006 Del Skrevet 27. november 2006 Jeg har laget et helt simpelt spill, det skal etter hvert enten bli tomannspong eller et arkanoid-aktig spill. Jeg poster koden her, fordi jeg lurer på om den er bra/dårlig, og om det er noe jeg har gjort feil, eller kunne gjort på bedre måter. Jeg har bare skrevet kode for meg selv til nå, og det er derfor litt vanskelig å avgjøre hva jeg gjør feil. Jeg har brukt brukt cone3d sin mail til å sette opp sdl. #include <stdio.h> #include <stdlib.h> #include <ctime> #include <SDL/SDL.h> const int SCREENWIDTH=1024; const int SCREENHEIGHT=768; float timePerFrame; struct ship { int x; int y; int lastx; int lasty; int width; float speed; }; struct point { int x; int y; int lastx; int lasty; }; bool ballsprite[20][20]= {//0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 {0,0,0,0,0,0,0,0,1,1,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,0,0,0,0,0},//1 {0,0,0,0,1,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0},//2 {0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,1,1,0,0,0},//3 {0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,0,0},//4 {0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,0},//5 {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,0},//6 {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0},//7 {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1},//8 {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1},//9 {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1},//0 {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},//1 {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0},//2 {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0},//3 {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0},//4 {0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0},//5 {0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0},//6 {0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0},//7 {0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0},//8 {0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0} //9 }; //game variables point ball; float ballspeed; ship ship; const int SHIPHEIGHT=10; void Slock(SDL_Surface *screen) { if ( SDL_MUSTLOCK(screen) ) { if ( SDL_LockSurface(screen) < 0 ) { return; } } } void Sulock(SDL_Surface *screen) { if ( SDL_MUSTLOCK(screen) ) { SDL_UnlockSurface(screen); } } void DrawPixel(SDL_Surface *screen, int x, int y, Uint8 R, Uint8 G, Uint8 B) { Uint32 color = SDL_MapRGB(screen->format, R, G, B); switch (screen->format->BytesPerPixel) { case 1: // Assuming 8-bpp { Uint8 *bufp; bufp = (Uint8 *)screen->pixels + y*screen->pitch + x; *bufp = color; } break; case 2: // Probably 15-bpp or 16-bpp { Uint16 *bufp; bufp = (Uint16 *)screen->pixels + y*screen->pitch/2 + x; *bufp = color; } break; case 3: // Slow 24-bpp mode, usually not used { Uint8 *bufp; bufp = (Uint8 *)screen->pixels + y*screen->pitch + x * 3; if(SDL_BYTEORDER == SDL_LIL_ENDIAN) { bufp[0] = color; bufp[1] = color >> 8; bufp[2] = color >> 16; } else { bufp[2] = color; bufp[1] = color >> 8; bufp[0] = color >> 16; } } break; case 4: // Probably 32-bpp { Uint32 *bufp; bufp = (Uint32 *)screen->pixels + y*screen->pitch/4 + x; *bufp = color; } break; } } void updatebg(SDL_Surface *screen, int x, int y, int width, int height) { for(int x2=x; x2<x+width; x2++) { for(int y2=y; y2<y+height; y2++) { if(y2>=0 && x2<SCREENWIDTH && y2>=0 && y2<SCREENHEIGHT) DrawPixel(screen, x2,y2,0,0,0); } } } void drawsprite(SDL_Surface *screen, bool sprite[20][20], int x, int y) { updatebg(screen, ball.x-2, ball.y-2, 2+20+2, 2+20+2); for(int y2=0; y2<20; y2++) { for(int x2=0; x2<20; x2++) { if(sprite[y2][x2]) DrawPixel(screen, (x2+x),(y2+y),255,255,255); } } } void DrawScene(SDL_Surface *screen) { Slock(screen); //pikseltegning starter her, spillet skal bare inneholde piksler, ingen bilder updatebg(screen, ball.lastx, ball.lasty, 20, 20); updatebg(screen, ship.lastx, ship.lasty, ship.width, SHIPHEIGHT); drawsprite(screen, ballsprite, ball.x, ball.y); for(int x=ship.x; x<ship.x+ship.width; x++) { for(int y=ship.y; y<ship.y+SHIPHEIGHT; y++) { DrawPixel(screen, x,y,255,255,255); } } Sulock(screen); SDL_Flip(screen); } int main(int argc, char *argv[]) { ship.x=60; ship.y=700; ship.width=75; ship.speed=1.0; ball.x=150; ball.y=150; ballspeed=0.45; int xdir=1; int ydir=1; Uint8* keys; if ( SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO) < 0 ) { printf("Unable to init SDL: %s\n", SDL_GetError()); exit(1); } atexit(SDL_Quit); SDL_Surface *screen; screen=SDL_SetVideoMode(SCREENWIDTH,SCREENHEIGHT,32,SDL_HWSURFACE|SDL_DOUBLEBUF); if ( screen == NULL ) { printf("Unable to set 1024x768 video: %s\n", SDL_GetError()); exit(1); } clock_t startTime=clock(); int totalFrames=0; int done=0; while(done == 0) { timePerFrame=(clock()-startTime)/(float)totalFrames; ++totalFrames; ship.lastx=ship.x; ship.lasty=ship.y; ball.lastx=ball.x; ball.lasty=ball.y; keys = SDL_GetKeyState(NULL); if ( keys[SDLK_LEFT]) { ship.x -= (int)(ship.speed*timePerFrame); if(ship.x<0)ship.x=0; } if ( keys[SDLK_RIGHT]) { ship.x += (int)(ship.speed*timePerFrame); if(ship.x>SCREENWIDTH-ship.width)ship.x=SCREENWIDTH-ship.width; } do { if(ball.x<0) xdir=1; if(ball.x>SCREENWIDTH-21) xdir=-1; if(ball.y<0) ydir=1; if(ball.y>SCREENHEIGHT-20) { done=1; break; } if(ball.x>ship.x-10 && ball.x<ship.x+ship.width+10 && ball.y>700-20 && ball.lasty<=700-20+1) ydir=-1; ball.x+=xdir*(int)(ballspeed*timePerFrame); ball.y+=ydir*(int)(ballspeed*timePerFrame); } while(ball.x>SCREENWIDTH-20 || ball.x<0 || ball.y<0 || ball.y>SCREENHEIGHT); SDL_Event event; while ( SDL_PollEvent(&event) ) { if ( event.type == SDL_QUIT ) { done = 1; } if ( event.type == SDL_KEYDOWN ) { if ( event.key.keysym.sym == SDLK_ESCAPE ) { done = 1; } } } DrawScene(screen); } return 0; } .exe-fil ligger vedlagt Arkanoid_alpha0.2.zip Lenke til kommentar
HolgerL Skrevet 27. november 2006 Del Skrevet 27. november 2006 (endret) Jeg vil anbefale å implementere ulike vinkler som ballen spretter i avhengig av hvor på platen man treffer. Jeg har ikke lest koden så godt, men det ser ut til at du ikke har fart i x-retning skilt ut fra fart i y-retning. Å ha to variabler for hver av dem, og la bevegelsene bestemmes av dem gir deg større frihet til å la ballen gå slik du vil. Det vil kanskje være en ide å splitte koden opp i egne filer slik at den blir mer oversiktlig. Det kan lønne seg når koden blir lengre. Så kan du jobbe på en isolert del om gangen. Det ser ut til å være en glipp når ballen treffer på kanten av platen. Da går den igjennom, selv om den ikke burde det. Se etter hvordan kollisjon mellom ball og plate behandles. Kanskje kollisjonen ikke detekteres om midtkoordinatene ikke treffer platen, selv om selve spriten gjør det. Ellers ser det ut til å kunne bli et morsomt lite spill. Lykke til Endret 27. november 2006 av HolgerLudvigsen Lenke til kommentar
Lednar Skrevet 28. november 2006 Del Skrevet 28. november 2006 (endret) For en kode... Har prøvd det(Har programmering på skolen så jeg gjør jo egentlig skolearbeid ) Men av og til treffer ikke kula den linjen. Vet ikke hva feilen er. Ellers var det kjempeartig Vi sitter 2/3 personer og spiller det nå EDIT: Synes btw du burde fikse at den går igjennom linjen. Og kanskje legge til en teller som forteller hvor mange ganger du har truffet linjen. Sånn at det blir litt mer konkurranse Endret 28. november 2006 av Lednar Lenke til kommentar
Giddion Skrevet 28. november 2006 Del Skrevet 28. november 2006 Jeg digger hvordan du har laget ballen. Men bruken av variabel typen bool bør man holde seg unna, bruk heller int, dette siden en vanlig CPU bruker mer tid på å jobbe med 1 bit enn 32 bit. Kompilatoren gjør sannsynligvis bool om til int uansett så du vil nok ikke merke noen forskjell. Så bør du bruke const i de fleste av funksjonene dine siden de aller fleste av funksjonene ikke gjøre endringer på variablene. Så er det hvordan du regner ut [timePerFrame], det er mulig du vil ha det slik og det skal du få lov til, men du regner bare ut gjennomsnittlig tpf (hvis jeg har forstått det riktig) gjennom hele spilltiden og det kan/har konsekvenser som gir ulik hastighet når maskinen jobber mer/mindre. Lykke til videre. Lenke til kommentar
Ueland Skrevet 28. november 2006 Del Skrevet 28. november 2006 Ballen bare kjører gjennom platen, vanskelig å stoppe ballen da. Lenke til kommentar
einaros Skrevet 28. november 2006 Del Skrevet 28. november 2006 Litt sweeping (spør google) må ofte til når man skal ha kollisjoner. Akkurat hvilke kriterier du legger til grunn for å gjøre sweepingen er opp til deg, men i en såpass enkel sammenheng, med et veldig begrenset antall operasjoner, vil du komme langt med å sjekke bevegelseslengde. Dersom ballen i løpet av én frame flytter seg lengre enn sin egen diameter, bør du gjøre bevegelsen i chunks som ikke er større enn f.eks. diameteren. For hvert flytt må du da sjekke for kollisjoner, og deretter bestemme vinkel mellom ball og objektet den kolliderer med. For vinkelbestemmelse i kulekollisjonen kan du f.eks. sjekke i sirkelens ytterpunkter, med nøyaktigheten (antall grader per steg) som passer deg. Trekker du normal fra kollisjonspunkt og speiler ballens bevegelsesvinkel om denne, får du ny utgangsvinkel. Lenke til kommentar
nahoy Skrevet 29. november 2006 Forfatter Del Skrevet 29. november 2006 Tusen takk for alle tilbakemeldinger, de kom fantastisk kjapt. Har hatt en del tentamner og styr nå, så jeg har ikke jobbet noe med det før nå. Jeg vil anbefale å implementere ulike vinkler som ballen spretter i avhengig av hvor på platen man treffer. Jeg har ikke lest koden så godt, men det ser ut til at du ikke har fart i x-retning skilt ut fra fart i y-retning. Å ha to variabler for hver av dem, og la bevegelsene bestemmes av dem gir deg større frihet til å la ballen gå slik du vil. Enig, er morsommere når ballen ikke alltid går i 45-graders vinkel. Det vil kanskje være en ide å splitte koden opp i egne filer slik at den blir mer oversiktlig. Det kan lønne seg når koden blir lengre. Så kan du jobbe på en isolert del om gangen. Det var spesielt sånne ting jeg tenkte på da jeg posta koden. Hvordan er det lurt å dele opp koden? Det ser ut til å være en glipp når ballen treffer på kanten av platen. Da går den igjennom, selv om den ikke burde det. Se etter hvordan kollisjon mellom ball og plate behandles. Kanskje kollisjonen ikke detekteres om midtkoordinatene ikke treffer platen, selv om selve spriten gjør det. Mange som har meldt fra om at ballen går igjennom platen, dette er litt rart, for det gjør det nemlig ikke på min maskin. Grunnen til dette er vel kanskje at ballen beveger seg forbi platen før det blir sjekket for kollisjon? For en kode... Har prøvd det(Har programmering på skolen så jeg gjør jo egentlig skolearbeid ) Men av og til treffer ikke kula den linjen. Vet ikke hva feilen er.Ellers var det kjempeartig Vi sitter 2/3 personer og spiller det nå EDIT: Synes btw du burde fikse at den går igjennom linjen. Og kanskje legge til en teller som forteller hvor mange ganger du har truffet linjen. Sånn at det blir litt mer konkurranse 7374815[/snapback] Problemet med tellere er at de krever tekst, og dette er litt komplisert i sdl, det er jo selvfølgelig planen å ta det med etter hvert, men jeg synes det er litt kronglete. Har brukt sdl_ttf i et annet spill jeg har laget, men synes dette var mye styr. Er det noen enklere måte å fikse tekst på? Jeg digger hvordan du har laget ballen. Men bruken av variabel typen bool bør man holde seg unna, bruk heller int, dette siden en vanlig CPU bruker mer tid på å jobbe med 1 bit enn 32 bit. Kompilatoren gjør sannsynligvis bool om til int uansett så du vil nok ikke merke noen forskjell. Jeg tror også jeg har lest noe sånt, har rettet det nå. Hva er egentlig grunnen? Det burde jo være minst like enkelt med bare 1 bit? Så bør du bruke const i de fleste av funksjonene dine siden de aller fleste av funksjonene ikke gjøre endringer på variablene. Done. Så er det hvordan du regner ut [timePerFrame], det er mulig du vil ha det slik og det skal du få lov til, men du regner bare ut gjennomsnittlig tpf (hvis jeg har forstått det riktig) gjennom hele spilltiden og det kan/har konsekvenser som gir ulik hastighet når maskinen jobber mer/mindre. Du har forstått det riktig, lurte litt på dette når jeg skrev dette. Hva tror dere er lurest? Burde jeg ha gjennomsnittlig tid eller ta tiden på siste frame? Hva med gjennomsnitt av de 10 siste frames? Litt sweeping (spør google) må ofte til når man skal ha kollisjoner. Akkurat hvilke kriterier du legger til grunn for å gjøre sweepingen er opp til deg, men i en såpass enkel sammenheng, med et veldig begrenset antall operasjoner, vil du komme langt med å sjekke bevegelseslengde. Dersom ballen i løpet av én frame flytter seg lengre enn sin egen diameter, bør du gjøre bevegelsen i chunks som ikke er større enn f.eks. diameteren. For hvert flytt må du da sjekke for kollisjoner, og deretter bestemme vinkel mellom ball og objektet den kolliderer med. For vinkelbestemmelse i kulekollisjonen kan du f.eks. sjekke i sirkelens ytterpunkter, med nøyaktigheten (antall grader per steg) som passer deg. Trekker du normal fra kollisjonspunkt og speiler ballens bevegelsesvinkel om denne, får du ny utgangsvinkel. 7375465[/snapback] Har ikke fått sett på dette enda, men skal se på det nå, siden dette er den feilen som flest har meldt i fra om. Poster ny kode her når jeg har fiksa det. Lenke til kommentar
Dead_Rabbit Skrevet 29. november 2006 Del Skrevet 29. november 2006 (endret) Obs, obs: Advarer om til dels subjektive meninger. Det vil kanskje være en ide å splitte koden opp i egne filer slik at den blir mer oversiktlig. Det kan lønne seg når koden blir lengre. Så kan du jobbe på en isolert del om gangen. Det var spesielt sånne ting jeg tenkte på da jeg posta koden. Hvordan er det lurt å dele opp koden? Jeg vil anbefale å objektorientere programmet ditt så fort som overhodet mulig. Da er det vanlig å ha en klassedeklarasjonen i en .hpp-fil og klassedefinisjonen i en .cpp fil. Hvis du ikke har planer om å objektorientere, kan du allikevel ha funksjoner i egne filer. Det er heller ikke dumt å implementere forskjellige subsystemer. Ett display-subsystem, et input-subsystem, et update-subsystem, et audio-subsystem, osv. Da blir det også lettere å vite hvordan man bør gruppere klasser/funksjoner ved å se på hva som hører til hva. Du bør forøvrig ta en titt på «Programming Linux Games». Den forklarer det på en god måte hvordan du kan implementere subsystems o.l. i spillet ditt. For en kode... Har prøvd det(Har programmering på skolen så jeg gjør jo egentlig skolearbeid ) Men av og til treffer ikke kula den linjen. Vet ikke hva feilen er.Ellers var det kjempeartig Vi sitter 2/3 personer og spiller det nå EDIT: Synes btw du burde fikse at den går igjennom linjen. Og kanskje legge til en teller som forteller hvor mange ganger du har truffet linjen. Sånn at det blir litt mer konkurranse 7374815[/snapback] Problemet med tellere er at de krever tekst, og dette er litt komplisert i sdl, det er jo selvfølgelig planen å ta det med etter hvert, men jeg synes det er litt kronglete. Har brukt sdl_ttf i et annet spill jeg har laget, men synes dette var mye styr. Er det noen enklere måte å fikse tekst på? Her kan du lage en wrapper for SDL_ttf ved å lage en Text-klasse. Her kan du f.eks. bestemme farge, font og størrelse i konstruktøren i klassen, og gjemme detaljer du helst vil glemme. Jeg digger hvordan du har laget ballen. Men bruken av variabel typen bool bør man holde seg unna, bruk heller int, dette siden en vanlig CPU bruker mer tid på å jobbe med 1 bit enn 32 bit. Kompilatoren gjør sannsynligvis bool om til int uansett så du vil nok ikke merke noen forskjell. Jeg tror også jeg har lest noe sånt, har rettet det nå. Hva er egentlig grunnen? Det burde jo være minst like enkelt med bare 1 bit? På en annen side, så blir koden mer lettlest om du heller bruker bool, da denne bare kan inneholde to verdier, som i ditt tilfelle jo er det du er ute etter. Det er vel heller ikke ved slike ting at flaskehalsene i et program som oftest sitter. Håper dette hjalp litt. Endret 29. november 2006 av zirener Lenke til kommentar
nahoy Skrevet 1. desember 2006 Forfatter Del Skrevet 1. desember 2006 Det hjalp en god del, zirener. Jeg skal ta en titt på boka snart, får ikke gjort det helt enda. Imens prøvde jeg å objektorientere programmet mitt. Jeg støtte imidlertid på et problem. const int ballsprite[20][20]= {//0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 {0,0,0,0,0,0,0,0,1,1,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,0,0,0,0,0},//1 {0,0,0,0,1,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0},//2 {0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,1,1,0,0,0},//3 {0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,0,0},//4 {0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,0},//5 {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,0},//6 {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0},//7 {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1},//8 {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1},//9 {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1},//0 {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},//1 {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0},//2 {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0},//3 {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0},//4 {0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0},//5 {0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0},//6 {0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0},//7 {0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0},//8 {0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0} //9 }; class ball { public: int x; int y; int lastx; int lasty; float xspeed; float yspeed; int* sprite[20][20]; void init(); }; void ball::init() { sprite=&ballsprite; } Får en error: 53 E:\My Documents\programmering\C++\Arkanoid\globals.hpp incompatible types in assignment of `const int (*)[20][20]' to `int*[20][20]' Lenke til kommentar
Giddion Skrevet 1. desember 2006 Del Skrevet 1. desember 2006 Først så er jeg ikke helt med på hva du skal med en peker til en global, men det får være så. Jeg har desverre ikke klart å få til en peker som peker til en [20][20] array (vet ikke om dette er mulig heller, men det er det sikkert) Men jeg har fått laget en int* som peker til arrayen. Problemet med det er at man ikke kan garantere at pekeren peker til en [20][20] array og ikke en [2] array. For å si det på en annen måte så må du ta det for god fisk at ball::sprite pker til en [20][20] array. Så lenge koden er som så så er det ikke no problem. koden Klikk for å se/fjerne innholdet nedenfor class ball { public: int x; int y; int lastx; int lasty; float xspeed; float yspeed; int* sprite; void init(); }; void ball::init() { sprite=(int*)ballsprite; } lykke til Lenke til kommentar
nahoy Skrevet 6. desember 2006 Forfatter Del Skrevet 6. desember 2006 Er kommet ganske langt nå, men jeg har et problem. Jeg lurer på hvordan jeg får hentet en variabel fra classen ship fra classen ball. class ball { public: ball() { for(int y=0; y<20; y++) { for(int x=0; x<20; x++) { sprite[y][x]=ballsprite[y][x]; } } xdir=1; ydir=1; } int x; int y; int lastx; int lasty; float xspeed; float yspeed; int xdir; int ydir; int sprite[20][20]; void move() { x=lastx+xdir*(int)(xspeed*frameTimeAvg); y=lasty+ydir*(int)(yspeed*frameTimeAvg); //kollisjonstesting //noen av verdiene er litt rare fordi jeg ikke vil at ballen skal ødelegge kanten if(x<1) { xdir*=-1; x=1; } if(x>SCREENWIDTH-21) { xdir*=-1; x=SCREENWIDTH-21; } if(y<1) { ydir*=-1; y=1; } if(y>SCREENHEIGHT-20) { done=1; } //sjekker om ballen treffer skipet if(x>ship.x-20 && x< ship.x+ship.width+20 && y>700-20 && lasty<=700-20 && ydir==1) { ydir=-1; y=700-20; } //Slutt på kollisjonstesting } }; Det går visst ikke an å skrive ship.x inne i ball , da får jeg denne erroren: expected primary-expression "before '.' token Hva skal man egentlig skrive? Lenke til kommentar
Giddion Skrevet 7. desember 2006 Del Skrevet 7. desember 2006 Er kommet ganske langt nå, men jeg har et problem.Jeg lurer på hvordan jeg får hentet en variabel fra classen ship fra classen ball. kode..... Det går visst ikke an å skrive ship.x inne i ball , da får jeg denne erroren: expected primary-expression "before '.' token Hva skal man egentlig skrive? 7442159[/snapback] det er litt vanslkelig å si siden det virker som om det mangler noe kode. Du må inkudere header filen som inneholder ship klassen [#include "ship.h"] eller navnet på headeren som du har definert ship klassen. Så spørs det hvor du har deklarert ship klassen hvis du har deklarert den som en global så kan du skrive [extern Cship ship] Cship er da variable typen til ship variablen. lykke til. Lenke til kommentar
nahoy Skrevet 8. desember 2006 Forfatter Del Skrevet 8. desember 2006 (endret) Fant ut av det nå, bare jeg som hadde vært så tullete at jeg klarte å definere Cship ship først. Nå har jeg imidlertid et annet problem. Jeg har delt opp prosjektet slik: main.cpp globals.hpp classes.cpp Jeg trenger noen av globalene i både main.cpp og classes.cpp Problemet er at jeg da får en multiple definition error. Hvordan skal jeg fikse dette? Mener å ha sett "#pragma once" eller noe et eller annet sted, er det dette jeg skal skriver? EDIT: Fikk det til nå, endret filnavnet til classes.hpp. Dette synes jeg var litt merkelig, trodde ikke filetternavnet hadde noe å si. Hvoror er det slik? Hvordan burde jeg egentlig fikse det? Endret 8. desember 2006 av nahoy Lenke til kommentar
Dead_Rabbit Skrevet 8. desember 2006 Del Skrevet 8. desember 2006 Jeg tror ikke du skal være nødt til å bruke #pragma hvi sdu har include-guards i header-filen din.. Altså #ifndef _header_hpp_ #define _header_hpp_ class Header { }; #endif Lenke til kommentar
nahoy Skrevet 9. desember 2006 Forfatter Del Skrevet 9. desember 2006 Jeg har nå laget en ny versjon. Jeg håper den er litt bedre. Dette har jeg gjort: 1. delt opp koden i tre filer, main, en med klassene og spriten og en med globaler. Og en main.cpp 2. Har gått over til å bruke musa i stedenfor tastaturet. 3. Tegnet en hvit kant rundt skjermen. 4. Forbedret kollisjonstestingen (har ikke lest om sweeping enda, synes det var vanskelig å finne noe om.) 5. Har gjort slik at ballen går i ulike vinkler avhengig av hvor den treffer. globals.hpp Klikk for å se/fjerne innholdet nedenfor #ifndef _globals_hpp_ #define _globals_hpp_ class globals { }; #endif const int SCREENWIDTH=1024; const int SCREENHEIGHT=768; float frameTimeAvg=3.5; int done; main.cpp Klikk for å se/fjerne innholdet nedenfor #include <stdio.h> #include <stdlib.h> #include <ctime> #include <cmath> //skal fjernes når jeg er ferdig med utviklingen #include <iostream> #include <SDL/SDL.h> #include "globals.hpp" #include "classes.hpp" //skal og fjernes using std::cout; //ting som hører til tidperframe og sånt clock_t startTime; clock_t lastFrameStart; float timePerFrame[10]; int totalFrames=0; float setFrameTime() { //sender alt lenger "bakover" i fartsarrayet for(int i=9; i>0; i--) { timePerFrame[i]=timePerFrame[i-1]; } timePerFrame[0]=clock()-lastFrameStart; //finner gjennomsnittlig fart float totalTime=0.0; for(int i=9; i>=-1; i--) { totalTime+=timePerFrame[i]; } if(totalFrames>20) frameTimeAvg=totalTime/10.0; //cout << frameTimeAvg << "\n"; lastFrameStart=clock(); } //game variables const int SHIPHEIGHT=10; bool drawborder=1; void Slock(SDL_Surface *screen) { if ( SDL_MUSTLOCK(screen) ) { if ( SDL_LockSurface(screen) < 0 ) { return; } } } void Sulock(SDL_Surface *screen) { if ( SDL_MUSTLOCK(screen) ) { SDL_UnlockSurface(screen); } } void DrawPixel(SDL_Surface *screen, int x, int y, Uint8 R, Uint8 G, Uint8 B) { Uint32 color = SDL_MapRGB(screen->format, R, G, B); switch (screen->format->BytesPerPixel) { case 1: // Assuming 8-bpp { Uint8 *bufp; bufp = (Uint8 *)screen->pixels + y*screen->pitch + x; *bufp = color; } break; case 2: // Probably 15-bpp or 16-bpp { Uint16 *bufp; bufp = (Uint16 *)screen->pixels + y*screen->pitch/2 + x; *bufp = color; } break; case 3: // Slow 24-bpp mode, usually not used { Uint8 *bufp; bufp = (Uint8 *)screen->pixels + y*screen->pitch + x * 3; if(SDL_BYTEORDER == SDL_LIL_ENDIAN) { bufp[0] = color; bufp[1] = color >> 8; bufp[2] = color >> 16; } else { bufp[2] = color; bufp[1] = color >> 8; bufp[0] = color >> 16; } } break; case 4: // Probably 32-bpp { Uint32 *bufp; bufp = (Uint32 *)screen->pixels + y*screen->pitch/4 + x; *bufp = color; } break; } } void updatebg(SDL_Surface *screen, const int X, const int Y, const int WIDTH, const int HEIGHT) { for(int x2=X; x2<X+WIDTH; x2++) { for(int y2=Y; y2<Y+HEIGHT; y2++) { if(y2>=0 && x2<SCREENWIDTH && y2>=0 && y2<SCREENHEIGHT) DrawPixel(screen, x2,y2,0,0,0); } } } void drawsprite(SDL_Surface *screen, const int SPRITE[20][20], const int X, const int Y) { for(int y2=0; y2<20; y2++) { for(int x2=0; x2<20; x2++) { if(SPRITE[y2][x2]) DrawPixel(screen, (x2+X),(y2+Y),255,255,255); } } } void DrawScene(SDL_Surface *screen) { Slock(screen); //pikseltegning starter her, spillet skal bare inneholde piksler, ingen bilder updatebg(screen, (int)ball.lastx, (int)ball.lasty, 20, 20); updatebg(screen, ship.lastx, ship.lasty, ship.width, SHIPHEIGHT); drawsprite(screen, ball.sprite, (int)ball.x, (int)ball.y); for(int x=ship.x; x<ship.x+ship.width; x++) { for(int y=ship.y; y<ship.y+SHIPHEIGHT; y++) { DrawPixel(screen, x,y,255,255,255); } } //tegner fint hvit kant if(drawborder) { for(int x=1; x<SCREENWIDTH-1; x++) { DrawPixel(screen, x,0,255,255,255); DrawPixel(screen, x,SCREENHEIGHT-1,255,255,255); } for(int y=1; y<SCREENHEIGHT-1; y++) { DrawPixel(screen, 0,y,255,255,255); DrawPixel(screen, SCREENWIDTH-1,y,255,255,255); } drawborder=0; } Sulock(screen); SDL_Flip(screen); } int main(int argc, char *argv[]) { //input variables int mousex, mousey; Uint8* keys; if ( SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO) < 0 ) { printf("Unable to init SDL: %s\n", SDL_GetError()); exit(1); } atexit(SDL_Quit); SDL_Surface *screen; screen=SDL_SetVideoMode(SCREENWIDTH,SCREENHEIGHT,32,SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_FULLSCREEN); if ( screen == NULL ) { printf("Unable to set 1024x768 video: %s\n", SDL_GetError()); exit(1); } SDL_Delay(1000); //A small delay to make sure that the game doesn't start before the resulution is set. SDL_ShowCursor(SDL_DISABLE); /*************************** * Game loop starting here * ***************************/ clock_t startTime=clock(); done=0; while(done == 0) { setFrameTime(); //input here //keyboard keys = SDL_GetKeyState(NULL); if ( keys[SDLK_p]) while(keys[SDLK_p]) keys = SDL_GetKeyState(NULL); //mouse SDL_GetMouseState(&mousex, &mousey); ship.move(mousex); ball.move(); SDL_Event event; while ( SDL_PollEvent(&event) ) { if ( event.type == SDL_QUIT ) { done = 1; } if ( event.type == SDL_KEYDOWN ) { if ( event.key.keysym.sym == SDLK_ESCAPE ) { done = 1; } } } //for debugging, simulating bad pc //SDL_Delay(55); DrawScene(screen); ship.lastx=ship.x; ship.lasty=ship.y; ball.lastx=ball.x; ball.lasty=ball.y; totalFrames++; } return 0; } classes.hpp Klikk for å se/fjerne innholdet nedenfor #ifndef _classes_hpp_ #define _classes_hpp_ class classes { }; #endif #include <cmath> class Cship { public: int x; int y; int lastx; int lasty; int width; float speed; Cship() { x=60; y=700; width=75; speed=1.0; } void move(int newX) { x=newX; //check if the ship is moving outside the screen if(x<1)x=1; if(x>SCREENWIDTH-width-1)x=SCREENWIDTH-width-1; } }; Cship ship; const int ballsprite[20][20]= {//0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 {0,0,0,0,0,0,0,0,1,1,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,0,0,0,0,0},//1 {0,0,0,0,1,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0},//2 {0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,1,1,0,0,0},//3 {0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,0,0},//4 {0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,0},//5 {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,0},//6 {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0},//7 {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1},//8 {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1},//9 {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1},//0 {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},//1 {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0},//2 {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0},//3 {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0},//4 {0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0},//5 {0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0},//6 {0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0},//7 {0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0},//8 {0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0} //9 }; class Cball { public: Cball(); void move(); float x; float y; float lastx; float lasty; float totalSpeed; float xspeed; float yspeed; int sprite[20][20]; }; Cball::Cball() { for(int a=0; a<20; a++) { for(int b=0; b<20; b++) { sprite[a][b]=ballsprite[a][b]; } } x=150; y=150; totalSpeed=1.1; xspeed=yspeed=totalSpeed/2; } void Cball::move() { x=lastx+(int)(xspeed*frameTimeAvg); y=lasty+(int)(yspeed*frameTimeAvg); //kollisjonstesting //noen av verdiene er litt rare fordi jeg ikke vil at ballen skal ødelegge kanten if(x<1) { xspeed*=-1; x=1; } if(x>SCREENWIDTH-21) { xspeed*=-1; x=SCREENWIDTH-21; } if(y<1) { yspeed*=-1; y=1; } if(y>SCREENHEIGHT-20) { done=1; } //sjekker om ballen treffer skipet if((x > ship.x-15) && (x < ship.x+ship.width+15) && y>700-20 && lasty<=700-20 && yspeed>0) { yspeed*=-1; float ballCentre=x+10.0; float shipCentre=ship.x+ship.width/2; float ballShippositioning=ballCentre-shipCentre; float relationalPos=ballShippositioning/(ship.width*0.7);//0.7 ikke 0.5 slik at yspeed ikke blir 0 og ballen ikke snurrer evig rundt xspeed=relationalPos * totalSpeed; yspeed=(1-(std::abs(relationalPos))) * -totalSpeed; if(yspeed>-0.3)yspeed=-0.3; // i tilfelle bøgg } //Slutt på kollisjonstesting } Cball ball; Kommentarene er for tiden en herlig blanding av norsk og engelsk. Planlegger å skrive om til engelsk. Arkanoid_alpha0.3_src.zip Lenke til kommentar
Dead_Rabbit Skrevet 9. desember 2006 Del Skrevet 9. desember 2006 (endret) Mulig jeg ikke var helt klar på denne biten, men for å hindre at ting blir inkludert flere ganger, må du ha alt mellom #define og #endif. Det er heller ikke en absolutt nødvendig å ha en klasse med samme navn som headerfilen, eller i det hele tatt en klasse pr. headerfil, jeg brukte det bare som et eksempel. Endret 9. desember 2006 av staalezh Lenke til kommentar
Giddion Skrevet 9. desember 2006 Del Skrevet 9. desember 2006 Den ballen er litt rar, hvorfor kopierer du ballen inn i en klasse fra en const global. Hadde du forandret på ballen så hadde jeg skjønt det, men det skjer jo ikke, hva med å gjøre det som koden under da slipper man hverfall å ha to kopier av ballen, men koden under er heller ikke helt bra. Klikk for å se/fjerne innholdet nedenfor Cball::Cball() { sprite = {//0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 {0,0,0,0,0,0,0,0,1,1,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,0,0,0,0,0},//1 {0,0,0,0,1,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0},//2 {0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,1,1,0,0,0},//3 {0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,0,0},//4 {0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,0},//5 {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,0},//6 {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,0},//7 {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1},//8 {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1},//9 {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1},//0 {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},//1 {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0},//2 {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0},//3 {0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0},//4 {0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0},//5 {0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0},//6 {0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0},//7 {0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0},//8 {0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0} //9 }; for(int a=0; a<20; a++) { for(int b=0; b<20; b++) { sprite[a][b]=ballsprite[a][b]; } } x=150; y=150; totalSpeed=1.1; xspeed=yspeed=totalSpeed/2; } lykke til og god jul Lenke til kommentar
nahoy Skrevet 9. desember 2006 Forfatter Del Skrevet 9. desember 2006 Hmmm.. du sier noe. Kanskje jeg bare skulle a spriten ligge utenfor klassen. Fikk vel objektorientingsdilla Takk for at du tar deg tid til å hjelpe Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå