Permalänk

c++ SDL tile kollision!

Hej, jag jobbar på ett "spel" för att lära mig mer om SDL. Spelet använder sig av tiles som sparas i en tvådimensionel std::vector. 0 betyder ingenting och det som är skilt från 0 är olika blocktyper. Det har faktiskt gått ganska bra så här långt men det har tagit totalstopp nu när jag kom till kollisionen. suttit med detta problemet i en vecka snart. Jag är en sådan person som inte slutar tänka på mina problem förren dom är lösta. Så detta är rejält jobbigt för mig.

Jag kommer endast skicka med det jag anser berör kollisionen, känner ni att jag behöver skicka mer så skriv det!

Ni får gärna ge mig övriga tips ang SDL.

Tack i förhand!

Klassen base ärvs av de andra klasserna och innehåller alla konstanter och en funktion för att kolla kollision mellan 2 SDL_Rects.
Såhär ser den funktionen ut.

bool base::CheckCollision(SDL_Rect r1,SDL_Rect r2) { if(r1.x >= r2.x+r2.w){ return false; } else if(r1.y >= r2.y+r2.h){ return false; } else if(r1.x+r1.w <= r2.x){ return false; } else if(r1.y+r1.h <= r2.y){ return false; }else{ return true; } }

Detta är från klassen game som innehåller själva spelets "hjärta" som skapar alla objekt och den har även själva spel loopen i sig.

Jag skickar med själva loopen.

void game::GameLoop() { Uint32 start, end; running = true; while(running) { start = SDL_GetTicks(); this->HandleEvents(); this->UpdateGame(); this->Render(); end = SDL_GetTicks(); if(1000/FPS > end - start) { SDL_Delay(1000/FPS - (end - start)); } } } void game::HandleEvents() { while(SDL_PollEvent(&event)) { switch(event.type) { case SDL_QUIT: running = false; break; case SDL_KEYDOWN: keys[event.key.keysym.sym] = true; break; case SDL_KEYUP: keys[event.key.keysym.sym] = false; break; } } } void game::UpdateGame() { Player->SetXvel(0); Player->SetYvel(0); if(keys[SDLK_a]){ coord.x-=vel; BackgroundBox.x-=vel; Player->SetXvel(-3); if(BackgroundBox.x <= 0) { BackgroundBox.x = Background->w - SCREEN_WIDTH; } } else if(keys[SDLK_d]){ coord.x+=vel; BackgroundBox.x+=vel; Player->SetXvel(3); if(BackgroundBox.x >= Background->w - SCREEN_WIDTH) { BackgroundBox.x = 0; } } if(keys[SDLK_w]){ Player->SetYvel(-3); }else if(keys[SDLK_s]){ Player->SetYvel(3); } else if(keys[SDLK_ESCAPE]){ running = false; }else if(keys[SDLK_F5]){ fullscreen = (!fullscreen); if(fullscreen) { screen = SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,SDL_HWSURFACE|SDL_DOUBLEBUF|SDL_FULLSCREEN); }else{ screen = SDL_SetVideoMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP,SDL_HWSURFACE|SDL_DOUBLEBUF); } } Player->MovePlayer(); } void game::Render() { SDL_BlitSurface(Background,&BackgroundBox,screen,NULL); this->BlitMap(); Player->Blit(screen); SDL_Flip(screen); }

Här är själva player klassen och jag anser att de flesta delarna i den berör hur spelaren ska röra sig och kollision på ett eller annat sätt så jag skickar med hela.

#include "player.h" player::player(void) { image = Load_Image("Player.png"); SDL_SetColorKey(image,SDL_SRCCOLORKEY,SDL_MapRGB(image->format,200,0,200)); box.w = image->w; box.h = image->h; box.x = SCREEN_WIDTH/2 - box.w/2; box.y = SCREEN_HEIGHT/2; Ground = false; } void player::SetXvel(int vel) { Xvel = vel; } void player::SetYvel(int vel) { Yvel = vel; } void player::MovePlayer() { box.x += Xvel; box.y += Yvel; int start = (coord.x - coord.x % TILE_SIZE)/TILE_SIZE; if(start < 0){start = 0;} int end = ((coord.x + coord.w - coord.x % TILE_SIZE)/TILE_SIZE + 1); if(end > map[0].size()){end = map[0].size();} for(int j = 0; j != map.size();j++) { for(int k = start; k != end; k++) { if(map[j][k] == 0) { continue; } SDL_Rect DestRect = {k * TILE_SIZE - coord.x,j*TILE_SIZE,TILE_SIZE,TILE_SIZE}; if(CheckCollision(box,DestRect)) { if(box.x+box.w >= DestRect.x) { box.x-=Xvel; } else if(box.x <= DestRect.x + DestRect.w) { box.x-=Xvel; } if(box.y+box.h >= DestRect.y) { box.y-=Yvel; } else if(box.y <= DestRect.y + DestRect.h) { box.y-=Yvel; } } } } } void player::CurrentMap(vector<vector<int> > Map) { map = Map; } void player::Blit(SDL_Surface * screen) { SDL_BlitSurface(image,NULL,screen,&box); } player::~player(void) { SDL_FreeSurface(image); }

Visa signatur

| i5 2500k | h100 | Evga 580 | Fractal Design arc | Asrock P67 Fatal1ty | Hx1050w | 24" BenQ | 16GB Vengeance Ram | Razer DeathAdder | Razer Carcharias | Razer Arctosa |

Permalänk
Medlem
Skrivet av stoffe1100:

bool base::CheckCollision(SDL_Rect r1,SDL_Rect r2) { if(r1.x >= r2.x+r2.w){ return false; } else if(r1.y >= r2.y+r2.h){ return false; } else if(r1.x+r1.w <= r2.x){ return false; } else if(r1.y+r1.h <= r2.y){ return false; }else{ return true; } }

void player::MovePlayer() { box.x += Xvel; box.y += Yvel; int start = (coord.x - coord.x % TILE_SIZE)/TILE_SIZE; if(start < 0){start = 0;} int end = ((coord.x + coord.w - coord.x % TILE_SIZE)/TILE_SIZE + 1); if(end > map[0].size()){end = map[0].size();} for(int j = 0; j != map.size();j++) { for(int k = start; k != end; k++) { if(map[j][k] == 0) { continue; } SDL_Rect DestRect = {k * TILE_SIZE - coord.x,j*TILE_SIZE,TILE_SIZE,TILE_SIZE}; if(CheckCollision(box,DestRect)) { if(box.x+box.w >= DestRect.x) { box.x-=Xvel; } else if(box.x <= DestRect.x + DestRect.w) { box.x-=Xvel; } if(box.y+box.h >= DestRect.y) { box.y-=Yvel; } else if(box.y <= DestRect.y + DestRect.h) { box.y-=Yvel; } } } } }

Nu var det länge sedan jag programmerade, men checkar du inte collision 2 gånger i player men på olika sätt? nu vet jag inte helt vad för fel du får med din collision, men kan vara värt att kolla på.

Permalänk
Skrivet av Misona:

Nu var det länge sedan jag programmerade, men checkar du inte collision 2 gånger i player men på olika sätt? nu vet jag inte helt vad för fel du får med din collision, men kan vara värt att kolla på.

Vad jag gör är att jag kollar först om det är någon kollision överhuvudtaget. Sedan kollar jag vilken sida den skedde på och flyttar tillbaka efter det.

Visa signatur

| i5 2500k | h100 | Evga 580 | Fractal Design arc | Asrock P67 Fatal1ty | Hx1050w | 24" BenQ | 16GB Vengeance Ram | Razer DeathAdder | Razer Carcharias | Razer Arctosa |