SpriteBuilder复杂CCB在App场景加载时报错排查

本文探讨了在使用CCB构建游戏场景时遇到的问题,即在GameScene.ccb中添加Player.ccb和其他物理对象(如Wall.ccb)时发生的错误。通过逐步排查,最终定位到问题是由于Player.ccb中的Arm类在didLoadFromCCB方法中不恰当地修改了物理世界导致的。

Player.CCB由body和arm两部分组成,它们都开启物理使能.

在GameScene.ccb中新建一个物理对象,将Player.ccb拖入该对象.此时编译运行App均正常.

然后继续添加其他物理对象Wall.ccb组成屏幕边界,这时App运行发生错误,log为:

Collection <__NSArrayM: 0x78f97730> was mutated while being enumerated

发现源代码中断在场景的初始化方法中,该方法的功能是递归调用场景中每个子CCNode的didLoadFromCCB方法.

接下来删除Player对象,再添加Player对象,这时App运行又正常.多次测试发现,只有当最后一个对象是Player时程序才不出错.

但是不能到这里停止.假如游戏场景中要有2个Player对象真么办?总有一个不是最后一个对象.所以还得找原因.

因为异常发生在didLoadFromCCB的递归调用中,而Player只有arm子对象添加了该函数.遂将其注释掉,在添加多个Player的情况下App运行正常.

这时可以锁定是arm类Arm中的didLoadFromCCB方法里做了不应该的事.检查该方法,发现其间接使用了GameScene.ccb中的物理对象:

_phyWorld = (CCPhysicsNode*)self.parent.parent;
CCLOG(@"name is %@",_phyWorld.name);
//省去无关代码
for (int i = 0; i < MAX_BULLETS; i++) {
        bullet = [CCBReader load:@"Sprites/Bullet"];
        bullet.visible = NO;
        [_phyWorld addChild:bullet];
    }

注意,在GameScene.ccb子对象的枚举过程中修改了物理对象.只有Player放在物理对象的最后才不会出错.

知道了问题所在,简单的取消Arm中对物理对象的引用就可以了,将必要的逻辑放到GameScene类里去即可.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值