C++ C++;:std::vector-std::find&;距离查询
为了给我的问题提供上下文,我将描述我最终想要实现的目标-我正在开发一个游戏,我有一个C++ C++;:std::vector-std::find&;距离查询,c++,stdvector,C++,Stdvector,为了给我的问题提供上下文,我将描述我最终想要实现的目标-我正在开发一个游戏,我有一个.obj模型,我将它用作我的地形,我必须在玩家穿越地形时更新他们的高度(因为地形远不是平坦的)。目前,我通过以下操作实现了这一点-当我加载网格(terrain.obj)时,我将其所有顶点(每个顶点都是一个Vector3f对象,该对象具有xy和z值)存储在std::vector meshVertices,然后每秒存储在“主游戏循环”中我在meshVertices中循环遍历Vector3f中的每一个对象,并根据玩家x
.obj
模型,我将它用作我的地形,我必须在玩家穿越地形时更新他们的高度(因为地形远不是平坦的)。目前,我通过以下操作实现了这一点-当我加载网格(terrain.obj
)时,我将其所有顶点(每个顶点都是一个Vector3f
对象,该对象具有x
y和z
值)存储在std::vector meshVertices
,然后每秒存储在“主游戏循环”中我在meshVertices
中循环遍历Vector3f
中的每一个对象,并根据玩家x
和z
值检查其x
和z
值,如果他们发生碰撞,我将玩家高度设置为匹配Vector3f
对象的y
值
这个系统实际上可以在玩家穿越地形时更新他们的高度,唯一的问题是——我每秒根据玩家位置检查每个网格顶点的方法会降低我的帧速率,我需要一个更好的系统
现在,我将描述我在尝试保存帧速率时的新优化方法-首先,在创建网格时,我不只是将每个Vector3f
顶点存储在单个std::vector
,我将网格的每个Vector3f
顶点的x
y
和z
值存储在三个独立的std::vector
中,分别命名为meshVerticesX
、mechVerticesY
和meshVerticesZ
<代码>这些std::vector可以在以下代码中看到:
for (Vector3f currentVertex : meshVertices) {
meshVerticesX.push_back((int)currentVertex.GetX());
}
for (Vector3f currentVertex : meshVertices) {
meshVerticesZ.push_back((int)currentVertex.GetZ());
}
for (Vector3f currentVertex : meshVertices) {
meshVerticesY.push_back((int)currentVertex.GetY());
}
现在,每秒钟我都会得到玩家位置的x
和z
值(转换为int,因为我觉得让这个系统使用int值而不是float值会更容易在以后进行比较)然后通过返回bool将它们发送到函数,以检查它们是否存在于前面提到的meshVerticesX
和mechVerticesZ
中,负责此操作的代码如下:
int playerPosX = (int) freeMoveObjects[0]->GetParent()->GetTransform()->GetPos()->GetX();
int playerPosZ = (int) freeMoveObjects[0]->GetParent()->GetTransform()->GetPos()->GetZ();
bool x = meshObjects[0]->checkMeshVerticesX(playerPosX);
bool z = meshObjects[0]->checkMeshVerticesZ(playerPosZ);
bool Mesh::checkMeshVerticesX(int playerPosX)
{
return std::find(meshVerticesX.begin(), meshVerticesX.end(), playerPosX) != meshVerticesX.end();
}
int Mesh::getMeshYHeight(int playerXPos, int playerZPos) {//15/2/20
auto iterX = std::find(meshVerticesX.begin(), meshVerticesX.end(), playerXPos) != meshVerticesX.end();
auto iterZ = std::find(meshVerticesZ.begin(), meshVerticesZ.end(), playerZPos) != meshVerticesZ.end();
int indexX = std::distance(meshVerticesX.begin(), iterX);
int indexZ = std::distance(meshVerticesZ.begin(), iterZ);
if (indexX == indexZ)
{
return meshVerticesY[indexX];
}
}
功能checkMeshVerticesX
和checkMeshVerticesZ
如下:
int playerPosX = (int) freeMoveObjects[0]->GetParent()->GetTransform()->GetPos()->GetX();
int playerPosZ = (int) freeMoveObjects[0]->GetParent()->GetTransform()->GetPos()->GetZ();
bool x = meshObjects[0]->checkMeshVerticesX(playerPosX);
bool z = meshObjects[0]->checkMeshVerticesZ(playerPosZ);
bool Mesh::checkMeshVerticesX(int playerPosX)
{
return std::find(meshVerticesX.begin(), meshVerticesX.end(), playerPosX) != meshVerticesX.end();
}
int Mesh::getMeshYHeight(int playerXPos, int playerZPos) {//15/2/20
auto iterX = std::find(meshVerticesX.begin(), meshVerticesX.end(), playerXPos) != meshVerticesX.end();
auto iterZ = std::find(meshVerticesZ.begin(), meshVerticesZ.end(), playerZPos) != meshVerticesZ.end();
int indexX = std::distance(meshVerticesX.begin(), iterX);
int indexZ = std::distance(meshVerticesZ.begin(), iterZ);
if (indexX == indexZ)
{
return meshVerticesY[indexX];
}
}
使用返回的布尔值(如果播放机位置在相应的std::vector
中,则为true;如果不是,则为false),然后我调用另一个函数(getMeshYHeight
),该函数也会传递播放机x和z位置,然后检查相应的std::vector
的索引(meshVerticesX
&meshVerticesZ
)如果找到匹配项,则检查这些索引是否相等,如果相等,则从前面提到的meshVerticesY
std::vector
返回该索引的整数,此代码可以在以下内容中看到:
if (x == true & z == true) {// boolean values returned by checkMeshVerticesX & checkMeshVerticesZ
int terrainVertexYHeight = meshObjects[0]->getMeshYHeight(playerPosX, playerPosZ);
freeMoveObjects[0]->GetParent()->GetTransform()->GetPos()->SetY(terrainVertexYHeight);
}
函数getMeshYHeight
如下所示:
int playerPosX = (int) freeMoveObjects[0]->GetParent()->GetTransform()->GetPos()->GetX();
int playerPosZ = (int) freeMoveObjects[0]->GetParent()->GetTransform()->GetPos()->GetZ();
bool x = meshObjects[0]->checkMeshVerticesX(playerPosX);
bool z = meshObjects[0]->checkMeshVerticesZ(playerPosZ);
bool Mesh::checkMeshVerticesX(int playerPosX)
{
return std::find(meshVerticesX.begin(), meshVerticesX.end(), playerPosX) != meshVerticesX.end();
}
int Mesh::getMeshYHeight(int playerXPos, int playerZPos) {//15/2/20
auto iterX = std::find(meshVerticesX.begin(), meshVerticesX.end(), playerXPos) != meshVerticesX.end();
auto iterZ = std::find(meshVerticesZ.begin(), meshVerticesZ.end(), playerZPos) != meshVerticesZ.end();
int indexX = std::distance(meshVerticesX.begin(), iterX);
int indexZ = std::distance(meshVerticesZ.begin(), iterZ);
if (indexX == indexZ)
{
return meshVerticesY[indexX];
}
}
这里的想法是,如果原始检查的meshVerticesX
和meshVerticesZ
std::vectors
的索引匹配,那么它们必须是我第一次创建网格时原始Vector3f对象的x和z值,因此meshVerticesY
中的相同索引必须包含that sameVector3f
的对象y
值,因此返回该值并使用它设置玩家高度
问题是,我甚至无法测试这是否有效,因为代码行int indexX=std::distance(meshVerticesX.begin(),iterX);
给出了一个错误,表示提供给std::distance
的参数是错误的(它说iterX
是bool,而不是我所认为的int
)
我的问题是,首先,如果我没有这个错误,我的方法会起作用吗?如果是的话,我怎么解决这个错误? < p>我在你中间的某个地方迷失了你的逻辑,但是为了解决手头的问题:ITEX是一个BoOL!
auto iterX = std::find(...) != meshVerticesX.end();
在该语句中,find返回一个迭代器,将其与另一个迭代器meshVerticesX.end()进行比较。该表达式的结果(比较运算符)是一个布尔,然后分配给iterX,因此自动推断iterX需要为布尔类型。能否将地形的x,y坐标转换为整数,您可能需要对其进行缩放,然后在加载网格时,只需存储每个x,y点的z值(您可能需要在1x1平方上取某种平均值)。现在,你不必寻找碰撞,相反,对于游戏中的每个对象,你只需通过(缩放)x,y坐标查找其z值。“…如果是这样,我如何修复错误?…”请发布一个包含错误消息的帖子。“代码行…出现错误,说明提供给
std::distance
的参数错误。”iterX
声明为auto iterX=std::find(meshVerticesX.begin(),meshVerticesX.end(),playerXPos)!=meshVerticesX.end()这是一个布尔表达式。因此,iterX
是一个布尔表达式。它也不是一个int
;它将是一个迭代器(因此您为它选择了一个名称!)。我还建议您前往,看看您是否能找到以前提出的关于如何找到给定位置的地形高度的问题。“高度图”“可能是您可以搜索的术语。此外,getMeshYHeight
必须始终返回一个值。目前,它只能有条件地返回该值。”。