2012-04-05 10 views
2

私はWeb全体で見つかったいくつかのチュートリアルに基づいて、単純な2フレームのスプライトアニメーションを作成しました。私は2枚の画像をとり、plistとpngファイルのスプライトシートを作成し、以下に示すようにそれらを私のコードに組み込みました。この設定はCocos2d V 1.0.1でもうまくいきました。私はちょうど2.0rc0aに私のプロジェクトをアップグレードし、今すぐ最初のフレームから2番目に切り替えるべきポイントで次のエラーで私のアプリケーションがクラッシュします:'CCSprite: setTexture doesn't work when the sprite is rendered using a CCSpriteBatchNode'Cocos2d 1.0.1から2.0にアップグレードした後、スプライトシートのアニメーションが失敗する

私はこの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]; 

YvesLeBorgはrestoreOriginalFrameステートメントを使用して提案し、それは2.0のverで廃止されました。私は

CCAnimation *mouthAnim = [CCAnimation animationWithAnimationFrames:chameleonFrames delayPerUnit:0.3f loops:5];

を使用してみましたし、エラー'-[CCSpriteFrame delayUnits]: unrecognized selector sent to instance'を取得します。私はなぜそれが動作していないか、ここから試して他に何がわからない。

EDIT:だから今、それが働いている...しかし、私は好きなように効率的にコーディングされていない:

新しいコード:

//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]; 

私は本当に私はそれをやっていた方法を言っていますなぜなら、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

+0

興味があれば私のコードをここに答えとして掲示することができます。 – mokagio

+0

最後の1つは、私のフレームはちょうどフレームと非常に単純なアニメーションです。これは関連する可能性があります。残念ながら、私は今、より多くのフレームでテストする時間がありません。( – mokagio

0

これは2.0の問題であるかどうかはわかりませんが、同じシーケンスでchameleonDelayオブジェクトを2回使用しています。これはあなたが達成しようとしていたものなのですか?つまり、

遅延、アクション、遅延、遅延、アクション、遅延、遅延、アクションなどです。

は、それが動作するかどうかを確認するために、これを試してみてください。

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

はい、意図的です。それは問題の組み合わせだった。私はそれを追加せずに、何らかの理由でアクションがフレーム1からフレーム2に移動し、次にフレーム1に素早く戻ることを意図したものではないことがわかりました.2番目の遅延がなければ、フレーム2にとどまります。それは私がそれを扱っている方法だと確信していますが、タイミングは実際に私が達成したいもののために実際に動作します。それを指摘してくれてありがとう。 – BobbyScon

+0

フレーム1に素早く戻らないようにするには、[CCAnimate actionWithAnimation:mouthAnim restoreOriginalFrame:NO]を使用します。しかし、いずれにしても、同じシーケンスで2つの用途がある場合は、CCDelayTimeの別のインスタンスを作成してみてください。 – YvesLeBorg

+0

申し訳ありませんが、私はおそらくそれを正確にフレーズしませんでした。私はそれをフレーム1に戻したい。それは口の開閉です。私はこのコードで終わる前にrestoreOriginalFrame:YESを試してみました。実際には最初のフレームに戻りませんでした。なぜか言わない。このコーディングは、私が望んでいた方法とまったく同じように機能しました。第二のインスタンスを作成することについては、私はそれを行うつもりです。 – BobbyScon