繁体   English   中英

Cocos2D:重用存储在CCArray中的CCSequence

[英]Cocos2D: Reusing a CCSequence stored in a CCArray

我对精灵执行的操作有疑问。 我在CCArray中有一个CCSequence,并且有一个计划的方法(每5秒调用一次),使该精灵运行操作。 仅在第一次(前5秒钟)内正确执行该操作,然后,该操作将按照自己的意愿进行操作。

这是代码:

在.h->

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

@property (nonatomic, retain) CCArray *trajectories;

在.mm->

@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;
    }
}

这是计划的方法:

-(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])];
    }
}

我不知道发生了什么事。 第一次之后,我再也不会修改CCSequence的内容。

谢谢!

CCAction类是一次性的。 一旦运行,便不会重置其状态。 如果您第二次重新执行操作,则可能会发生任何事情。

有一个公开的问题要求可重复使用的操作已经存在了两年多了。 有些人建议再次调用该动作的initWith…方法以重置其状态,但这违背了良好实践,如果特定动作保留了对象,则可能会带来危险 您可能最终会遇到内存泄漏,甚至更糟。

解决方案:每次需要时都重新创建序列。 当前没有更安全的选择。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM