Winsock应用中的线性航位推算

 yngbzl_165 发布于 2023-02-06 17:19

我在服务器 - 客户端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,并且游戏仅在服务器上播放.服务器将更新消息发送到客户端.

有人可以帮我回答我的问题吗?

谢谢

1 个回答
  • 航位推算需要一组变量才能起作用 - 称为运动状态 - 通常包含给定物体的位置,速度,加速度,方向和角速度.如果只查找位置,可以选择忽略方向和角速度.如果您希望预测方向和位置,请发表评论,我会更新我的答案.

    这里显示了用于网络游戏的标准航位推算算法:

    航位推算方程

    上面的变量描述如下:

    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;
    }
    

    祝你好运,呃,如果你碰巧在比赛中赚了数百万美元,试着把我放进学分;)

    2023-02-06 17:21 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有