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'

私はこの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 を使用するのには直感的ではないようです。今後数日以内に、より良い解決策または「実際の」回答を提供できる人がいない場合は、これを回答として投稿し、それを受け入れて質問を締めくくります。

4

2 に答える 2

3

これが私が最終的に正しく動作するコードです。なぜこれらの変更を行わなければならなかったのかはわかりませんが、それはあります。(これを修正するために新しいプロジェクトを開始したため、名前の一部が変更されましたが、元のコードとこれの違いは明らかです)。このスレッドを見つけた他の人にとって、私の元のコードはRay Wenderlich のスプライト シート チュートリアルに基づいていました。

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];
于 2012-04-17T14:31:39.087 に答える
0

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

遅延、アクション、遅延、遅延、アクション、遅延、遅延、アクション .... など

これが機能するかどうかを確認するためにこれを試してください:

CCRepeatForever *chameleonRepeat = [CCRepeatForever actionWithAction:[CCSequence actions:chameleonDelay, chameleonAction, nil]];
于 2012-04-05T17:14:06.377 に答える