2D game with collision detection, and I need help with how to resolve a collision

by Aquaphor   Last Updated September 11, 2019 08:13 AM - source

At the moment I have built a custom Vector2 class and have a character object that has an acceleration vector (modified by vector forces), a velocity, and a position as well as bounding boxes for every entity within the scene.

Right now my physics works quite well and the character falls and moves with gravity and player input and is able to detect when it collides with another rectangle bounding box shown here:

`````` void
PhysicsEngine::TimeStepProcess(float deltaTime,
Entity* character, std::vector<Walls*> walls,
double screenWidth, double screenHeight,
int timeStep)
{
double processedDeltaTime = deltaTime / timeStep;

//Process entire physics engine multiple times per step with
//a smaller deltaTime for more accuracy
for (int i = 0; i < timeStep; ++i) {
//Add forces back per frame
ComputeForceAndTorque(character);
//ApplyForce(character, gravity);
ApplyForce(character, character->GetForce());

//Calculate and resolve collisions
ResolveCollisions(character, walls, processedDeltaTime);

//Set angular acceleration
angularAcceleration = character->GetTorque() / character->GetIntertia();

//Add Velocity per frame for linear and angular
Vector2::ScaleMult(*character->GetVelocity(), *linearAcceleration, processedDeltaTime, Vector2::ADDITON);
*character->GetAngularVelocity() += angularAcceleration * processedDeltaTime;

//Add displacement per frame for linear and angular
Vector2::ScaleMult(*character->GetPos(), *character->GetVelocity(), processedDeltaTime, Vector2::ADDITON);
*character->GetAngle() += *character->GetAngularVelocity() * processedDeltaTime;

CalculateFriction(character, processedDeltaTime);

//Clear forces per frame
Vector2::ScaleMult(*linearAcceleration, *linearAcceleration, 0, Vector2::EQUAL);
}

//Log
LogCurrent(character);
}
``````

With the collision being detected quite accurately here:

``````void
PhysicsEngine::ResolveCollisions(Entity* character, std::vector<Walls*> walls, double deltaTime)
{
double minDistanceFromObject = 1; //pixels

//Iterate through all walls
vector<Walls*>::iterator wallIter;
for (wallIter = walls.begin(); wallIter != walls.end(); ++wallIter) {
if (character->GetCollisionBox()->CheckCollision((*wallIter)->GetCollisionBox())) {
//Resolve collision
}
}
}

//Does this rectangle contain other rectangle
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;
}
``````

But my vector math is quite shaky and I have no idea how to resolve these collisions and stop the character moving through surfaces. I want to be able to walk along floors and collide with any surfaces realistically. I have now been trying to accomplish this for over a week and have gone through at least 20-30 posts, comments, articles and questions about this and cannot understand how it works or how to implement it.

Can someone please help me with the coding aspect of this?

Tags :

Collision avoidance not only AI wrong

Updated August 02, 2017 13:13 PM

Collision decetion and solution

Updated August 13, 2019 15:13 PM