关于对象池Size大小的一些问题

先附上源码:

extends: cc.Component,

properties: {
    bullet_vPerfab:{
        type:cc.Prefab,
        default:null,
    },
    myTransfer:{
        type:cc.Node,
        default:null,
    },
    position:{
        default:new cc.Vec2(),
        tooltip:"这个变量控制弹幕出现的位置",  
    },
    rotatePerTimes:{
        default:20,
        tooltip:"这个变量控制弹幕每次射出的角度",
    },
    bullet_vNumber:{
        default:18,
        tooltip:"这个变量控制生成弹幕的数量",
    }
},

onLoad(){
    //0.5s生成一个弹幕
    this._Bullet_vpool=new cc.NodePool();
    //对象池初始大小为20
    let initCount=20;
    for (let i = 0; i < initCount; i++) {
        this._Bullet_vpool.put(cc.instantiate(this.bullet_vPerfab));
    }
    this._rotate=0;
    this.schedule(this.init,0.5,this.bullet_vNumber-1);
},
init()
{
    var bullet_v=this._Bullet_vpool.get();
    if (!bullet_v) {
        bullet_v=cc.instantiate(this.bullet_vPerfab);
    }
    this._rotate+=this.rotatePerTimes;
    bullet_v.rotation=this._rotate;
    bullet_v.position=this.position;
    var newV = cc.v2(1,0).rotate(cc.misc.degreesToRadians(-this.node.rotation));
    bullet_v.runAction(cc.sequence(
        cc.moveBy(2,newV),
        cc.callFunc(()=>{
            this._Bullet_vpool.put(bullet_v);
        },this),
    ));
    this.node.addChild(bullet_v);
},
update(){
    //cc.log(this.node.children);
    cc.log(this._Bullet_vpool.size());
}

这一段代码是实现了一种向周围散射的子弹的效果,但是遇到了一些问题,当代码中的bullet_vNumber(弹幕的数量)
小于8个的时候,最后检测的对象池size为20。但是当bullet_vNumber(弹幕的数量)大于8个的时候最后的最的对象池size则小于20个,于是开始寻找原因。

在init()函数中get到了子弹后加入了一行代码
cc.log(bullet_v.uuid);
在这之后发现当子弹数目为8的时候,uuid会按照从大到小一次减一的形式不断循环,比如uuid=256,255,254,253,256,255,254,253。此时size=20
但是当子弹数目大于8的时候,此时用子弹数目为18做测试,uuid循环了两次以后会发生突然的跳转,测试结果:uuid=102,101,100,99,102,101,100,99,102,101,100,99,102,101,98,97,96,95。此时size=14
作为刚学cocos的新人,我猜测这可能与系统有关,在第四次循环的时候uuid=100和99的单位还没来得及返回就直接get了,所以unid的数字跳过了100和99,然后从98继续向下递减。

在这期间我也检测过这个节点的子节点数目,当子弹数目为20的时候子节点数目最后确实为0,但是size确是14,真的不太明白是什么原因。

然后我想问一下,当子弹数目很大的时候能不能也让对象池最后的size也是20,是我写的代码有问题吗?表示不太明白,请大佬解释一下

你这代码有问题吧,你要保持池里面的数量不变, this._Bullet_vpool.put(bullet_v)这边要加判断,是从池里面面拿的,才放回池里面去,不然当池里面的节点都用完了,不就会导致又往池里面加了节点。

感谢,这个问题已经解决了