重制AdvanceWars第一步 -- 搞定地图
首先来聊下高级战争吧
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第一步 -- 搞定地图的更多相关文章
- 【开源】简单4步搞定QQ登录,无需什么代码功底【无语言界限】
说17号发超简单的教程就17号,qq核审通过后就封装了这个,现在放出来~~ 这个是我封装的一个开源项目:https://github.com/dunitian/LoTQQLogin ————————— ...
- APP设计师拿到APP产品原型开始,七步搞定APP设计(转)
任何一款成功的APP都需要以坚实的产品概念作为基础,因为概念决定了产品最终完成的潜力. 一般情况下,交到app设计师手里的都是移动app产品原型图.当然这个是在移动产品经理反复斟酌,并且与大家开会讨论 ...
- iOS开发三步搞定百度推送
iOS开发三步搞定百度推送 百度推送很简单,准备工作:在百度云推送平台注册应用,上传证书. 步骤一: 百度云推送平台 http://push.baidu.com/sdk/push_client_s ...
- SmaterWeatherApi---签名加密和数据訪问--简单粗暴一步搞定
-----------------------------------------------------更新-2014-07-09---------------------------------- ...
- 破解jar包5步搞定,jira7.9.2操作成功,附github代码库
1,从要破解的程序中拷贝.jar包文件,运行1_jar.sh将其解压.以jira7.9.2为例: $install_dir\JIRA\atlassian-jira\WEB-INF\lib\atlass ...
- 轻松八步搞定Cacti配置安装(原创视频)
轻松八步搞定Cacti配置安装 1.安装web server $sudo apt-get install apache2 验证 http://localhost 2.$sudo apt-get ins ...
- Docker 一步搞定 ZooKeeper 集群的搭建
Docker 一步搞定 ZooKeeper 集群的搭建 背景 原来学习 ZK 时, 我是在本地搭建的伪集群, 虽然说使用起来没有什么问题, 但是总感觉部署起来有点麻烦. 刚好我发现了 ZK 已经有了 ...
- Spring Boot 集成 Ehcache 缓存,三步搞定!
作者:谭朝红 www.ramostear.com/articles/spring_boot_ehcache.html 本次内容主要介绍基于Ehcache 3.0来快速实现Spring Boot应用程序 ...
- 全面系统讲解CSS工作应用+面试一步搞定
[TOC] 一.课程介绍 二.HTML基础强化 html常见元素和理解 html常见元素分类 head区元素:(不会在页面上留下元素) * meta * title * style * link * ...
随机推荐
- HTTP 协议缓存
http 缓存分为客户端缓存和服务端缓存 1. 客户端缓存 客户端缓存指的是浏览器缓存, 浏览器缓存是最快的缓存, 因为它直接从本地获取(但有可能需要发送一个请求), 它的优势是可以减少网络流量, 加 ...
- Xcode Custom Shortcut
edit file "/Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Resources" add < ...
- grunt配置太复杂?使用Qbuild进行文件合并、压缩、格式化等处理
上次简单介绍了下Qbuild的特点和配置,其实实现一个自动化工具并不复杂,往简单里说,无非就是筛选文件和处理文件.但Qbuild的源码也并不少,还是做了不少工作的. 1. 引入了插件机制.在Qbuil ...
- 微信公众平台创建自定义菜单中文编码导致system error
创建包含了中文的自定义菜单时总是返回{"errcode":-1,"errmsg":"system error"},要将编码方式设置为UTF- ...
- 过滤Xss
/** * 防xss过滤 * * @author rentingshuang <tingshuang@rrkd.cn> * @param type $string * @param typ ...
- 漫谈Linux内核哈希表(2)
对照前面介绍过的内核通知链.链表,本章我们将要介绍的哈希表的初始化和定义也是如出一辙的: 点击(此处)折叠或打开 定义并初始化一个名为name的哈希链表表头 #define HLIST_HEAD(na ...
- DEV设计之自动流水号,DEV专家解答,自己折腾了半天也没有搞定,怪英文不好
() 老外专家给了回答,结果没有全到懂,又折腾了20分钟朋友提示才搞定 获取一个自动增加1的流水号值, 第一个参数是本事的数据库连接对象,第2个参数是也这个值为唯一标识返回来一个增量的值,第三个好像没 ...
- survey on Time Series Analysis Lib
(1)I spent my 4th year Computing project on implementing time series forecasting for Java heap usage ...
- saas简介
SaaS是Software-as-a-Service(软件即服务)的简称,随着互联网技术的发展和应用软件的成熟, 在21世纪开始兴起的一种完全创新的软件应用模式.它与“on-demand softwa ...
- 无法卸载jdk的解决方法
装了java之后非常纠结的就是无法卸载,总不能因为卸载一个jdk去重装系统,但是看着它残存在那又非常不爽, 因为卸载会牵扯注册表等琐碎的东西,,,后来在官网发现神器一枚,此神器就是java卸载工具. ...