用字节数组存放二维地图数据
来源:互联网 发布:淘宝关闭订单规则 编辑:程序博客网 时间:2024/04/25 16:22
一 二维地图数据内容
在RPG的大地图中,我们往往会分割成很多小块(逻辑上),用于玩家行走,比如使用A星寻路等等,就需要的二维地图数据。一般情况,存放的是数值,主要是指每个格子里的数值,这里的数值是指我们赋予他的需要表示的内容。例如:
0,0,0,0,1,1,0,0,1,1,1,0,0,0,2,0,1,1,2
- 0表示为可行走区域
- 1表示不可行走
- 2表示可飞行
- 3表示传送点
- 4表示出生点
- 等等根据需要来扩充
当然有人说我要采用对象的形式来存放,这也是可以的,但是存储对象就大太多了,一般情况是没有这个必要的。关于这点,也不在这篇文章的讨论范围。(曾经和同事关于使用数值和对象争论过,事实上,都有道理,完全可以根据实际情况选择使用,或者两者都使用)
二 地图数据的存放方式
- 一般采用数组Array或者Vector来进行存放
array[0][1]或者 vector[0][1]
那么读取数值的时候也是直接传入相应的二维坐标即可。
/** * 返回指定的点是否可行走 * @param row 行 * @param col 列 * @return 是否可行走 */public function isWalk(row:int,col:int):Boolean{ //实际这里还需要做边界检测 return array[col][row] == 0;}
- 用ByteArray存储
之所以需要采用ByteArray,是因为AS3没有byte这个数值类型。最小数值是int或者uint,占用4个字节,而使用ByteArray可以直接使用1个字节。
由于ByteArray是一维的,所以整个二维地图的数值是写成一个ByteArray里。那么获取的时候,则需要使用 列 * 行 + 行的方式来获取。有两个方式读取,
一个是采用readByte
byteMap.position = col * rowMax + col;byteMap.readByte();
另外是采用[]的方式
byteMap[col * rowMax + col]
完整的判断一个点是否可走的方法:
/** 最大行数 **/private var rowMax:int;/** * 返回指定的点是否可行走 * @param row 行 * @param col 列 * @return 是否可行走 */public function isWalk(row:int,col:int):Boolean{ return byteMap[col * rowMax + col] == 0; //byteMap.position = col * rowMax + col; //return byteMap.readByte() == 0;}
三 测试例子
接下来是一个简单的测试例子,主要是测试存放对象和读取的速度。
最终的结果证明是两个的读取速度几乎是一样的。但是带却相差4倍。(4个字节肯定是1个字节的4倍了:)
row = 600;col = 400;
是比较中间的数值了,一般情况下,一个格子可以是30 * 30像素或者30 * 60像之类的。所以一般 10000 * 8000像素的场景,纵和列也就是几百的数值。
占用字节的计算方式:
//行 * 纵 * 4个字节 / 1024 = 字节row * col * 4 / 1024600 * 400 * 4 / 1024 = 937.5 KB
/** * 用ByteArray存放二维地图数据 * @author sodaChen */public class ByteArrayMapTest extends Sprite{ /** 字节数值集合 **/ private var byteMap:ByteArray = new ByteArray(); /** 二维数组 **/ private var maps:Vector.<Vector.<int>> = new Vector.<Vector.<int>>(); /** 行数 **/ private var row:int = 600; /** 列数 **/ private var col:int = 400; public function ByteArrayMapTest() { //初始化地图信息 //列 for (var i:int = 0; i < col; i++) { var vec:Vector.<int> = new Vector.<int>(); maps.push(vec); //纵 for (var j:int = 0; j < row; j++) { var value:int = RandomUtils.randomInt(0,1); byteMap.writeByte(value); vec.push(value); } } //测试读取性能 var count:int = 0; var t:Number = getTimer(); for (var k:int = 0; k < col; k++) { for (var i2:int = 0; i2 < row; i2++) { count += maps[k][i2]; } } trace("Vector" + count + "耗时:" + (getTimer() - t)); count = 0; t = getTimer(); for (var i3:int = 0; i3 < col; i3++) { for (var i4:int = 0; i4 < row; i4++) { count += byteMap[i3 * row + i4];// byteMap.position = i3 * row + i4;// count += byteMap.readByte(); } } trace("byteMap" + count + "耗时:" + (getTimer() - t)); //计算体积大小 var bytes:ByteArray = new ByteArray(); bytes.writeObject(maps); trace("数组大小:" + bytes.length / 1024 + "KB"); trace("字节:" + byteMap.length / 1024 + "KB"); }}
最终输出结果是:
Vector120139耗时:15byteMap120139耗时:15数组大小:939.0673828125KB字节:234.375KB
当然,那个毫秒数有时会变化的,但是相差不大。不过如果加大数值,比如都超过1000,ByteArray的性能会差一点。比如设置成
/** 行数 **/private var row:int = 1600;/** 列数 **/private var col:int = 1400;
输出结果是:
Vector1120119耗时:143byteMap1120119耗时:146数组大小:8755.4736328125KB字节:2187.5KB
体积比例不变,大毫秒数变化了。因为具体要怎么选择使用,就得看实际情况和需要了。
- 用字节数组存放二维地图数据
- 用字符数组存放一个字符串
- c++ 逆向存放二维数组
- C++用数组存放数据
- javaweb图片上传用字节数组
- 二维数组有关数据
- C++编程入门系列之三十三(数组、指针和字符串:用字符数组存放和处理字符串)
- //申请一个存放PSTR(char *)的二维数组空间
- C\C++动态申请内存用于存放二维数组
- 二维数组的初始化与内存存放关系。
- 用字符串变量存放字符串
- 整型数据存放入字符数组
- 天地图二维地图数据的接入
- 特殊二维数组数据查找
- 数组存放
- JS 用字符串做数组下标
- 游戏地图编辑器之list动态二维数组(C#)
- Postgres数据库是否可以存放数组形式的数据
- 使用Fragment和Viewpager实现Tab嵌套,仿网易云音乐tab
- PAT乙级1021
- Linux系统下的简单命令【一】
- 函数库
- javascript 中 typeof的返回值
- 用字节数组存放二维地图数据
- cogs 272 [NOI1998] 免费馅饼 (dp)
- 远程连接oracle数据库设置
- jquery.pagination.js分页插件的简单使用
- 最大熵模型及Python实现
- 内部类
- 一道笔试题,引发我的基础问题的反思
- 程序员的“第一天”
- Java多线程(2):创建与启动