【问题标题】:Problems With Client Side Prediction for X-Velocity in JavaScriptJavaScript 中 X 速度的客户端预测问题
【发布时间】:2022-11-06 15:59:36
【问题描述】:

所以我正在尝试使用 JavaScript 和 WebSockets 编写一个简单的在线多人游戏。 我目前正在努力解决滞后问题: 为此,我测量了包含玩家更新位置的消息从玩家的计算机到服务器,然后到所有其他玩家的计算机所花费的时间,然后我根据该位置向该位置施加物理力数量。 我使用播放器类上的方法应用了物理,如下所示:

  // dt is deltaTime
  update(dt) {
    const groundLevel = 350;

    this.yVal += this.weight * dt;
    this.y += this.yVal * dt;
    if (this.y > groundLevel) {
      while (this.y > groundLevel) {
        this.y -= this.yVal / Math.abs(this.yVal);
      }
      this.yVal = 0;
    }

    this.xVal /= this.friction * dt;
    this.x += this.xVal * dt;
  }

然后我在获取更新位置时重复调用该函数,如下所示:

  // p is the player
  // data is the object sent by the server containing the required data, and data.data is the player's transform data.
  p.setData(data.data);
  // 16.4 is about 1/60 seconds - simulating the average fps of 60
  // data.time is the time when the message was sent.
  let timeTook = new Date().getTime() - data.time;
  for (let i = 0; i < timeTook ; i += 16.4) {
    p.update(16.4);
  }

这适用于 y 位置: 正如您在this clip 中看到的那样 - 我模拟了 1 秒的延迟 - 在 1 秒延迟之后,对象跳到它应该出现的确切位置。

然而,当我尝试向左或向右移动玩家时,位置变得很偏离! 正如您在this clip 中看到的那样 - 具有相同的滞后 - 对象在一个窗口中的移动比在另一个窗口中移动得更远。

我不知道为什么会发生这种情况,或者为什么它只发生在 x 位置,我希望能得到任何帮助。

【问题讨论】:

    标签: javascript websocket game-development multiplayer


    【解决方案1】:

    我解决了!

    原来我的问题与我处理位置更新的方式无关,而是与我的update 方法有关: 基本上,当我写道:

    this.xVal /= this.friction*dt
    

    我这样做是为了让xVal 属性根据增量时间更快/更慢。

    让我解释:

    假设我的起始 xVal 为 1,friction 为 1.5,并且我有 2 台不同的计算机运行更新功能 1 秒。但一台计算机以 2fps 运行,另一台以 4fps 运行。 这意味着一台计算机将运行此代码两次:

    // 1.5*500=750 (500 is dt)
    this.xVal /= 750;
    

    这导致xValof 1/562500。 但是另一台计算机会运行 4 次:

    // 1.5*250=375 (500 is dt)
    this.xVal /= 375;
    

    这导致xValof 1/52787109.375。 如您所见,一个会比另一个移动得更快,这是一个问题。

    为了解决这个问题,我们可以更改代码,使其从xVal 中减去而不是除以它:

    // Checks if the subtraction wouldn't flip the direction
    if (Math.abs(this.xVal) > this.friction * dt)
      // If it isn't, it subtracts
      this.xVal -=
      this.friction * dt
      // Makes the subtraction poisitve/negative depending on whether the current xVal is poisitve/negative.
      * (this.xVal / Math.abs(this.xVal));
    // If it is it sets xVal to 0
    else this.xVal = 0;
    

    【讨论】:

      【解决方案2】:

      如果您只是通过服务器发送信号而不是位移值并在另一侧的evey信号上调用运动函数,那么它会执行相同的运动怎么办。而不是实时位置的修正?

      【讨论】:

        猜你喜欢
        • 2019-01-21
        • 2019-08-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-17
        • 2016-06-10
        • 2015-05-17
        相关资源
        最近更新 更多