的cocos2d和SpriteBatchNode:不能识别哪个子画面帧是造成一个断言失败(Cocos

2019-08-17 02:32发布

我已经问类似的东西,但我无法弄清楚如何正确调试此。 这就是问题 。

我加了一些异常处理程序(捕获所有的Objective-C)例外,这就是什么,我看到的结果是:

该问题是与的SetTexture方法和它在断言验证需要显示纹理名称是否相同的一个在当前子画面批次节点出现故障。

发生这种情况时,试图用另一个更换一个场景,但不会发生所有的时间。 它做的新的场景,我试图通过调用游戏的不同部分替换“隔离”的问题,它仍然无法给予的麻烦。

在游戏场景我有几个精灵表和精灵一批节点,但因为我不设法隔离精灵表ID我无法理解其前景帧是给我的问题,以及我不明白为什么这个发生只是有时。

我想要:

  • 了解哪些前景帧的名字给我的AssertionFailure
  • 理解到它所属的子画面片

这将有助于我了解,如果它是一个命名问题,或者这个有别的东西要做。

希望不要是这个问题太蹩脚的..

编辑:我试过了答案,但我不能够读取文件名“”的信息,这里是调试器说“摘要不可用”:

这就是我创建的文件名属性:

/** TMP: Bug solving filename */
@property (copy) NSString *fileName;

-(id) initWithTexture:(CCTexture2D*)texture rectInPixels:(CGRect)rect rotated:(BOOL)rotated offset:(CGPoint)offset originalSize:(CGSize)originalSize
{
    if( (self=[super init]) )
    {
        self.fileName = [NSString stringWithFormat:@"GLUINT texture name: %i", texture.name];
        self.texture = texture;
        rectInPixels_ = rect;
        rect_ = CC_RECT_PIXELS_TO_POINTS( rect );
        offsetInPixels_ = offset;
        offset_ = CC_POINT_PIXELS_TO_POINTS( offsetInPixels_ );
        originalSizeInPixels_ = originalSize;
        originalSize_ = CC_SIZE_PIXELS_TO_POINTS( originalSizeInPixels_ );
        rotated_ = rotated;
    }
    return self;
}

-(id) initWithTextureFilename:(NSString *)filename rectInPixels:(CGRect)rect rotated:(BOOL)rotated offset:(CGPoint)offset originalSize:(CGSize)originalSize
{
    if( (self=[super init]) )
    {
        self.fileName = fileName; //TMP
        texture_ = nil;
        textureFilename_ = [filename copy];
        rectInPixels_ = rect;
        rect_ = CC_RECT_PIXELS_TO_POINTS( rect );
        offsetInPixels_ = offset;
        offset_ = CC_POINT_PIXELS_TO_POINTS( offsetInPixels_ );
        originalSizeInPixels_ = originalSize;
        originalSize_ = CC_SIZE_PIXELS_TO_POINTS( originalSizeInPixels_ );
        rotated_ = rotated;
    }
    return self;
}

Answer 1:

在这种情况下记录是你的朋友。 每当你创建一个CCAnimate动作(或CCAnimation),你应该记录是这样的:

// during 'create sprite frames from sprite frame names' loop
NSLog(@"adding sprite frame name for CCAnimate: %@", spriteFrameName);

// after CCAnimate was created
NSLog(@"creating CCAnimate %@ with sprite frames: %@, animate, arrayOfSpriteFrames);

你可能会想添加更多细节,比如其前景帧的名称添加至该CCAnimate。 您可能还需要增加额外的记录如果缓存CCAnimations后来重用它们(重新使用时,记录每个CCAnimation)。

现在,当您收到错误,您应该选择[CCSprite setDisplayFrame:]在调用堆栈方法。 然后,调试器会告诉你它想要设置CCSpriteFrame值。 寻找指针值,它会读取类似0x254fb22e

搜索在日志中值,这将带你回到了“创建CCAnimate ..”日志之一。 从日志线上面可以看到它所包含的前景帧的名字。 既然你也记录了“arrayOfSpriteFrames”你可以得到他们的指针的值,它与导致断言的CCSpriteFrame的指针值进行比较。

当你有一个比赛,它的前景帧数组中的第四个项目,只是仰望加入CCAnimate第四前景帧名的名称。

有可能做到这一点,这取决于信息是在调试器(以及如何深谙你在调试)提供更快的方法,但是这是一个办法,肯定会导致你的问题的前景帧的名字在相对较短的时间。

需要注意的是,指针的值是不是唯一的 - 这可能是一个不同的CCAnimate用相同的指针值创建的。 特别是,如果有的CCAnimate播放和停止它可能发生另一CCAnimate在以前的一个完全相同的内存位置分配的超高频。 所以要谨慎,如果看上去结果不匹配起来。 一个快速的方法,找出是测试在不同的设备或模拟器与设备,如指针值和分配策略有所不同。

你并不需要登录框名称属于哪个纹理图集哪个精灵。 只需打开每个图谱的plist中,搜索前景帧的名字。 plist中是一个XML文件。

提示:常见的原因为这个问题可以有两种不同的纹理地图具有相同前景帧的名字-当你请求一个精灵帧使用重复名称的cocos2d可以使用任何纹理。

另一个提示:如果日志似乎令人生畏,我只需做到以下几点:

  • 对于CCSpriteFrame级开放源代码
  • 添加的NSString *财产“名”与“复制”属性
  • 每次创建CCSpriteFrame对象时,文件名分配给CCSpriteFrame

现在,只要你在调试器中看到一个CCSpriteFrame,它会告诉你在调试器中查看相关的文件名。



Answer 2:

好吧,看起来你已经有前...评论第一NSAssert,取消注释如果块。 然后把一个破发点上的新注释去掉,NSAssert。 执行将暂停异常之前,你应该检查调用堆栈中的每一个类实例的实例变量(至少我可以用AppCode,希望Xcode的允许)。 也许你会得到足够的提示,以找出哪些纹理/动画/ batchnode是给你一个困难时期。

此外...仅供参考。 每当我开始了cocos2d(所有版本)的一个项目,我申请的一些“标准”的修正它,因此我的生命将是调试更容易。 一个标准的“补丁”是一个名称添加到CCNode,我设置了一些有意义的值:始终。 此外,我重写descpription方法返回我的名字。 分配有意义的名字已经帮助了我很多次,特别是当正走(或向上)节点层次找出的错误。 我也核弹许多NSAsserts并尽可能(尤其是在构建函数),回归零和记录错误消息。 按照斯蒂芬的建议,如果是Cocos2d构造函数返回我一个零,我喷涌出一个错误日志消息。 然后我就可以在日志中陈述和向下钻取问题突破。



文章来源: Cocos2d and SpriteBatchNode: cannot identify which sprite frame is causing an Assertion to fail