2D游戏的战争迷雾实现方式
转自: http://bbs.gameres.com/forum.php?mod=viewthread&tid=201878&extra=page%3D16%26filter%3Dsortall%26sortall%3D1
在开发游戏的过程中,特别是地图编辑器中,需要利用最少的资源,实现最丰富的地形地貌。虽然现在众多的RPG开始使用整图,但是我们偶尔还是需要能够让玩家自己编辑地图,或者其他需要自动进行地图构建的功能。 另外,就是在一些策略类游戏里经常用到的战争迷雾,我试过自己编写Pixel Bender自己来编写过滤器而实现战争迷雾。不过效果不是很理想(速度太慢)。后来想到,可以利用地图拼接的原理来进行战争迷雾的实现。 数学原理 首先,我们先来看一下现成的地图拼接算法。下面是一张《魔兽争霸3》的地表素材。 看到了比较清楚的图片边界是吗?我们把这张图按照64X64进行一下切分 其实把图摆成这样是有原因的,现在,我们来看4张图:1号,2号,4号以及8号。可以发现,他们刚好是四个角落的素材。如果我们把一张64X64的图,再进行4等分,默认以0来标识,如下: 0 | 0 ---------------- 0 | 0 再把刚才所提到的4张图,根据编号和位置,填到上面的结构里,如: 1号图(右上角): 0 | 1 ---------------- 0 | 0 2号图(左上角): 2 | 0 ---------------- 0 | 0 4号图(右下角): 0 | 0 ---------------- 0 | 4 8号图(左下角): 0 | 0 ---------------- 8 | 0 或许你会很奇怪,我们为什么要定义这4个数字,下面,来做一些有趣的事情吧。 我们把4号结构和8号结构按照对应的位置相加,得到了什么? 0 | 0 ---------------- 8 | 4 此时,4个角落的数字相加,为0+0+4+8 = 12 12,这个数字貌似我们在前面的图中看到过,找找编号看。你会发现,刚好12就是下面连成一气的草地素材。 再做个其他试验?例如把8号和1号结构相加: 0 | 1 ---------------- 8 | 0 此时,4个角落的数字相加,为0+1+8+0=9 当然,9也刚好就是我们的素材里,右下和左上连成一气的草地素材。 数学原理:以1,2,4,8分别代表一个区块的4个角落的素材编号。当发生叠加时候,将角落里的值进行累加,最后,4个角的合即为地图区块所对应的编号。 程序实现 有了数学原理,下一步就是通过程序去实现他。首先,我们需要根据编号,来保存对应的素材,为了大家看的清楚,我用了比较笨的方法——二维数组,实际上,循环取一次就可以了。 然后,把图片中的各个部分取出来,放到一个数组去,数组的下表刚好就是这个图片素材的编号: 好了,这样,素材就准备好了。下面我们做一个地图试验一下 首先,生成一个空地图,还是用数组好了: 来看一下,当我们点击(或者说叫做地图的笔刷。。。)时,我们期望发生什么情况: 当我们点下鼠标时候,如图所示,我们会把鼠标指针所在的位置的顶点数值设置为4,而临近的顶点数值分别设置为8,1,2,刚好拼凑成上面这样的图形。 当然,同样用这样的方法在临近的位置点击,我们就会得到这样的效果: 如图,我们点击的鼠标位置,和上次点击一样,我们把点击的位置顶点值设置为4,临近顶点为8,1,2。而此时,因为这个顶点和上次的8号顶点其实在同一个Tile里,导致这个Tile内的顶点总和变成了12,所以更换了素材。于是我们得到了一个非常平滑的过度。 当然,再继续点下去,也是同样的算法,这里就不再赘述了。 来看一下后面的代码,点击的时候,当然是计算点击位置对应的区块,然后把改区块的右下角顶点值设置为4,这里要注意,如果这个顶点已经是4了,那就没必要再设置了。如果再设置,这个顶点变成了8,很显然就不对了。 然后就是根据现在的顶点,重新绘制地形: 战争迷雾扩展 同样的原理,只要我们把素材处理成战争迷雾的黑色和半透明,即可实现战争迷雾效果。 附:自己的感悟 (看了更加了解:1、http://blog.****.net/hust_xy/article/details/9712321 ,《C++游戏开发》笔记十三 平滑过渡的战争迷雾(一) 原理:Warcraft3地形拼接算法 2、http://blog.****.net/hust_xy/article/details/9611887,《C++游戏开发》笔记十四 平滑过渡的战争迷雾(二) 实现:真正的迷雾来了) 这是一个分散好的散图集,对应塞进一个数组 mapList,多张图片合成一张的时候,即加起来的和对应到mapList里去找一张对应的图片替换 2、这是根据 4 | 8 对应排列的一张图a,当a重叠到其他区域时,a里的4个小图数字对应被覆盖地图的数子相加求得4个和,然后4个和对应到mapList里找到对应的4张散图,分别替换掉被覆盖地图对应的4张小图 1 | 2 3、如下图b图是两张a图合成 如果将图a放在图b正中间,则变成下图 此时根据第2步骤里的理论,a的4张小图根据mapList散图数组里面找到对应4张散图如下图c图 将c图放到图b正中间,替换掉之前的图a,覆盖掉地图,则形成的迷雾图如下图d,过渡会比较圆滑 |