我不想使用 SKLabelNode
因为我想有像渐变填充、阴影和自定义字体这样的特殊效果,所以我创建了 10 个 png
图像,每个数字一个,我将它们添加为图像图集。然后,在设置要显示的数字时,我为每个数字创建一个新的 SKSpriteNode
,其中包含图集中数字的纹理,并将其添加到父级 SKSpriteNode
中没有质感。我遇到的问题是我试图将 anchor 设置到所有添加的节点的中间,但是在设置 anchor 时,它只是相对于它自己的框架设置 anchor ,这不是添加子节点时更新。
我已经做了更多的工作,但我不能完全让 sprite 居中。这是我正在执行此操作的 SKNode
的子类:Gist .当我创建这个节点的实例时,将位置设置为 0,0,设置 currentValue
,并将节点添加到游戏场景中,它看起来像 this .它下面的方框是一个SKShapeNode
,带有number节点累加帧的frame,和number节点位置相同。游戏场景中黑点为0,0。
有更好的方法吗?或者我能做些什么来解决我的问题?
最佳答案
这是非常基本的 UI 内容,无论是用于游戏还是其他应用程序。 “说起来容易做起来难”更多的是一种心态。当谈到构建游戏的复杂性时,这就是简单的东西。
无论如何,关键是您需要知道如何获得数字的宽度。对于与此相关的任何文本,此问题都是相同的。因此,如果您了解如何执行此操作,您实际上可以制作自己的自定义字体。
下面是一些“代码”。它不会编译,我还没有填写方法。原因是多方面的。首先,您将从边做边学中获得更多好处。此外,我不知道你是怎么做的,而且为一个不是我的项目输入所有细节是很乏味的。
为此,我创建了一个虚构的类 NumberLabel
。这是一个组合 SKNode
/“自定义字体”类。实际上,我会将两者分开。但就目前而言,这样做是为了简单起见(尽管作为副产品非常困惑,我不会将其构建在单一类中)。
class NumberLabel {
// Root for all digits. This is also the "center"
var root:SKNode = SKNode()
private var underlyingValue:UInt = 0
// These will hold each digit, for example 1234 will be [1, 2, 3, 4]
private var digits: Array<UInt>
var value: UInt {
get {
return underlyingValue
}
set {
// There is no optimization checks (ie. if underlyingValue != newValue, you can do that later WHEN you get this working properly)
underlyingValue = newValue
// Release old nodes
// You will build your other nodes here
buildDigits()
let width = getWidth()
let x = -width / 2
let y = ??? // Determine what your y should be based on your anchoring policy for sprites
// I now know that -width/2
for (digit in digits) {
// This is all pseudo code
var digitNode = createDigitNodeForDigit(digit, x, y)
// You need to determine any trailing spacing, this would be also accounted for in getWidth
x += getWidthOfDigit(digit)
root.addChild(digitNode)
}
}
}
// Initialization omitted
// Build the digits array
// For laziness this uses underlyingValue. Safer would be to take it as an argument, but this is just example code
private func buildDigits() {
// Populate array based on the number value
// For example 1234 will be the array [1, 2, 3, 4]
}
// Get's width of underlyingValue (use float if you want)
// For laziness of writing this, it assumes BOTH underlyingValue and digits are properly assigned
public func getWidth() -> UInt {
// Get the width of the number
// Traverse your digits array, determine the width based on number, and insert any kerning (if appropropiate)
}
// Use float if you want
public func getHeight() -> UInt {
// Return height. While width may not be uniform, for digits, there should be uniform height
}
}
所以一些关键要点:
我没有派生自
SKNode
。你可以自由地这样做。我从来没有从SKNode
派生出这样的类。对于这些情况,我使用“有一个”与“是一个”的方法。如果你想子类化,它不会改变太多。getWidth
是你的 friend 。您正在构建的任何字体系统都需要将其作为基石。它是您渲染的方式,也是在 UI 中放置的方式。假设您知道自己的宽度或将推导出它们。你会需要它们
假设您知道如何从数字到单个数字。您将使用它来填充
数字
这一切都是为了成为一个快速的例子,所以我的界面很草率。他们不接受参数,而一个更清晰的界面将是
createDigitNodeForDigit
将是您获取数字值 (0-9) 并创建您的SKSpriteNode
或“数字节点”对象的方法getWidthOfDigit
将是您获取该数字宽度的方法。大概你可以查询纹理的宽度。如何处理数字之间的间距取决于您请注意,我们仅在设置值时执行此操作。因此,您不会在每一帧都进行节点的解构和构造。
我在这里回答了一个类似的问题:Add custom "number" images to SKLabelNode in as a Score in SpriteKit with Swift
所以也许还有一些其他信息供您吸收。
关于ios - 如何使用自定义设计显示一串数字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39783844/