网页功能: 加入收藏 设为首页 网站搜索  
续《地图遮挡算法》
发表日期:2007-01-17作者:[转贴] 出处:  

Softboy:
看了你的关于《流星之舟地图遮挡算法》及其系列文章,有一些看法。
不过首先要声明的是我没有编过什么大程序,对你和天眼的文章也看不太懂,这里只是抱着学习的态度。(我认为我对这一类算法问题比较强)

关于物体的相互遮挡问题很复杂,我想最完整的解决方案就是建立三维方位数组。
实际上目前流行的三维游戏都会采用这一类方法,而且它们的数据比《流星之舟》更复杂。对于《流星之舟》这一类游戏来说,速度和内存占用方面应没有问题。

不过,对于《流星之舟》来说,我们还可以简化这个问题:
1、没有物体的空间重合
2、没有物体的相互遮挡
例如,人站在大树前面,人挡住了树,树叶也可能挡住人。
人站在水池中,水池边挡住了人,人也挡住了水池(这里含有空间重合问题)
3、物体的遮挡部分不扩散到周围。
例如,人站在房屋旁边,但并不在房屋之后,也可能被屋檐遮挡。这会使我下面给出的例子出现问题。
4、没有其他穿透问题。
例如,桌子的腿可能露出人腿、栏杆露出后面的物体等。
窗户半透明等等。

那么,我想知道下面的方案是否可行?

1、首先,对每一种物体进行分析,建立struct GameObject的结构来描述各种物体。
2、把不可移动的物体事先处理,这样可以加快运行速度。
3、建立两张map图表,一张用于进行关于游戏的各种运算,一张专门用于显示,当然,也可合而为一。
4、关于用于显示的图表,我这里给出了一个简化的例子。这个例子要求每次都重新处理全部物体。实际上应该可以找到更加技术的方法只处理和变化有关的物体。
5、这里要求采用天眼所说的“静态分图”?
6、合成完显示图表后,再在分图的基础上画出全部图案。
7、对map和GameObject的复杂化可能可以处理互相遮挡等问题。
8、当然,也可按天眼的方法只把图形分成列,但不同之处在于这里采用的是覆盖,而不是搜索。

总之,中心思想是数据和图像分开处理,游戏只是在显示时才用到图像数据。当然,如果你不愿意分图,在没有互相遮挡等问题时,也可先计算出物体的显示顺序,再整块整块地画图。不过,在计算显示先后顺序时,不需要用递归,可先建立静止物体显示先后顺序链表,再把动态人物插入列表中。这种显示方法的好处是可部分解决穿透问题。
如有互相遮挡等问题,你一定要采用分图技术。

===================================================
      struct GameObject包括Number表示该物体一共占有的方格数。

      ShelteredNumber表示该物体阴影占的方格数。

data指向一一维列表,x、y分别表示该方格相对该物体的位置。

其中前Number个元素指向该物体根部占据的位置。

ID:该物体的ID。

mapstruct为地图结构,其中的主要元素为:

ID:地表元素ID

CoverID:物体元素ID

CoverObjectNumber:该处相对于该物体所在的位置
      ===============================================

      A:指向GameObject结构的指针

ObjectID:A物体的ID。注意:可能有不同的ObjectID之相同一A

x、y是该物体所在的位置

对于每一个物体,进行如下处理:

int i;

for (i=0; i< A->Number+A->ShelteredNumber; i++)//对A物体的每一个区域进行处理
{
    int mapx,mapy;
    struct mapstruct *mapdeal;
    mapx=x+A->data[i].x;
    mapy=y+A->data[i].y;
    mapdeal=&map[mapx][mapy]; //使用指针以避免重复的数组下标计算
    // TempObject=GetObjectPtr(mapdeal->CoverID);//由ID获得GameObject指针
    //如CoverID=0,则返回NULL
    if (IsNotSheltered(A,mapdeal->CoverID))//A没有被TempObject遮挡
    { //则应当显示A物体
        mapdeal->CoverID=ObjectID;
        mapdeal->CoverObjectNumber=i;
    }
}

====================================================

BOOL IsNotSheltered(GameObject *A,ObjectNumber ID)
{
    BOOL judge=TRUE;

    if (ID==0) return TRUE; //如果没有B物体则不被遮挡

    ASSERT(没有互相遮挡,物体不能重叠);

    for (int i=0; i< A->Number ; i++)
    {
        if (map[x+A->data[i].x][y+A->data[i].y].CoverID==ID)
        //如果A物体根部所在的位置被物体ID遮挡,则A物体一定在
        { //物体ID之后-----参看ASSERT
            judge=FALSE;
            break;
        }
    }

    return judge;
}

 

我来说两句】 【加入收藏】 【返加顶部】 【打印本页】 【关闭窗口
中搜索 续《地图遮挡算法》
本类热点文章
  脚本系统的实现
  C++基本功和 Design Pattern系列(2) Ty..
  C++基本功和 Design Pattern系列(1) - ..
  斜45度游戏开发(提高篇)
  睱酵笴栏祘Α砞璸?? - [秈顶絞]
  斜45度游戏开发(二)
  第一次写技术文献。Collision AI
  斜视角游戏中遮挡的判断
  C语言基本功教程系列(5) - 文件, Socke..
  用rand()和srand()产生伪随机数的方法总..
  C++基本功和 Design Pattern系列(3) co..
  C语言基本功教程系列(1)
最新分类信息我要发布 
最新招聘信息

关于我们 / 合作推广 / 给我留言 / 版权举报 / 意见建议 / 广告投放  
Copyright ©2003-2024 Lihuasoft.net webmaster(at)lihuasoft.net
网站编程QQ群   京ICP备05001064号 页面生成时间:0.00453