问题描述
好的,所以我一直在为一个项目做一个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
}
}
解决方法
好吧,所以在输入这个字母时,我有了更多的想法,并最终解决了自己的问题,所以我觉得我会在这里分享解决方案,而不是在所有人身上拉一个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,elapsed) in
self?.showContinueMarker()
})
基本上,我们需要在更新序列的末尾添加一个显示为三角形的动作,而不是仅仅假设它会在更新后出现,因为该函数是在以后的时间调用的。
由于固定时间后,所有3种方法均能很好地工作,因此我回到了.alpha = 0
方法来简化它。