-
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的位置上。
如果你看看api接口。你会有机会看到一个叫 _destroyImmediate 的方法,也就是说destroy其实不会立即销毁节点。对具体的机制我也没有太深入了解。但是以我的经验,这应该是为了避免某些逻辑正在循环或者遍历中导致出现问题。
诶诶是这样吗?那大佬有没有什么解决建议呢?
用一个自己定义的状态值来判定球是否是幽灵就行了。destroy其实也不可以不做,用对象池缓存起来。未在使用中的统统设置为幽灵。这样还能减少重复销毁创建的开销。

