SDL Kollision
-
Hi,
ich möchte gern ein 2D Super Mario Game programmieren.
So nun habe ich probleme mit der Kollision, es gibt ja einige Tutorials mit verschiedenen Lösungsmöglichkeiten
wie z.B.bool check_collision( SDL_Rect A, SDL_Rect B ) { //The sides of the rectangles int leftA, leftB; int rightA, rightB; int topA, topB; int bottomA, bottomB; //Calculate the sides of rect A leftA = A.x; rightA = A.x + A.w; topA = A.y; bottomA = A.y + A.h; //Calculate the sides of rect B leftB = B.x; rightB = B.x + B.w; topB = B.y; bottomB = B.y + B.h; //If any of the sides from A are outside of B if( bottomA <= topB ) { return false; } if( topA >= bottomB ) { return false; } if( rightA <= leftB ) { return false; } if( leftA >= rightB ) { return false; } //If none of the sides from A are outside B return true; }Das funktioniert soweit ganz gut, er gibt True heraus wenn eine Kollision vorliegt.
Das Problem ist nur ich muss wissen an welche Stelle er kollidiert ist...
Da es ja ein Unterschied ist ob Mario an den Seiten einer Hitbox springt, oben drauf steht oder von unten die
Hitbox aktiviert.
So deshalb hab ich mir ne eigene Funktion geschriebenint Collision(SDL_Rect A, SDL_Rect B) { ////////// BOX A ////////////////////////////////////////////////// int ALinksObenX = A.x; int ALinksObenY = A.y; int ALinksMitteX = A.x; int ALinksMitteY = A.h / 2 + A.y; int ALinksUntenX = A.x; int ALinksUntenY = A.y + A.h - 5; int AObenMitteX = A.x + ( A.w / 2) - 5; int AObenMitteY = A.y; int ARechtsObenX = A.x + A.w - 5; int ARechtsObenY = A.y; int ARechtsMitteX = A.x + A.w - 5; int ARechtsMitteY = A.h / 2 + A.y; int ARechtsUntenX = A.x + A.w - 5; int ARechtsUntenY = A.y + A.h - 5; int AUntenMitteX = A.x + ( A.w / 2) - 5; int AUntenMitteY = A.y + A.h - 5; ////////// BOX B ////////////////////////////////////////////////// int BLinksObenX = B.x; int BLinksObenY = B.y; int BLinksMitteX = B.x; int BLinksMitteY = B.h / 2 + B.y; int BLinksUntenX = B.x; int BLinksUntenY = B.y + B.h - 5; int BObenMitteX = B.x + ( B.w / 2) - 5; int BObenMitteY = B.y; int BRechtsObenX = B.x + B.w - 5; int BRechtsObenY = B.y; int BRechtsMitteX = B.x + B.w - 5; int BRechtsMitteY = B.h / 2 + B.y; int BRechtsUntenX = B.x + B.w - 5; int BRechtsUntenY = B.y + B.h - 5; int BUntenMitteX = B.x + ( B.w / 2) - 5; int BUntenMitteY = B.y + B.h - 5; if( velox > 0 && ARechtsObenX + 8 > BLinksObenX && ARechtsUntenY > BLinksObenY && ARechtsObenY < BLinksUntenY && ARechtsMitteX < BRechtsMitteX) { } if( velox < 0 && ALinksObenX - 8 < BRechtsObenX && ALinksUntenY > BRechtsObenY && ALinksObenY < BRechtsUntenY && ALinksMitteX > BLinksMitteX) { } if( veloy > 0 && ARechtsUntenY + 5 > BObenMitteY && ARechtsMitteX > BLinksMitteX && ALinksMitteX < BRechtsMitteX && AUntenMitteY < BRechtsMitteY) { } if( veloy < 0 && ARechtsObenY - 5 < BUntenMitteY && ARechtsMitteX > BLinksMitteX && ALinksMitteX < BRechtsMitteX && AObenMitteY > BRechtsMitteY) { } return 0; } //velox Bewegung in X Richtung //veloy Bewegung in Y RichtungDie funktioniert wiederrum nicht so gut.
Sie basiert darauf das Mario ein Viereck ist und die Hitbox auch.
Das würde dann so aussehen
http://37076.no-ip.org/bild1.jpgWeiteres Problem ist das sich Mario x+=6 fortbewegt und nicht in einer schritten x+=1 (würde sonst nicht zu der Animation von Mario passen)
Wäre echt cool von euch wenn ihr mir helfen könntet mit nen neuen Denkansatz oder Funktion oder oder oder

Vielen Dank
Goodies
-
Goodies schrieb:
Weiteres Problem ist das sich Mario x+=6 fortbewegt und nicht in einer schritten x+=1 (würde sonst nicht zu der Animation von Mario passen)
Dir ist hoffentlich klar, daß sich "Mario" dadurch auf langsamen Rechnern langsam und auf schnellen Rechnern schneller bewegt.
Die Bewegung solltest du über Timer regeln, damit die Geschw. überall gleich bleibt.Allgemein: Sieh Dir zB mal den Code von "Supertux" an. Dort wird u.a. auch eine Kollision von oben behandelt.
-
danke
ich hab eine Framebremse drin was ich übern Timer mache..
ok ich werd mir mal Supertux anschauenGoodies
-
Könnte folgendes Konstrukt nicht reichen?
bool is_collision = 0; /* ** Hier wird getestet und festgestellt, daß es eine Kollision gab */ is_collision = 1; if(is_collision) { if(player.y_pos<monster.y_pos) // evtl player.y_pos-offset um sicherzustellen, { // dass er nicht schräg von der seite kommt // Es gab eine Kollision und die y-Koordinate des Spielers // ist kleiner als die des Monsters, also muß der Spieler // "über" dem Monster sein } }Edit:
oder kürzer:int CollisionDir(Tile t_1, Tile t_2) { /* es gab eine kollision */ t_1.y_pos<t_2.y_pos ? return 1 : return 0; // von oben t_1.y_pos>t_2.y_pos ? return 2 : return 0; // von unten }
-
Hmm das ist garnicht schlecht..
Ich werds mal ausprobieren und ich glaube das wird auch ganz gut funktionieren..
Danke
