AABB Collision 使实际精灵的大小加倍
AABB Collision doubles the size of actual sprite
所以,在我决定使精灵在 Y 轴上比在 X 轴上更大之前,我使用这段代码来处理 AABB 碰撞。我试图修复代码,但现在它只是使碰撞大小比实际精灵大小增加了一倍。前任。精灵 1 iVec2(50,100) 的大小,精灵 2 iVec2(30,30) 的大小。
CollisionData Collision::DoCollision(GameObject &object1, GameObject &object2) {
iVec2 center(object1.Position.x + object1.Size.x / 2, object1.Position.y + object1.Size.y / 2);
iVec2 half_extents(object2.Size.x / 2, object2.Size.y / 2);
iVec2 aabb_center(object2.Position.x + half_extents.x, object2.Position.y + half_extents.y);
iVec2 difference = center - aabb_center;
iVec2 difference2 = center - aabb_center;
iVec2 clamped = glm::clamp(difference, -half_extents, half_extents);
iVec2 clamped2 = glm::clamp(difference2, -iVec2(object1.Size.x / 2, object1.Size.y / 2), iVec2(object1.Size.x / 2, object1.Size.y / 2));
iVec2 closest = aabb_center + clamped;
iVec2 closest2 = aabb_center + clamped2;
difference = closest - center;
difference2 = closest2 - center;
if (glm::length(difference) <= object1.Size.x / 2 || glm::length(difference2) <= object1.Size.y / 2)
return std::make_tuple(GL_TRUE, VectorDirection(difference), difference);
else return std::make_tuple(GL_FALSE, UP, glm::vec2(0, 0));
}
我建议做一个简单的重叠检查。
如果 2 个片段重叠,可以通过以下方式检查:
overlap = (x1+w1) > x2 && (x2+w2) > x1
其中 x1
是第一段的起点,w1
是第一段的宽度。 x2
是开始,w2
是第 2n 段的宽度。
如果你想检查轴对齐的边界框是否重叠,那么你必须对两个维度进行测试
bool overlap =
(object1.Position.x + object1.Size.x) > object2.Position.x) &&
(object2.Position.x + object2.Size.x) > object1.Position.x) &&
(object1.Position.y + object1.Size.y) > object2.Position.y) &&
(object2.Position.y + object2.Size.y) > object1.Position.y);
如果你想知道重叠的数量,你必须计算盒子的中心点并比较中心点的距离,到盒子的一半大小:
CollisionData Collision::DoCollision(GameObject &object1, GameObject &object2) {
iVec2 center1(
object1.Position.x + object1.Size.x / 2,
object1.Position.y + object1.Size.y / 2);
iVec2 center2(
object2.Position.x + object2.Size.x / 2,
object2.Position.y + object2.Size.y / 2);
iVec2 dist = center1 - center2;
iVec2 size((object1.Size.x + object2.Size.x) / 2, (object1.Size.y + object2.Size.y) / 2);
iVec2 difference = size - iVec2(abs(dist.x), abs(dist.y));
bool overlap = difference.x > 0 && difference.y > 0;
if ( overlap )
{
iVec2 min1 = object1.Position;
iVec2 min2 = object2.Position;
iVec2 max1 = object1.Position + object1.Size;
iVec2 max2 = object2.Position + object2.Size;
bool horizontal = difference.x > difference.y;
if ( min2.x > min1.x && max1.x < max2.x || min1.x > min2.x && max2.x < max1.x )
horizontal = false;
else if ( min2.y > min1.y && max1.y < max2.y || min1.y > min2.y && max2.y < max1.y )
horizontal = true;
return std::make_tuple(
GL_TRUE, !horizontal ? (dist.x < 0 ? LEFT: RIGHT) : (dist.y < 0 ? UP : DOWN), difference );
}
return std::make_tuple(GL_FALSE, UP, glm::vec2(0, 0));
}
所以,在我决定使精灵在 Y 轴上比在 X 轴上更大之前,我使用这段代码来处理 AABB 碰撞。我试图修复代码,但现在它只是使碰撞大小比实际精灵大小增加了一倍。前任。精灵 1 iVec2(50,100) 的大小,精灵 2 iVec2(30,30) 的大小。
CollisionData Collision::DoCollision(GameObject &object1, GameObject &object2) {
iVec2 center(object1.Position.x + object1.Size.x / 2, object1.Position.y + object1.Size.y / 2);
iVec2 half_extents(object2.Size.x / 2, object2.Size.y / 2);
iVec2 aabb_center(object2.Position.x + half_extents.x, object2.Position.y + half_extents.y);
iVec2 difference = center - aabb_center;
iVec2 difference2 = center - aabb_center;
iVec2 clamped = glm::clamp(difference, -half_extents, half_extents);
iVec2 clamped2 = glm::clamp(difference2, -iVec2(object1.Size.x / 2, object1.Size.y / 2), iVec2(object1.Size.x / 2, object1.Size.y / 2));
iVec2 closest = aabb_center + clamped;
iVec2 closest2 = aabb_center + clamped2;
difference = closest - center;
difference2 = closest2 - center;
if (glm::length(difference) <= object1.Size.x / 2 || glm::length(difference2) <= object1.Size.y / 2)
return std::make_tuple(GL_TRUE, VectorDirection(difference), difference);
else return std::make_tuple(GL_FALSE, UP, glm::vec2(0, 0));
}
我建议做一个简单的重叠检查。
如果 2 个片段重叠,可以通过以下方式检查:
overlap = (x1+w1) > x2 && (x2+w2) > x1
其中 x1
是第一段的起点,w1
是第一段的宽度。 x2
是开始,w2
是第 2n 段的宽度。
如果你想检查轴对齐的边界框是否重叠,那么你必须对两个维度进行测试
bool overlap =
(object1.Position.x + object1.Size.x) > object2.Position.x) &&
(object2.Position.x + object2.Size.x) > object1.Position.x) &&
(object1.Position.y + object1.Size.y) > object2.Position.y) &&
(object2.Position.y + object2.Size.y) > object1.Position.y);
如果你想知道重叠的数量,你必须计算盒子的中心点并比较中心点的距离,到盒子的一半大小:
CollisionData Collision::DoCollision(GameObject &object1, GameObject &object2) {
iVec2 center1(
object1.Position.x + object1.Size.x / 2,
object1.Position.y + object1.Size.y / 2);
iVec2 center2(
object2.Position.x + object2.Size.x / 2,
object2.Position.y + object2.Size.y / 2);
iVec2 dist = center1 - center2;
iVec2 size((object1.Size.x + object2.Size.x) / 2, (object1.Size.y + object2.Size.y) / 2);
iVec2 difference = size - iVec2(abs(dist.x), abs(dist.y));
bool overlap = difference.x > 0 && difference.y > 0;
if ( overlap )
{
iVec2 min1 = object1.Position;
iVec2 min2 = object2.Position;
iVec2 max1 = object1.Position + object1.Size;
iVec2 max2 = object2.Position + object2.Size;
bool horizontal = difference.x > difference.y;
if ( min2.x > min1.x && max1.x < max2.x || min1.x > min2.x && max2.x < max1.x )
horizontal = false;
else if ( min2.y > min1.y && max1.y < max2.y || min1.y > min2.y && max2.y < max1.y )
horizontal = true;
return std::make_tuple(
GL_TRUE, !horizontal ? (dist.x < 0 ? LEFT: RIGHT) : (dist.y < 0 ? UP : DOWN), difference );
}
return std::make_tuple(GL_FALSE, UP, glm::vec2(0, 0));
}