2012-04-05 104 views
2

我根據在網上找到的一些教程創建了一個簡單的2幀精靈動畫。我拿走了我的2張圖片,用plist和png文件創建了一個精靈圖表,並將它們合併到我的代碼中,如下所示。這個設置在Cocos2d V 1.0.1中運行正常。我剛剛將我的項目升級到2.0rc0a,現在我的應用程序在第一幀切換到第二幀時出現以下錯誤:'CCSprite: setTexture doesn't work when the sprite is rendered using a CCSpriteBatchNode'從Cocos2d 1.0.1升級到2.0後,Sprite Sheet動畫失敗

我看着這個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,但很明顯,通過動畫不走。

好的,所以爲了讓我更加困惑,因爲我肯定錯過了一些東西,我試着將代碼底部改爲這個,動畫從第1幀開始到第2幀,然後無限期地停留在第2幀。但是,如果延遲時間超過1.0,我會收到與之前相同的錯誤。如果我在重複永久聲明之前重新包含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]; 

使用restoreOriginalFrame語句YvesLeBorg建議,但在版本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相反。如果沒有人能夠在未來幾天內提供更好的解決方案或「真實」答案,我會將其作爲答案發布,並接受它來解決問題。

回答

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]; 
+0

你好。首先感謝詳細的問題+答案。今天我偶然發現了同樣的問題,但我用不同的方式解決了這個問題。現在我不知道哪一個是最好的,或者即使我所做的都是正確的。在我的其中一次嘗試中,我注意到精靈尺寸裁剪出現問題,所以我添加了對Retina的檢查並根據該檢查加載了文件。和粉撲!問題(似乎是)解決了。那麼你如何處理視網膜? – mokagio 2012-08-03 14:13:26

+0

如果您有興趣,我可以在這裏發佈我的代碼作爲答案。 – mokagio 2012-08-03 14:14:22

+0

最後一件事,我的是一個非常簡單的動畫,只是爲了框架。這可能是相關的。不幸的是,我現在沒有時間用更多的框架來測試:( – mokagio 2012-08-03 14:15:29

0

不確定這是否是2.0問題,但我注意到你正在使用相同序列中的兩倍chameleonDelay對象。這真的是你試圖完成,即

延遲,行動,延遲,延遲,行動,延遲,延遲,行動等。

試試這個,看看它的工作原理:

CCRepeatForever *chameleonRepeat = [CCRepeatForever actionWithAction:[CCSequence actions:chameleonDelay, chameleonAction, nil]]; 
+0

是的,那是故意的。這是問題的組合。我發現如果不添加它,出於某種原因,這些動作不會做我想要的,從第1幀開始到第2幀,然後快速回到第1幀。如果沒有第二次延遲,它會停留在第2幀。我確定這是我處理它的方式,但實際上時機正好符合我想要完成的任務。感謝您指出了這一點。 – BobbyScon 2012-04-05 17:18:11

+0

爲了防止快速回到第一幀,您可能需要使用[CCAnimate actionWithAnimation:mouthAnim restoreOriginalFrame:NO]。但是,無論如何,如果您有兩個使用相同的序列,請嘗試創建另一個CCDelayTime實例。 – YvesLeBorg 2012-04-05 17:36:12

+0

對不起,我可能沒有正確說出它。我希望它回到第一幀。這是一個開口和關閉的嘴。我在結束這段代碼之前嘗試了restoreOriginalFrame:YES,它實際上並沒有返回到第一幀。不知道爲什麼。這種編碼的工作方式正是我想要的,所以我只是把它放在一邊。關於創建第二個實例的觀點,我會這樣做。 – BobbyScon 2012-04-05 17:45:59