在开发游戏的过程中,特别是地图编辑器中,需要利用最少的资源,实现最丰富的地形地貌。虽然现在众多的RPG开始使用整图,但是我们偶尔还是需要能够让玩家自己编辑地图,或者其他需要自动进行地图构建的功能。
另外,就是在一些策略类游戏里经常用到的战争迷雾,我试过自己编写Pixel Bender自己来编写过滤器而实现战争迷雾。不过效果不是很理想(速度太慢)。后来想到,可以利用地图拼接的原理来进行战争迷雾的实现。

数学原理

首先,我们先来看一下现成的地图拼接算法。下面是一张《魔兽争霸3》的地表素材。

<ignore_js_op>

看到了比较清楚的图片边界是吗?我们把这张图按照64X64进行一下切分

<ignore_js_op>

其实把图摆成这样是有原因的,现在,我们来看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个角的合即为地图区块所对应的编号。

程序实现

有了数学原理,下一步就是通过程序去实现他。首先,我们需要根据编号,来保存对应的素材,为了大家看的清楚,我用了比较笨的方法——二维数组,实际上,循环取一次就可以了。

  1. // 用一个数组来标记图形中各个位置的编号
  2. var config:Array = [
  3. [0,4,8,12],
  4. [1,5,9,13],
  5. [2,6,10,14],
  6. [3,7,11,15],
  7. ];

复制代码

然后,把图片中的各个部分取出来,放到一个数组去,数组的下表刚好就是这个图片素材的编号:

  1. // 用来存放图片素材的数组
  2. var lib:Array = new Array();
  3. var bitmap:BitmapData;
  4. // 源素材,就是我们上面的那张PNG
  5. var bd:BitmapData = new BMD();
  6. var py:uint;
  7. var px:uint;
  8. // 进行切割
  9. for(py = 0;py<config.length;py++)
  10. {
  11. var line:Array = config[py];
  12. for(px = 0;px < line.length;px++)
  13. {
  14. bitmap = new BitmapData(128,128,true,0);
  15. bitmap.copyPixels(bd,new Rectangle(px*128,py*128,128,128),new Point(),null,null,true);
  16. // 把素材编号作为下表进行素材的保存
  17. lib[line[px]] = bitmap;
  18. }
  19. }

复制代码

好了,这样,素材就准备好了。下面我们做一个地图试验一下

首先,生成一个空地图,还是用数组好了:

  1. var arr:Array = new Array();
  2. // 生成10X10的地图
  3. for(py=0;py<10;py++)
  4. {
  5. var data:Array = new Array();
  6. for(px=0;px<10;px++)
  7. {
  8. // 每个地图区块包含4个顶点数据,默认为0
  9. data.push([0,0,0,0]);
  10. }
  11. arr.push(data);
  12. }

复制代码

来看一下,当我们点击(或者说叫做地图的笔刷。。。)时,我们期望发生什么情况:

<ignore_js_op>

当我们点下鼠标时候,如图所示,我们会把鼠标指针所在的位置的顶点数值设置为4,而临近的顶点数值分别设置为8,1,2,刚好拼凑成上面这样的图形。

当然,同样用这样的方法在临近的位置点击,我们就会得到这样的效果:

<ignore_js_op>

如图,我们点击的鼠标位置,和上次点击一样,我们把点击的位置顶点值设置为4,临近顶点为8,1,2。而此时,因为这个顶点和上次的8号顶点其实在同一个Tile里,导致这个Tile内的顶点总和变成了12,所以更换了素材。于是我们得到了一个非常平滑的过度。

当然,再继续点下去,也是同样的算法,这里就不再赘述了。

<ignore_js_op>

来看一下后面的代码,点击的时候,当然是计算点击位置对应的区块,然后把改区块的右下角顶点值设置为4,这里要注意,如果这个顶点已经是4了,那就没必要再设置了。如果再设置,这个顶点变成了8,很显然就不对了。

  1. stage.addEventListener(MouseEvent.CLICK,onClick);
  2. function onClick(e:MouseEvent):void
  3. {
  4. // 计算区块
  5. var _mx:uint = int(e.stageX/64);
  6. var _my:uint = int(e.stageY/64);
  7. // 区块顶点设置,3右下 2右上 1左下  0左上
  8. if(arr[_my][_mx][3]!=4) arr[_my][_mx][3]+=4; // 当前区块的右下
  9. if(arr[_my][_mx+1][1]!=8) arr[_my][_mx+1][1]+=8; // 右边区块的左下
  10. if(arr[_my+1][_mx][2]!=1)arr[_my+1][_mx][2]+=1; // 下面区块的右上
  11. if(arr[_my+1][_mx+1][0]!=2)arr[_my+1][_mx+1][0]+=2; // 下面右边区块的左上
  12. reDraw();
  13. }

复制代码

然后就是根据现在的顶点,重新绘制地形:

  1. var resBD:BitmapData = new BitmapData(640,640,true,0xff000000);
  2. addChild(new Bitmap(resBD));
  3. function reDraw():void
  4. {
  5. resBD.fillRect(resBD.rect,0);
  6. for(py=0;py<10;py++)
  7. {
  8. for(px=0;px<10;px++)
  9. {
  10. var b:uint=arr[py][px][0]+arr[py][px][1]+arr[py][px][2]+arr[py][px][3];// 计算顶点合
  11. if(b==0) continue;
  12. if(b>15) b=15; // 超出15的顶点合是没有意义的。在魔兽争霸里,超出15会随机一个填充满的样式以丰富地表
  13. resBD.copyPixels(lib[b],lib[b].rect,new Point(px*64,py*64),null,null,true);
  14. }
  15. }
  16. }

复制代码

战争迷雾扩展

同样的原理,只要我们把素材处理成战争迷雾的黑色和半透明,即可实现战争迷雾效果。

<ignore_js_op>

<ignore_js_op>

原帖地址:http://bbs.9ria.com/thread-157487-1-1.html

[转] AS3地图拼接与战争迷雾的实现的更多相关文章

  1. 《C++游戏开发》笔记十二 战争迷雾:初步实现

    本系列文章由七十一雾央编写,转载请注明出处.  http://blog.csdn.net/u011371356/article/details/9475979 作者:七十一雾央 新浪微博:http:/ ...

  2. 平滑过渡的战争迷雾(一) 原理:Warcraft3地形拼接算法

    本系列文章由七十一雾央编写,转载请注明出处.  http://blog.csdn.net/u011371356/article/details/9611887 作者:七十一雾央 新浪微博:http:/ ...

  3. 《C++游戏开发》笔记十三 平滑过渡的战争迷雾(一) 原理:Warcraft3地形拼接算法

    本系列文章由七十一雾央编写,转载请注明出处.  http://blog.csdn.net/u011371356/article/details/9611887 作者:七十一雾央 新浪微博:http:/ ...

  4. 《C++游戏开发》笔记十四 平滑过渡的战争迷雾(二) 实现:真正的迷雾来了

    本系列文章由七十一雾央编写,转载请注明出处.  http://blog.csdn.net/u011371356/article/details/9712321 作者:七十一雾央 新浪微博:http:/ ...

  5. Unity3D高性能战争迷雾实现

    效果图 先上效果图吧,这是为了吸引到你们的ヽ(。◕‿◕。)ノ゚ 战争迷雾效果演示图 战争调试界面演示图 由于是gif录制,为了压缩图片,帧率有点低,实际运行时,参数调整好是不会像这样一卡一顿的. 战争 ...

  6. Unity3D游戏高性能战争迷雾系统实现

    一 效果图 先上效果图吧,这是为了吸引到你们的ヽ(。◕‿◕。)ノ゚ 战争迷雾效果演示图 战争迷雾调试界面演示图 由于是gif录制,为了压缩图片,帧率有点低,实际运行时,参数调整好是不会像这样一卡一顿的 ...

  7. Unity3D战争迷雾效果

    原地址:http://liweizhaolili.blog.163.com/blog/static/16230744201431835652233/ 最近一直都在做Flash相关的东西,很久没有空搞U ...

  8. unity中绘制战争迷雾

    接上一篇中说的游戏,我们已经实现了client.host上的一个物体可见不可见的行为.之后我们可以加入类似检查两个单位之间的距离.或是两个单位之间有无阻挡物来进一步实现游戏机制. 在这篇随笔中我会首先 ...

  9. Laya中地图拼接的缝隙问题

    拼图的空隙. Egret也有拼图的空隙.比如制作飞机游戏,背景拼接轮换着下移,有明显的缝隙.用TextureMerger可以解决. 看了下Laya.可以设置repeat. 编辑模式,图片上右键,设置默 ...

随机推荐

  1. 前端之CSS样式

    一.CSS 1.什么是CSS 层叠样式表(英文全称:Cascading Style Sheets)是一种用来表现HTML(标准通用标记语言的一个应用)或XML(标准通用标记语言的一个子集)等文件样式的 ...

  2. Python编程-常用模块及方法

    常用模块介绍 一.time模块 在Python中,通常有这几种方式来表示时间: 时间戳(timestamp):通常来说,时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量.我们运行 ...

  3. 以太坊钱包Geth使用命令

    一.启动以太坊钱包Geth 打开一个控制台,执行同步区块命令 #同步测试链geth --fast --cache=512 --rpc --rpcapi personal,db,eth,net,web3 ...

  4. canvas 视频音乐播放器

    canvas 视频音乐播放器 var play_nor_img_path = 'images/play_btn_n.png'; //播放按钮 正常时 60x60 px var play_sec_img ...

  5. Qt打包过大

    经常看到网上有些论调说 Qt 程序无比庞大,甚至拿 .NET 程序来比,说 Qt 程序打包以后跟 .NET 安装包差不多大.由此影响了很多人对 Qt 的选择.我觉得有必要对此做一些澄清—— 显然这个说 ...

  6. VMware VIC

    vSphere Integrated Containers - a short intro High-Level view of VCH Networking vSphere Integrated C ...

  7. QT QMimeData类

    http://blog.csdn.net/xie376450483/article/details/5863810 QMimeData类提为数据提供一个容器,用来记录关于MIME类型数据的信息 QMi ...

  8. Codeforces Round #283 (Div. 2) A ,B ,C 暴力,暴力,暴力

    A. Minimum Difficulty time limit per test 2 seconds memory limit per test 256 megabytes input standa ...

  9. Functions should do one thing一个函数应该只做一件事

    if you take nothing else away from this guide other than this, you'll be ahead of many developers. 如 ...

  10. hdu 1907 John(anti nim)

    John Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submis ...