2012-04-05 4 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으로 업그레이드 한 후 스프라이트 시트 애니메이션이 실패합니다.

이 코드는 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];을 주석 처리하면 chameleon이 프레임, chameleon1.png을 표시하지만 분명히 애니메이션을 통과하지는 않습니다.

그래, 내가 뭔가를 놓치고 있기 때문에 혼란 스럽네. 코드의 하단 부분을 이것으로 변경해 보았는데 애니메이션이 프레임 1에서 프레임 2로 간 다음 무한정 2에 머문다. 그러나 지연 1.0 이상으로 만들면 이전과 같은 오류가 발생합니다. 반복 영원히 성명을하지 않고 동작 전에 chameleonDelay을 다시 포함하면 같은 충돌이 발생합니다. 전환을 수행하는 데 1 초 이상 기다려야하는 경우 앱이 다운 된 것으로 보입니다. 내가 필요한 것은 프레임 1이 잠시 동안 (10 초) 앉아서 0.3 초 ​​동안 프레임 2로 전환 한 다음 프레임 1로 다시 전환하고 잠시 동안 앉아있는 것입니다.

시도 코드 # 2 : YvesLeBorg가 restoreOriginalFrame 문을 사용하여 제안

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

하지만이 버전 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

안녕하세요. 우선 상세한 질문 + 답변에 감사드립니다. 나는 오늘 같은 문제에 비틀 거 렸지만, 나는 그것을 다른 방식으로 풀었다. 지금 나는 어느 것이 최고인지, 심지어 내가 한 것이 정확하다는 것을 알지 못한다. 내 시도 중 하나에서 클리핑 치수를 정하는 스프라이트에 문제가 있음을 발견 했으므로 망막 검사를 추가하고 그에 따라 파일을로드했습니다. 그리고 퍼프! 문제는 (해결 될 것 같습니다) 해결되었습니다. 그러면 여기 망막을 어떻게 다룰까요? – mokagio

+0

관심이 있으시면 여기에 답변으로 내 코드를 게시 할 수 있습니다. – mokagio

+0

마지막으로, 내 작품은 단지 프레임 만있는 매우 간단한 애니메이션입니다. 이것은 적절할 수 있습니다. 불행히도 지금은 더 많은 프레임을 테스트 할 시간이 없습니다. ( – mokagio

0

2.0 문제인지 여부는 확실하지 않지만 동일한 순서로 chameleonDelay 개체를 두 번 사용하고 있음을 확인했습니다. 이것은 실제로 당신이 달성하려고 시도한 것입니까? 예 :

지연, 행동, 지연, 지연, 행동, 지연, 지연, 행동 등.

그것이 작동하는 경우이보고 시도 : 그와 함께 결국

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

예, 의도적입니다. 그것은 여러 가지 문제를 조합 한 것입니다. 나는 그것을 추가하지 않고, 어떤 이유로 든 액션이 프레임 1에서 프레임 2로 가고 나서 프레임 1로 재빨리 되돌아 가려고 의도 한 바를하지 않는다는 것을 알았습니다. 두 번째 지연이 없으면 프레임 2에 머물러 있습니다. 내가 처리하는 방법인지는 모르겠지만 타이밍은 실제로 내가 성취하려는 것을 위해 실제로 작동합니다. 그 점을 지적 해 주셔서 감사합니다. – BobbyScon

+0

프레임 1로 빠르게 돌아 가지 않도록하려면 [CCAnimate actionWithAnimation : mouthAnim restoreOriginalFrame : NO]를 사용하는 것이 좋습니다. 그러나 어떤 경우에도 동일한 순서로 두 가지 용도가있는 경우 CCDelayTime의 다른 인스턴스를 만들어보십시오. – YvesLeBorg

+0

죄송합니다. 아마 정확하게 구절을 사용하지 않았을 것입니다. 프레임 1로 돌아가고 싶습니다. 입 열기와 닫기입니다. 내가 restoreOriginalFrame : 예 전에이 코드로 끝내려고했는데 실제로 첫 번째 프레임으로 돌아 가지 않았다. 아무 단서. 이 코딩은 내가 원했던 것과 정확히 동일하게 작동하므로 혼자 남겨 두었습니다. 두 번째 인스턴스를 만드는 방법에 대해 알아 보겠습니다. – BobbyScon

관련 문제