I need some help with precise collision in my game. I already got code working, but somehow it glitches up when I land on the ground. First, here is the collision code:
bool check_collision( std::vector<SDL_Rect> &A, std::vector<SDL_Rect> &B ) { //The sides of the rectangles int leftA, leftB; int rightA, rightB; int topA, topB; int bottomA, bottomB; //Go through the A boxes for( int Abox = 0; Abox < A.size(); Abox++ ) { //Calculate the sides of rect A leftA = A[ Abox ].x; rightA = A[ Abox ].x + A[ Abox ].w; topA = A[ Abox ].y; bottomA = A[ Abox ].y + A[ Abox ].h; //Go through the B boxes for( int Bbox = 0; Bbox < B.size(); Bbox++ ) { //Calculate the sides of rect B leftB = B[ Bbox ].x; rightB = B[ Bbox ].x + B[ Bbox ].w; topB = B[ Bbox ].y; bottomB = B[ Bbox ].y + B[ Bbox ].h; //If no sides from A are outside of B if( ( ( bottomA <= topB ) || ( topA >= bottomB ) || ( rightA <= leftB ) || ( leftA >= rightB ) ) == false ) { //cout << "Touching" << endl; //A collision is detected return true; } } } //If neither set of collision boxes touched return false; }
Here is the movement code of my player:
void player::move( std::vector<SDL_Rect> &rects ) { //Move the player left or right x += xVel; //Move the collision boxes shift_boxes(); //If the player went too far to the left or right or has collided if( check_collision( box, rects ) ) { //Move back x -= xVel; shift_boxes(); } yNew = y + yVel; while ( y != yNew && yVel != 0 ) { if (yVel >= 0) { y ++; cout << "y++;" << endl; } else { y --; cout << "y--;" << endl; } shift_boxes(); // Check collisions at pixel level if( check_collision( box, rects ) ) { if( falling == true && ( on_ground && jumping ) == false ) { cout << "collision with ground" << endl; on_ground = true; falling = false; } if( jumping == true && ( on_ground && falling ) == false ) { cout << "collision with ceiling" << endl; yVel = 0; air_time = air_climax; } if( on_ground == true && ( jumping && falling ) == false ) { cout << "still on the ground" << endl; y -= yVel; } shift_boxes(); } else { if ( jumping == false ) { cout << "nothing below you so falling" << endl; falling = true; on_ground = false; } } } }Here is the air code of my player (which decides when to fall, after jumping):
void player::air() { if( jumping == true && ( on_ground && falling ) == false ) { //if( yVel > 0 ){ yVel = 0; } //if( yVel > -yspeed ){ yVel--; } yVel = -yspeed; if( air_time < air_climax ) { air_time++; } else { //when air_time is greater than or equal to air_climax yVel = 0; falling = true; jumping = false; } } if( jumping == false ){ air_time = 0; } if( falling == true && ( on_ground && jumping ) == false ) { //if( yVel < yspeed ){ yVel++; } yVel = yspeed; } }You will see I have commented out code in the player::air code, that is because I want to make this easier for you and for me right now. With my current code in player::movement, the part with the yNew variable and all that, I see that it collides spot on with the cieling (in some older code I had, which had y+=yVel instead of yNew = y + yVel and didn't have the "while ( y != yNew && yVel != 0 )" as well as the "if (yVel >= 0)" code in it, the player jumped at a contant rate and his head would stick into the cieling a little bit before the falling occured) and then falls. While it is jumping, it will print the "y--;" message to console, while it is falling it will do "y++;". When you are falling and land on the ground, the game freezes and prints about 6 or 7 "y++;" at an alarming rate to every "collision with ground" and once in awhile "nothing below you so falling" pops up.
I have no idea what needs to be fixed, but that is where the code I need help with is. If you think you need anything else to help me, just ask. Thanks