简体   繁体   中英

How should I resize label nodes in SpriteKit?

So I have a couple of SKLabelNodes in my scene like this:

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];

And when the scene starts up I want them to scale up. I used an SKAction for this, but scaleBy caused the text to be blurry and resizeTo didn't work.

Also I'm guessing this is not the way to go with fonts. Is there a way better way of doing this, or should I use UILabels? I didn't want to do that because that would mean I couldn't use SpriteKit physics on it, or could I?

Thanks

I ran a [SKAction scaleBy: from a font size 10 to a scale factor of 8 and you're right about the text being blurry when increasing size by a scale of 3 or more.

You can use a block to increase the font size over time. You will have to use a lot of steps but the results are much better.

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]]];

I use this class that I knocked up to render it as a texture first, and then you can set the filtering mode to .nearest of the texture.

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
        }

    }

}

Here is my input on your issue.

  1. I would never scale anything UP. Following general guidelines, if you scale down you are generally going to preserve quality. Scaling up creates that pixel art feel.

  2. If you are not using the label node to display numbers that frequently change, use an SKSpriteNode. Use a basic photo editor to type your label and save it as an image that you would assign to a spritenode. Spritenodes are made to handle physics so you should use them to handle all your physics.

  3. If you do need to display numbers of a wide range that change often but you still need them to be affected by physics, you may ask yourself, am I supposed to create an image with each possible outcome that I could assign to my spritenode? The answer is no. You could set you label size to be way bigger than you need and scale it down. To handle physics, you would add this label as a child of some SKSpriteNode that has the physics properties you wish to use for your label. Now, you have a spritenode that interacts with physics as you desire yet also has a label node that displays your information.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM