使用 D3DXVectors c++ 进行碰撞检测,发生碰撞后要做什么?
Collision Detection using D3DXVectors c++, What to do AFTER the collision has been made?
希望有人能回答我的问题。目前我正在使用 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 个布尔值来判断玩家是先与 X 还是 Z 接触,但由于第一个 if 语句甚至要查看我们是否在盒子里,我相信它会触发它们两者同时出现,无法区分哪个先出现。
如果有人能就此问题提供一些建议,将不胜感激!谢谢。
为了实现或多或少逼真的弹跳,仅有碰撞对象的位置和边界框是不够的。你需要有某种运动学历史:为了能够知道物体如何移动 after 你还应该知道它们如何移动 before碰撞。
在最简单的情况下,您希望至少有一个 velocity(速度)向量(方向和大小),并且可能每个对象都有一个质量。当检测到碰撞时,您可以简单地反转其中一个物体(例如,更小更轻的物体)的速度矢量的方向。
伪代码类似于:
if have_collided(object1, object2):
if object1.mass > object2.mass:
object2.velocity = -object2.velocity
else:
object1.velocity = -object1.velocity
这看起来不太现实,但实现起来非常简单。
为了更加真实,您可以使用 动量守恒 原理或 弹性碰撞 。为了更真实的弹跳,实现加速度矢量和re-calculate两者,检测碰撞后的速度和加速度。有了加速度,您现在可以添加影响对象的任意力(重力、摩擦力,甚至可能是电磁力等)。添加更多属性使其更有趣:例如添加弹性和粘性可以用于计算变形。
如您所见,对象交互涉及的不仅仅是位置。
此外,碰撞检测和弹跳代码可以(并且应该)分离。这意味着您可能希望在代码的不同部分(不同的函数集和 类)中实现它们:碰撞子系统将检测碰撞事件,并提供以下信息:是否发生了碰撞,如果是,是如何发生的远处的物体目前彼此相交。之后,弹跳代码将根据这些信息决定如何改变物体的行进,而变形代码将决定如何改变物体的形状等。因此,不会出现碰撞代码中的 which "if" 语句等愚蠢的问题先来决定弹跳方向
总的来说我建议你:
要查找一些物理知识。例如:
获得这本优秀的书:Real-Time Collision Detection
阅读 gamedev.stackexchange.com, for example on collision 上的一些热门问题(按投票排序)
最后,您应该知道 DirectX 9 API 已经过时,不受支持,不应该用于新项目。众所周知,将 D3DX* 内容移植到现代 APIs 是非常困难的。您可能想看看 DirectX 11 and OpenGL 4, along with their support library ecosystems, or maybe even a good rendering or game engine. Specifically you may want to use some good math library(包含向量、矩阵、线性代数、几何)。
希望有人能回答我的问题。目前我正在使用 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 个布尔值来判断玩家是先与 X 还是 Z 接触,但由于第一个 if 语句甚至要查看我们是否在盒子里,我相信它会触发它们两者同时出现,无法区分哪个先出现。
如果有人能就此问题提供一些建议,将不胜感激!谢谢。
为了实现或多或少逼真的弹跳,仅有碰撞对象的位置和边界框是不够的。你需要有某种运动学历史:为了能够知道物体如何移动 after 你还应该知道它们如何移动 before碰撞。
在最简单的情况下,您希望至少有一个 velocity(速度)向量(方向和大小),并且可能每个对象都有一个质量。当检测到碰撞时,您可以简单地反转其中一个物体(例如,更小更轻的物体)的速度矢量的方向。
伪代码类似于:
if have_collided(object1, object2):
if object1.mass > object2.mass:
object2.velocity = -object2.velocity
else:
object1.velocity = -object1.velocity
这看起来不太现实,但实现起来非常简单。 为了更加真实,您可以使用 动量守恒 原理或 弹性碰撞 。为了更真实的弹跳,实现加速度矢量和re-calculate两者,检测碰撞后的速度和加速度。有了加速度,您现在可以添加影响对象的任意力(重力、摩擦力,甚至可能是电磁力等)。添加更多属性使其更有趣:例如添加弹性和粘性可以用于计算变形。
如您所见,对象交互涉及的不仅仅是位置。
此外,碰撞检测和弹跳代码可以(并且应该)分离。这意味着您可能希望在代码的不同部分(不同的函数集和 类)中实现它们:碰撞子系统将检测碰撞事件,并提供以下信息:是否发生了碰撞,如果是,是如何发生的远处的物体目前彼此相交。之后,弹跳代码将根据这些信息决定如何改变物体的行进,而变形代码将决定如何改变物体的形状等。因此,不会出现碰撞代码中的 which "if" 语句等愚蠢的问题先来决定弹跳方向
总的来说我建议你:
要查找一些物理知识。例如:
获得这本优秀的书:Real-Time Collision Detection
阅读 gamedev.stackexchange.com, for example on collision 上的一些热门问题(按投票排序)
最后,您应该知道 DirectX 9 API 已经过时,不受支持,不应该用于新项目。众所周知,将 D3DX* 内容移植到现代 APIs 是非常困难的。您可能想看看 DirectX 11 and OpenGL 4, along with their support library ecosystems, or maybe even a good rendering or game engine. Specifically you may want to use some good math library(包含向量、矩阵、线性代数、几何)。