I am able to get collision detection (CD) into my game but... what do I do with it? Do I push the player back to the last location? Something else?
I am programming the game in C++ using the Irrlicht 3D rendering engine, everything is blocks, because the game is a voxel game so there is no need to throw different techiniques of doing CD. All I can find are different methods of doing CD but nothing about what to actually do when I detect collision. The code I use is the following:
// ^^^ all character movement is redundant for this post but is is above this comment
std::vector<scene::ISceneNode *> objects; // A vector containing all of the different blocks
objects.push_back(block); // I add the objects in an array, for later access and easability
// after all character movement, check if player rect intersects with any block
for(int i = 0; i < objects.size(); i++) { // go through all the block objects
if(player->getTransformedBoundingBox().intersectsWithBox(objects[i]->getTransformedBoundingBox())) { // if they intersect, do the following
falling = false;
can_jump = true;
walk = false;
player->setPosition(last_pos); // makes the character stuck, since it always collides with floor
break;
} else {
falling = true;
can_jump = false;
walk = true;
}
}
I have tried to create a variable BEFORE ALL MOVEMENT in a frame called last_pos = player->getPosition();
and then if there is a collision then I do player->setPosition(last_pos);
but the issue is that I constantly collide with the floor, therefore I never move since I always go back to last position because of the collision. So what should I do?
Edit: the way I understand it: one way to do collision detection is to get the coordinate of EVERY corner of every voxel block I have in the world and check if that corner is in between any one of the corners of my character? Is that waaaayy off or does someone has an actual tutorial / concrete code that actually deals with 3D collision and not just tutorials and theory?
Edit 2: Each block the player can collide with is exactly 10 units long. I crafted up this piece of code to check if ANY corder of ANY block is colliding with my character who is 10x20x10 (x, y, z) where y is heigh.
bool axisCollision(vector3df object1, vector3df object2, int axis) {
int pos1_x = object1.X;
int pos1_y = object1.Y;
int pos1_z = object1.Z;
int pos2_x = object2.X;
int pos2_y = object2.Y;
int pos2_z = object2.Z;
// x, y, z
if(pos2_x < pos1_x + 10 && pos2_x > pos1_x &&
pos2_y < pos1_y + 20 && pos2_y > pos1_y &&
pos2_z < pos1_z + 10 && pos2_z > pos1_z) {
std::cout << "collision!\n";
return false;
}
// x, y, z + 10
if(pos2_x < pos1_x + 10 && pos2_x > pos1_x &&
pos2_y < pos1_y + 20 && pos2_y > pos1_y &&
pos2_z + 10 < pos1_z + 10 && pos2_z + 10 > pos1_z) {
std::cout << "collision!\n";
return false;
}
// x, y + 10, z + 10
if(pos2_x < pos1_x + 10 && pos2_x > pos1_x &&
pos2_y + 10 < pos1_y + 20 && pos2_y + 10 > pos1_y &&
pos2_z + 10 < pos1_z + 10 && pos2_z + 10 > pos1_z) {
std::cout << "collision!\n";
return false;
}
// x, y + 10, z
if(pos2_x < pos1_x + 10 && pos2_x > pos1_x &&
pos2_y + 10 < pos1_y + 20 && pos2_y > pos1_y &&
pos2_z < pos1_z + 10 && pos2_z > pos1_z) {
std::cout << "collision!\n";
return false;
}
// x + 10, y, z
if(pos2_x + 10 < pos1_x + 10 && pos2_x + 10 > pos1_x &&
pos2_y < pos1_y + 20 && pos2_y > pos1_y &&
pos2_z < pos1_z + 10 && pos2_z > pos1_z) {
std::cout << "collision!\n";
return false;
}
// x + 10, y, z + 10
if(pos2_x + 10 < pos1_x + 10 && pos2_x + 10 > pos1_x &&
pos2_y < pos1_y + 20 && pos2_y > pos1_y &&
pos2_z + 10 < pos1_z + 10 && pos2_z + 10 > pos1_z) {
std::cout << "collision!\n";
return false;
}
// x + 10, y + 10, z
if(pos2_x + 10 < pos1_x + 10 && pos2_x + 10 > pos1_x &&
pos2_y + 10 < pos1_y + 20 && pos2_y + 10 > pos1_y &&
pos2_z < pos1_z + 10 && pos2_z > pos1_z) {
std::cout << "collision!\n";
return false;
}
// x + 10, y + 10, z + 10
if(pos2_x + 10 < pos1_x + 10 && pos2_x + 10 > pos1_x &&
pos2_y + 10 < pos1_y + 20 && pos2_y + 10 > pos1_y &&
pos2_z + 10 < pos1_z + 10 && pos2_z + 10 > pos1_z) {
std::cout << "collision!\n";
return false;
}
return true;
}
The function takes in the players coordination and every single coordination for each block in the world. It then checks if ANY corner of ANY block is inside the character, then it will return false, which results in the player not executing the movement. My issue with this code snippet is that... well... it never returns false! It never detects wall collision, whether I walk inside a wall or on a floor does not matter. Any ideas why?