SKAction: как анимировать случайные повторяющиеся действия

Я хотел бы запустить повторяющийся SKAction но со случайными значениями на каждом повторении. Я прочитал этот вопрос здесь, который показывает один из способов сделать это. Однако я хочу, чтобы движения моего спрайта были анимированными, а не просто менялись. Одно решение, которое я придумала, состоит в том, чтобы выполнить последовательность действий, при этом последнее действие вызывает мой метод move рекурсивным способом:

- (void)moveTheBomber {
    __weak typeof(self) weakSelf = self;

    float randomX = //  determine new "randomX" position

    SKAction *moveAction = [SKAction moveToX:randomX duration:0.25f];
    SKAction *waitAction = [SKAction waitForDuration:0.15 withRange:0.4];
    SKAction *completionAction = [SKAction customActionWithDuration:0 actionBlock:^(SKNode *node, CGFloat elapsedTime) {
        [weakSelf moveTheBomber];
    }];

    SKAction *sequence = [SKAction sequence:@[moveAction, waitAction, completionAction]];

    [self.bomber runAction:sequence];
}

При рекурсивном вызове этого метода я чувствую себя "неприлично", но, учитывая мой ограниченный опыт работы с SpriteKit, мне показалось, что это самый очевидный способ сделать это.

Как я могу анимировать случайное движение спрайта на экране навсегда?

2 ответа

Решение

Никаких наворотов, но я думаю, что это должно помочь вам в этом:

Изменить: Извините, это должно быть:

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];

Да, есть отличное действие, которое вы можете использовать.

Так что вместо того, чтобы делать свой текущий runAction сделай это:

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

Вам также необходимо изменить moveActionmoveToX: значение для чего-то вроде arc4random

Так как случайная функция вычисляется только один раз, ее нельзя поместить в последовательность или SKAction repeatForever. Ссылка на: Почему вызов случайной функции не работает в последовательности?

Итак, хороший ответ Swift:

func newLocation(_ circle: SKShapeNode) {
    circle.run(SKAction.move(to: randomPosition(), duration: 2), completion: {
        [weak self] in self?.newLocation(circle)
    })
}

С randomPosition():

func randomPosition() -> CGPoint {
    let height = Int(self.view?.frame.height ?? 0)
    let width = Int(self.view?.frame.width ?? 0)

    let randomPosition = CGPoint(x: Int.random(in: 0..<width), y: Int.random(in: 0..<height))

    return randomPosition
}

Завершение действия запуска вызывает себя снова и снова с новой вычисленной случайной позицией.

Другие вопросы по тегам