2012-03-31 11 views
1

スプライトで実行されたアクションに問題があります。私はCCArrayに1つのCCSequenceを持っており、スプライトがアクションを実行するようにスケジュールされたメソッド(5秒ごとに呼び出されます)を持っています。アクションは最初の(最初の5秒)だけ正しく実行され、その後、アクションはそれが欲しいものは何でも実行します。Cocos2D:CCArrayに格納されたCCSequenceの再利用

-(void)spawn:(ccTime)dt 
{ 
    if(powerUp == nil) 
    { 
     powerUp = [[PowerUp alloc] initWithType:0]; 

     powerUp.sprite.position = CGPointMake([[CCDirector sharedDirector] winSize].width + powerUp.sprite.contentSize.width, [[CCDirector sharedDirector] winSize].height/2); 

     [self addChild:powerUp.sprite z:-1]; 

     [powerUp.sprite runAction:((CCSequence *)[self.trajectories objectAtIndex:0])]; 
    } 
} 

:これは、スケジュールされた方法である>

@implementation PowerUpLayer 

@synthesize trajectories; 

-(id)init 
{ 
    if((self = [super init])) 
    { 
     [self createTrajectories]; 
     self.isTouchEnabled = YES; 
     [self schedule:@selector(spawn:) interval:5]; 
    } 

    return self; 
} 

-(void)createTrajectories 
{ 
    self.trajectories = [CCArray arrayWithCapacity:1]; 

    //Wave trajectory 
    ccBezierConfig firstWave, secondWave; 

    firstWave.controlPoint_1 = CGPointMake([[CCDirector sharedDirector] winSize].width + 30, [[CCDirector sharedDirector] winSize].height/2);//powerUp.sprite.position.x, powerUp.sprite.position.y); 
    firstWave.controlPoint_2 = CGPointMake([[CCDirector sharedDirector] winSize].width - ([[CCDirector sharedDirector] winSize].width/4), 0); 
    firstWave.endPosition = CGPointMake([[CCDirector sharedDirector] winSize].width/2, [[CCDirector sharedDirector] winSize].height/2); 

    secondWave.controlPoint_1 = CGPointMake([[CCDirector sharedDirector] winSize].width/2, [[CCDirector sharedDirector] winSize].height/2); 
    secondWave.controlPoint_2 = CGPointMake([[CCDirector sharedDirector] winSize].width/4, [[CCDirector sharedDirector] winSize].height); 

    secondWave.endPosition = CGPointMake(-30, [[CCDirector sharedDirector] winSize].height/2); 

    id bezierWave1 = [CCBezierTo actionWithDuration:1 bezier:firstWave]; 
    id bezierWave2 = [CCBezierTo actionWithDuration:1 bezier:secondWave]; 

    id waveTrajectory = [CCSequence actions:bezierWave1, bezierWave2, [CCCallFuncN actionWithTarget:self selector:@selector(setInvisible:)], nil]; 

    [self.trajectories addObject:waveTrajectory]; 
    //[powerUp.sprite runAction:bezierForward]; 

    //  [CCMoveBy actionWithDuration:3 position:CGPointMake(-[[CCDirector sharedDirector] winSize].width - powerUp.sprite.contentSize.width, 0)] 
    //[powerUp.sprite runAction:[CCSequence actions:bezierWave1, bezierWave2, [CCCallFuncN actionWithTarget:self selector:@selector(setInvisible:)], nil]]; 

} 

-(void)setInvisible:(id)sender 
{ 
    if(powerUp != nil) 
    { 
     [self removeChild:sender cleanup:YES]; 
     powerUp = nil; 
    } 
} 

- .mmで>

@interface PowerUpLayer : CCLayer { 
    PowerUp *powerUp; 
    CCArray *trajectories; 
} 

@property (nonatomic, retain) CCArray *trajectories; 

-

.Hで

:ここ

コードであります私は何が起こっているのか分からない。初めてCCSequenceの内容を変更することはありません。

ありがとうございます!

答えて

0

CCActionクラスはワンショットです。一度実行すると、状態をリセットしません。 2回目のアクションを再実行すると何かが起きる可能性があります。

ここには2年以上にわたって存在していたopen issue requesting reusable actionsがあります。アクションのinitWith ...メソッドを再度呼び出して状態をリセットすることを提案する人もいますが、特定のアクションがオブジェクトを保持している場合はthat's against good practices and may be downright dangerousです。メモリリークが発生するか、悪化する可能性があります。

解決策:必要なたびにシーケンスを再作成してください。現在、より安全な方法はありません。

+0

こんにちはスティーブン、あなたの本には、行動を記憶して、それらを再び使うことが言及されています。あなたの文書にもかかわらず、これは実際にあなたが提案するものではないと思いますか? – johnbakers

+0

ありがとう、Steffen!私はそれをするでしょう:D – Axort

+0

ちょっとステファン!あなたは、Jackによって与えられた解決策についてどう思いますか:[GameDev Stack Exchange](http://gamedev.stackexchange.com/questions/26511/cocos2d-adding-a-ccsequence-to-a-ccarray)。私はその質問を同時にそこに掲示した。私はその解決策を試しましたが、それは機能しますが、どれくらい安全かを知りたいと思います。どうもありがとうございました! – Axort

関連する問題