简体   繁体   English

如何使用自定义设计显示一串数字?

[英]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.

相关问题 如何在Swift中将UIColor转换为3/4/6/8位十六进制字符串? - How do I convert a UIColor to a 3/4/6/8 digits hexadecimal string in Swift? 如何将UIKeyboardType.NumberPad的设计更改为Xamarin.iOS / Monotouch中的自定义设计? - How do I change the design of the UIKeyboardType.NumberPad to a custom custom design in Xamarin.iOS/Monotouch? 如何在MKMapView上显示自定义注释? - How do I display a custom annotation on MKMapView? 如何提取Float小数点后的任意位数并将其转换为Swift中的字符串? - How do I extract any number of digits after the decimal point of a Float and convert it to a String in Swift? 如何将Digits迁移到Firebase? - How do I migrate Digits to Firebase? 如何在Xcode 6中设计时自定义字体? - How to do Custom Fonts at design time in Xcode 6? 如何在iOS应用程序中的自定义相册中显示图像 - How do I display the images in a custom album in my iOS App 如何将[UILabel]的集合转换为要在ViewController上显示的字符串文本? - How do I convert Collection of [UILabel] to string text to display on ViewController? 格式化浮点数以显示在两位数的字符串中? - Format a float to display in a string with two digits? 我如何只接受C#Xamarin中的数字数字 - How Do I only accept Numeric Digits in C# Xamarin
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM