使用D3DXVectors进行碰撞检测c ++,碰撞后该怎么办?

时间:2018-03-30 04:13:51

标签: c++ vector directx game-physics

我希望有人可以回答我的问题。目前我正在使用D3DXVectors进行一些碰撞检测。 我发生了碰撞,但我需要的是在发生碰撞后该怎么做。

我有一个玩家对象和玩家正在碰撞的对象,并将这些对象传递给我的函数。

基本上,我到目前为止(为了清晰起见,变量名称已经更改):

D3DXVECTOR3 Collision::wallCol(D3DXVECTOR3 player, D3DXVECTOR3 object, float playerWidth, float playerDepth, float objectWidth, float objectDepth)
{
        //store the values of the objects into temps
        //left hand side of a box
        float minX = object.x - (objectWidth / 2);

        //right hand side of a box
        float maxX = object.x + (objectWidth / 2);

        //front of a box
        float minZ = object.z - (objectDepth / 2);

        //back of a box
        float maxZ = object.z + (objectDepth / 2);

        //store the players positions into temps
        float pminX = player.x - (playerWidth / 2);
        float pmaxX = player.x + (playerWidth / 2);
        float pminZ = player.z - (playerDepth / 2);
        float pmaxZ = player.z + (playerDepth / 2);


        //check to see if we are in the box at all
        if (pminX <= maxX && pmaxX >= minX &&
            pminZ <= maxZ && pmaxZ >= minZ)
        {

            //x collision for the left side of the block
            if (pmaxX >= minX && pmaxX <= maxX)
            {
                pmaxX = minX - 50;
                player.x = pmaxX;

                return player;
            }

            //x collision for the right side of the block
            if (pminX <= maxX && pminX >= minX)
            {
                pminX = maxX + 50;
                player.x = pminX;

                return player;
            }

            //z collision for the front
            if (pmaxZ >= minZ && pmaxZ <= maxZ)
            {
                pmaxZ = minZ - 20;
                player.z = pmaxZ;

                return player;
            }

            //z collision for the back
            if (pminZ <= maxZ && pminZ >= minZ)
            {
                pminZ = maxZ + 20;
                player.z = pminZ;

                return player;
            }
        }
        return player;
    }

正如你所看到的,我想让我的玩家对象远离它碰到的任何东西。我遇到的问题是无论怎样,我的播放器总是会在X轴上向左或向右移动,因为它首先占据了X,它甚至没有机会获得Z if语句。 / p>

我考虑让2个布尔人告诉玩家是否首先接触X或Z,但是因为第一个if语句甚至会看到我们是否在框中,我相信它会触发他们两个在同一时间,没有办法说出哪个是第一个。

如果有人可以就此问题提供一些建议,我们将不胜感激!谢谢。

1 个答案:

答案 0 :(得分:1)

为了实现更多或更少的逼真弹跳,仅仅具有碰撞对象的位置和边界框是不够的。你需要有一些运动历史记录:为了能够告诉物体在碰撞后如何移动你还应该知道它们在碰撞之前是如何移动的。

在最简单的情况下,您希望至少具有速度(速度)矢量(方向和幅度),并且可能是每个物体的质量。当检测到碰撞时,您可以简单地反转其中一个物体的速度矢量的方向(例如,更小和更轻的一个)。

伪代码将类似于:

if have_collided(object1, object2):
   if object1.mass > object2.mass:
      object2.velocity = -object2.velocity
   else:
      object1.velocity = -object1.velocity

这看起来不太现实,但实施起来非常简单。 为了更真实,您可以使用动量守恒原理或弹性碰撞。对于更逼真的弹跳,​​实施加速度矢量并在检测到碰撞后重新计算速度和加速度。加速后,您现在可以添加影响物体的任意力(重力,摩擦力,甚至是电磁力等)。添加更多属性使其更有趣:例如,可以使用添加弹性和粘度来计算变形。

如您所见,涉及的对象互动不仅仅是位置。

此外,碰撞检测和弹跳代码可以(并且应该)解耦。这意味着您希望在代码的不同部分(不同的函数和类集)中实现它们:碰撞子系统将检测碰撞事件,提供如下信息:是否发生碰撞,如果是,则表示对象当前相交的距离彼此。在此之后,基于此信息的弹跳代码将决定如何更改行进的对象,而变形代码将决定如何更改对象形状等。因此,将不存在诸如&#34; if&#34;碰撞代码中的陈述首先决定了弹跳的方向。

总的来说,我建议你:

<子> 最后,您应该知道DirectX 9 API已经过时,不受支持,不应该用于新项目。将D3DX *东西移植到现代API是非常困难的。您可能需要查看DirectX 11OpenGL 4及其支持库生态系统,或者甚至是一个好的渲染或游戏引擎。具体来说,您可能想要使用一些good math library(使用向量,矩阵,线性代数,几何)。