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'
私はこのSOの質問を見ましたが、それが私が間違っているのと同じかどうかはわかりません.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 を示すカメレオンが表示されますが、明らかにアニメーションは実行されません。
OK、間違いなく何かが欠けているのでさらに混乱させるために、コードの下部をこれに変更してみました. ただし、遅延を 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 で廃止されました。使ってみた
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 を使用するのには直感的ではないようです。今後数日以内に、より良い解決策または「実際の」回答を提供できる人がいない場合は、これを回答として投稿し、それを受け入れて質問を締めくくります。