SKAction repeatActionForever not spawning entity

2019-08-10 01:57发布

问题:

Basically I have a spawn entity function that should in theory, spawn a random balloon onto the screen with certain properties. I have designed the method as such:

-(void)spawnBalloon
{
    int a = arc4random_uniform(self.frame.size.width);
    int b = self.frame.size.height - 50;
    CGPoint loc = CGPointMake(a, b);
    [self spawnBalloonAtPoint:loc];
}

And this method works. When I call it in the init function, it works. When I call it in the touchesMoved() function it works. However, when I try and call it in the init method with the

[self runAction:[SKAction repeatActionForever:[SKAction performSelector:@selector(spawnBalloon) onTarget:self]]];

It fails. Why is this? Do I have to just use a performSelector function from "self" and then use an NSTimer to have it repeat forever?

Also, I tried throwing an NSLog into the code to see if it was even being executed when it was in the repeat action, and it is. The only problem is that the balloon is not being added to the screen. My feeling is that when I call the spawnBalloon function through the repeatActionForever, self refers to a different class ? Sorry if this is confusing, I'm still new to Objective C and SpriteKit, and instead of really reading much I dived in and decided to learn-when-needed (However I have a vast knowledge of Java/C)

EDIT: I figured out that if I don't have the repeatForever action, the code will execute and work. However, if its there, it doesn't work.

回答1:

Try this:

[self runAction:[SKAction repeatActionForever:[SKAction sequence:@[
                                                                   [SKAction waitForDuration:0.1],
                                                                   [SKAction performSelector:@selector(spawnBalloon) onTarget:self]
                                                                   ]]]];


回答2:

As an addition on DFrog's answer, which will give you desired results, I think you will find useful to understand why your code not working when using repeatActionForever: method.

repeatActionForever: method requires a non-instantaneous action in order to work. This is from docs:

The action to be repeated must have a non-instantaneous duration.

An instantaneous action

An instantaneous action starts and completes in a single frame of animation. For example, an action to remove a node from its parent is an instantaneous action because a node can’t be partially removed. Instead, when the action executes, the node is removed immediately.

A non-instantaneous action

A non-instantaneous action has a duration over which it animates its effects. When executed, the action is processed in each frame of animation until the action completes

As you figured out already performSelector:onTarget creates an action that calls a method on some object, but that action runs instantaneously. Quote from docs:

...When the action executes, the target object’s method is called. This action occurs instantaneously...

and as I mentioned above repeatActionForever: method requires an action with non-instantaneous duration so that's why it won't work as you expect.