demo在此:NewProject.zip (2.1 MB)
请教论坛的大佬们帮忙搞定地块的加载。
目前是地块会有50*50=2500个,第一次打开矿场预制件的时候,因为有个从右向左的刷入动画,
由于生成预制件太多了,会导致动画直接卡在中间很长时间。加上调试信息里triangle 三角形高到3000-7000的,手机发热挺烫的(dc100左右),所以想着优化一下,改成类似虚拟列表那样的,在视野范围内的显示,视野之外的隐藏,但是我自己写的很■■,还穿帮,只能来论坛求助了。
我想要的效果就是拖动scrollview的时候可以把地块(红圈)加载进来,设计是以矿工所在的地块行列值±2的所有格子都显示(排除已经显示了的,代码里面使用tileUtil.getResMap(h,l)方法模拟服务端的返回数据,随机生成新地块格子),然后是左上角方向的地块移出视野了就隐藏掉
以下是游戏内代码说明:
1.MinePage脚本和预制件对应的是我写的半成品,MinePage2预制件和代码应该是一样的,由大佬修改,方便对比效果;
2.代码中的点坐标y是指行数,x是列数;
3.EventManager.emit(‘scrollHL’,h,l)消息是滚动卷轴到具体某个行列值的格子,会显示在视野的中心,这个代码实现没问题的;
4.刚进矿场预制件时不要点左下角的position位置,先挖一个地块把矿工刷新出来后再点可以scroll滚动到最后挖的地块,直接点会有bug,移动的地块位置不对的。Click to jump to the door的提示飘字是可以点击的,点击后会跳转到传送门所在位置,两个结合起来可以验证虚拟加载的效果;
5.游戏中设置地块坐标的数据在MinePage脚本的64行左右 this.mineScroll.node.on 的监听消息注释中写了的,比如:
let off = this.mineScroll.getScrollOffset();//获取当前scroll的滚动偏移量
let px = -off.x - 5125;//105
let py = -off.y - 400;//-6310 px py是理论上当前视野中心地块的坐标
let lhSum = (px + 5145) / 105;//50 列行数值和
let lhSub = (py + 3475) / 67.5;//-42 列行数值差 中间变量,不用特意关注的
let h = (lhSum - lhSub) / 2;
let l = (lhSum + lhSub) / 2; 计算式中心地块的行列值,会有小数的
接着圆整一下行列值:
if (Math.abs(h - Math.round(h)) > 0.0001 || Math.abs(l - Math.round(l)) > 0.0001) {
LogMgr.redLog(’=----=h:’, Math.round(h), ‘l:’, Math.round(l));
EventManager.emit(‘scrollHL’, Math.round(h), Math.round(l));
//如果滚动后的行列值差异大则滚动到新地块
return;
} else {
h = Math.round(h);
l = Math.round(l);//把地块行列数变成整数
}
// 回收视野外的节点
this.mineLayer.children.forEach(tile => {
let [pre, gH, gL] = tile.name.split(’-’);
let tileH = Number(gH);
let tileL = Number(gL);
//如果行数小于当前行数-4或者大于当前行数+4,则回收
if (tileH < h - 4 || tileH > h + 4) {
TilePoolMgr.put(tile);//节点池回收地块节点
return;
}
//行数序号在当前行数-4和当前行数+4之间的,则需要判断列序号是否在显示列之间
//确定当前行数所需要显示的列的序号
let startL = tileL - 4 + tileH - h;
let endL = tileL + 4 - tileH + h;
LogMgr.warn(’==tile:’, tile.name, startL, endL);
if (tileL < startL || tileL > endL) {
TilePoolMgr.put(tile);
}
});
LogMgr.warn(’==h:生成可视区域内的地块h:’, h, ‘l:’, l);
let tileArr = DataMgr.getMineInfo().tileArr;
// 生成可视区域内的地块
for (let row = h - 4; row <= h + 4; row++) {
let startCol = l - 4 + row - h;
let endCol = l + 4 - row + h;
for (let col = startCol; col <= endCol; col++) {
if (row >= 0 && row < 50 && col >= 0 && col < 50) {
LogMgr.warn(’==h:生成可视区域内的地块row:’, row, col, tileArr[row][col]);
this.showNewTile(row, col, tileArr[row][col]);
}
}
}
默认显示中心地块行列值±4的格子,理论上就显示81个格子就行了。
我自己写的虚拟加载(解开 //监听 自动挖矿时自动移动视图 事件的 行数以下的 注释 外加把init函数中的showFirstMineInfo方法修改成showFirstMineInfo2函数)的bug之处在于拖动scroll之后尤其是从左向右拖动后,左上角的部分经常出现穿帮,地块以非常水平垂直的方式显示出来的,不像是本来应该显示的地块的。