客户端 - 服务器多人游戏(MMO)游戏中的运动"算法"?

Tom*_*Tom 8 sockets animation multiplayer

我一直在写2D闪存多人游戏和套接字服务器.我对客户端和服务器之间的移动算法的原始计划如下:

  • 当这些改变时,客户端向服务器通知玩家的移动模式(向前移动或不移动)和玩家的转向模式(不转动,向左转或向右转).
    • 服务器每隔几毫秒循环所有玩家,并根据时间差计算转动的角度和移动的距离.客户端完成相同的计算.

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

车削

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;
        }
Run Code Online (Sandbox Code Playgroud)

运动

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)];
        }
Run Code Online (Sandbox Code Playgroud)

这似乎很有效.为了考虑滞后,服务器会不时地通过发送此数据来更正客户端的信息.

使用该系统,使用非常小的带宽来处理移动.但是,我的服务器和客户端的坐标和角度之间的差异太大.我是否应该扩展我的"算法",还要考虑用户的延迟?或者是否有更好的方法来处理客户端<>服务器多人游戏中的移动性能?

Bil*_*l K 6

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

因此,如果您上次报告的位置是X,则下一个位置必须在距离X的半径范围内,其中半径基于客户端使用x,y数据发送的时间戳的差异.

大多数情况下,只需要检测作弊行为.

停止,战斗等需要与攻击一起发送一个位置,并且只有在客户端发送该位置的更新但基于服务器之后才会触发由位置触发的操作.

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

评论回复:

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

我想我只是说让客户做所有的工作,弄清楚角色在哪里并告诉服务器,但包含足够的信息,服务器可以选择检查有效性以确保没有人作弊.

甚至可以关闭作弊检测的性能或设置为随机检查.

注意:需要将行程范围内对象的所有碰撞/位置信息发送给客户端才能使其正常工作.