首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >二维平台碰撞处理

二维平台碰撞处理
EN

Stack Overflow用户
提问于 2011-03-01 01:25:48
回答 1查看 6.9K关注 0票数 5

我正在尝试创建一个2D平台(马里奥式)游戏,我有一些问题,处理碰撞适当。我写这个游戏在C++,使用SDL作为输入,图像加载,字体加载,等等。我还通过OpenGL库和SDL一起使用FreeGLUT来显示图形。

我的碰撞检测方法是AABB (轴对齐包围盒),这是我首先需要做的。我需要的是一种简单的方法,既可以检测碰撞发生在哪一边,也可以正确地处理碰撞。因此,基本上,如果玩家与平台顶部发生碰撞,将他重新定位到平台的顶部;如果双方发生碰撞,则将玩家重新定位到物体的侧面;如果与平台底部发生碰撞,则将玩家重新定位在平台下。

我已经尝试过许多不同的方法来实现这一点,比如试图找到穿透深度,并根据穿透深度向后重新定位播放器。可悲的是,我尝试过的一切似乎都是正确的。当我不想让玩家移动的时候,他的动作就会变得很不正常。部分原因可能是因为我觉得这件事很简单,但我想太多了。

如果有人认为他们可以帮助,请看下面的代码,并帮助我尝试改进,如果你可以的话。如果可能的话,我不想使用库来处理这个问题(我想自己学习)或类似SAT (分离轴定理)之类的东西。提前感谢您的帮助!

代码语言:javascript
复制
void world1Level1CollisionDetection()
{
for(int i; i < blocks; i++)
{
    if (de2dCheckCollision(ball,block[i],0.0f,0.0f)==true)
    {
        de2dObj ballPrev;
        ballPrev.coords[0] = ball.coords[0];
        ballPrev.coords[1] = ball.coords[1];
        ballPrev.coords[2] = ball.coords[2];
        ballPrev.coords[3] = ball.coords[3];
        ballPrev.coords[0] -= ball.xspeed;
        ballPrev.coords[1] -= ball.yspeed;
        ballPrev.coords[2] -= ball.xspeed;
        ballPrev.coords[3] -= ball.yspeed;

        int up = 0;
        int left = 0;
        int right = 0;
        int down = 0;

        if (ballPrev.coords[0] < block[i].coords[0] && ballPrev.coords[2] < block[i].coords[0] && (((ball.coords[1] < block[i].coords[1]) || (ball.coords[3] < ball.coords[1]))  || ((ball.coords[1] < block[i].coords[3]) || ball.coords[3] < block[i].coords[3])))
        {
            left = 1;
        }

        if (ballPrev.coords[0] > block[i].coords[2] && ballPrev.coords[2] > block[i].coords[2] && (((ball.coords[1] < block[i].coords[1]) || (ball.coords[3] < ball.coords[1]))  || ((ball.coords[1] < block[i].coords[3]) || (ball.coords[3] < block[i].coords[3]))))
        {
            right = 1;
        }
        if(ballPrev.coords[1] < block[i].coords[1] && block[i].coords[1] < ballPrev.coords[3] && ballPrev.coords[3] < block[i].coords[3])
        {
            up = 1;
        }
        if(block[i].coords[1] < ballPrev.coords[1] && ballPrev.coords[1] < block[i].coords[3] && block[i].coords[3] < ballPrev.coords[3])
        {
            down = 1;
        }

        cout << left << ", " << right << ", " << up << ", " << down << ", " << endl;

        if (left == 1)
        {
            ball.coords[0] = block[i].coords[0] - 18.0f;
            ball.coords[2] = block[i].coords[0] - 2.0f;
        }
        else if (right == 1)
        {
            ball.coords[0] = block[i].coords[2] + 2.0f;
            ball.coords[2] = block[i].coords[2] + 18.0f;
        }
        else if (down == 1)
        {
            ball.coords[1] = block[i].coords[3] + 4.0f;
            ball.coords[3] = block[i].coords[3] + 20.0f;
        }
        else if (up == 1)
        {
            ball.yspeed = 0.0f;
            ball.gravity = 0.0f;
            ball.coords[1] = block[i].coords[1] - 17.0f;
            ball.coords[3] = block[i].coords[1] - 1.0f;
        }
    }
    if (de2dCheckCollision(ball,block[i],0.0f,0.0f)==false)
    {
        ball.gravity = -0.5f;
    }
}
}

为了解释其中一些代码的含义:

块变量基本上是一个整数,它存储块或平台的数量。我正在使用for循环检查所有的块,循环当前所使用的数字用整数i表示,坐标系统可能看起来有点奇怪,因此值得解释。和弦表示对象的x位置(左)(从x轴开始)。coords1表示对象的y位置(顶部)(从y轴开始)。coords2表示对象的宽度加上和弦0。coords3表示对象的高度加上和弦1。de2dCheckCollision执行AABB碰撞检测。向上是负y,向下是正y,就像在大多数游戏中一样。

希望我已经提供了足够的信息,以帮助我成功。如果我遗漏了一些可能很关键的东西,请告诉我,我会提供必要的信息。最后,对于任何能够提供帮助的人来说,提供代码将是非常有用和非常感激的。

再次感谢你的帮助!

编辑2:我已经用一个新算法更新了我的代码,该算法检查球在碰撞前的位置。角落的情况现在正确的工作在单一的平台上,当我有一堵墙的物体,我可以正确地滑动到它现在。唯一剩下的问题是,当我在地面上时,会有一个小的抖动效应,在那里,球不断地上下移动,就好像它是被重力拉着的,然后球又落回了物体。

编辑:这是一个用于显示我遇到的问题的图片的网址:http://img8.imageshack.us/img8/4603/collisionproblem.png

如果图片中的解释没有多大意义,除非我跳过它,否则球不能左移过物体的角。然而,球可以向右移动,但它在移动时会被重新定位到物体的右边,这是不需要的。这从本质上创造了一种跳跃运动,当我向右移动时,当球跳过物体的一半左右时,它就会出现。如果这没有道理,请问我,我会尽量澄清更多。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-03-01 02:00:49

代码的一个问题是,您只检测到这样的情况:

如果圆圈恰好完全在块内,你根本就不会重新定位。这是个问题。

你试图把你的模拟当作是连续的,但是要记住它是离散的。一般来说,如果你只看球的当前状态,你真的不知道它与哪一边相撞。看看这两种可能性:

想到的第一个解决方案也是看球的最后位置,更准确地说,看三角形矢量。看看三角矢量是否与墙相交。如果是的话,在轴向向墙的方向重新定位,与三角形矢量相交.

编辑:,当我说“增量向量”时,我忘了你在移动一个正方形,而不是一个点。所以,如果你只看左上角的三角形矢量,那是不够的,因为它可能没有探测到球进入了一个街区。相反,您可以查看所有4个角的增量向量。

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

https://stackoverflow.com/questions/5149548

复制
相关文章

相似问题

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