C ++ DirectX11 2D游戏:阻止敌人精灵互相移动?

时间:2014-04-04 19:32:45

标签: c++ collision

我正在使用IntersectsWith(this->boundingBox))方法来检测精灵和玩家之间的碰撞。我想以某种方式能够使用这种方法来检测彼此碰撞的敌人精灵,并确保它们不会相互移动。

所有敌人精灵都跟随玩家。

MainGame.cpp

循环向量中的每个敌人并执行更新循环:

for (auto &enemyMobsObj : this->enemyMobs)
        {

            enemyMobsObj->Update(tickTotal, tickDelta, timeTotal, timeDelta, windowBounds, this->ship, this->firstBoss,
                this->enemyMobs, this->bullets, this->missiles, NULL, "NULL", "NULL");
        }

以下是我之前尝试阻止每个精灵互相移动的内容:

EnemyMobOne ::更新:

int nextEnemy;

    for (int i = 0; i < enemyMobOne.size(); i++)
    {
        nextEnemy = i + 1;
        if (nextEnemy < enemyMobOne.size())
        {
            //Deal with mobs collision
            if (enemyMobOne[i].boundingBox.IntersectsWith(enemyMobOne[nextEnemy].boundingBox))
            {
                enemyMobOne[i].position.x = enemyMobOne[nextEnemy].position.x - enemyMobOne[i].boundingBox.Width;
            }
        }
    }   

然而这使得每个敌人的精灵显然彼此坚持,这看起来并不正确,这也让他们传送。

任何人都知道正确的代码阻止他们互相移动?感谢。

1 个答案:

答案 0 :(得分:0)

当您检测到两个碰撞对象之间的交叉点时,您需要决定如何抵消重叠(因为我确定您已经弄明白了)。但是,如何做到这一点比简单地推动&#34;他们在一边(正如你在代码中所做的那样)。您可能想要做的是对施加的力施加反作用力,可以这么说。基本上,你想要计算最小平移,或者需要最小移动量的方向,以使至少一个方框移出另一个方框。

这比简单的更复杂一点#34;把我放在右边(或左边,取决于你设置坐标的方式,我想)另一个人的一面,&#34;这或多或少是你的代码所做的,现在。

对于一个简单的解决方案,只需检查其中一个碰撞器是否更靠近另一个碰撞器的左侧,右侧,顶部或底部。为此,您可以简单地获取碰撞交叉点位置并检查该点与相对于其中一个碰撞器的最小和最大x和y坐标之间的相对距离,然后相应地移动一个或两个精灵。

例: [编辑]在回顾了我之前的答案之后,我意识到你需要计算盒子的重叠,这样可以更容易地完成这一切:

float minX = min(sprite0.boundingBox.maxX, sprite1.boundingBox.maxX);// Minimum of the boxes' right-side points (top right and bottom right) x coordinates
float minY = min(sprite0.boundingBox.maxY, sprite1.boundingBox.maxY);// Minimum of the boxes' top-side points (top left and top right) y coordinates

float maxX = max(sprite0.boundingBox.minX, sprite1.boundingBox.minX);// Maximum of the boxes' left-side points (top left and bottom left) x coordinates
float maxY = max(sprite0.boundingBox.minY, sprite1.boundingBox.minY);// Maximum of the boxes' bottom-side points (bottom left and bottom right) y coordinates

float distHoriz = minX - maxX;// The horizontal intersection distance
float distVert = minY - maxY;// The vertical instersection distance

// If the boxes are overlapping less on the horizontal axis than the vertical axis,
// move one of the sprites (in this case, sprite0) in the opposite direction of the
// x-axis overlap
if(abs(distHoriz) < abs(distVert))
{
    sprite0.x -= distHoriz;
}
// Else, move one of the sprites (again, I just decided to use sprite0 here,
// arbitrarily) in the opposite direction of the y-axis overlap
else
{
    sprite0.y -= distVert;
}

为了进一步澄清(除了评论之外),我们在这里基本上做的是检查重叠线之间的距离。例如:

Box 0 x-axis  xmin0|------------------|xmax0
Box 1 x-axis                xmin1|----------------------|xmax1
                                 |----|<-- Overlap (xmax0 - xmin1)

请注意,用于重叠的两个边界框中的最小值是两个最小值(xmin0和xmin1)中的最大值,并且用于重叠的最大值是两个最大值中的最小值(xmax0和xmax1)。

y轴计算的工作方式完全相同。一旦我们有两个轴,我们只需检查哪一个具有较低的绝对值(哪个距离较短)并沿着该距离移动以抵消交叉点。