循环列表虽然是游戏中非常基础的一个功能,但是我觉得对于新手来说,如果有一个循环列表,它很好理解,能自己掌握起来使用,那我觉得这件事情真的是,泰酷了!!!
先来看看效果
相对于最原始的做法这个方式能尽可能减少节点数量,自然渲染量也下来了,为了让小白更好的理解循环列表的大概原理,没有用数据位置来代替节点。
下面是demo,想要快速了解的新建一个项目导入就可以看啦~,觉得不错就给个赞吧
LoopList.zip (38.5 KB)
下面开始讲解怎么实现这个功能吧,首我用的cocos版本是3.8.2(建议大家都用3.X吧,这样大家可以帮cocos查bug查的更快),用2.X版本的同学也不用担心,道理懂了,哪个版本都好写。
简单的说说吧.
简单的判断一下ItemCell是否在显示区域呗,下面代码附带说明
//显示区域左边缘
let viewLeftSide = this.scrollView.view.node.worldPosition.x - (this.scrollView.view.width * this.scrollView.view.anchorX);
//显示区域右边缘
let viewRightSide = this.scrollView.view.node.worldPosition.x + (this.scrollView.view.width * (1 - this.scrollView.view.anchorX));
//显示区域下边缘
let viewBottomSide = this.scrollView.view.node.worldPosition.y - (this.scrollView.view.height * (1 - this.scrollView.view.anchorY));
//显示区域上边缘
let viewTipSide = this.scrollView.view.node.worldPosition.y + (this.scrollView.view.height * this.scrollView.view.anchorY);
this.sideArr = {
viewLeftSide, viewRightSide, viewBottomSide, viewTipSide
};
checkInView(itemCell: ItemCell<T>) {
//节点右侧边缘在屏幕左侧外面或者节点左边缘在屏幕右侧外面 则不在显示区域
let horizontalOutside = itemCell.node.worldPosition.x + (itemCell.size.x * 0.5) <
this.sideArr.viewLeftSide
|| itemCell.node.worldPosition.x - (itemCell.size.x * 0.5) > this.sideArr.viewRightSide;
let verticalOutside = false;
if (!horizontalOutside) {
//节点上边缘在屏幕下方外面或者节点下边缘在屏幕上方外面 则不在显示区域
verticalOutside = itemCell.node.worldPosition.y + (itemCell.size.y * 0.5) <
this.sideArr.viewBottomSide
|| itemCell.node.worldPosition.y - (itemCell.size.y * 0.5) > this.sideArr.viewTipSide;
}
return !horizontalOutside && !verticalOutside;
}
剩下就是监听scrollView的滚动事件并对判断的频率做一下控制
this.scrollView.node.on(ScrollView.EventType.SCROLLING, () => {
this.updateInv--;
if (this.updateInv <= 0) {
this.updateInv = 3;
this.updateNodes();
}
})
然后根据是否显示内容对需要显示的节点进行对象池管理就能最大限度的保证性能了。
本方法使用简单,只要需要处理ShowNode节点绑定的显示内容的脚本即可,也高度自定义自己想要业务内容,代码总量不超过200行,简简单单的优化列表性能,这不香吗?