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

把我以前学习过的一个东西拿出来分享下~

3D服务器端玩家行走处理是服务器端根据客户端行走路径、玩家行走时间以及速度(包括变化速度)计算得出玩家的当前位置。

由于客户端行走是一条路径,不使用2D中的格子计算算法,未能高效的获取角色的当前位置,运用玩家行走路径,行走速度,行走时间这些已量,进行计算玩家的当前精确位置。由于3D游戏中的点为xyz的空间点,所以牵连的计算为3维向量计算。

空间两点距离计算公式为:

玩家在某条线段上的坐标x:

玩家在某条线段上的坐标y:

玩家在某条线段上的坐标z:

角色当前位置计算原理分析:

角色行走是一条路径,这条路径使用点序列表示,角色开始行走记录当前时间TimeStart,获取觉得当前位置的计算,首先获取当前时间TimeNow,根据TimeNow-TimeStart的时间差与角色的行走速度,获取角色已经行走过的距离distance,计算每两点的距离,判定角色当前时间所处在哪一条路径上,及角色在哪两点之间。然后使用向量计算公式计算当前角色处于的坐标点位置。

角色位置位置计算的类封装实现代码:

  1 #pragma once
  2 
  3 class CCoordinatePath
  4 {
  5 public:
  6     CCoordinatePath(void);
  7     ~CCoordinatePath(void);
  8 
  9 public:
 10     // 更新行走路径
 11     void UpdatePath(COORDINATE_3D stopCoordinate3D);
 12     void UpdatePath(vector<COORDINATE_3DPATH> vtPath, COORDINATE_3D stopCoordinate3D, float nCompletePath = 0);
 13     // 开始行走(移动计算)
 14     void StartMove(DWORD dwStartTime);
 15     // 获取当前空间位置
 16     COORDINATE_3D GetCoordinate(DWORD dwNowTime);
 17     // 获取行走路径
 18     const vector<COORDINATE_3DPATH>* GetPath();
 19     // 获取停止位置
 20     COORDINATE_3D GetStopCoordinate();
 21     // 获取移动总距离(从开始行走到现在的行走总距离)
 22     float GetCompletePath(DWORD dwNowTime);
 23     // 更新玩家速度
 24     void UpdateSpeed(unsigned short wSpeed, DWORD dwNowTime);
 25     // 获取当前速度
 26     unsigned short GetSpeed();
 27     // 玩家是否正在移动
 28     bool IsMoving(DWORD dwNowTime);
 29 
 30 private:
 31     // 行走路径
 32     vector<COORDINATE_3DPATH> m_vtPath;
 33     // 停止点
 34     COORDINATE_3D m_stopCoordinate3D;
 35 
 36     // 已完成路径
 37     float m_nCompletePath;
 38     // 玩家当前速度
 39     unsigned short m_wCurSpeed;
 40     // 行走路径开始时间
 41     DWORD m_dwStartMoveTime;
 42     
 43 };
 44  
 45 #include "StdAfx.h"
 46 #include "CoordinatePath.h"
 47 
 48 CCoordinatePath::CCoordinatePath(void)
 49 {
 50     m_wCurSpeed = 4;
 51 }
 52 
 53 CCoordinatePath::~CCoordinatePath(void)
 54 {
 55 }
 56 
 57 void CCoordinatePath::UpdatePath( COORDINATE_3D stopCoordinate3D )
 58 {
 59     m_vtPath.clear();
 60     m_stopCoordinate3D = stopCoordinate3D;
 61     m_nCompletePath = 0;
 62 }
 63 
 64 void CCoordinatePath::UpdatePath( vector<COORDINATE_3DPATH> vtPath, COORDINATE_3D stopCoordinate3D, float nCompletePath /*= 0*/ )
 65 {
 66     m_vtPath = vtPath;
 67     m_stopCoordinate3D = stopCoordinate3D;
 68     m_nCompletePath = nCompletePath;
 69 }
 70 
 71 void CCoordinatePath::StartMove( DWORD dwStartTime )
 72 {
 73     m_dwStartMoveTime = dwStartTime;
 74 }
 75 
 76 COORDINATE_3D CCoordinatePath::GetCoordinate(DWORD dwNowTime)
 77 {
 78     if (m_vtPath.size() == 0)
 79     {
 80         return m_stopCoordinate3D;
 81     }
 82 
 83     float nTotalDistance = GetCompletePath(dwNowTime);
 84 
 85     if (nTotalDistance < 0)
 86     {
 87         cout << "计算玩家移动距离错误" << endl;
 88         return m_stopCoordinate3D;
 89     }
 90 
 91     // ceshi
 92     //cout << "距离:" << nTotalDistance << "时间" << (dwNowTime-m_dwStartMoveTime) << endl;
 93 
 94     COORDINATE_3D coordinate3D;
 95 
 96     // 上面已经计算出玩家行走总距离,计算玩家位置
 97     vector<COORDINATE_3DPATH>::iterator itPath = m_vtPath.begin();
 98     for (; itPath!=m_vtPath.end(); ++itPath)
 99     {
100         if (itPath->allDistance > nTotalDistance)
101         {
102             // 角色当前位置在当前path中,计算当前位置
103             float nCurDistance = nTotalDistance - (itPath->allDistance - itPath->curDistance);
104 
105             if (nCurDistance < 0)
106             {
107                 cout << "[严重错误]获取坐标" << endl;
108                 return m_stopCoordinate3D;
109             }
110 
111             coordinate3D.x = itPath->x + itPath->dFormula*itPath->xDistance*nCurDistance;
112             coordinate3D.y = itPath->y + itPath->dFormula*itPath->yDistance*nCurDistance;
113             coordinate3D.z = itPath->z + itPath->dFormula*itPath->zDistance*nCurDistance;
114             coordinate3D.dir = itPath->dir;
115 
116             if (coordinate3D.x ==1 && coordinate3D.y==1 && coordinate3D.z == 1)
117             {
118                 int i = 0;
119             }
120             ///yang
121             //cout << "当前移动坐标:x:" << coordinate3D.x << ",y:" << coordinate3D.y << ",z:" << coordinate3D.z << endl;
122             ///yang
123             return coordinate3D;
124         }
125     }
126 
127     // 到达目标点做先前点路径的清理工作
128     m_vtPath.clear();
129 
130     return m_stopCoordinate3D;
131 }
132 
133 const vector<COORDINATE_3DPATH>* CCoordinatePath::GetPath()
134 {
135     return &m_vtPath;
136 }
137 
138 COORDINATE_3D CCoordinatePath::GetStopCoordinate()
139 {
140     return m_stopCoordinate3D;
141 }
142 
143 float CCoordinatePath::GetCompletePath( DWORD dwNowTime )
144 {
145     // 无变速的移动距离计算
146     DWORD dwMoveTime = dwNowTime-m_dwStartMoveTime;
147 
148     return (m_nCompletePath + m_wCurSpeed*dwMoveTime/1000.0f);
149 }
150 
151 void CCoordinatePath::UpdateSpeed( unsigned short wSpeed, DWORD dwNowTime )
152 {
153     // 计算已经完成路径
154     m_nCompletePath += GetCompletePath(dwNowTime);
155     m_dwStartMoveTime = dwNowTime;
156 
157     m_wCurSpeed = wSpeed;    //当前速度
158 }
159 
160 unsigned short CCoordinatePath::GetSpeed()
161 {
162     return m_wCurSpeed;
163 }
164 
165 bool CCoordinatePath::IsMoving( DWORD dwNowTime )
166 {
167     GetCoordinate(dwNowTime);
168 
169     if (m_vtPath.size() > 0)
170     {
171         return true;
172     }
173     else
174     {
175         return false;
176     }
177 }
原文地址:https://www.cnblogs.com/Mushrooms/p/3141819.html