当我的AABB物理引擎解析一个交叉点时,它通过找到穿透力较小的轴来实现,然后“推出”该轴上的实体。
考虑“向左跳跃”的例子:
我该如何解决这个问题?
public void Update()
{
Position += Velocity;
Velocity += World.Gravity;
List<SSSPBody> toCheck = World.SpatialHash.GetNearbyItems(this);
for (int i = 0; i < toCheck.Count; i++)
{
SSSPBody body = toCheck[i];
body.Test.Color = Color.White;
if (body != this && body.Static)
{
float left = (body.CornerMin.X - CornerMax.X);
float right = (body.CornerMax.X - CornerMin.X);
float top = (body.CornerMin.Y - CornerMax.Y);
float bottom = (body.CornerMax.Y - CornerMin.Y);
if (SSSPUtils.AABBIsOverlapping(this, body))
{
body.Test.Color = Color.Yellow;
Vector2 overlapVector = SSSPUtils.AABBGetOverlapVector(left, right, top, bottom);
Position += overlapVector;
}
if (SSSPUtils.AABBIsCollidingTop(this, body))
{
if ((Position.X >= body.CornerMin.X && Position.X <= body.CornerMax.X) &&
(Position.Y + Height/2f == body.Position.Y - body.Height/2f))
{
body.Test.Color = Color.Red;
Velocity = new Vector2(Velocity.X, 0);
}
}
}
}
}
public static bool AABBIsOverlapping(SSSPBody mBody1, SSSPBody mBody2)
{
if(mBody1.CornerMax.X <= mBody2.CornerMin.X || mBody1.CornerMin.X >= mBody2.CornerMax.X)
return false;
if (mBody1.CornerMax.Y <= mBody2.CornerMin.Y || mBody1.CornerMin.Y >= mBody2.CornerMax.Y)
return false;
return true;
}
public static bool AABBIsColliding(SSSPBody mBody1, SSSPBody mBody2)
{
if (mBody1.CornerMax.X < mBody2.CornerMin.X || mBody1.CornerMin.X > mBody2.CornerMax.X)
return false;
if (mBody1.CornerMax.Y < mBody2.CornerMin.Y || mBody1.CornerMin.Y > mBody2.CornerMax.Y)
return false;
return true;
}
public static bool AABBIsCollidingTop(SSSPBody mBody1, SSSPBody mBody2)
{
if (mBody1.CornerMax.X < mBody2.CornerMin.X || mBody1.CornerMin.X > mBody2.CornerMax.X)
return false;
if (mBody1.CornerMax.Y < mBody2.CornerMin.Y || mBody1.CornerMin.Y > mBody2.CornerMax.Y)
return false;
if(mBody1.CornerMax.Y == mBody2.CornerMin.Y)
return true;
return false;
}
public static Vector2 AABBGetOverlapVector(float mLeft, float mRight, float mTop, float mBottom)
{
Vector2 result = new Vector2(0, 0);
if ((mLeft > 0 || mRight < 0) || (mTop > 0 || mBottom < 0))
return result;
if (Math.Abs(mLeft) < mRight)
result.X = mLeft;
else
result.X = mRight;
if (Math.Abs(mTop) < mBottom)
result.Y = mTop;
else
result.Y = mBottom;
if (Math.Abs(result.X) < Math.Abs(result.Y))
result.Y = 0;
else
result.X = 0;
return result;
}
答案 0 :(得分:1)
很难读取其他人的代码,但我认为这是一种可能的(纯粹是头脑风暴的)解决方法,虽然我当然无法测试它:
顺便说一下,当你的玩家在跳跃时撞到屋顶时,你当前的代码会发生什么?
答案 1 :(得分:0)
我遇到了同样的问题。即使是微软的平台游戏初学者套件也似乎有这个错误。
我到目前为止找到的解决方案是使用多重采样(argh)或使用对象的移动方向:仅在检测到碰撞时移动这两个对象之间的距离而不再移动(并为每个轴执行此操作)
答案 2 :(得分:0)
我找到的一个可能的解决方案是在解析之前根据玩家的速度对对象进行排序。