当前位置:编程学习 > C/C++ >>

3D服务器端以向量计算为主的角色位置的算法

3D服务器端玩家行走处理是服务器端根据客户端行走路径、玩家行走时间以及速度(包括变化速度)计算得出玩家的当前位置。
由于客户端行走是一条路径,不使用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.zzzyk.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<COORDINATE_3DPATH>::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 - prevCoordinate3D;
// 总路径距离
nAllPathDistance += coordinate3DPath.curDistance;
coordinate3DPath.allDistance = nAllPathDistance;
 
// 位置计算公式
double nValue = (curCoordinate3D.x-prevCoordinate3D.x)*(curCoordinate3D.x-prevCoordinate3D.x) + (curCoordinate3D.y-prevCoordinate3D.y)*(curCoordinate3D.y-prevCoordinate3D.y)
+ (curCoordinate3D.z-prevCoordinate3D.z)*(curCoordinate3D.z-prevCoordinate3D.z);
 
if (nValue <= 0)
{
cout << "开根号为0" << endl;
return ;
}
 
double dValue = sqrt(nValue);
if (0 == dValue)
{
cout << "错误" << endl;
return;
}
 
coordinate3DPath.xDistance = curCoordinate3D.x-prevCoordinate3D.x;
coordinate3DPath.yDistance = curCoordinate3D.y-prevCoordinate3D.y;
coordinate3DPath.zDistance = curCoordinate3D.z-prevCoordinate3D.z;
coordinate3DPath.dFormula = 1/dValue;
 
// 间断取path线段中的点,进行格子可行走点的判定。
 
 
vtWalkPath.push_back(coordinate3DPath)
补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,