javascript - 实现 Hermite 插值 - 多人游戏

标签 javascript node.js algorithm networking hermite

我正在尝试建立一个客户端-服务器架构。我被困在插值部分。现在,我有一个非常简单的插值算法实现。我为每个玩家提供了位置历史记录,每当我从服务器收到其他玩家的位置数据时,我都会将该位置插入该数组。每个客户端框架我都使用最旧的位置历史记录以恒定的速度插入到新位置。

// when new position for other player recieved 
p.stateHistory.push(data)

// Every client frame
if(p.stateHistory.length < 1)
            return false

    let deltaPosition = p.stateHistory[0].position.clone().sub(p.clientPosition)
    let direction = Math.atan2(deltaPosition.y, deltaPosition.x)
    let velocity = new Vector2(Math.cos(direction), Math.sin(direction)).scale(30/100)

    let threshold = 10
    if(deltaPosition.magnitude() < threshold) {
        p.clientPosition.x = p.stateHistory[0].position.x
        p.clientPosition.y = p.stateHistory[0].position.y
        p.stateHistory.shift()
    } else {
        p.clientPosition.add(velocity.clone().scale(deltaTime))
    }

我找不到其他方法以恒定速度进行插值。我是从 gafferongames 了解到 Hermite 插值的。但令人遗憾的是,这篇文章没有任何关于其数学及其实现的内容。我尝试浏览维基百科关于 Hermite 插值的文章,但没有帮助。我对其背后的数学一无所知。如果有伪代码,我们将不胜感激。

到目前为止我能做的事情:http://client-side-prediction-attempt.herokuapp.com/

最佳答案

假设您的客户端在 currentTime 时间收到新的位置速度更新。然后,您需要保存当前位置/速度、目标位置/速度、当前时间以及期望下次更新的时间:

function updateFromServer(position, velocity) {
    startP = currentPosition; //the current position of the player
    startV = currentVelocity;
    endP   = position;
    endV   = velocity;
    startT = currentTime; //the current time of the game
    endT   = startT + 0.1; //expect the next update in 100 ms
}

存储此数据后,您可以使用插值进行帧更新。如果您位于[startT, endT] 间隔之外,您可能只想继续匀速运动:

function frameUpdate(deltaT) {
    if(currentTime > endT)
        //uniform motion
        currentPosition += deltaT * currentVelocity;
    else {
        //cubic Hermite interpolation
        var t = (currentTime - startT) / (endT - startT); //interpolation parameter
        var t2 = t * t;
        var t3 = t2 * t;
        currentPosition = 
            (2 * t3 - 3 * t2 + 1) * startP + 
            (t3 - 2 * t2 + t)     * (endT - startT) * startV + 
            (-2 * t3 + 3 * t2)    * endP   + 
            (t3 - t2)             * (endT - startT) * endV;
        currentVelocity = 1 / (endT - startT) * (
            (6 * t2 - 6 * t)     * startP + 
            (3 * t2 - 4 * t + 1) * (endT - startT) * startV +
            (-6 * t2 + 6 * t)    * endP   +
            (3 * t2 - 2 * t)     * (endT - startT) * endV);
    }
}

请注意,此代码段中的公式不是有效的 JavaScript 代码。它们必须翻译成您使用的任何库。

关于javascript - 实现 Hermite 插值 - 多人游戏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55302066/

相关文章:

c++ - 3D vector 的高效量级计算

javascript - PHP Javascript 动态指示单击的菜单项

mysql - Sequelize include 即使它是空的

node.js - Discord 机器人无法通过 ID 获取用户集合

javascript - Heroku 应用程序崩溃

python - 获取 K 组 N 成员和 L 组 M 成员的组合列表

javascript - 如何使用类装饰器将装饰器应用于所有类方法

javascript - 如何从 json 访问对象以自动下拉

javascript - ajax 发布后提交表单按钮卡住

algorithm - 在完美二叉树中获取顶点的父节点