我根据网上发现的一些教程创建了一个简单的2帧精灵动画。我拍摄了我的2张图片,用plist和png文件创建了一张精灵表,并将它们合并到我的代码中,如下所示。这种设置在Cocos2d V 1.0.1中运行良好。我刚刚将我的项目升级到2.0rc0a,现在我的应用程序在应该从第一帧切换到第二帧时出现以下错误而崩溃:'CCSprite: setTexture doesn't work when the sprite is rendered using a CCSpriteBatchNode'
我查看了这个SO question,但我不确定这是不是我做错了,因为我还是Cocos2d的新手,我不确定如何正确调整我的代码。这是我在2.0中没有看到的内容,我应该报告的错误,或者我的编码不正确吗?我仍然拥有相同代码的1.0.1项目的副本,动画正常工作。
//CHAMELEON
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"front page/mainchameleon.plist"];
mainChameleon = [CCSpriteBatchNode batchNodeWithFile:@"front page/mainchameleon.png"];
[self addChild:mainChameleon z:7];
NSMutableArray *chameleonFrames = [NSMutableArray array];
for (int i = 1; i <= 2; ++i)
{
[chameleonFrames addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:@"chameleon%d.png", i]]];
}
CCAnimation *mouthAnim = [CCAnimation animationWithSpriteFrames:chameleonFrames delay:0.3f];
chameleon = [CCSprite spriteWithSpriteFrameName:@"chameleon1.png"];
CCAnimate *chameleonAction = [CCAnimate actionWithAnimation:mouthAnim];
CCDelayTime *chameleonDelay = [CCDelayTime actionWithDuration:10];
CCRepeatForever *chameleonRepeat = [CCRepeatForever actionWithAction:[CCSequence actions:chameleonDelay, chameleonAction, chameleonDelay, nil]];
[chameleon runAction:chameleonRepeat];
[mainChameleon addChild:chameleon];
如果我注释掉chameleon = [CCSprite spriteWithSpriteFrameName:@"chameleon1.png"];
,那么应用程序不会崩溃,但变色龙根本不会出现,正如代码当前的编写方式所预期的那样。
或者,如果我注释掉[chameleon runAction:chameleonRepeat];
,那么变色龙会出现显示框架chameleon1.png,但显然不会通过动画。
chameleonDelay
而没有重复永久声明,我也会遇到同样的崩溃。如果必须等待超过1秒才能执行切换,应用程序似乎崩溃了。我需要的是第1帧静置一会儿(10秒)然后切换到第2帧0.3秒,然后切换回第1帧再坐一会儿。
尝试过的代码#2:
CCAnimation *mouthAnim = [CCAnimation animationWithSpriteFrames:chameleonFrames delay:0.3f]; //<--- maxes out at 1.0. Anything more causes crash
chameleon = [CCSprite spriteWithSpriteFrameName:@"chameleon1.png"];
CCAnimate *chameleonAction = [CCAnimate actionWithAnimation:mouthAnim];
[chameleon runAction:chameleonAction];
[mainChameleon addChild:chameleon];
YvesLeBorg建议使用restoreOriginalFrame语句,但在2.0版中已弃用。我尝试使用
CCAnimation *mouthAnim = [CCAnimation animationWithAnimationFrames:chameleonFrames delayPerUnit:0.3f loops:5];
并获取错误'-[CCSpriteFrame delayUnits]: unrecognized selector sent to instance'
。我不确定为什么那不起作用或者还有什么可以尝试的。
编辑:所以现在它正在工作......但不像我想的那样有效编码:
新守则:
//CHAMELEON
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"front page/mainchameleon.plist"];
mainChameleon = [CCSpriteBatchNode batchNodeWithFile:@"front page/mainchameleon.png"];
[self addChild:mainChameleon z:7];
NSMutableArray *chameleonFrames = [NSMutableArray array];
//Frame 1 - closed mouth
[chameleonFrames addObject:[CCSpriteFrame frameWithTexture:mainChameleon.texture rect:CGRectMake(0, 124, 149, 122)]];
//Frame 2 - Open Mouth
[chameleonFrames addObject:[CCSpriteFrame frameWithTexture:mainChameleon.texture rect:CGRectMake(0, 0, 149, 122)]];
//Frame 1 - closed mouth
[chameleonFrames addObject:[CCSpriteFrame frameWithTexture:mainChameleon.texture rect:CGRectMake(0, 124, 149, 122)]];
CCAnimation *mouthAnim = [CCAnimation animationWithSpriteFrames:chameleonFrames delay:0.9f];
chameleon = [CCSprite spriteWithTexture:mainChameleon.texture rect:CGRectMake(0,124,149,122)];
CCAnimate *chameleonAction = [CCAnimate actionWithAnimation:mouthAnim];
CCDelayTime *chameleonDelay = [CCDelayTime actionWithDuration:10];
CCRepeatForever *chameleonRepeat = [CCRepeatForever actionWithAction:[CCSequence actions:chameleonDelay, chameleonAction, nil]];
[chameleon runAction:chameleonRepeat];
[mainChameleon addChild:chameleon];
我真的很喜欢我在1.0.1中这样做的方式,因为如果我有2帧或100帧,我只需要对if语句做一个小调整。这种方式需要对每个单独的帧进行编码,这似乎与使用plist相反。如果没有人能够在接下来的几天内提供更好的解决方案或“真正的”答案,我会将此作为答案发布并接受它以结束问题。
答案 0 :(得分:3)
这是我最终使用的代码正常工作。不知道为什么我必须做出这些改变,但确实如此。 (当我开始一个新的项目来解决这个问题时,一些名称已经改变了,但我原来的代码与此之间的差异很明显)。对于找到此主题的其他人,我的原始代码基于Ray Wenderlich's sprite sheet tutorial。
CCSpriteBatchNode *chameleonBN = [CCSpriteBatchNode batchNodeWithFile:@"chameleonimages.png"];
[self addChild:chameleonBN];
//ADDED the texture part to resolve: 'CCSprite: setTexture doesn't work when the sprite is rendered using a CCSpriteBatchNode'
[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"chameleonplist.plist" texture:chameleonBN.texture];
NSMutableArray *chameleonframes = [NSMutableArray array];
for (int i = 1; i <= 2 ; i++)
{
[chameleonframes addObject:[[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:[NSString stringWithFormat:@"chameleon%d.png", i]]];
}
CCAnimation *mouthAnim = [CCAnimation animationWithSpriteFrames:chameleonframes delay:0.9f];
//ADDED this sprite frame to resolve texture id assert error
CCSpriteFrame *frame = [CCSpriteFrame frameWithTexture:chameleonBN.texture rect:CGRectMake(0, 0, 149, 122)];
CCSprite *chameleon = [CCSprite spriteWithSpriteFrame:frame];
chameleon.position = ccp(512,384);
CCAnimate *chameleonAnimate = [CCAnimate actionWithAnimation:mouthAnim];
CCDelayTime *chameleonDelay = [CCDelayTime actionWithDuration:10];
CCDelayTime *chameleonDelay2 = [CCDelayTime actionWithDuration:0.1];//Had to use this to ge tthe mouth to close. Using restore original frame doesn't work for me.
CCRepeatForever *chameleonRepeat = [CCRepeatForever actionWithAction:[CCSequence actions:chameleonDelay, chameleonAnimate, chameleonDelay2, nil]];
[chameleon runAction:chameleonRepeat];
[chameleonBN addChild:chameleon];
答案 1 :(得分:0)
不确定这是否是2.0问题,但我注意到你在同一序列中使用了两次chameleonDelay对象。这真的是你想要实现的目标,即
延迟,行动,延迟,延迟,行动,延迟,延迟,行动......等等。
试试看它是否有效:
CCRepeatForever *chameleonRepeat = [CCRepeatForever actionWithAction:[CCSequence actions:chameleonDelay, chameleonAction, nil]];