如何更改永远运行的SKAction

时间:2014-09-23 13:03:41

标签: ios objective-c sprite-kit

我有一个涉及两个动作的SKAction序列。 1)根据变量2)产生对象等待时间

SKAction *sequence = [SKAction sequence:@[
                                        wait,
                                        addObject]];

此操作设置为永久运行。但是,我希望等待时间根据更新变量而改变,但它保持不变,因为它在永远运行时不会使用新变量

[self runAction:[SKAction repeatActionForever:sequence]];

如何让它稳定地增加值,从而提高对象产生率?

由于

2 个答案:

答案 0 :(得分:3)

有两种解决方案:

  1. 每次需要时重新创建序列或至少等待操作。行动应该被丢弃并经常重复使用。
  2. 如果这会导致性能问题并且您已经拥有对序列的引用,则还可以更改其速度变量。这应该相应地改变等待时间,即如果速度为0.5,则等待时间应该加倍。
  3. 解决方案1的示例:

    CGFloat waitDuration = (value to be determined by you);
    SKAction *sequence = [SKAction sequence:@[
                                            [SKAction waitForDuration:waitDuration],
                                            addObject]];
    

    解决方案2的示例:

    SKAction *sequence = [SKAction sequence:@[
                                            wait,
                                            addObject]];
    
    // half the speed, double the wait time
    sequence.speed = 0.5; 
    
    // or if you need to derive speed from waitDuration (which must be >0.0)
    sequence.speed = (1.0 / waitDuration);
    

    如果序列不受速度影响,请尝试设置wait动作的速度。

答案 1 :(得分:0)

所以我按照LearnCocos2D的回答,但我做了一些修改,我认为这很有效。它适用于我的目的,所以我想把它放在那里。

我做的是:

//This is the boring bits for creating the SKSpriteNode 
    headsNode = [SKSpriteNode spriteNodeWithTexture:[self.textureAtlas firstObject]size:CGSizeMake(100, 100)];
    headsNode.position = CGPointMake(CGRectGetMidX(self.frame)*0.5, CGRectGetMidY(self.frame)-coinSize/2);

    headsNode.name = @"Heads";
    [self addChild:headsNode];

// I added a timer with winkWaitingTime as interval. This is the variable
// to change. Set this to something at the beginning.
NSTimer *timered= [NSTimer scheduledTimerWithTimeInterval:winkWaitingTime target:self selector:@selector(timerFired:) userInfo:nil repeats:YES];
    [timered fire];
}

-(void)timerFired:(NSTimer*)timer{
//In the NSTimer Selector, I set the timer interval / SKAction waiting interval to a random
// number
    winkWaitingTime =[[SharedInfo sharedManager] randomFloatBetween:3 and:8];
    [headsNode removeAllActions];
//I thought it's best to remove the actions JIC :) 
    [headsNode runAction:[self returnActionForAnimationKey:headsNode.name]];
    NSLog(@"winktimer: %f",winkWaitingTime);
}
-(SKAction*)returnActionForAnimationKey:(NSString*)animationKey{
    CGFloat waitDuration;
//This is for just to prevent timer fire interfering with the SKAction
//This will make the SKAction waiting time shorter than NSTimer Fire rate
    if (winkWaitingTime >4) {
        waitDuration = winkWaitingTime-3;
    }else{
        waitDuration = 1;
    }

    SKAction *sequence = [SKAction sequence:@[
                                              [SKAction waitForDuration:waitDuration],
                                              [SKAction animateWithTextures:self.textureAtlas timePerFrame:0.1f resize:NO restore:YES]]];

    return sequence;
}

正如我所说,它适用于我,通过改变winkWaitingTime和一些预防管理,它可以工作。

我希望你发现它也很有用。在内存管理方面,我的Xcode显示出稳定的CPU /内存/电池使用率,因此使用率没有增加。

注意:收到评论后,我认为最好讨论使用NSTimer。如果您需要“外部”完成某些操作,即独立于视图或场景,那么我将使用NSTimer(这是我的情况)。但是你必须为计时器实现暂停和取消暂停。 (您必须使NSTimer无效以停止,并重新安排一个新的,或将其作为变量重新安排,并重新安排相同的一个)。否则,请使用SKAction,您无需暂停和取消暂停NSTimer