萌新求助:未知问题求助(可能与destroy相关)

  • Creator 版本: 2.3.3

  • 目标平台:微信小游戏开发工具

  • 实测发现:onBeginContact(contact, selfCollider, otherCollider){
    if(otherCollider.node.name === ‘ball’ && this.node.name != ‘+block’){
    this.bloodNum -= 1;
    this.blockManager.addScore();
    this.bloodNode.getComponent(cc.Label).string = this.bloodNum.toString();
    }}
    update (dt) {
    //当blood减到0时,摧毁节点
    if(this.node.name != ‘+block’){
    if(this.bloodNum < 1){
    this.node.destroy();
    }
    }
    }
    但是实测发现最后检测是否被destroy时,
    moveBlock(){
    let blockNodes = this.node.children;
    for(let i = 0;i < blockNodes.length;i++){
    let block = blockNodes[i];
    if(block.y > 300 && block.getComponent(“block2”).bloodNum > 0){
    this.game.gameOver = true;
    }
    }
    gameOver变量无法被正确赋值
    也就是说,能在模拟器上看到该节点消失,但是会出现即使没有显示有node到达了y>300,游戏仍然会结束的现象,求助一下这是为什么呢?(可有偿,可提供源代码,可追问,萌新第一次提问不太了解)

使用了物理引擎的时候,需要destroy,都建议在下一帧处理。当前帧使用active关闭,把碰撞检测关闭掉。

感觉情况可能有一点区别?因为实测效果确实是已经不会再被碰撞了,也确实是不可视的状态,但是不知道为什么在较长时间后仍然会被父节点检测到,甚至可能是检测到未被destroy的状态,这让我感到很奇怪。在cocos中,子节点在自己的脚本中被destroy需要额外向父节点更新吗?

不知道楼主有没有做过数组元素删除。
做个for循环,i递增,逐步去删除第i个元素,这时候会有个错误,因为i号元素删除后,原本的i+1号元素的位置移动到了i,i+2号元素移动到了i+1。所以下一步删除i+1号元素时,其实会错过一个元素。
节点的销毁也会有类似的问题,因为大部分节点会是其他节点的子节点,会存在于一个children数组中。
碰撞之类的判定,在底层是会在for循环,父子节点遍历这些逻辑里操作的,所以有了destroy操作,往往会出现很多问题。

倒序删除呀

我的destroy操作是在子节点的脚本中的,应该不太会出现这个问题?我的问题可能更偏向于为什么感觉父结点中它的状态没有更新,即使使用了if(block.y >= 300 && block.getComponent(“block”).bloodNum > 0)仍然无法正确进入,而从模拟器的结果来看,又确实变为了不可视+没有碰撞监听的状态,却又会错误的认为有节点出现在了y>300的位置上。

对比前后不难看出blood变为0后小球确实“消失”了,这是正常的。但是如右图在最后统计结果的时候又会认为已经消失的第一排(最上面那排)越过了y=300,判断游戏结束,感觉就像是有“幽灵球”一样没有destroy干净

如果你看看api接口。你会有机会看到一个叫 _destroyImmediate 的方法,也就是说destroy其实不会立即销毁节点。对具体的机制我也没有太深入了解。但是以我的经验,这应该是为了避免某些逻辑正在循环或者遍历中导致出现问题。

诶诶是这样吗?那大佬有没有什么解决建议呢?

用一个自己定义的状态值来判定球是否是幽灵就行了。destroy其实也不可以不做,用对象池缓存起来。未在使用中的统统设置为幽灵。这样还能减少重复销毁创建的开销。

image


这样应该也可以起到类似的作用?但是实际结果好像不是很对?就是模拟器里能看到是被destroy了,但实际判断(p2的判断语句结果)又是错误的,不知道这种有可能是什么问题呢?