Cocos2d 2.0和CCSpriteBatchNode:CCAnimation崩溃APP当CCRepeatForever开始第二个动画周期 [英] Cocos2d 2.0 and CCSpriteBatchNode: CCAnimation crashes APP when CCRepeatForever starts second animation cycle
问题描述
编辑4:我添加了一个断点到CCSpriteFrameCache spriteFrameByName方法,并且不能跨过以下步骤(它清楚地告诉我,不知何故spriteFrames从CCSpriteFrameCache删除):
EDIT 4: I added a breakpoint to CCSpriteFrameCache spriteFrameByName method and cannot step over the following step (its clear to me that somehow the spriteFrames gets deleted from the CCSpriteFrameCache):
编辑3:在投票使用 Cocos2d 2.0以及附加的文件和plist文件之前,请先投票以关闭该问题请尝试下面的代码(EDIT2)。
EDIT 3: Before voting to close the question actually PLEASE TRY the code below (EDIT2) using Cocos2d 2.0 and the file and plist file attached.
编辑2:我创建了一个全新的GameScene测试类,所以你可以试试这个问题。动画开始重复时会崩溃。我也将标题更新为结果。
EDIT 2: I created a brand new GameScene test class so you can all try out the issue. It crashes as soon as the animation starts to repeat. I update the title as consequence as well.
// GameScene2.h
//
#import <Foundation/Foundation.h>
#import "cocos2d.h"
@interface GameScene2 : CCScene {
}
@end
// GameScene2.m
//
#import "GameScene2.h"
@implementation GameScene2
-(id)init {
self = [super init];
if (self != nil) {
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"artfile.plist"];
CCSpriteBatchNode* batchNode = [CCSpriteBatchNode batchNodeWithFile:@"artfile.png"];
[self addChild:batchNode];
CCSprite * test = [CCSprite spriteWithSpriteFrameName:@"frame0.png"];
test.anchorPoint = CGPointMake(0.5f, 0.5f);
test.position = CGPointMake(160.0f, 160.0f);
[batchNode addChild:test z:1];
NSMutableArray* frames = [[NSMutableArray alloc]initWithCapacity:2];
CCSpriteFrame* frame = [[CCSpriteFrameCache sharedSpriteFrameCache]spriteFrameByName:@"frame0.png"];
[frames addObject:frame];
CCSpriteFrame* frame2 = [[CCSpriteFrameCache sharedSpriteFrameCache]spriteFrameByName:@"frame1.png"];
[frames addObject:frame2];
CCAnimation* anim = [CCAnimation animationWithSpriteFrames:frames delay:0.3f];
[[CCAnimationCache sharedAnimationCache] addAnimation:anim name:@"test"];
CCAnimate * animate = [CCAnimate actionWithAnimation:anim];
CCRepeatForever * repeat = [CCRepeatForever actionWithAction:animate];
//CCSequence * seq = [CCSequence actions:anim, nil];
[test runAction:repeat];
}
return self;
}
@end
artfile.png如下:
The artfile.png looks as following:
和plist文件是:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>frames</key>
<dict>
<key>frame0.png</key>
<dict>
<key>aliases</key>
<array>
</array>
<key>spriteColorRect</key>
<string>{{3, 40}, {76, 28}}</string>
<key>spriteOffset</key>
<string>{0, 0}</string>
<key>spriteSize</key>
<string>{150, 94}</string>
<key>spriteSourceSize</key>
<string>{150, 94}</string>
<key>spriteTrimmed</key>
<false/>
<key>textureRect</key>
<string>{{0, 96}, {150, 94}}</string>
<key>textureRotated</key>
<false/>
</dict>
<key>frame1.png</key>
<dict>
<key>aliases</key>
<array>
</array>
<key>spriteColorRect</key>
<string>{{10, 33}, {98, 32}}</string>
<key>spriteOffset</key>
<string>{0, 0}</string>
<key>spriteSize</key>
<string>{150, 94}</string>
<key>spriteSourceSize</key>
<string>{150, 94}</string>
<key>spriteTrimmed</key>
<false/>
<key>textureRect</key>
<string>{{0, 192}, {150, 94}}</string>
<key>textureRotated</key>
<false/>
</dict>
<key>frame2.png</key>
<dict>
<key>aliases</key>
<array>
</array>
<key>spriteColorRect</key>
<string>{{4, 17}, {146, 48}}</string>
<key>spriteOffset</key>
<string>{0, 0}</string>
<key>spriteSize</key>
<string>{150, 94}</string>
<key>spriteSourceSize</key>
<string>{150, 94}</string>
<key>spriteTrimmed</key>
<false/>
<key>textureRect</key>
<string>{{0, 0}, {150, 94}}</string>
<key>textureRotated</key>
<false/>
</dict>
</dict>
<key>metadata</key>
<dict>
<key>version</key>
<string>1.5.2</string>
<key>format</key>
<integer>3</integer>
<key>size</key>
<string>{1024, 1024}</string>
<key>name</key>
<string>artfile</string>
<key>premultipliedAlpha</key>
<false/>
<key>target</key>
<dict>
<key>name</key>
<string>default</string>
<key>textureFileName</key>
<string>artfile_default</string>
<key>textureFileExtension</key>
<string>.png</string>
<key>coordinatesFileName</key>
<string>artfile_default</string>
<key>coordinatesFileExtension</key>
<string>.plist</string>
<key>premultipliedAlpha</key>
<false/>
</dict>
</dict>
</dict>
</plist>
编辑结束2:
原始问题:
END OF
ORIGINAL QUESTION:
我得到:
声明失败 - [CCSprite setTexture:], ... / libs / cocos2d / CCSprite.m:934
它与batchNode有明确的关系,因为没有它,
It has definetely to do with the batchNode because without it it used to work...
我知道动画的精灵帧应该在同一个精灵表中,这是case。我不知道如何解决这个问题,它必须是使用批处理节点。
I know that the sprite frames for the animation should be in the same sprite sheet, and that's the case. I have no idea how to solve this apart that it must be something to do with the use of batch node.
//
// Navigator.h
@interface Navigator : CCLayer {
}
//Batch Nodes
@property(readwrite, nonatomic) CCSpriteBatchNode* batchNode;
// Navigator.m
@implementation Navigator
@synthesize batchNode;
+(id) scene {
CCScene *scene = [CCScene node];
Navigator *layer = [Navigator node];//??
[scene addChild:layer];
return scene;
}
-(void) loadStuff{
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"art1-hd.plist"];
batchNode = [CCSpriteBatchNode batchNodeWithFile:@"art1-hd.png"];
[self addChild:batchNode];
CCSprite * test = [CCSprite spriteWithSpriteFrameName:@"emptyCircle0.png"];
test.anchorPoint = CGPointMake(0.5f, 0.5f);
test.position = CGPointMake(160.0f, 160.0f);
[batchNode addChild:test z:1];
NSMutableArray* frames = [[NSMutableArray alloc]initWithCapacity:2];
CCSpriteFrame* frame = [[CCSpriteFrameCache sharedSpriteFrameCache]spriteFrameByName:@"emptyCircle0.png"];
[frames addObject:frame];
CCSpriteFrame* frame2 = [[CCSpriteFrameCache sharedSpriteFrameCache]spriteFrameByName:@"emptyCircle1.png"];
[frames addObject:frame2];
CCAnimation* anim = [CCAnimation animationWithSpriteFrames:frames delay:0.3f];
//[[CCAnimationCache sharedAnimationCache] addAnimation:anim name:@"test"];
CCAnimate * animate = [CCAnimate actionWithAnimation:anim];
CCRepeatForever * repeat = [CCRepeatForever actionWithAction:animate];
//CCSequence * seq = [CCSequence actions:anim, nil];
[test runAction:repeat];
}
-(id)init
{
CCLOG(@"Navigator init");
if((self=[super init])){
CCLOG(@"%@: %@", NSStringFromSelector(_cmd), self);
[self loadStuff];
}
return self;
}
编辑:我检查了CCSprite setTexture的源代码,我看到了。然而控制台日志确实说只有NSAssert没有给出日志消息是什么问题。添加断点似乎失败了第一个NSAssert,但我不是100%肯定,因为应用程序立即到这个图像:
-(void) setTexture:(CCTexture2D*)texture
{
// If batchnode, then texture id should be the same
NSAssert( !batchNode_ || texture.name == batchNode_.texture.name , @"CCSprite: Batched sprites should use the same texture as the batchnode");
// accept texture==nil as argument
NSAssert( !texture || [texture isKindOfClass:[CCTexture2D class]], @"setTexture expects a CCTexture2D. Invalid argument");
if( ! batchNode_ && texture_ != texture ) {
[texture_ release];
texture_ = [texture retain];
[self updateBlendFunc];
}
}
推荐答案
I发现这是为什么发生的原因...我从前一个场景调用[self startGame]方法,然后cleanup方法被调用,也调用了一段代码,我从纹理缓存中删除sprites。
I found the reason why this was happening... I was calling the [self startGame] method from a previous scene and then the cleanup method was being called calling also the piece of code where I was removing sprites from the texture cache.
愚蠢的我,我没有想到这个正确。对象导航器场景被创建并且纹理被加载,但是在同时(在动画实际开始之前),先前的场景清理调用执行 [CCSpriteFrameCache purgeSharedSpriteFrameCache]; 。
Stupid me that I didn't thought about this properly. The object Navigator scene gets created and the texture loaded, but in the meanwhile (Before the animation actually starts) the previous scene cleanup call executes the [CCSpriteFrameCache purgeSharedSpriteFrameCache]; call.
愚蠢的我!
-(void) startGame
{
[[CCDirector sharedDirector] replaceScene:[CCTransitionFade transitionWithDuration:1.0 scene:[Navigator scene] withColor:ccc3(255, 255, 255)]];
}
-(void) cleanup
{
// [[CCSpriteFrameCache sharedSpriteFrameCache] removeSpriteFrames];
[super cleanup];
[CCTextureCache purgeSharedTextureCache];
[CCSpriteFrameCache purgeSharedSpriteFrameCache];
[CCAnimationCache purgeSharedAnimationCache];
//Remove music
}
这篇关于Cocos2d 2.0和CCSpriteBatchNode:CCAnimation崩溃APP当CCRepeatForever开始第二个动画周期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!