猫史档案馆


[优化技术:数组瘦身] 整个地图压缩在一行字?

用户:芜湖咸鱼芜湖咸鱼查看:12 回复:31 评论:12 创建时间:2021-02-24T16:27:04


不知道大家有没有想过,假如用一个数组来存储整个Box3地图呢?

这样你就能在代码中存储多个地图,或者存到SQL中,然后随时切换,是不是听起来超棒?

但是,Box3地图(以128*128*128地图为例),一共大约有2097152个方块,即使每个方块使用ID存储,那么数组也大约会占用8388608 Bytes的内存,换算下来就是8M数据,相当于Box3一个地图的文件容量的一半,写到代码文件里无疑瞬间卡崩。。。

 

那么,真的不能用数组存地图数据吗?

其实是可以的!

我们首先观察一个16*16*16的小区域,分析数据:

center_image

有没有发现,重复数据特别多

这时候我们想想生活中的一个例子,假设你要告诉别人200000000007这个数字,你会怎么念?

相信大部分人都是读作“一个二10个零然后一个七”,这里,你把很多个零读作10个零,在一定程度上就节省了文字长度。

对于数组也是,假如数组可以把多个连续重复的数据记作 "x个y" 那就可以压缩数组了!特别针对这种重复性特别高的数据来说,压缩非常有效!

经过实验,存储这个地图的数据:https://box3.codemao.cn/e/e5c6bf60ce9e8cccad1b

使用传统数组存储,数组长度为 2000376 !

使用压缩数组存储,数组长度只有 76*2=152 !

 

到这里,你一定十分想要知道是怎么做到的吧?

其实,对于数组,一般用法就是存入和取出了,存入的时候,先判断数组最后一个数据是否相同,如果相同,就把次数加1,不相同才创建新的数据,而取出数据时只要逆向这个过程即可。

而且这种数据很容易复制:

center_image

整个地图就压缩在这些数字中了(每个长度为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)

(开源工具稍后置顶回帖补上)

快分享给朋友吧~

 

温馨提示:创作不易,盗用者追究法律责任


回复

上一页1 页 / 共 2下一页
该账号已被封禁该账号已被封禁

你是shy?

点赞0


评论


Alex79Alex79

地板

点赞1


评论


Chengxuyee_已退Chengxuyee_已退

试过,但是只会用那种传统数组

点赞0


评论


86135clc86135clc

模型

点赞0


评论


DL1DL1

积木大赛还评奖吗??

点赞0


评论


一个STUB用户_6923702一个STUB用户_6923702

OHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH

点赞0


评论


async_functionasync_function

游客好像可以操控模型。。。

点赞0


评论


开舒克的飞稽开舒克的飞稽

这只是地图啊,如果要做到地图切换功能,模型也要加上。这时候就要存储模型id(到时候调用服务器里的就行了),模型位置,方位角,实体碰撞,物理效果,标签等,数据又要增加好多。并且很少有重复的字符,难度可能会加大

点赞0


评论


平凡的第五玩家平凡的第五玩家

16*16······   一个区块

点赞1


评论


凌_墨水凌_墨水

小级压缩功能

点赞0


评论


财产喵财产喵

大佬层出啊

点赞1


评论


卫道士32_32*2没了卫道士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


评论


你来教我怎么不会在刷地图的时候网站不会崩溃???

点赞0


评论


战神_小火熊_光影轮回战神_小火熊_光影轮回

nb……

点赞0


评论


迷失冷光迷失冷光

顶习惯了吧欸呃……

点赞0


评论


芙兰朵露_斯卡雷特芙兰朵露_斯卡雷特

OHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH NBNBNB

点赞0


评论


uHuoYuBaiuHuoYuBai

好像有点像压缩文件的工作原理……

点赞0


评论


极限小白极限小白

…………

点赞0


评论


极限小白极限小白

就是不知拿超级计算机玩代码岛3会咋样……

 

点赞0


评论


闻乐溪闻乐溪

大佬,顶帖程序借下行吗,急用

点赞1


评论


a_b_c_a_b_c_

https://box3.codemao.cn/e/c47d6457f410c3d5eda5

点赞0


评论


a_b_c_a_b_c_

https://box3.codemao.cn/e/c47d6457f410c3d5eda5

点赞0


评论


7654Fox7654Fox

这是真的大佬……

 

 

说吧,信奥赛拿了第几?

点赞2


评论


不知道该叫啥的一只萌新不知道该叫啥的一只萌新

大佬 能私发我一下通过数组换成建筑的代码吗 邮箱:MX13520032365@163.com openwxat@126.com

点赞0


评论


86135clc86135clc

挖坟

点赞0


评论


治愈绾兮治愈绾兮

对于一个高档次的的电脑来说,不需要优化()

点赞0


评论


Dao3的C6H8O7Dao3的C6H8O7

thank you~ 

我的一个地图差点卡爆了

 

点赞0


评论


FML饭米粒FML饭米粒

压缩+解压全代码:https://shequ.codemao.cn/community/429470

点赞0


评论


一个STUB用户_14302596一个STUB用户_14302596

比较垃圾的代码:

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


评论


IaeaIaea

a'z

点赞0


评论