用户:
芜湖咸鱼查看:12 回复:31 评论:12 创建时间:2021-02-24T16:27:04
不知道大家有没有想过,假如用一个数组来存储整个Box3地图呢?
这样你就能在代码中存储多个地图,或者存到SQL中,然后随时切换,是不是听起来超棒?
但是,Box3地图(以128*128*128地图为例),一共大约有2097152个方块,即使每个方块使用ID存储,那么数组也大约会占用8388608 Bytes的内存,换算下来就是8M数据,相当于Box3一个地图的文件容量的一半,写到代码文件里无疑瞬间卡崩。。。
那么,真的不能用数组存地图数据吗?
其实是可以的!
我们首先观察一个16*16*16的小区域,分析数据:

有没有发现,重复数据特别多
这时候我们想想生活中的一个例子,假设你要告诉别人200000000007这个数字,你会怎么念?
相信大部分人都是读作“一个二10个零然后一个七”,这里,你把很多个零读作10个零,在一定程度上就节省了文字长度。
对于数组也是,假如数组可以把多个连续重复的数据记作 "x个y" 那就可以压缩数组了!特别针对这种重复性特别高的数据来说,压缩非常有效!
经过实验,存储这个地图的数据:https://box3.codemao.cn/e/e5c6bf60ce9e8cccad1b
使用传统数组存储,数组长度为 2000376 !
使用压缩数组存储,数组长度只有 76*2=152 !
到这里,你一定十分想要知道是怎么做到的吧?
其实,对于数组,一般用法就是存入和取出了,存入的时候,先判断数组最后一个数据是否相同,如果相同,就把次数加1,不相同才创建新的数据,而取出数据时只要逆向这个过程即可。
而且这种数据很容易复制:

整个地图就压缩在这些数字中了(每个长度为2的数组中第一个表示方块数据,第二个表示重复次数)!
实验室地址: https://box3.codemao.cn/e/e5c6bf60ce9e8cccad1b
实验代码(仅针对小型地图):
console.clear();
// 实验代码,只能用来呈现压缩效果
let blocks = [
];
function append(item) {
if (blocks.length > 0 && blocks[blocks.length - 1][0] === item) {
blocks[blocks.length - 1][1] += 1;
}
else {
blocks.push([item, 1]);
}
}
function forEach(fun) {
for (let l of blocks) {
for (let x = 0; x < l[1]; x++) {
fun(l[0]);
}
}
}
for (y = 0; y < 126; y++) {
for (x = 0; x < 126; x++) {
for (z = 0; z < 126; z++) {
append(voxels.getVoxel(x, y, z));
}
}
}
let t = "["
blocks.forEach(i => {
t += `[${i[0]}, ${i[1]}], `
})
t += "]"
console.log(t)
(开源工具稍后置顶回帖补上)
快分享给朋友吧~
温馨提示:创作不易,盗用者追究法律责任
这只是地图啊,如果要做到地图切换功能,模型也要加上。这时候就要存储模型id(到时候调用服务器里的就行了),模型位置,方位角,实体碰撞,物理效果,标签等,数据又要增加好多。并且很少有重复的字符,难度可能会加大
点赞0
评论
卫道士32_32*2没了大哥,0(空气)别记了!!!(浪费空间)(V8只有4-8M的可支配内存)
代码应该是这样:
let blocks=[]; function append(item) { if(blocks.length > 0 && blocks[blocks.length - 1][0] === item) { blocks[blocks.length - 1][1] += 1; }else if(item!=0){ blocks.push([item,1]); } } function forEach(fun) { for(l in blocks) { for(x=0;x<l[1];x++) { fun(l[0]); } } } for(y=0;y<126;y++) { for(x=0;x<126;x++) { for(z=0;z<126;z++) { append(voxels.getVoxel(x,y,z)); } } } let t="["; blocks.forEach(i => { t+=`[${i[0]},${i[1]}],` }); t+="]"; console.log(t);点赞2
评论
比较垃圾的代码:
console.clear()
let a = 0
async function copyvox() {
console.error('-•--;');
world.say('-----');
world.say('typeing...')
var ts = [];
for (var x = 0; x <= 256; x++) {
for (var y = 0; y <= 喵; y++) {
for (var z = 0; z <= 256; z++) {
if (voxels.getVoxelId(x, y, z) == 0) continue
ts.unshift([x, y, z, voxels.getVoxelId(x, y, z)])
a =a+1
console.log(a)
}
}
await sleep(200);
};
world.say('finally!');
console.log(`var sx={x:喵,y:8,z:喵};`);
console.log(`const ts = ${JSON.stringify(ts)};`);
console.log(`sx.x-=ts[0][0];sx.z-=ts[0][2];for(i=0;i<ts.length;i++){voxels.setVoxel(sx.x+ts[i][0],sx.y+ts[i][1],sx.z+ts[i][2],ts[i][3])}`);
};
copyvox()
版权:没名某人 改编:Evens_勿安
点赞2
评论