在运行时进行节点的创建(cc.instantiate)和销毁(node.destroy)操作是非常耗费性能
开头创建:通常只有在场景初始化逻辑(onLoad)中才会进行节点的创建
结束销毁:在切换场景时才会进行节点的销毁
对象池的概念
目的是减少创建和销毁这种费性能的操作
管理一组节点归于一个对象池对象(cc.NodePool),用对象池对象管理这些节点
你要用的时候 就找他申请:用户通过 node.addChild 将这个新节点加入到场景节点树中
不用的时候 再还给它:调用对象池实例的 put(node) 方法
假如玩家在一关中要杀死 100 个敌人,但同时出现的敌人不超过 5 个,那我们就只需要生成 5 个节点大小的对象池,然后循环使用就可以了
流程介绍
首先你要有一个prefab
然后你要创建对象池
在对象池里放入一定数量的对象(实例化上面的prefab)
试试调用
试试归还
我做了一个测试例子
一张图片,隔一段时间地在屏幕上出现,但隔一会就从屏幕上消失
//PoolTest1.ts
@property(cc.Prefab)
mon: null;
// LIFE-CYCLE CALLBACKS:
monPool:cc.NodePool;
onLoad () {
this.monPool = new cc.NodePool();
for(let xx =0;xx<5;xx++){
let node = cc.instantiate(this.mon);
this.monPool.put(node);
}
this.schedule(this.CreatMon,1);
this.scheduleOnce(()=>{ this.monPool.clear() },5);//10秒后清除对象池
}
CreatMon(pool:cc.NodePool){
pool = this.monPool;
let size = this.monPool.size();
let node;
if( size > 0 ){
node = this.monPool.get();
cc.log("对象池里 拿出来一个");
}else{
node = cc.instantiate(this.mon);
cc.log("新创一个");
}
cc.find("Canvas").addChild(node);
node.getComponent("mon").init(pool);
node.position = new cc.Vec3(Math.random()*100,Math.random()*100,0);
}
//prefab身上的脚本 mon.ts
_pool:cc.NodePool;
init(pool:cc.NodePool){
this._pool = pool;
this.scheduleOnce(this.backPol,2);
}
backPol(){
this._pool.put(this.node);
}
使用组件来处理回收和复用的事件
指定组件类型,该组件挂在节点上的,用于处理节点回收和复用
对象池.get() 能调用指定组件里的方法 reuse()
对象池.put()能调用指定组件里的方法 unuse()
测试: 确实是这样的
//PoolTest2
@property(cc.Prefab)
mon:null;
monPool:cc.NodePool;
start () {
this.monPool = new cc.NodePool("mon2")
for(let i=0;i<5;i++){
let node = cc.instantiate(this.mon);
this.monPool.put(node);
}
this.scheduleOnce(this.CreatMon,1);
}
CreatMon(){
let node;
if(this.monPool.size()>0){
node = this.monPool.get();
}else{
node = cc.instantiate(this.mon);
}
cc.find("Canvas").addChild(node);
}
//mon2
reuse(){
cc.log("mon2 reuse");
}
官方案例的例子是,在列表里
按钮出来就注册点击事件
按钮回去就取消点击事件

1028

被折叠的 条评论
为什么被折叠?



