【问题标题】:Movement "algorithm" in client-server Multiplayer (MMO) Games?客户端-服务器多人 (MMO) 游戏中的运动“算法”?
【发布时间】:2009-06-30 20:06:31
【问题描述】:

我一直在编写一个 2D Flash 多人游戏和一个套接字服务器。我最初对客户端和服务器之间的移动算法的计划如下:

  • 每当这些变化时,客户端都会通知服务器玩家的移动模式(向前或不移动)和玩家的转弯模式(不转弯、左转或右转)。
    • 服务器每隔几毫秒循环一次所有玩家,并根据时间差计算转角和移动距离。客户端进行相同的计算。

我当前对客户端的计算(在服务器中使用相同的数学)==>

转弯

var newTimeStamp:uint = UtilLib.getTimeStamp(); //set current timeStamp
                var rot:uint = Math.round((newTimeStamp - turningTimeStamp) / 1000 * 90); //speed = x degrees turning every 1 second
                turningTimeStamp = newTimeStamp; //update timeStamp
                if (turningMode == 1) //left
                {
                    movementAngle = fixAngle(movementAngle - rot);
                }
                else if (turningMode == 2) //right
                {
                    movementAngle = fixAngle(movementAngle + rot);
                }

private function fixAngle(angle:int):uint //fixes an angle in degrees (365 -> 5, -5 -> 355, etc.)
        {
            if (angle > 360)
            {
                angle -= (Math.round(angle / 360) * 360);
            }
            else if (angle < 0)
            {
                angle += (Math.round(Math.abs(angle) / 360) + 1) * 360;
            }
            return angle;
        }

运动

var newTimeStamp:uint = UtilLib.getTimeStamp(); //set current timeStamp
                var distance:uint = Math.round((newTimeStamp - movementTimeStamp) / 1000 * 300); //speed = x pixels forward every 1 second
                movementTimeStamp = newTimeStamp; //update old timeStamp
                var diagonalChange:Array = getDiagonalChange(movementAngle, distance); //with the current angle, howmuch is dX and dY?
                x += diagonalChange[0];
                y += diagonalChange[1];

private function getDiagonalChange(angle:uint, distance:uint):Array
        {
            var rAngle:Number = angle * Math.PI/180;
            return [Math.round(Math.sin(rAngle) * distance), Math.round((Math.cos(rAngle) * distance) * -1)];
        }

这似乎工作得很好。为了考虑延迟,服务器不时通过发送此数据来更正客户端的信息。

有了这个系统,很少有带宽用于处理移动。但是,我的服务器和客户端的坐标和角度之间的差异太大了。我是否应该扩展我的“算法”,以考虑用户的延迟?或者有没有更好的方法来处理客户端服务器多人游戏中的运动并具有出色的性能?

【问题讨论】:

    标签: sockets animation multiplayer


    【解决方案1】:

    我的初始设计与您的类似,但如果这不起作用,也许您可​​以让客户端完成所有移动,而让服务器进行一些范围检查。

    因此,如果您上次报告的位置是 X,则下一个位置必须在 X 的半径范围内,该半径基于客户端发送的带有 x,y 数据的时间戳的差异。

    大多数情况下,这只是检测作弊所需要的。

    停止、战斗等需要与攻击一起发送位置,并且位置触发的动作只会在客户端发送该位置的更新后触发,但将基于服务器。

    不确定这是否会有太大帮助,但它可能会阻止您从初始算法中看到的颠簸重新同步。

    评论回复:

    不,客户端仍会通知服务器他们的位置,但服务器不会尝试计算下一个位置。这意味着服务器(和所有其他客户端)将至少落后一个发送/接收周期。

    我想我的意思是让客户端完成所有工作,找出角色在哪里并告诉服务器,但要包含足够的信息,以便服务器可以选择检查有效性以确保没有人作弊。

    甚至可以关闭作弊检测以提高性能或设置为随机检查。

    注意:所有在行驶范围内的物体的碰撞/位置信息都需要发送给客户端才能正常工作。

    【讨论】:

    • 如果所有客户端都必须通知所有其他客户端他们当前的位置,服务器是否必须继续接收和重新发送大量消息?
    • +1 我实际上打算提出同样的建议。这就是许多流行的多人视频游戏所做的。服务器只是确保每个人都定期同步。 (我相信雷神之锤游戏就是这样做的。)
    • 好吧,我的第一个问题仍然适用。客户端不是必须一直发送数千条消息以使服务器在每一步都保持最新状态吗?随后服务器再次将此数据发送给附近的所有玩家。
    • '一直有数千条消息'有点夸张,但客户端每秒通知服务器 10 次左右的位置并让服务器广播的情况并不少见其中大部分以类似的频率退出。
    • 此外,如果您每秒向服务器发送 10 次更新,您可能会忽略/错过一些更新,而几乎没有或没有负面影响。
    【解决方案2】:

    我可以想到两种方法 - 让客户端向服务器发出命令,而服务器将成为最终的地图管理员。

    或者,将地图保存在客户端中,并且客户端必须与他们“附近”的其他客户端建立连接才能进行移动,记录保存由服务器完成并由几个对等方检查(黑客警察)。

    让我感兴趣的是监控对等连接的可能性,延迟超过特定阈值的对等将不会出现在游戏中。

    【讨论】:

    • 很有趣,但是这种限制了大型战斗,因为 P2P 无法同时处理那么多连接 - 您现在还依赖客户端的连接来处理其他客户端。我还在寻找最好的服务器客户端系统。
    • 为什么P2P不能处理很多连接?每次有人做某事时,您要么需要来自服务器的重播,要么需要来自对等方的消息。我以为流量差不多(我可能错了)。
    【解决方案3】:

    您的服务器是否太慢以至于无法处理所有移动?尤其是在二维游戏中?通常,当我制作小型 2d 游戏时,服务器会返回我所有的动作,因此客户端不需要计算。如果服务器开始滞后,我会稍微冻结一下,这通常是人们通常所期望的(尽管这几乎不会发生)。

    无论如何,我肯定会在没有客户自己进行任何实际计算的情况下看到性能如何。如果性能不够好,请查看在服务器上循环播放玩家动作是否会导致延迟(并开始为每个客户端使用不同的线程)。

    如果带宽确实存在真正的限制(运动本身传递的数据很少),那么您当然需要找到该特定用户的平均延迟并将其计算到算法中。但是,为了不断地找到平均值(为了精确),您必须继续 ping 服务器以找到往返时间,这不应该是那么昂贵。

    【讨论】:

    • 这不是一个小小的 2D 游戏。它应该同时处理数百名玩家。我需要尽可能优化系统。
    • hmm,在这种情况下,必须调整服务器以便它以足够小的间隔发送数据。当然,所有服务器都需要某种玩家上限,但至少在客户端移动端增加 10-20 毫秒的延迟。它几乎不引人注意,并且在大多数情况下应该与玩家的实际位置相对应。
    猜你喜欢
    • 2010-11-29
    • 1970-01-01
    • 1970-01-01
    • 2021-05-08
    • 2018-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-14
    相关资源
    最近更新 更多