首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AABB碰撞平台跳跃问题

AABB碰撞平台跳跃问题
EN

Stack Overflow用户
提问于 2011-06-20 19:58:30
回答 3查看 1.1K关注 0票数 5

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

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

如果

  • 大于velocityY,则AABB将实体推到Y轴上,从而有效地停止跳跃(结果:玩家在半空中停止)。如果velocityX小于velocitY (未在图中显示),则程序按预期工作,因为AABB将实体推到X轴上。

我该如何解决这个问题?

源代码:

代码语言:javascript
复制
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);

                    }
                }
            }               
        }
    }

代码语言:javascript
复制
    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;
    }
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-09-22 10:24:55

我发现的一个可能的解决方案是在根据播放器的速度进行解析之前对对象进行排序。

票数 0
EN

Stack Overflow用户

发布于 2011-06-20 21:03:08

很难阅读其他人的代码,但我认为这是一种可能的(纯粹的头脑风暴)解决办法,尽管我当然无法测试它:

在碰撞检测发生之前,将玩家的速度保存到某个临时的variable.

  • After,您已经完成了碰撞响应,如果X位置被更改,检查玩家的X或Y位置是否已被纠正,手动重置(作为一种“安全重置”),将玩家的Y速度恢复到响应前的速度。

顺便问一下,当你的玩家在跳跃时撞上屋顶时,你的当前代码会发生什么呢?

票数 1
EN

Stack Overflow用户

发布于 2011-08-07 17:48:10

我也有同样的问题。就连微软平台的创业小品似乎也有这个缺陷。

到目前为止,我发现的解决方案是要么使用多采样(argh),要么使用对象的移动方向:只移动这两个对象之间的距离,当检测到碰撞时不再进一步移动(并且对每个轴都这样做)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6416725

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档