SKAction: how to generate a random delay in genera

2019-06-03 16:28发布

问题:

I use the following piece of code to generate SKNodes periodically. Is there a way to make the period of generation of these SKNodes random. Specifically, how do I make the "delayFish" in the following code an action with a random delay?

[self removeActionForKey:@"fishSpawn"];
SKAction* spawnFish = [SKAction performSelector:@selector(spawnLittleFishes) onTarget:self];
SKAction* delayFish = [SKAction waitForDuration:3.0/_moving.speed];
SKAction* spawnThenDelayFish = [SKAction sequence:@[spawnFish, delayFish]];
SKAction* spawnThenDelayFishForever = [SKAction repeatActionForever:spawnThenDelayFish];
[self runAction:spawnThenDelayFishForever withKey:@"fishSpawn"];

回答1:

ObjC:

First set an average delay and range...

#define kAverageDelay    2.0
#define kDelayRange      1.0     // vary by plus or minus 0.5 seconds

and then change your delayFish action to this...

SKAction* delayFish = [SKAction waitForDuration:kAverageDelay withRange:kDelayRange];

Swift:

First set an average delay and range...

let averageDelay:TimeInterval = 2.0
let delayRange:TimeInterval = 1.0     // vary by plus or minus 0.5 seconds

and then change your delayFish action to this...

let delayFish = SKAction.wait(forDuration:averageDelay, withRange:delayRange)


回答2:

Insert a random float instead of a fixed one.

In your case something like this:

double value = ((double)arc4random() / ARC4RANDOM_MAX) 
   * (maxValue - minValue)
   + minValue;

SKAction* delayFish = [SKAction waitForDuration:value/_moving.speed];

I see. This won't work in your case as repeatActionForever will run with the last created random value. Forever. Maybe try this instead. I'm not sure if this works though:

SKAction* delayFish = [SKAction waitForDuration: (((double)arc4random() / ARC4RANDOM_MAX) * (maxValue - minValue)+ minValue)/_moving.speed];

I suggest making the random value an own method though.

-(double) getRandomValue(){
    return (((double)arc4random() / ARC4RANDOM_MAX) * (maxValue - minValue)+ minValue);
}

EDIT:

Here is a link to a similar issue. Maybe that might help. Sorry!

SKAction *randomXMovement = [SKAction runBlock:^(void){
    NSInteger xMovement = arc4random() % 20;
    NSInteger leftOrRight = arc4random() % 2;
    if (leftOrRight == 1) {
        xMovement *= -1;
    }
    SKAction *moveX = [SKAction moveByX:xMovement y:0 duration:1.0];
    [aSprite runAction:moveX];
}];

SKAction *wait = [SKAction waitForDuration:1.0];
SKAction *sequence = [SKAction sequence:@[randomXMovement, wait]];
SKAction *repeat = [SKAction repeatActionForever:sequence];
[aSprite runAction: repeat];

Source: SKAction: How to Animate Random Repeated Actions