#swift #sprite-kit #skspritenode #skaction
#swift #sprite-kit #skspritenode #skaction
Вопрос:
Хорошо, итак, я работал над созданием диалогового окна в стиле RPG для проекта, и хотя большая часть этого проходит гладко, единственное, что меня сейчас смущает, это маленький значок в углу окна, чтобы сообщить вам, что есть еще.
Я пытался выяснить, как нарисовать фигуру, но, не добившись успеха в получении Core Graphics для рисования треугольников, я решил просто использовать изображение одного из них в формате PNG. Приведенный ниже код показывает все, что относится к тому, как он был настроен и управлялся.
Теперь, когда это выяснено, я пытаюсь заставить его скрывать маркер при обновлении поля и показывать его снова позже. Вот что я пробовал до сих пор:
- Метод 1: используйте
.alpha = 0
, чтобы скрыть его от просмотра во время обновлений, восстановите с помощью.alpha = 1
- Метод 2: удалите его из дерева узлов
- Метод 3: поместите его за фоном окна (находится по адресу
.zPosition = -1
)
Результат был одинаковым для всех 3 методов: треугольник просто остается на месте, не реагируя при вызове.
class DialogBox: SKNode {
private var continueMarker = SKSpriteNode(imageNamed: "continueTriangle") // The triangle that shows in the lower-right to show there's more to read
init() {
/// Setup and placement. It appears in the proper position if I draw it and don't try to hide anything
continueMarker.size.width = 50
continueMarker.size.height = 25
continueMarker.position = CGPoint(x: ((width / 2) - (continueMarker.size.width * 0.9)), y: ((continueMarker.size.height * 0.9) - (height - margin)))
addChild(continueMarker)
}
func updateContent(forceAnimation: Bool = false) {
/// Determine what content to put into the box
hideContinueMarker()
/// Perform the content update in the box (which works as it should)
showContinueMarker()
}
func showContinueMarker() {
// continueMarker.alpha = 1 /// Method 1: Use .alpha to hide it from view during updates
// if (continueMarker.parent == nil) { // Method 2: Remove it from the tree
// addChild(continueMarker)
// }
continueMarker.zPosition = -2 /// Method 3: place it behind the box background (zPosition -1)
}
func hideContinueMarker() {
// continueMarker.alpha = 0 /// Method 1
// if (continueMarker.parent != nil) { /// Method 2
// continueMarker.removeFromParent()
// }
continueMarker.zPosition = 2 /// Method 3
}
}
Ответ №1:
Хорошо, поэтому при вводе этого у меня появилось еще несколько идей, и в итоге я решил свою собственную проблему, поэтому я решил поделиться решением здесь, а не использовать DenverCoder9 для всех.
С положительной стороны, вы увидите простой способ анимации текста в SpriteKit! Ура!
В последней проверке, чтобы убедиться, что я не сошел с ума, я добавил несколько операторов печати в showContinueMarker()
и hideContinueMarker()
и заметил, что они всегда появлялись одновременно.
Что это значит? SKAction
вероятно, ошибка. Вот посмотрите на код для анимации обновлений в поле:
private func animatedContentUpdate(contentBody: String, speaker: String? = nil) {
if let speaker = speaker {
// Update speaker box, if provided
speakerLabel.text = speaker
}
var updatedText = "" // Text shown so far
var actionSequence: [SKAction] = []
for char in contentBody {
updatedText = "(char)"
dialogTextLabel.text = updatedText
// Set up a custom action to update the label with the new text
let updateLabelAction = SKAction.customAction(withDuration: animateUpdateSpeed.rawValue, actionBlock: { [weak self, updatedText] (node, elapsed) in
self?.dialogTextLabel.text = updatedText
})
// Queue up the action so we can run the batch afterward
actionSequence.append(updateLabelAction)
}
/// HERE'S THE FIX
// We needed to add another action to the end of the sequence so that showing the marker again didn't occur concurrent with the update sequence.
let showMarker = SKAction.customAction(withDuration: animateUpdateSpeed.rawValue, actionBlock: { [weak self] (node, elapsed) in
self?.showContinueMarker()
})
// Run the sequence
actionSequence.append(showMarker)
removeAction(forKey: "animatedUpdate") // Cancel any animated updates already in progress
run(SKAction.sequence(actionSequence), withKey: "animatedUpdate") // Start the update
}
На случай, если вы пропустили это в большом блоке, вот конкретный бит в изоляции
let showMarker = SKAction.customAction(withDuration: animateUpdateSpeed.rawValue, actionBlock: { [weak self] (node, elapsed) in
self?.showContinueMarker()
})
В принципе, нам нужно было добавить отображение треугольника в качестве действия в конце последовательности обновлений вместо того, чтобы просто предполагать, что это произойдет после обновления, поскольку функция была вызвана позже. Время.
И поскольку все 3 метода работают одинаково хорошо теперь, когда время было исправлено, я вернулся к .alpha = 0
методу, чтобы упростить его.