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

标签 ios swift sprite-kit

我不想使用 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/

相关文章:

php - 将 json 对象检索到 xCode 中始终带有 nil 值

ios - 在 Sprite Kit 中创建赛道

ios - ReactiveCocoa 4.0 :- Unable to map the NSURLSession. sharedSession().rac_dataWithRequest

ios - UISearchBar 'prompt' 显示不正常

ios - 从转换后的 json 字符串中删除\n 和斜杠\

ios - 在swift中点击一个颜色 Sprite 后如何返回到之前的场景?

Swift Spritekit 我检测到碰撞,但它多次读取碰撞

ios - locationManager 中的 swift 和 iBeacon firedate 通知

objective-c - UITableView 使用 Storyboard 深入了解 UITableView 的详细信息

swift - 如何使用 Socket.io 解开传递给 swift 的数组?