[英]How do I display a string of digits with custom design?
I don't want to use SKLabelNode
because I want to have special effects like a gradient fill, a shadow, and a custom font, so I created 10 png
images, one for each digit, and I added them as an image atlas. 我不想使用
SKLabelNode
因为我想具有特殊效果,例如渐变填充,阴影和自定义字体,因此我创建了10个png
图像,每个数字一个,然后将它们添加为图像图集。 Then, when setting up the number to display, I create for each digit a new SKSpriteNode
with the texture of the digit from the atlas, and add it to a parent SKSpriteNode
with no texture. 然后,在设置要显示的数字时,我为每个数字创建一个新的
SKSpriteNode
并带有来自图集的数字纹理,然后将其添加到没有纹理的父级SKSpriteNode
。 The problem I'm having with this is that I'm trying to set the anchor point to the middle of all the nodes added, but when setting the anchor point, it's only setting the anchor point relative to its own frame, which is not updated when child nodes are added. 我遇到的问题是我试图将锚点设置为添加的所有节点的中间,但是在设置锚点时,它只是相对于其自己的框架设置锚点,而不是添加子节点时更新。
I've worked on it some more and I can't quite get the sprites centered. 我已经做了更多的工作,但我无法使子画面居中。 Here's a subclass of
SKNode
where I'm doing this: Gist . 这是我正在执行此操作的
SKNode
的子类: Gist 。 When I create an instance of this node, set the position to 0,0, set currentValue
, and add the node to the game scene, it looks like this . 当我创建该节点的实例时,将位置设置为0,0,设置
currentValue
,然后将该节点添加到游戏场景中,如下所示 。 The box under it is a SKShapeNode
with a frame of the number node's accumulated frame and the same position as the number node. 它下面的框是一个
SKShapeNode
,其框架包含数字节点的累积帧,并且与数字节点的位置相同。 The black dot is 0,0 on the game scene. 黑点在游戏场景中为0,0。
Is there a better way to do it? 有更好的方法吗? Or what can I do to fix my problem?
或者我该怎么解决我的问题?
This is pretty basic UI stuff, whether it be for games or other applications. 这是非常基本的UI内容,无论是用于游戏还是其他应用程序。 "Easier said than done" is more of a state of mind.
“说起来容易做起来难”更是一种心态。 When it comes to complexity in building games, this is the simple stuff.
说到构建游戏的复杂性,这很简单。
Anyways, the key to this is you need to know how to get the width of you number. 无论如何,关键在于您需要知道如何获得数字的宽度。 This problem is the same for any text for that matter.
这个问题对于任何文本都是一样的。 So if you understand how to do this, you can actually make your own custom fonts.
因此,如果您了解如何执行此操作,则实际上可以制作自己的自定义字体。
Below is some "code". 下面是一些“代码”。 It won't compile and I have not filled out methods.
它不会编译,我还没有填写方法。 The reason for this is manifold.
原因是多方面的。 First and foremost, you will get more benefit out of learning by doing.
首先,您将从实践中学到更多的利益。 Additionally, I have no idea how you are doing your stuff and it's tedious to type out all the details for a project that is not mine.
此外,我不知道您的工作方式如何,并且为非我的项目输入所有细节很繁琐。
For this I'm creating a fictitious class NumberLabel
. 为此,我创建了一个虚拟类
NumberLabel
。 This is a combo SKNode
/"custom font" class. 这是组合的
SKNode
/“自定义字体”类。 In reality, I would separate the two. 实际上,我将两者分开。 But for now, this was done for simplicity (albeit very messy as a byproduct that I would not build it in a singular class).
但是现在,这样做是为了简化(尽管作为一个副产品非常混乱 ,我不会在单个类中构建它)。
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
}
}
So some key takeaways: 以下是一些关键要点:
I have not derived from SKNode
. 我不是从
SKNode
派生的。 You are free to do so. 您可以这样做。 I never derive from
SKNode
myself for classes like this. 我从来没有从
SKNode
派生SKNode
类。 I use a "has a" versus "is a" approach for these cases. 对于这些情况,我使用“具有”与“是”的方法。 Subclass if you want, it won't change things too much.
如果需要子类,它不会改变太多。
getWidth
is your friend. getWidth
是您的朋友。 Any font system you are building needs this as a corner stone. 您正在构建的任何字体系统都需要将此作为基础。 It is by which you render but also the means for placement within the UI.
它不仅可以渲染,而且可以在UI中进行放置。
There are assumptions you know your widths or will derive them. 假设您知道宽度或将得出宽度。 You'll need them
你需要他们
There is an assumption you know how to go from number to individual digits. 假设您知道如何将数字转换为单个数字。 You will use this to populate
digits
您将用它来填充
digits
This is all meant to be a fast example, so my interfaces are sloppy. 所有这些都是一个快速的示例,因此我的界面很草率。 They don't take arguments whereas a cleaner interface for this would
他们不争论,而更清洁的界面会
createDigitNodeForDigit
would be your method to take a digit value (0-9) and create your SKSpriteNode
or "digit node" object createDigitNodeForDigit
是您采用数字值(0-9)并创建SKSpriteNode
或“数字节点”对象的方法
getWidthOfDigit
would be your method to get the width of that digit. getWidthOfDigit
将是您获取该数字的宽度的方法。 Presumably you can just query the width of the texture. 大概您可以只查询纹理的宽度。 It's up to you on how you want to deal with spacing between digits
由您决定如何处理数字间距
Note that we only do this on the setting of the value. 请注意,我们仅在值的设置上执行此操作。 Thus you are not incurring deconstruction and construction of the nodes every frame.
因此,您不会在每一帧中都造成节点的破坏和构建。
I answered a similar question here: Add custom "number" images to SKLabelNode in as a Score in SpriteKit with Swift 我在这里回答了类似的问题: 将自定义“数字”图像添加到SKLabelNode中,作为带有Swift的SpriteKit中的得分
So maybe that has some other info for you to absorb. 因此,也许还有一些其他信息可供您吸收。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.