c++ - 使用 D3DXVectors c++ 进行碰撞检测,发生碰撞后要做什么?

标签 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 语句。

我考虑过制作 2 个 bool 值来判断玩家是先与 X 还是 Z 接触,但由于第一个 if 语句是为了查看我们是否在盒子里,我相信它会在同一时间,无法分辨哪个先出现。

如果有人能就这个问题提供一些建议,将不胜感激!谢谢。

最佳答案

为了实现或多或少逼真的弹跳,​​仅有碰撞对象的位置和边界框是不够的。您需要了解某种运动学历史:要能够了解对象 碰撞之后如何移动,您还应该知道它们在 碰撞之前如何移动。

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

伪代码是这样的:

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

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

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

此外,碰撞检测和弹跳代码可以(也应该)分离。这意味着您可能希望在不同的代码部分(不同的函数和类集)实现它们:碰撞子系统将检测碰撞事件,提供如下信息:碰撞是否发生,如果是,对象当前相交的距离彼此。之后,基于这些信息,弹跳代码将决定如何改变物体的行进,而变形代码将决定如何改变物体的形状等。因此,不会出现碰撞代码中哪个“if”语句先出现的愚蠢问题决定弹跳的方向。

总体而言,我建议您:

<子> 最后,您应该知道 DirectX 9 API 已经过时,不受支持,不应该用于新项目。众所周知,将 D3DX* 内容移植到现代 API 是非常困难的。你可能想看看 DirectX 11OpenGL 4 ,连同他们的支持库生态系统,甚至可能是一个好的渲染或游戏引擎。具体来说,您可能想使用一些 good math library (带有 vector 、矩阵、线性代数、几何)。

关于c++ - 使用 D3DXVectors c++ 进行碰撞检测,发生碰撞后要做什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49568266/

相关文章:

c++ - 删除 CallBack 函数中 new 创建的指针

java - 如何从 vector 内的数组中读取?

c++ - 我可以在 STL::vector::iterator 上做指针运算吗

c++ - Direct2D --- 为什么画笔资源绑定(bind)到各个 Direct2D 渲染目标?

c++ - 基于 shared_ptr 的设计问题

c++ - 如何在 C++ 中进行 SystemVerilog 风格的位 vector 切片赋值?

c++ - 垃圾收集器 : data structure of the object graph

c++ - 删除 vector 中指针的适当方法

c++ - 多渲染系统

c++ - 计算刚体惯性张量世界坐标