[转] AS3地图拼接与战争迷雾的实现
在开发游戏的过程中,特别是地图编辑器中,需要利用最少的资源,实现最丰富的地形地貌。虽然现在众多的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个角的合即为地图区块所对应的编号。
程序实现
有了数学原理,下一步就是通过程序去实现他。首先,我们需要根据编号,来保存对应的素材,为了大家看的清楚,我用了比较笨的方法——二维数组,实际上,循环取一次就可以了。
- // 用一个数组来标记图形中各个位置的编号
- var config:Array = [
- [0,4,8,12],
- [1,5,9,13],
- [2,6,10,14],
- [3,7,11,15],
- ];
复制代码
然后,把图片中的各个部分取出来,放到一个数组去,数组的下表刚好就是这个图片素材的编号:
- // 用来存放图片素材的数组
- var lib:Array = new Array();
- var bitmap:BitmapData;
- // 源素材,就是我们上面的那张PNG
- var bd:BitmapData = new BMD();
- var py:uint;
- var px:uint;
- // 进行切割
- for(py = 0;py<config.length;py++)
- {
- var line:Array = config[py];
- for(px = 0;px < line.length;px++)
- {
- bitmap = new BitmapData(128,128,true,0);
- bitmap.copyPixels(bd,new Rectangle(px*128,py*128,128,128),new Point(),null,null,true);
- // 把素材编号作为下表进行素材的保存
- lib[line[px]] = bitmap;
- }
- }
复制代码
好了,这样,素材就准备好了。下面我们做一个地图试验一下
首先,生成一个空地图,还是用数组好了:
- var arr:Array = new Array();
- // 生成10X10的地图
- for(py=0;py<10;py++)
- {
- var data:Array = new Array();
- for(px=0;px<10;px++)
- {
- // 每个地图区块包含4个顶点数据,默认为0
- data.push([0,0,0,0]);
- }
- arr.push(data);
- }
复制代码
来看一下,当我们点击(或者说叫做地图的笔刷。。。)时,我们期望发生什么情况:
<ignore_js_op>
当我们点下鼠标时候,如图所示,我们会把鼠标指针所在的位置的顶点数值设置为4,而临近的顶点数值分别设置为8,1,2,刚好拼凑成上面这样的图形。
当然,同样用这样的方法在临近的位置点击,我们就会得到这样的效果:
<ignore_js_op>
如图,我们点击的鼠标位置,和上次点击一样,我们把点击的位置顶点值设置为4,临近顶点为8,1,2。而此时,因为这个顶点和上次的8号顶点其实在同一个Tile里,导致这个Tile内的顶点总和变成了12,所以更换了素材。于是我们得到了一个非常平滑的过度。
当然,再继续点下去,也是同样的算法,这里就不再赘述了。
<ignore_js_op>
来看一下后面的代码,点击的时候,当然是计算点击位置对应的区块,然后把改区块的右下角顶点值设置为4,这里要注意,如果这个顶点已经是4了,那就没必要再设置了。如果再设置,这个顶点变成了8,很显然就不对了。
- stage.addEventListener(MouseEvent.CLICK,onClick);
- function onClick(e:MouseEvent):void
- {
- // 计算区块
- var _mx:uint = int(e.stageX/64);
- var _my:uint = int(e.stageY/64);
- // 区块顶点设置,3右下 2右上 1左下 0左上
- if(arr[_my][_mx][3]!=4) arr[_my][_mx][3]+=4; // 当前区块的右下
- if(arr[_my][_mx+1][1]!=8) arr[_my][_mx+1][1]+=8; // 右边区块的左下
- if(arr[_my+1][_mx][2]!=1)arr[_my+1][_mx][2]+=1; // 下面区块的右上
- if(arr[_my+1][_mx+1][0]!=2)arr[_my+1][_mx+1][0]+=2; // 下面右边区块的左上
- reDraw();
- }
复制代码
然后就是根据现在的顶点,重新绘制地形:
- var resBD:BitmapData = new BitmapData(640,640,true,0xff000000);
- addChild(new Bitmap(resBD));
- function reDraw():void
- {
- resBD.fillRect(resBD.rect,0);
- for(py=0;py<10;py++)
- {
- for(px=0;px<10;px++)
- {
- var b:uint=arr[py][px][0]+arr[py][px][1]+arr[py][px][2]+arr[py][px][3];// 计算顶点合
- if(b==0) continue;
- if(b>15) b=15; // 超出15的顶点合是没有意义的。在魔兽争霸里,超出15会随机一个填充满的样式以丰富地表
- resBD.copyPixels(lib[b],lib[b].rect,new Point(px*64,py*64),null,null,true);
- }
- }
- }
复制代码
战争迷雾扩展
同样的原理,只要我们把素材处理成战争迷雾的黑色和半透明,即可实现战争迷雾效果。
<ignore_js_op>
<ignore_js_op>
原帖地址:http://bbs.9ria.com/thread-157487-1-1.html
[转] AS3地图拼接与战争迷雾的实现的更多相关文章
- 《C++游戏开发》笔记十二 战争迷雾:初步实现
本系列文章由七十一雾央编写,转载请注明出处. http://blog.csdn.net/u011371356/article/details/9475979 作者:七十一雾央 新浪微博:http:/ ...
- 平滑过渡的战争迷雾(一) 原理:Warcraft3地形拼接算法
本系列文章由七十一雾央编写,转载请注明出处. http://blog.csdn.net/u011371356/article/details/9611887 作者:七十一雾央 新浪微博:http:/ ...
- 《C++游戏开发》笔记十三 平滑过渡的战争迷雾(一) 原理:Warcraft3地形拼接算法
本系列文章由七十一雾央编写,转载请注明出处. http://blog.csdn.net/u011371356/article/details/9611887 作者:七十一雾央 新浪微博:http:/ ...
- 《C++游戏开发》笔记十四 平滑过渡的战争迷雾(二) 实现:真正的迷雾来了
本系列文章由七十一雾央编写,转载请注明出处. http://blog.csdn.net/u011371356/article/details/9712321 作者:七十一雾央 新浪微博:http:/ ...
- Unity3D高性能战争迷雾实现
效果图 先上效果图吧,这是为了吸引到你们的ヽ(。◕‿◕。)ノ゚ 战争迷雾效果演示图 战争调试界面演示图 由于是gif录制,为了压缩图片,帧率有点低,实际运行时,参数调整好是不会像这样一卡一顿的. 战争 ...
- Unity3D游戏高性能战争迷雾系统实现
一 效果图 先上效果图吧,这是为了吸引到你们的ヽ(。◕‿◕。)ノ゚ 战争迷雾效果演示图 战争迷雾调试界面演示图 由于是gif录制,为了压缩图片,帧率有点低,实际运行时,参数调整好是不会像这样一卡一顿的 ...
- Unity3D战争迷雾效果
原地址:http://liweizhaolili.blog.163.com/blog/static/16230744201431835652233/ 最近一直都在做Flash相关的东西,很久没有空搞U ...
- unity中绘制战争迷雾
接上一篇中说的游戏,我们已经实现了client.host上的一个物体可见不可见的行为.之后我们可以加入类似检查两个单位之间的距离.或是两个单位之间有无阻挡物来进一步实现游戏机制. 在这篇随笔中我会首先 ...
- Laya中地图拼接的缝隙问题
拼图的空隙. Egret也有拼图的空隙.比如制作飞机游戏,背景拼接轮换着下移,有明显的缝隙.用TextureMerger可以解决. 看了下Laya.可以设置repeat. 编辑模式,图片上右键,设置默 ...
随机推荐
- 每日练习level-7
1.有序列表.无序列表.自定义列表如何使用?写个简单的例子.三者在语义上有什么区别?使用场景是什么? 能否嵌套? 有序列表是一列使用数字进行标记的项目,它使用<li>包含于<ol&g ...
- Laravel 学习笔记之 Composer 自动加载
说明:本文主要以Laravel的容器类Container为例做简单说明Composer的自动加载机制. Composer的自动加载机制 1.初始化一个composer项目 在一个空目录下compose ...
- ResourceLoader笔记
Ant路径匹配 Ant路径通配符支持“?”.“*”.“**”,注意通配符匹配不包括目录分隔符“/”: “?”:匹配一个字符,如“config?.xml”将匹配“config1.xml”: “*”:匹配 ...
- 20145240 《Java程序设计》第五次实验报告
20145240 <Java程序设计>第五次实验报告 北京电子科技学院(BESTI)实验报告 课程:Java程序设计 班级:1452 指导教师:娄嘉鹏 实验日期:2016.05.06 实验 ...
- debian下使用dynamic printk分析usb转串口驱动执行流程
看了一篇文章<debug by printing>,文中提到了多种通过printk来调试驱动的方法,其中最有用的就是"Dynamic debugging". “Dyna ...
- SQL Server获取数据库的当前连接状态
SELECT * FROM [Master].[dbo].[SYSPROCESSES] WHERE [DBID]=(SELECT [DBID] FROM [Master].[dbo].[SYSDATA ...
- keepalived检测脚本及注意事项
keepalived检测脚本的作用及注意事项: 默认每隔3秒钟执行一次检测脚本,检查nginx服务是否启动,如果没启动就把nginx服务启动起来,如果启动不成功,就把keepalived服务down掉 ...
- 【atcoder】All Your Paths are Different Lengths[arc102D](乱搞)
题目传送门:https://arc102.contest.atcoder.jp/tasks/arc102_b 这道题有点毒瘤啊,罚时上天.. 显然若$ l=2^n $那么就可以直接二进制拆分,但是如果 ...
- 分布式服务管理zookeeper的java api
zookeeper是一个分布式服务管理工具,本身具备高可用性,很多知名分布式系统入hadoop.Hbase等都采用zk管理. 常见的两个应用场景:1.服务的注册与发现 2.集群统一配置 下面看一下使用 ...
- HDU 5884 Sort(2016年青岛网络赛 G 二分+贪心+小优化)
好题 题意:给你n<=100000个数,每个数范围[0,1000],然后给你一个最大的代价T,每次最多合并k个数成为一个数,代价为k个数的总和.问最后合成1个数的总代价不大于T的最小k 题解:我 ...