CocosCreator的ScrollView优化

效果图

截图

新建一个预制件

prefab

预制件代码

Item.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
const {ccclass, property} = cc._decorator;

@ccclass
export default class Item extends cc.Component {

@property(cc.Label) label: cc.Label = null;

index: number = 0

getIndex(): number {
return this.index
}

init(index: number) {
this.label.string = `${index}`
this.index = index
}

itemShow() {
this.node.opacity = 255
}

itemHide() {
this.node.opacity = 0
}
}

主文件代码

Main.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import Item from "./Item";

const {ccclass, property} = cc._decorator;

@ccclass
export default class Main extends cc.Component {

@property(cc.ScrollView) scrollView: cc.ScrollView = null
@property(cc.Prefab) itemPrefab: cc.Prefab = null
@property(cc.Button) startBtn: cc.Button = null
@property(cc.EditBox) editBox: cc.EditBox = null

needItem: number = 0
index: number = 0
viewRect: cc.Rect = null
needCulling = false
// onLoad () {}

start() {
this.startBtn.node.on('click', () => {
this.needItem += parseInt(this.editBox.string)
})
let pos = this.scrollView.node.parent.convertToNodeSpace(
this.scrollView.node.position
)
// 构造碰撞盒子 需要有预留
this.viewRect = cc.rect(pos.x - 125, pos.y - 125, this.scrollView.node.width + 250, this.scrollView.node.height + 300 )
this.scrollView.node.on('scroll-began', () => {
this.needCulling = true
console.log('scroll-began')
})
this.scrollView.node.on('scroll-ended', () => {
this.culling()
this.needCulling = false
console.log('scroll-ended')
})
this.scrollView.node.on(cc.Node.EventType.TOUCH_CANCEL, () => {
this.culling()
// this.needCulling = false
console.log('TOUCH_CANCEL')
})
}

frameCreator(dt: number) {
if (this.needItem < 1) {
return
} else if(this.needItem === 1) {
this.culling()
}
this.needItem--
this.index++
let itemNode = cc.instantiate(this.itemPrefab)
itemNode.getComponent(Item).init(this.index)
itemNode.color = cc.color(~~(Math.random() * 255), ~~(Math.random() * 255), ~~(Math.random() * 255))
this.scrollView.content.addChild(itemNode)
}

culling() {
this.scrollView.content.children.forEach((node) => {
if(this.viewRect.containsRect(node.getBoundingBoxToWorld())){
node.getComponent(Item).itemShow()
} else {
node.getComponent(Item).itemHide()
}
})
}

update(dt) {
this.frameCreator(dt)
if (this.needCulling) {
console.log('is culling')
this.culling()
}
}
}

简单分析

  • 将预制件实例化的操作分到每一帧, 每一帧生成实体
  • 在每一帧16ms的时间内,生成一个或者多个实体
  • 当item的位置超出view的位置时就设置透明度为0(减少drawCall)