I'm currently writing a simple game engine and encountered an error while trying to resolve rectangular collisions. When an object moves diagonally and collides with a solid object I only correct it in the axis that would require less translation to resolve the collision. The problem with this is that when a diagonally moving object travels "over" a corner the smaller axis flips to the opposite axis before the two objects stop colliding and the non-solid object "teleports" to fix itself.
Here's a piece of the collision resolution method (c++):
/*
0: UP
1: UP RIGHT
2: RIGHT
3: DOWN RIGHT
4: DOWN
5: DOWN LEFT
6: LEFT
7: UP LEFT
*/
switch(lastDir){
case 0:
{
rect.y = (other->rect.y+other->rect.height)+fixed(0.0078125);
//0.007 is padding amount, fixed is fixed point number class due to hardware constraints, rect is rectangle with x, y, width, height
break;
}
case 1:
{
fPoint l1(rect.x, rect.y); //fPoint is Point using fixed
fPoint r1(rect.x+rect.width, rect.y+rect.height);
fPoint l2(other->rect.x, other->rect.y);
fPoint r2(other->rect.x+other->rect.width, other->rect.y+other->rect.height);
fixed distX = abs(min(r1.x, r2.x)- max(l1.x, l2.x));
fixed distY = abs(min(r1.y, r2.y) - max(l1.y, l2.y));
if(distX > distY){
//if y is shorter correct y
rect.y = (other->rect.y-rect.height)-fixed(0.0078125);
}
else if(distY > distX){
//if x is shorter correct x
rect.x = (other->rect.x-rect.width)-fixed(0.0078125);
}
break;
}
case 2:
{
rect.x = (other->rect.x-rect.width)-fixed(0.0078125);
break;
}
//continues for directions 3-7
}