N游戏教程 碰撞检测凸/凹

发布于 2024-11-16 10:33:54 字数 2104 浏览 4 评论 0原文

我正在遵循 N 游戏教程来处理我的一款游戏的碰撞检测,这种方法中不清楚的一件事是他们在本页上讨论分离轴定理,但如果您在实现(教程 A)中看到我在哪里看不到处理单独的轴。在下面的 URL 中,--= 圆形 =-- 部分讨论了如何处理 AABB 与凸/凹形状之间的碰撞。 http://www.metanetsoftware.com/technique/tutorialA.html#section2

我有向量和单独轴实现的基本思想,但不是这种方法,我从本教程中了解到的是整个 N 游戏世界由 5 - 8 个不同的形状(图块)组成,每个图块依次水平/垂直旋转给出 4 个面向左、右、上和左的组合底部。这些朝向信息存储在每个图块中,即符号x,y。

obj - 是玩家(矩形) T 形瓷砖 x,y - 边界框投影

实现:有人可以解释一下这段代码到底在做什么吗?

function ProjAABB_Concave(x,y,obj,t)
{       
    //if distance from "innermost" corner of AABB is further than tile radius,
    //collision is occuring and we need to project

    var signx = t.signx;
    var signy = t.signy;

    var ox = (t.pos.x + (signx*t.xw)) - (obj.pos.x - (signx*obj.xw));//(ox,oy) is the vector form the innermost AABB corner to the
    var oy = (t.pos.y + (signy*t.yw))- (obj.pos.y - (signy*obj.yw));//circle's center

    var twid = t.xw*2;
    var rad = Math.sqrt(twid*twid + 0);//this gives us the radius of a circle centered on the tile's corner and extending to the opposite edge of the tile;
                                        //note that this should be precomputed at compile-time since it's constant

    var len = Math.sqrt(ox*ox + oy*oy);
    var pen = len - rad;
    if(0 < pen)
    {
        //collision; we need to either project along the axes, or project along corner->circlecenter vector

        var lenP = Math.sqrt(x*x + y*y);
        if(lenP < pen)
        {
            //it's shorter to move along axis directions
            obj.ReportCollisionVsWorld(x,y,x/lenP, y/lenP, t);

            return COL_AXIS;
        }
        else
        {
            //project along corner->circle vector
            ox /= len;//len should never be 0, since if it IS 0, rad should be > than len
            oy /= len;//and we should never reach here

            obj.ReportCollisionVsWorld(ox*pen, oy*pen, ox, oy, t);

            return COL_OTHER;
        }

    }

    return COL_NONE;

}

Am following N game tutorial for handling collision detection for one of my game , one thing which is unclear in this approach is they were talking about separate axis theorem on this page but if you see in the implementation(Tutorial A) no where I could see separate axis was handled. From the below URL, section --= round shapes =-- talks about how to handle collision between AABB vs convex/concave shapes.
http://www.metanetsoftware.com/technique/tutorialA.html#section2

I have the basic idea of vectors and separate axis implementation but not this approach , what I understood from this tutorial is the whole N game world is made of 5 - 8 different shapes (tile) each tile in turn rotated horizontally/vertically which gives 4 combination facing left,right,top & bottom. These facing info is stored in each tile which is signx,y.

obj - is the player (rectangle)
t - tile
x,y - bounding box projection

Implementation : Could someone explain what exactly this code is doing?

function ProjAABB_Concave(x,y,obj,t)
{       
    //if distance from "innermost" corner of AABB is further than tile radius,
    //collision is occuring and we need to project

    var signx = t.signx;
    var signy = t.signy;

    var ox = (t.pos.x + (signx*t.xw)) - (obj.pos.x - (signx*obj.xw));//(ox,oy) is the vector form the innermost AABB corner to the
    var oy = (t.pos.y + (signy*t.yw))- (obj.pos.y - (signy*obj.yw));//circle's center

    var twid = t.xw*2;
    var rad = Math.sqrt(twid*twid + 0);//this gives us the radius of a circle centered on the tile's corner and extending to the opposite edge of the tile;
                                        //note that this should be precomputed at compile-time since it's constant

    var len = Math.sqrt(ox*ox + oy*oy);
    var pen = len - rad;
    if(0 < pen)
    {
        //collision; we need to either project along the axes, or project along corner->circlecenter vector

        var lenP = Math.sqrt(x*x + y*y);
        if(lenP < pen)
        {
            //it's shorter to move along axis directions
            obj.ReportCollisionVsWorld(x,y,x/lenP, y/lenP, t);

            return COL_AXIS;
        }
        else
        {
            //project along corner->circle vector
            ox /= len;//len should never be 0, since if it IS 0, rad should be > than len
            oy /= len;//and we should never reach here

            obj.ReportCollisionVsWorld(ox*pen, oy*pen, ox, oy, t);

            return COL_OTHER;
        }

    }

    return COL_NONE;

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

盗梦空间 2024-11-23 10:33:55

我认为展示底层物理算法会更好,这样你就可以更快地理解代码

I think it would be much better to show the underlying physical algorithm, then you can understand code faster

攒眉千度 2024-11-23 10:33:54

这是一个简单的球体与球体的碰撞。查看他们所做的部分

var pen = len - rad;
if(0 < pen)

他们只是检查“t”对象半径减去当前对象半径是否接触(=0)或交叉(<0)。

他们所做的部分

var ox = (t.pos.x + (signx*t.xw)) - (obj.pos.x - (signx*obj.xw));//(ox,oy) is the vector form the innermost AABB corner to the
var oy = (t.pos.y + (signy*t.yw))- (obj.pos.y - (signy*obj.yw));//circle's center

是将“t”对象移动到“obj”参考系。

That's a simple sphere-vs-sphere collision. See the part where they do

var pen = len - rad;
if(0 < pen)

They are just checking that the "t" object radius minus the current object radius are touching (=0) or crossing (<0).

The part where they do

var ox = (t.pos.x + (signx*t.xw)) - (obj.pos.x - (signx*obj.xw));//(ox,oy) is the vector form the innermost AABB corner to the
var oy = (t.pos.y + (signy*t.yw))- (obj.pos.y - (signy*obj.yw));//circle's center

They are moving the "t" object to "obj" frame of reference.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文