• 《action script大型网页游戏开发》读书笔记 (二)


    【 实时运动 】

    1)基于帧的运功。

        基于帧的运功,思路是这样的:如果一个画面里有A、B、C、D 4个角色,其中A由你自己控制,而B、C、D是由其他玩家控制的。A的移动完全实时监听我们在客户端的操作,也许是键盘也许是鼠标,总之,不会听服务器端的返回再去移动——这么做是为了不产生用户操作的延迟,当然,如果server端的返回信息说当前操作是非法的,用户的角色会抖动,返回到正确的位置上。而B、C、D的移动是如何实现的呢?在A的玩家电脑上,B、C、D三个角色会保存一个变量——目标坐标,然后会在每一帧中向目标坐标移动一定距离。如果B的玩家进行了移动,会向server端发出请求,然后server端会广播给A、B、C、D四个玩家B的新目标坐标。目标坐标是一直在变的,通过server端进行广播,然后在每帧中,除玩家本人的角色外,其它角色都会朝自己的目标坐标移动一步。

         简单地说,每个游戏对象都在不停地说“我在这里,我在这里,我在这里”,游戏对象并没有说将要往哪里去,只是说它在什么地方。这种方法的好处是易于编程。在时间同步不很重要的情况下它非常好用。而这种方法也有个主要的缺点,那就是:在某一时刻,运动中的游戏对象永远不会出现在它此刻应该在的位置。游戏对象的运动总是会有些延时,这是因为同步消息到达客户端之前需要一些时间。

          private function enterFrame(e:Event) : void {

              if (_myGuY != null){

                   checkKeys();

                   moveGuys();

                   if(getTimer() - _lastTimeSent > 500){

                         sendUpdate();

                   }

             }

          }

    当客户端收到sendUpdate()更新之后的server端通知时,会更新用户目标位置

       if(!guy.isMe){

          guy.walkTo(x,y);

       }

    注意:每500ms发送一次更新信息到server端是比较合适的,每稍2~3次发送更新信息就比较合适——如果超过这个频率,改送再多的信息也并不能让结果看起来更好,而且毫无裨益。

    2)网络延迟和服务器端时间。

         基于时间的运动,首先要说明的是,这个时间不是本地时间,而是server端时间,这是所有客户端应该达到的一个共识。获取server端时间必须先获得一个网络延迟时间。

          网络延迟的算法是从客户端发送一个请求至server端,server端广播回来,客户端接到到广播返回值的时间,从发送到返回的时间值除以2就是延迟时间。为了让延迟时间尽量精准,最好发送10次请求,然后去除10次请求中差导比较大的测量结果(如果某个测量值大于中间值的1.5倍,我们就可以断定该数据有问题然后舍弃它。),剩下的有价值的数据求一个平均值,就是比较精确的网络延时值了。

           具体来说,服务器端时间可以这么来求:客户端发送一个ping请求,接着服务器返回一个含有毫秒级时间标签的响应,随后客户端用下面这个简单的公式就能测算出服务器端的时间:

            server time = client time + offset

    而offset应该为

            offset = server time2 - client time2 + latency

    server time2为ping返回的服务器时间标签,client time2为响应到达时的客户端时刻,而latency为ping值的一半(即网络延迟)。

    3)基于时间的运动。

         基于时间的运动和帧的运功原理不同:当知道一个物体的当前位置、速度、加速度,就可以算出未来某个时刻物体的位置:

           x = x0 + vx * t + (1/2) * ax * t ^ 2

           y = y0 + vy * t + (1/2) * ay * t ^ 2

         一旦你接收到描述对象位置及其运动方向的信息后,你就可以继续让这个对象不断地运动下去。(不同于here I am的思路,运动路径是根据速度、方向、加速度自动计算的)。

        如果A、B两个玩家,A玩家向B玩家发射一颗子弹,子弹速度为100像素/秒,而“发射”子弹的消息在到达B玩家的客户端时,已经用去了150ms的时间,那么子弹在从被A发射出到B接收到信息的这段时间里共运动了15像素。所以当子弹被添加到B的屏幕上时,它应该按照上面的公式,直接出现在15像素处,而不是在枪口处。(在玩家A自己的电脑里,子弹是从枪口慢慢移动至15像素处的,而在玩家B的电脑里,一开始就是出现在15像素处)基于时间的运动,可以很好地处理“同步即时性要求高”的需求,但它他产生位置跳跃,也称“抖动”,游戏对象的加速度越大,它在客户端屏幕上的抖动也就越大。如果网络延时为0,当然也就不可能有抖动的现象发生。

          “网络延时隐藏”技术可以用来解决抖动的问题。这项技术通过尽量减小网络延时所带来的景程,为我们提供一种更为顺畅的游戏体验。在工业上也被称为“航位推测法”:在预测运动中加以平滑地修正航向,以使对象航向逐步收敛到正确航向。它需要先给定一个“收敛时间”,在这段时间里是用来纠正航向的,它会预测收敛时间后船的位置、航向和速度,用在“收敛时间”段里将船的当前位置、速度和方向调整为“收敛时间”后船的正确位置。“收敛时间”越短,船就越快地接近自己的真实位置,但抖动越大,而“收敛时间”越长,抖动越小,过程越平滑,但船离自己的真实位置越远。

          “加速度”是另一个用于处理抖动的技巧。当物体启动或停止时,不要让其马上变化状态,而是给一个加速时间,比如500ms,物体在急速运动忽然停住时,如果不给一个缓冲时间,基于时间同步的运动很可能会让其它客户端里出现“往回收”的现象。而如果给一个缓冲时间,而且这个缓冲时间要大于网络延迟,这个缓冲时间就可以解决“往回收”的现象。在玩家自己的电脑里,从满速到停止有一个整个500ms可用,物体有一个较慢的减速过程,而在其它玩家电脑里,从满速到停止有一个“500ms - 网络延迟”的时间用于减速,它是一个相对快得多的减速过程,利用不同的减速加速度,可以让不同玩家在同一时间点停住,避免“往回收”的现象。

         

    【 游戏流程 】

    玩家从大厅系统进入游戏时,有下面的流程:

    <1> 选择游戏列表中你想玩的游戏

    <2> 看到该游戏加载的画面

    <3> 游戏开始

    <4> 游戏中

    <5> 游戏结束

    <6> 返回游戏大厅

    而玩家将会存在并维持以下状态:

    <1> 等待状态

    <2> 初始化状态

    <3> 游戏进行状态

    <4> 游戏结束

    【 等距视图 】

    1)等距视图又被称为“2.5D”或者“3/4视图”。它是一种特殊的3D视图。

    2)等距视图中,区块形状为菱形。这种菱形按以下3步形成:

         <1> 绘制一个任意大小的正方形;

         <2> 把这个正方形旋转45度;

         <3> 把旋转后的正方形的高度缩放为原来的50%。

         菱形区块的宽度是高度的两倍,常见的区块尺寸是64 X 32或者 128 X 64。(2的倍数,计算起来速度快,对性能有帮助)。但有时过于精确也会有问题。如果所绘制的区块像素尺寸与64 X 32分毫不差,那么在所有区块之间就会产生一条很细的线。解决办法就是在所绘制的区块的宽度和高度上各加一个像素,但在排列区块时依然按照64 X 32来进行排列。将区块尺寸变成65 X 33就能消除那条小细线。

    3)等距视图的坐标问题。

          等距视图的坐标和真实的坐标系需要进行一个转换—— 先围绕其x轴旋转30度,再围绕其y轴旋转45度。

          public function Isometric(){

              var theta : Number = 30;

              var alpha : Number = 45;

              theta *= Math.PI / 180;

              alpha *= Math.PI / 180;

              _sinTheta = Math.sin(theta);

              _cosTheta = Math.cos(theta);

              _sinAlpha = Math.sin(alpha);

              _cosAlpha = Math.cos(alpha);        

          }

  • 相关阅读:
    《JavaScript高级程序设计》读书笔记 14章
    C# 程序集是啥
    C#之反射又是什么东西
    C#版 大数计算器加法
    C#版 大数计算器乘法
    我所认识的三层
    《JavaScript高级程序设计》读书笔记 56章
    C# 委托加深理解
    C#版 大数计算器减法
    C# 事件到底是什么
  • 原文地址:https://www.cnblogs.com/cly84920/p/4426629.html
Copyright © 2020-2023  润新知