【问题标题】:Player positions server side or client side?玩家位置服务器端还是客户端?
【发布时间】:2016-03-23 14:58:07
【问题描述】:

我刚刚使用 socket.io 制作了 Pong 游戏的多人浏览器实现,并且有一个关于实时物流的问题。基本上,玩家的桨只是一个彩色的 div,根据他们按下的按钮上下移动。当我使用 AWS 在两台不同的计算机上测试我的程序时,我注意到运动几乎完全同步,但有时并不精确。对于控制桨的玩家,他们的桨的移动是在本地完成的,但对于他们正在与服务器对战的人来说,他们会不断地向他们发送他们的对手是向上还是向下移动的数据。

我的问题是我应该在服务器端进行所有移动吗?就像用户按下向上键,它向服务器发送一个请求,该请求向两个玩家发出桨应该移动的请求,或者我的方式是在本地完成桨的移动吗?

我现在的代码如下所示:

客户端检查是否按下向上或向下按钮并发出移动请求:

paddleMove = 0; // Keep track of which direction to move
speed = 5; 
    if (paddleL.position().top > arena.position().top){ // If left paddle not at top
        if (keysPressed.up) paddleMove -= speed;
    }
    if (paddleL.position().top+paddleL.height() < arena.position().top + arena.height() - 15){ // If left paddle not at bottom
        if (keysPressed.down) paddleMove += speed;
    }
    paddleL.css({  // Move paddle locally
        top: paddleL.cssNumber('top') + paddleMove + 'px'
    });
    socket.emit("moveReq", paddleMove); // Send to server 

上面的代码是在每隔几分之一秒运行的时间间隔内。

那么服务器端是这样的:

socket.on('moveReq', function(data){   // Send to opponent that other paddle moved
    socket.broadcast.emit("movePaddle", data);
});

这反过来又提醒用户端代码的另一部分移动另一个桨:

socket.on("movePaddle", function(data){

        var paddleMove = 0;
        paddleMove += data; // Data is speed (direction) of movement
        paddleR.css({ // Move right paddle
            top: paddleR.cssNumber('top') + paddleMove + 'px'
        });

正如我所说,现在的运动非常好,但并不完美。我是否应该不进行任何本地移动并使其全部在服务器上发出?

【问题讨论】:

  • Imo 你应该在客户端做动作并在特定时间与服务器端同步,在这种情况下,当球触摸桨时,这样你就可以防止服务器过载并防止黑客攻击。

标签: node.js socket.io pong


【解决方案1】:

目前我什至正在使用网络套接字开发多人游戏。 如果您想要实时播放器位置,则需要大量带宽。

到目前为止,我们所做的是 预测和 lerping 。 假设有两个名为 A 和 B 的玩家相连。

假设播放器 A 默认在 x=0 (t=0) 上,所以在 B 上它也将在 x=0 上。 现在我们要做的是开始每 1 秒发射 A 的 x 位置(取决于你的游戏,如果 fps 则降低值)

1 秒 (t=1) 后,A 的位置在 x=2 上(根据您的说法是 2px)。 B 在 1.2 秒后收到 A 的位置(由于网络问题考虑延迟)。现在我们必须从 x=0 到 x=1 预测时间的位置。 (这一切都可以通过脚本来实现)

基本公式(这将在更新函数中完成)

CurrentXposition = (NewXPosition - CurrentXPosition) * deltatime ;

嗯,你一定要在上面的公式上工作。每次我们收到新的位置时,都会计算 deltatime。所以在这里我们使用 deltatime 进行 lerp 和预测。

Lerping 将平滑玩家的移动,作为预测的 deltatime 将根据接收到的位置设置 lerping 的正确时间和平滑度。

Refer this blog for more into this ,

And This for lerping formula

【讨论】:

  • 感谢您。不过我遇到了一些麻烦。我每 250 毫秒左右发送一次NewXPosition,但是在插值时,只要NewXPosition 更新,如果你愿意,字符就会“跳跃”。我应该以与游戏 fps 相同的速率发送新的 lerping 值吗?
  • 您可以通过两种方式处理位置同步。一种是通过每秒发送 10 帧或按键来发送位置。当您使用时间戳接收每一帧时,您必须计算 deltaTime 。即从上一帧经过的时间,游戏更新率之间的差异,以及你必须使用一些逻辑来模拟物理。
【解决方案2】:

立即在客户端更新位置。然后将移动消息发送到服务器。 当您从服务器收到消息时,将位置同步到服务器的值。

这样,客户端移动在不稳定或高延迟连接上仍然看起来很流畅。然而,在某些极端情况下,客户端可能会非常不同步,以至于球拍似乎处于一个不同步的位置(球可能似乎穿过球拍)——尽管无论哪种方式,高 ping 都可以解决问题

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-29
    • 1970-01-01
    • 2015-11-04
    • 2018-06-06
    • 1970-01-01
    • 2020-07-18
    • 2011-04-30
    相关资源
    最近更新 更多