C# AABB碰撞的平台跳跃问题

C# AABB碰撞的平台跳跃问题,c#,collision-detection,physics,aabb,C#,Collision Detection,Physics,Aabb,当我的AABB物理引擎解析一个交点时,它通过找到穿透较小的轴来解析,然后“推出”该轴上的实体 考虑到“向左跳跃”的例子: 如果velocityX大于velocityY,AABB将实体推出Y轴,有效地阻止跳跃(结果:玩家在空中停止) 如果velocityX小于velocitY(图中未显示),程序将按预期工作,因为AABB将实体推出X轴 我怎样才能解决这个问题 源代码: public void Update() { 位置+=速度; 速度+=世界重力; List-toCheck=World.Spa

当我的AABB物理引擎解析一个交点时,它通过找到穿透较小的轴来解析,然后“推出”该轴上的实体

考虑到“向左跳跃”的例子:

  • 如果velocityX大于velocityY,AABB将实体推出Y轴,有效地阻止跳跃(结果:玩家在空中停止)
  • 如果velocityX小于velocitY(图中未显示),程序将按预期工作,因为AABB将实体推出X轴
我怎样才能解决这个问题

源代码:
public void Update()
{
位置+=速度;
速度+=世界重力;
List-toCheck=World.SpatialHash.GetNearbyItems(这个);
for(int i=0;i=body.CornerMin.X&&Position.X mBody2.CornerMax.X)
返回false;
if(mBody1.CornerMax.YmBody2.CornerMax.Y)
返回false;
返回true;
}
公共静态bool AABBIsCollidingTop(SSSPBody mBody1、SSSPBody mBody2)
{
如果(mBody1.CornerMax.XmBody2.CornerMax.X)
返回false;
if(mBody1.CornerMax.YmBody2.CornerMax.Y)
返回false;
if(mBody1.CornerMax.Y==mBody2.CornerMin.Y)
返回true;
返回false;
}
公共静态向量2 AABBGetOverlapVector(浮点mLeft、浮点mRight、浮点mTop、浮点MBOTOM)
{
Vector2结果=新的Vector2(0,0);
如果((mLeft>0 | | mRight<0)| |(mTop>0 | | mBottom<0))
返回结果;
if(数学绝对值(mLeft)
很难阅读其他人的代码,但我认为这是一种可能的(纯粹脑力激荡的)解决方法,尽管我当然无法测试它:

  • 在碰撞检测发生之前,将玩家速度保存到某个临时变量
  • 完成碰撞响应后,检查玩家的X或Y位置是否已纠正
  • 如果X位置已经改变,手动重置(作为一种“安全重置”)玩家的Y速度为他在响应之前的速度

  • 顺便问一下,当你的玩家跳到屋顶上时,你当前的代码会发生什么情况?

    我也有同样的问题。即使是微软platformer starterskit似乎也有这个缺陷


    到目前为止,我找到的解决方案是使用多重采样(argh)或使用对象的移动方向:仅移动这两个对象之间的距离,在检测到碰撞时不再移动(并对每个轴执行此操作)我发现,一种可能的解决方法是根据玩家的速度对物体进行分类。

    你应该考虑在www. gAMDEV.STACKExchange。com上发表这篇文章。说,我现在正在研究代码,看看我能不能帮助你。改变速度不会解决任何问题,因为速度不受COL的影响。lision响应。响应只是改变玩家的位置,保持速度不变。当玩家撞到屋顶时,它会漂浮一段时间,然后再下来。这是有意的,因为当它撞到天花板时,我不会将速度设置为0。
    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;
        }