首先来聊下高级战争吧
Advance Wars,由任天堂旗下的Intelligent Systems开发的战棋游戏。
初作诞生于GBA上,后来继续跟进了高战2黑洞崛,而后在下一代掌机DS上也出了三代续作高战DS,以及后来不太一样的毁灭日。
本人的高中时代正值GBA横行天下的时候,那时候最喜欢的事情就是晚上躲在宿舍厕所偷偷玩GBA(不熄灯)。有时候还和小伙伴联机打GT2赛车马里奥等等,而高战...这种时间吃货能和小伙伴联机一把就实在太珍贵了。
鉴于高战这种类型的硬核战棋在日本地区不受欢迎,估计以后是不会再出续作了。不过成为程序员的一个好处就是,自己做做这种游戏还是可以的。
除去了战棋类游戏漫长的回合太拖时间这种共有的硬伤之外,无需练级无需养成,兵种相克,个性鲜明的CO和强大的CO Power,高战绝对的硬核战棋,好游戏呀。
高战的核心玩法就是下棋,那么最重要的就是棋盘,也就是地图的制作。
作为一个穷屌程序员,我是没有资金投入买美术的,所以先去抠点图来。
抠图的方法有很多,其实老外很多网站都有很多这些古老游戏的资源。开始的时候我选择了通过GBA模拟器VisualBoy来抠图,方法是百度来的。
抠了一堆类似下面的图片之后,实在是不耐烦了。

还是先做点功能吧,比如在Unity里面拖个地图出来。然而......
Tile的大小、接合、不同地形的过渡....这要做一个地图编辑器太痛苦了。尤其是不同地形的过渡。比如海水和平地之间,九宫格的接壤就有八个边,还有登陆用的浅滩怎么办?海水里面还有礁石tile...道路的转向、交汇,哦天呐,这种东西不是那个年代几乎所有瓷砖游戏都有的吗?不如去找找工具吧!
于是被安利到一个工具:TiledMapEditor。百度一下就找到了官网,还是个开源的工具,下载是免费的只是会引诱用户捐点小钱。真是好东西。
具体怎么被安利的请转移这里看:https://www.zhihu.com/question/25876314
可是我不会用,也没有瓷砖贴图...一穷二白。
此时一个神器从天而降,被基友安利得知一个大洋彼岸的高战死忠有制作这个高级战争专用地图编辑器!
链接: http://pan.baidu.com/s/1qYf9d2O 密码: g2gr

啊!牛逼!
刷刷,编辑完毕,导出保存~~等等!保存之后的地图文件怎么读呢?天呐,还有一堵墙,别说看E文了,连网站都打不开啊!
在获取不到更多的资料的情况下,面对着这个导出后的*.aws文件发呆,还能怎么办,读取试试看啦。
第一步,打开文件,我直接拖拽到了手头上最强大的工具VisualStudio2013里,然后出现下图这样的一堆十六进制:

当然,除了开头,其他人类是看不了的。慢慢分析,开头是文件的标识,是个字符串,很简单,每个文件都一样,是固定的。后面开始就不一样了,最后的结尾部分还是字符串。
那么解决格式问题的关键就是处理中间的那串。
这种文件是不可能再做加密之类的事情的,所以,好的消息是只要创建一个新的地图,不断比对,就能够知道文件的格式。
于是我创建了一个新的地图,保存,用VS打开。发现中间出现了一大片的0000和FFFF,因为地图是空的,很明显,这些地方就是地图上的单位填充点。
一张2D的地图,可以看成是一个二维数组,保存文件里面必然有这个二维数组在一维上的展开。
继续分析,高战的地图不像RPG,RPG通常分三层:地形建筑和单位,而高战上没有地形和建筑的分层必要,根据编辑器设计地图时候的方式可以看出应该是分为两层,一层是地形和建筑物,二层是移动单位。
然后看地图的大小,我创建了10x11和20x21的地图,发现0000和FFFF的数量放大了,如果上面分层的猜测没错,那么0000和FFFF分别就是每一层。同时改变的还有第11和第12字节,肉眼一看就知道这两个字节分别是地图的长度和宽度了。再数一下0000的数量和FFFF的数量,发现是一样的,而且正好是长*宽的倍数,也就是棋格的倍数,正好是棋格数*2Byte,也就是一个int16代表了一个地图单位。
那么格式就很明了啦~
前面10个字节是固定字符串标题,11是width,12是height,用byte来做长宽也就是说地图不可能大过255*255嘛。13暂时不明,不过后来分析出是坏境相关的设定(普通草地、沙漠、雪地)。接下来根据width*height读取地形单位,每两个字节就是一个单位,读完之后就是移动作战单位同样的数量也是2个字节一个。剩下的是地图信息。

从图中可以看出来地图信息是个字符串,但是中间夹杂着一些不是字符串的东西。这部分的信息是地图制作者加上去的,所以字符串的长度不像标题固定10字节,是会变得。
而划分字符串很简单通常都是两种方法:分隔符分隔,或是头部声明长度。这里用肉眼就能看出来是头部声明的长度了,头部有四个字节不能转字符串,但是算一下十进制正好就是字符串的长度,OK了,后面都是一样,有三个字符串。
看下解析的代码:

             string path = null;
if (args.Length == )
{
Debug.WriteLine("请输入地图文件路径:");
path = Console.ReadLine().Trim('\"');
}
else
{
path = args[];
}
var data = File.ReadAllBytes(path);
Debug.WriteLine("开始解析...");
Debug.WriteLine("------------------------------------");
int offset = ;
string capition = Encoding.ASCII.GetString(data, offset, );
Debug.WriteLine("caption:{0}", capition, );
offset += ;
int width = data[offset];
offset += ;
int height = data[offset];
offset += ;
Debug.WriteLine("width:{0}, height:{1}", width, height);
int tileset = data[offset];
offset += ;
Debug.WriteLine("tileset:{0}", tileset); //terrain
for (int i = ; i < width*height; i++)
{
short terrain = BitConverter.ToInt16(data, offset);
offset += ;
//if (i < 10)
{
Debug.WriteLine("terrain:\t{0:X4}\t{0}", terrain);
}
}
//unit
for (int i = ; i < width * height; i++)
{
short unit = BitConverter.ToInt16(data, offset);
offset += ;
if (i < )
{
//Debug.WriteLine("unit:\t{0:X4}\t{0}", unit);
}
}
//info
int mapnameLength = BitConverter.ToInt32(data, offset);
offset += ;
string mapname = Encoding.ASCII.GetString(data, offset, mapnameLength);
offset += mapnameLength;
Debug.WriteLine("mapname:{0}", mapname, ); int authorLength = BitConverter.ToInt32(data, offset);
offset += ;
string author = Encoding.ASCII.GetString(data, offset, authorLength);
offset += authorLength;
Debug.WriteLine("author:{0}", author, ); int descriptionLength = BitConverter.ToInt32(data, offset);
offset += ;
string description = Encoding.ASCII.GetString(data, offset, descriptionLength);
offset += descriptionLength;
Debug.WriteLine("description:{0}", description, ); Debug.WriteLine("------------------------------------");
Debug.WriteLine("解析完毕!");

地图文件的格式就这么解决了,然后就是看每一个单位对应的编号了。
其实地形的编辑和最后贴图是不一样的,比如海水和陆地的接壤处拐弯处,其实地形只有海水和陆地之分,而贴图就会有四个弯角和纵向横向六种贴图。而贴图只要看看就好了,实际程序中需要参与计算的是海水/陆地的加成。马路桥梁管道等等都是一样。也就是说其实编号只分地形,不管最后在地图上的贴图是怎样。
下面整理出的就是建筑物表

地形表就更简单了,不区分阵营了。
这样,导出的aws文件配合地图png截屏就可以轻松地开发新棋盘啦~ 拿来主义真牛逼!
最后,检测下成果:

看unit的输出,和图中的单位位置一致的

重制AdvanceWars第一步 -- 搞定地图的更多相关文章

  1. 【开源】简单4步搞定QQ登录,无需什么代码功底【无语言界限】

    说17号发超简单的教程就17号,qq核审通过后就封装了这个,现在放出来~~ 这个是我封装的一个开源项目:https://github.com/dunitian/LoTQQLogin ————————— ...

  2. APP设计师拿到APP产品原型开始,七步搞定APP设计(转)

    任何一款成功的APP都需要以坚实的产品概念作为基础,因为概念决定了产品最终完成的潜力. 一般情况下,交到app设计师手里的都是移动app产品原型图.当然这个是在移动产品经理反复斟酌,并且与大家开会讨论 ...

  3. iOS开发三步搞定百度推送

    iOS开发三步搞定百度推送   百度推送很简单,准备工作:在百度云推送平台注册应用,上传证书. 步骤一: 百度云推送平台 http://push.baidu.com/sdk/push_client_s ...

  4. SmaterWeatherApi---签名加密和数据訪问--简单粗暴一步搞定

    -----------------------------------------------------更新-2014-07-09---------------------------------- ...

  5. 破解jar包5步搞定,jira7.9.2操作成功,附github代码库

    1,从要破解的程序中拷贝.jar包文件,运行1_jar.sh将其解压.以jira7.9.2为例: $install_dir\JIRA\atlassian-jira\WEB-INF\lib\atlass ...

  6. 轻松八步搞定Cacti配置安装(原创视频)

    轻松八步搞定Cacti配置安装 1.安装web server $sudo apt-get install apache2 验证 http://localhost 2.$sudo apt-get ins ...

  7. Docker 一步搞定 ZooKeeper 集群的搭建

    Docker 一步搞定 ZooKeeper 集群的搭建 背景 原来学习 ZK 时, 我是在本地搭建的伪集群, 虽然说使用起来没有什么问题, 但是总感觉部署起来有点麻烦. 刚好我发现了 ZK 已经有了 ...

  8. Spring Boot 集成 Ehcache 缓存,三步搞定!

    作者:谭朝红 www.ramostear.com/articles/spring_boot_ehcache.html 本次内容主要介绍基于Ehcache 3.0来快速实现Spring Boot应用程序 ...

  9. 全面系统讲解CSS工作应用+面试一步搞定

    [TOC] 一.课程介绍 二.HTML基础强化 html常见元素和理解 html常见元素分类 head区元素:(不会在页面上留下元素) * meta * title * style * link * ...

随机推荐

  1. js常用方法

    若未声明,则都是js的方法 1.indexOf indexOf(str):默认返回字符串中第一次出现索引位置 的下标,没有则返回-1 indexOf(str,position):返回从position ...

  2. 深入浅出Symfony2 - 结合MongoDB开发LBS应用

    简介 随着近几年各类移动终端的迅速普及,基于地理位置的服务(LBS)和相关应用也越来越多,而支撑这些应用的最基础技术之一,就是基于地理位置信息的处理.我所在的项目也正从事相关系统的开发,我们使用的是S ...

  3. 记一次PHP7+opcache+zmq出现SIGSEGV 问题的查找(一次不成功的bug查找)

    Title:  记一次PHP7+opcache+zmq出现SEGSEGV问题的查找(一次不成功的bug查找) bug来历自述:线上代码PHP环境是5.2,为了提升性能(逼格),于是升级为PHP7并使用 ...

  4. EF6配合MySQL或MSSQL(CodeFirst模式)配置指引

    一.新建一个解决方案,包含两个项目:EF6CodeFirstMySQL.Model(动态库项目),EF6CodeFirstMySQL.Tests(控制台应用) 二.通过NuGet将EntityFram ...

  5. Java线程池入门

    序 为什么要用线程池?什么情况下才会用到线程池? 并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结束了,这样频繁创建线程就会大大降低系统的效率,因为频繁创建线程和销毁线程需要时间. 因此 ...

  6. 安装软件 报错1304 C:\Program Files\Common Files\VMware\VMware VMRC Plug-in\Firefox\dbghelp.dll验证您对该目录具有访问权限

    现在情况是C:\Program Files\Common Files\VMware\VMware VMRC Plug-in\Firefox这个文件夹里面没有dbghelp.dll文件,就需要在百度上面 ...

  7. Mongodb无法访问28107的问题

    解压mongodb文件后,放到指定文件,最好别有空格.汉字之类的文件中 此时在mongodb文件夹下,建立一个 db 文件夹,此时执行启动命令,默认27017端口号可以打开,但是28017端口无法打开 ...

  8. My安卓知识5--百度地图api的使用,周边信息检索

    虽然查了很多资料,但是这个问题还是解决不了,不知道为什么检索城市内的相关信息能用,检索周边信息语句就是用不了.代码如下,第一段是检索保定市内的加油站,第二段是检索周边的加油站.centerToMyLo ...

  9. 20145316&20145229实验五:网络通信

    20145316&20145229实验五:网络通信 结对伙伴:20145316 博客链接:http://www.cnblogs.com/xxy745214935/p/6130897.html

  10. 如何用VB.Net创建一个三层的数据库应用程序

    [b]1.[/b][b]概论:[/b] 本文将介绍如何创建一个三层应用程序,并且将介绍如何创建一个Web Service服务. ADO.NET创建Windows三层结构应用程序的体系架构如下图所示: ...