首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >移动“算法”在客户端服务器多人游戏(MMO)游戏?

移动“算法”在客户端服务器多人游戏(MMO)游戏?
EN

Stack Overflow用户
提问于 2009-06-30 20:06:31
回答 3查看 12.8K关注 0票数 8

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

  • 客户端向服务器通报球员的移动模式(向前或不移动)和球员的转向模式(不转、转左或右转)。
    • 服务器每隔几毫秒循环一次所有玩家,并根据时间差计算转角和移动距离。同样的计算是由client.

完成的。

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

车削

代码语言:javascript
复制
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;
        }

运动

代码语言:javascript
复制
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)];
        }

这似乎很管用。为了考虑延迟,服务器不时地通过发送这些数据来纠正客户端的信息。

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-06-30 20:14:00

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

因此,如果您上一次报告的位置是X,那么下一个位置必须在离X的半径范围内,其中半径是基于客户机发送的时间戳与x,y数据之间的差异。

大多数情况下,这只是为了发现作弊。

停止、战斗等都需要在攻击的同时发送一个位置,而由位置触发的操作只有在客户端为该位置发送更新之后才会触发,而是基于服务器。

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

评论答复:

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

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

为了提高性能,甚至可以关闭欺骗检测,或者将其设置为随机检查。

注意:所有关于旅行范围内物体的碰撞/位置信息都需要发送到客户端,这样才能工作。

票数 6
EN

Stack Overflow用户

发布于 2009-06-30 23:51:56

有两种方法我可以这样做-让客户端发出命令到服务器&服务器将是最终的地图管理员。

或者,将地图保存在客户端中&客户端必须与他们“接近”的其他客户端建立联系,以便进行移动,记录保存由服务器完成,并由几个同行(黑客警察)检查。

我感兴趣的是监视对等连接的可能性,而延迟超过一定阈值的对等点就不会出现在游戏中。

票数 1
EN

Stack Overflow用户

发布于 2009-06-30 20:09:28

您的服务器是否速度太慢,无法处理所有的移动?尤其是在一场二维比赛中?通常情况下,当我做小2d游戏时,服务器会把我所有的动作都还给我,所以客户端不需要计算。如果服务器开始滞后,我只是冻结了一点,这通常是人们通常所期望的(尽管这种情况几乎从未发生)。

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

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1065758

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档