程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> 3D服務器端以向量計算為主的角色位置的算法

3D服務器端以向量計算為主的角色位置的算法

編輯:C++入門知識

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.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<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)

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved