Проблема в том, что вы пытаетесь сделать все это «вживую» в цикле for
. Весь код вашей функции выполняется между кадрами анимации, так что это не сработает.
Чтобы было понятнее, давайте на мгновение проигнорируем часть wait
. Когда вы запускаете функцию, которая выглядит так:
func changeColor() { // unrolled loop and pseudocode colors for clarity
circle.fillColor = blue
circle.fillColor = red
circle.fillColor = green
}
...SpriteKit действительно меняет цвет круга три раза — сразу — но не рисует результаты. Какой бы цвет вы ни установили последний, он появляется только после того, как весь ваш код завершит работу и SpriteKit отрисует экран.
Когда вы используете SKAction
s, вы выстраиваете инструкции для SpriteKit, которым нужно следовать с течением времени, включая инструкции для задач, требующих более одного кадра анимации. Но вызовы non-SKAction
в вашем коде остаются такими же, как и раньше — они вносят немедленные изменения, конечный результат которых вы видите при отрисовке следующего кадра.
Итак, когда ваш код выглядит так:
func changeColor() { // unrolled loop and pseudocode colors for clarity
circle.fillColor = blue
circle.runAction(SKAction.waitForDuration(0.4))
circle.fillColor = red
}
... порядок событий такой:
- установить цвет на синий
- добавить действие ожидания в список запланированных действий
- установить красный цвет
- рисуем следующий кадр (красный цвет)
- выполнить список запланированных действий (подождите 0,4 секунды перед выполнением следующего действия по порядку)
Итак, первое, что нужно сделать, это заставить ваши изменения цвета перестать быть изменениями между кадрами и добавить их в список дополнительных задач, то есть изменить цвет с помощью SKAction
. Существует colorizeWithColor
, но я не уверен, применимо ли оно к узлам формы (с их отдельными цветами заливки/обводки). Попробуйте, и если это не поможет, попробуйте runBlock
действие, которое напрямую устанавливает fillColor
/strokeColor
.
Однако вернемся к псевдокоду, чтобы поговорить о проблеме секвенирования...
func changeColor() { // unrolled loop and pseudocode color actions
circle.runAction(mySetBlueColorAction)
circle.runAction(SKAction.waitForDuration(0.4))
circle.runAction(mySetRedColorAction)
}
Если вы запустите это, вы заметите, что здесь все еще есть проблема. Просто вызов runAction
добавляет отдельные действия, которые выполняются (примерно) параллельно. Таким образом, ваш круг по-прежнему дважды меняет цвет, но оба изменения происходят одновременно. (Какой из них победит? Я не уверен, что есть определенный ответ.) И в то же время, когда ваш круг путается в своем цвете, он также начинает ждать 0,4 секунды для... чего именно?
Действие waitForDuration
имеет смысл только в контексте sequence
действие – чтобы оно имело смысл, после него должно быть что-то, что следует ожидать для.
Итак, если то, что вы хотите, звучит как эта последовательность:
- Установите цвет
- Подожди немного
- Установите цвет на что-то другое
... тогда вам нужно последовательное действие, описывающее, что вы хотите, чтобы произошло по порядку:
let sequence = SKAction.sequence([
mySetBlueColorAction,
SKAction.waitForDuration(0.4),
mySetRedColorAction,
SKAction.waitForDuration(0.4),
mySetGreenColorAction,
// etc.
])
26.10.2015