Hello, I am quite new to these forums but I have been trying for over a week and a half to find a working, optimized physics based collision detection system for a 2D plat-former game I am making right now in SDL. Everything anyone has suggested has not worked and is not what I am looking for.
At the moment I have created a custom bounding box (yes I know there is SDL_Rect) that has a custom Vector2 point, a width and a height and checking if two bounding boxes overlap. This is kindof working however I need a way to see the difference between hitting a wall or the floor/roof or at least be able to correctly collide off of a given surface.
I need a way to physically interact with surfaces so that I can walk along the floor, not walk through walls and jump around with physically based calculations. (Walls/Floors/Roofs are all the same class with the same data)
My current code for detecting if I hit a wall at all is:
//Iterate through all walls
vector<Walls*>::iterator wallIter;
for (wallIter = walls.begin(); wallIter != walls.end(); ++wallIter) {
//If entity went too far to the left or right or has collided with wall
if ((character->GetCollisionBox()->X() < 0) ||
(character->GetCollisionBox()->X() + character->GetCollisionBox()->W() > screenWidth) ||
(character->GetCollisionBox()->CheckCollision((*wallIter)->GetCollisionBox()))) {
//Move back
character->GetCollisionBox()->X() -= xVelocity * deltaTime;
}
//If entity went too far up or down or has collided with the wall
if ((character->GetCollisionBox()->Y() < 0) ||
(character->GetCollisionBox()->Y() + character->GetCollisionBox()->H() > screenHeight) ||
(character->GetCollisionBox()->CheckCollision((*wallIter)->GetCollisionBox()))) {
//Move back
character->GetCollisionBox()->Y() -= yVelocity * deltaTime;
}
}
bool
Rectangle::CheckCollision(Rectangle* other) {
//The sides of the rectangles
int leftA, leftB;
int rightA, rightB;
int topA, topB;
int bottomA, bottomB;
//Calculate the sides of rectangle A
leftA = static_cast<int>(this->X());
rightA = static_cast<int>(this->X() + this->W());
topA = static_cast<int>(this->Y());
bottomA = static_cast<int>(this->Y() + this->H());
//Calculate the sides of rectangle B
leftB = static_cast<int>(other->X());
rightB = static_cast<int>(other->X() + other->W());
topB = static_cast<int>(other->Y());
bottomB = static_cast<int>(other->Y() + other->H());
//If any of the sides from rectangle A are outside of B
//Then there is no possible way the two boxes are colliding
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 of the primary rectangle are outside of other
//Then there must be a collision of some sort
return true;
}
However this has the issue that the character canât tell if heâs hitting a wall or the floor/roof meaning as soon as he collides with anything, he can no longer jump, or move left and right. This same issue would occur if heâs colliding with the walls. Also, thereâs a weird issue with movement where the velocity will keep ticking up and at a certain point the velocity gets so high that the collision detection fails and the character flys off into the thousands of X, Y.
And my current movement code which I canât seem to get working realistically is bellow. The current code kindof works and makes the character realistically drop with gravity, move with velocity and friction and acceleration, but thereâs a lot of issues with jumping and moving left and right.
void
PhysicsEngine::ProcessEntity(float deltaTime,
Entity* character, vector<Walls*> walls,
double screenWidth, double screenHeight)
{
//Set initial velocities
//xVelocity = character->GetXVelocity();
//yVelocity = character->GetYVelocity();
//Get Accelerations
xAccel = character->GetMaxMovementSpeed() / deltaTime;
xAccel *= character->GetMovementState(); //Change in acceleration when player moves
yAccel = gravity / deltaTime; //Constant acceleration downwards due to gravity
//Set velocity
xVelocity += xAccel - mx_d_currentFrictionCoe * xVelocity;
yVelocity += yAccel * deltaTime;
//Displace the entity left or right
character->GetCollisionBox()->Y() += yVelocity * deltaTime;
character->GetCollisionBox()->X() += xVelocity * deltaTime;
Can someone please help me with this. I want to be able to walk along the surface of any floor positioned at any height within the window, bump my head and fall down along any roof within the window, and collide with walls left and right of the character correctly and be able to move away from the wall but not walk through it.