我在服务器 - 客户端Winsock游戏中理解我如何实现Dead Reckoning有点困难.
我一直在互联网上寻找一个可靠解释的解释:
当消息应该从服务器发送到客户端时
如果客户端没有收到更新消息,它应该如何操作,它是否继续使用预测位置作为当前位置来计算新的预测位置?
我使用的航位推算方法是:
path vector = oldPosition - oldestPosition delta time = oldTime - oldestTime delta velocity = path vector / delta time new delta time = current time / oldest time new prediction = oldPosition + new delta time * delta velocity
希望这是正确的配方!:)
还应注意连接类型是UDP,并且游戏仅在服务器上播放.服务器将更新消息发送到客户端.
有人可以帮我回答我的问题吗?
谢谢
航位推算需要一组变量才能起作用 - 称为运动状态 - 通常包含给定物体的位置,速度,加速度,方向和角速度.如果只查找位置,可以选择忽略方向和角速度.如果您希望预测方向和位置,请发表评论,我会更新我的答案.
这里显示了用于网络游戏的标准航位推算算法:
上面的变量描述如下:
P t:估计的位置.产量
P O:对象的最新位置更新
V O:对象的最新速度更新
A O:对象的最新加速更新
T:当前时间与上次更新的时间戳之间经过的秒数- 而不是收到数据包的时间.
这可用于移动对象,直到从服务器收到更新.然后,您有两种运动状态:估计位置(上述算法的最新输出)和刚收到的实际位置.实际上混合这两种状态可能很困难.
一种方法是创建一条直线,甚至更好的曲线,例如Bézier样条 曲线Catmull-Rom样条曲线和Hermite曲线(这里列出其他方法的一个很好的列表),两种状态之间仍然将旧方向投射到未来.所以,继续使用旧状态直到你得到一个新状态 - 当你融入的状态变成旧状态时.
另一种技术是使用投影速度混合,即两个投影的混合 - 最后已知状态和当前状态 - 其中当前渲染位置是在给定时间内最后已知和当前速度的混合.
这个网页引用了"游戏引擎宝石2"一书,是一个推算的金矿:
网络游戏的可信推算
编辑:以上所有内容仅适用于客户端在未获得更新时的行为方式.至于"当一条消息应该从服务器发送到客户端"时,Valve说好的服务器应该以大约15毫秒的间隔发送更新,大约每秒66.6.
注意:" Valve说 "链接实际上也有一些很好的网络技巧,使用Source Multiplayer Networking作为媒介.如果你有时间,请检查一下.
编辑2(代码更新!):
以下是我将如何在C++/DirectX环境中实现此类算法:
struct kinematicState { D3DXVECTOR3 position; D3DXVECTOR3 velocity; D3DXVECTOR3 acceleration; }; void PredictPosition(kinematicState *old, kinematicState *prediction, float elapsedSeconds) { prediction->position = old->position + (old->velocity * elapsedSeconds) + (0.5 * old->acceleration * (elapsedSeconds * elapsedSeconds));` } kinematicState *BlendKinematicStateLinear(kinematicState *olStated, kinematicState *newState, float percentageToNew) { //Explanation of percentateToNew: //A value of 0.0 will return the exact same state as "oldState", //A value of 1.0 will return the exact same state as "newState", //A value of 0.5 will return a state with data exactly in the middle of that of "old" and "new". //Its value should never be outside of [0, 1]. kinematicState *final = new kinematicState(); //Many other interpolation algorithms would create a smoother blend, //But this is just a linear interpolation to keep it simple. //Implementation of a different algorithm should be straightforward. //I suggest starting with Catmull-Rom splines. float percentageToOld = 1.0 - percentageToNew; final->position = (percentageToOld * oldState->position) + (percentageToNew * new-State>position); final->velocity = (percentageToOld * oldState->velocity) + (percentageToNew * newState->velocity); final->acceleration = (percentageToOld * oldState->acceleration) + (percentageToNew * newState->acceleration); return final; }
祝你好运,呃,如果你碰巧在比赛中赚了数百万美元,试着把我放进学分;)