由于客户端行走是一条路径,不使用2D中的格子计算算法,未能高效的获取角色的当前位置,运用玩家行走路径,行走速度,行走时间这些已量,进行计算玩家的当前精确位置。由于3D游戏中的点为xyz的空间点,所以牵连的计算为3维向量计算。
空间两点距离计算公式为:
玩家在某条线段上的坐标x:
玩家在某条线段上的坐标y:
玩家在某条线段上的坐标z:
备注:公式文件公式.rar
代码实现:
// 空间坐标
typedef struct tagCoordinate3D
{
tagCoordinate3D()
{
this->x = 0;
this->y = 0;
this->z = 0;
this->dir = 0;
}
tagCoordinate3D(int x, int y, int z, short dir = 0)
{ www.2cto.com
this->x = x;
this->y = y;
this->z = z;
this->dir = dir;
}
~tagCoordinate3D(){}
int operator - (tagCoordinate3D coordinate3D)
{
double nTemp = (this->x - coordinate3D.x)*(this->x - coordinate3D.x) + (this->y - coordinate3D.y)*(this->y - coordinate3D.y)
+ (this->z - coordinate3D.z)*(this->z - coordinate3D.z);
if (0 == nTemp)
{
return (int)-1;
}
return (int)sqrt(nTemp);
}
int x;//X坐标
int z;//Z坐标
int y;//Y坐标(高度)
short dir;//方向(范围:0-359)
}COORDINATE_3D, *PCOORDINATE_3D;
typedef struct tagCoordinate3DPath : public tagCoordinate3D
{
tagCoordinate3DPath()
{
}
tagCoordinate3DPath(int x, int y, int z, short dir = 0) : tagCoordinate3D(x, y, z, dir)
{
}
tagCoordinate3DPath(tagCoordinate3D coordinate3D) : tagCoordinate3D(coordinate3D.x, coordinate3D.y, coordinate3D.z, coordinate3D.dir)
{
}
~tagCoordinate3DPath() {}
int curDistance;//当前距离(和上个点的距离)
int allDistance;//总距离(和第一个点的距离,所有点距离之和)
int xDistance;
int yDistance;
int zDistance;
double dFormula;//位置计算公式
}COORDINATE_3DPATH, *PCOORDINATE_3DPATH;
获取角色当前坐标:
COORDINATE_3D CFightRole::GetPosition()
{
if (m_vtWalkPath.size() == 0)
{
return m_3DWalkPathEnd;
}
COORDINATE_3D coordinate3D;
DWORD dwNowTime = GetFrameTime();
int nWalkTime = dwNowTime - m_dwWalkPathBeginTime;
if (nWalkTime < 0)
{
cout << "[严重错误]不应该发生错误的地方,发生了错误" << endl;
return m_3DWalkPathEnd;
}
double nTotalDistance = m_wSpeed*nWalkTime/(1000.0f);
// 上面已经计算出玩家行走总距离,计算玩家位置
vector::iterator itPath = m_vtWalkPath.begin();
for (; itPath!=m_vtWalkPath.end(); ++itPath)
{
if (itPath->allDistance > (int)nTotalDistance)
{
// 角色当前位置在当前path中,计算当前位置
bFind = true;
double nCurDistance = nTotalDistance - (itPath->allDistance - itPath->curDistance);
if (nCurDistance < 0)
{
cout << "[严重错误]获取坐标" << endl;
return coordinate3D;
}
coordinate3D.x = (int)(itPath->x + itPath->dFormula*itPath->xDistance*nCurDistance);
coordinate3D.y = (int)(itPath->y + itPath->dFormula*itPath->yDistance*nCurDistance);
coordinate3D.z = (int)(itPath->z + itPath->dFormula*itPath->zDistance*nCurDistance);
coordinate3D.dir = itPath->dir;
if (coordinate3D.x ==1 && coordinate3D.y==1 && coordinate3D.z == 1)
{
int i = 0;
}
return coordinate3D;
}
}
// 到达目标点做先前点路径的清理工作
m_vtWalkPath.clear();
return m_3DWalkPathEnd;
}
部分计算公式初始化:
COORDINATE_3D curCoordinate3D(tempCoordinate3d.x(), tempCoordinate3d.y(), tempCoordinate3d.z(), tempCoordinate3d.dir());
// 第n段行走路径
COORDINATE_3DPATH coordinate3DPath(prevCoordinate3D);
// 当前路径距离
coordinate3DPath.curDistance = curCoordinate3D - p