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;
//Add friction
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) {
//Broad
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?