zoukankan      html  css  js  c++  java
  • 基于格子的AOI算法

    AOI( Area Of Interest )是网游服务器中必不可少要考虑的一个问题,当前主流的AOI算法依然是
    基于2D的格子的, 场景均分成为等大的格子,每个Entity都根据其位置放到所属格子的链表中.

    关键问题是当Entity移动后:
    一是要找到该Entity看到了哪些新的otherEntitys,
    二是要找到哪些otherEntitys以前可以看到而现在看不到了,
    三是要找到该Entity被哪些新的otherEntitys看到了,
    四是要找出以前看得到自己现在看不到自己的otherEntitys.


    1, 假定所有Entity的看到见的格子的数量都一样,为N*N,这意味着自己看得见的Entity也一定看得见自己,而
    自己看不见的Entity也一定看不见自己.因此当Entity移动后:

    <1>,找出Entity移动后新增的可见格子,将这些格子中的其它Entity加入自己的可见列表中(或者通知客户端有新的Entity可见).
    <2>,找出Entity移动前可见而移动后不可见的格子,将这些格子中的其它Entity从自己的可见列表中移除(或者通知客户端这些Entity不可见).
    <3>,找出Entity移动后新增的可见格子,将自已加入到这些格子中的其它Entity的可见列表中(或者通知其对应的客户端有新的Entity可见).
    <4>,找出Entity移动前可见而移动后不可见的格子,将自己从这些格子中的其它Entity的可见列表中移除(或者通知其对应的客户端本Entity不可见).

    2, 如果每个Entity的视野大小不等。每个格子增加一个observerGrids链表,保存所有"存在看得见该格子的对象"的格子。
    当Entity移动后:
    假定Entity移动前所在的gird命名为oldGrid, 移动后所在的grid命名为newGrid.

    <1>,找到该Entity看到了哪些新的otherEntitys. 
     
        找出Entity移动后新增的可见格子, 记为newVisibleGrids.    
        算法如下:

        foreach nGrid in newVisibleGrids
        {
             foreach nEntity in nGrid.entityList
             {
                 将nEntity加入到thisEntity的可见列表中.(通知thisEntity对应的客户端nEntity可见).
             }
             将newGrid加入nGrid.observerGirds中.
        }

    <2>,找到哪些otherEntitys以前可以看到而现在看不到了.
       
        找出Entity移动前可见而移动后不可见的格子,记为newHideGrids.
        算法如下:

        foreach nhGrid in newHideGrids
        {
           //找出以前看得到而移动后看不到的entity.
           for nhEntity in nhGrid.entityList
           {
              把nhEntity从thisEntity的可见列表中移除(通知客户端nhEntity不可见).
           } 
           如果oldGrid.entityList中的所有entity都看不见nhGrid,则将oldGrid从nhGrid.observerGrids中移除.      
        }
        注:可以考虑在每个grid中记下所属entity的最大视野,最小视野,平均视野优化移除算法.
             
    <3>,找到该Entity被哪些新的otherEntitys看到了. 

            foreach nGrid in newGrid.observerGrids
            { 
                   //优化:这里可以先排除掉同时存在于oldGrid.observerGrids中的nGrid?
                   foreach otherEntity in nGrid.entityList
                   {
                       oldDist = otherEntity.pos - thisEntity.oldPos; //oldPos为entity移动前的位置.
                       newDist = otherEntity.pos - thisEntity.pos;
                       //检测对于otherEntity来说是否为新增的可见entity.
                       如果oldDist > otherEntity.viewDist 且 newDist <= otherEntity.viewDist
                          将thisEntity加入到otherEntity的可见列表中(通知otherEntity对应的客户端thisEntity可见).
                   }          
            }

    <4>,找出以前看得到自己现在看不到自己的otherEntitys.
            foreach oGrid in oldGrid.observerGrids
            { 
                   //优化:这里可以先排除掉同时存在于newGird.observerGrids中的oGrid?
                   foreach otherEntity in oGrid.entityList
                   {
                       oldDist = otherEntity.pos - thisEntity.oldPos; //oldPos为entity移动前的位置.
                       newDist = otherEntity.pos - thisEntity.pos;
                       //检测对于otherEntity来说是否为新增的不可见entity.
                       如果oldDist <= otherEntity.viewDist 且 newDist > otherEntity.viewDist
                          将thisEntity从otherEntity的可见列表中移除(通知otherEntity对应的客户端thisEntity不可见).
                   }          
            }
     

     
    3,考虑多重感知系统,如视觉,听觉,嗅觉并存时的情况.
      比如:一个Entity隐身后无法被视觉感知,但可以被听觉和嗅觉感知.

  • 相关阅读:
    窗体设计器出不来
    maven ...../.m2/settings.xml
    myeclipse.ini
    人民币大小写
    驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立 安全连接。错误:
    写了一个浏览器插件
    用Excel计算加权平均分和GPA
    cfree使用cygwin编译程序出现计算机丢失cygwin1.dll解决办法
    apt-cyg update --2017-02-17 07:57:24-- http://mirrors.163.com/cygwin//x86_64/setup.bz2 正在解析主机 mirrors.163.com... 123.58.173.185, 123.58.173.186 正在连接 mirrors.163.com|123.58.173.185|:80... 已连接。 已发出 HTT
    生产者消费者问题
  • 原文地址:https://www.cnblogs.com/corefans/p/1529699.html
Copyright © 2011-2022 走看看