我应该如何在SpriteKit中调整标签节点的大小



所以我的场景中有几个SKLabelNodes,如下所示:

SKLabelNode *label1 = [SKLabelNode labelNodeWithFontNamed:@"Arial"];
label1.text = @"Hello World!";
label1.fontColor = [SKColor redColor];
label1.fontSize = 90;
label1.position = CGPointMake(CGRectGetMidX(self.frame),CGRectGetMidY(self.frame));
[self addChild: label1];

当场景开始时,我希望它们按比例放大。我使用了SKAction,但scaleBy导致文本模糊,resizeTo不起作用。

此外,我猜这不是使用字体的方法。有更好的方法吗?还是应该使用UILabels?我不想这么做,因为这意味着我不能在上面使用SpriteKit物理,或者我可以吗?

感谢

我运行了一个从字体大小10到比例因子8的[SKAction scaleBy:,当字体大小增加3或更大时,文本会变得模糊,这是正确的。

您可以使用块来随着时间的推移增加字体大小。你将不得不使用很多步骤,但结果要好得多。

myInt = 10;
SKAction *block0 = [SKAction runBlock:^{
    label0 = [SKLabelNode labelNodeWithFontNamed:@"Arial"];
    label0.text = @"Hello World!";
    label0.fontColor = [SKColor redColor];
    label0.fontSize = myInt;
    label0.position = CGPointMake(CGRectGetMidX(self.frame),CGRectGetMidY(self.frame));
    [self addChild: label0];
}];
SKAction *wait0 = [SKAction waitForDuration:1.5];
SKAction *wait1 = [SKAction waitForDuration:0.5];
SKAction *block1 = [SKAction runBlock:^{
    label0.fontSize += (myInt + 10);
}];
[self runAction:[SKAction sequence:@[wait0, block0, wait1, block1, wait1, block1, wait1, block1, wait1, block1, wait1, block1]]];

我首先使用这个类将其渲染为纹理,然后可以将过滤模式设置为纹理的最近值。

import SpriteKit
public class PKTexturedLabelNode : SKSpriteNode{
    fileprivate let embeddedLabel : SKLabelNode
    fileprivate var rasterizingView : SKView? {
        if let rasterizeInView = rasterizeInView {
            return rasterizeInView
        } else {
            return scene?.view
        }
    }
    public var rasterizeInView : SKView?
    public required init?(coder aDecoder: NSCoder) {
        embeddedLabel = SKLabelNode()
        super.init(coder: aDecoder)
    }
    public init(fontNamed: String?){
        embeddedLabel = SKLabelNode(fontNamed: fontNamed)
        super.init(texture: nil, color: SKColor.white, size: CGSize(width: 0, height: 0))
    }
    public init(text:String?){
        embeddedLabel = SKLabelNode(text: text)
        super.init(texture: nil, color: SKColor.white, size: CGSize(width: 0, height: 0))
    }
    var fontName : String? {
        get {
            return embeddedLabel.fontName
        }
        set {
            embeddedLabel.fontName = newValue
            render()
        }
    }
    var fontSize : CGFloat {
        get {
            return embeddedLabel.fontSize
        }
        set {
            embeddedLabel.fontSize = newValue
            render()
        }
    }
    var text : String? {
        get {
            return embeddedLabel.text
        }
        set {
            embeddedLabel.text = newValue
            render()
        }
    }
    fileprivate func render(){
        if let texture = rasterizingView?.texture(from: embeddedLabel){
            texture.filteringMode = .nearest
            size = texture.size()
            self.texture = texture
        }
    }
}

以下是我对您的问题的看法。

  1. 我永远不会放大任何东西。遵循一般指导原则,如果你缩小规模,你通常会保持质量。放大比例会产生像素艺术感。

  2. 如果不使用标签节点来显示经常更改的数字,请使用SKSpriteNode。使用基本的照片编辑器键入标签并将其保存为要分配给spritenode的图像。精灵是用来处理物理的,所以你应该用它们来处理你所有的物理。

  3. 如果你确实需要显示经常变化的大范围数字,但你仍然需要它们受到物理的影响,你可能会问自己,我是否应该创建一个图像,其中包含我可以分配给我的spritenode的每个可能的结果?答案是否定的。你可以把你的标签尺寸设置得比你需要的大得多,然后缩小。要处理物理,您需要将此标签添加为某个SKSpriteNode的子级,该节点具有您希望用于标签的物理属性。现在,您有一个spritenode,可以根据需要与物理交互,但也有一个显示信息的标签节点。

最新更新