Подтвердить что ты не робот

Какой был бы лучший подход для выделения или отбрасывания шрифта?

Я не нахожу поддержки для dropshadow или контура шрифта в Sprite Kit. Для dropshadow я предполагаю, что могу создать второй SKLabelNode и смещать его за другим.

Есть ли способ, которым я мог бы использовать SKEffectNode для контура или dropshadow? Возможно, SKLabelNode является дочерним элементом SKEffectNode?

update:

Я смог получить приличную dropshadow, используя второй SKLabelNode за первым, черный и смещенный. Все еще интересуются другими потенциальными вариантами, но это, похоже, хорошо работает.

4b9b3361

Ответ 1

Это, скорее всего, то, что вы делаете, но оно работает и прост.

- (SKLabelNode *) makeDropShadowString:(NSString *) myString
{
    int offSetX = 3;
    int offSetY = 3;

    SKLabelNode *completedString = [SKLabelNode labelNodeWithFontNamed:@"Arial"];
    completedString.fontSize = 30.0f;
    completedString.fontColor = [SKColor yellowColor];
    completedString.text = myString;


    SKLabelNode *dropShadow = [SKLabelNode labelNodeWithFontNamed:@"Arial"];
    dropShadow.fontSize = 30.0f;
    dropShadow.fontColor = [SKColor blackColor];
    dropShadow.text = myString;
    dropShadow.zPosition = completedString.zPosition - 1;
    dropShadow.position = CGPointMake(dropShadow.position.x - offSetX, dropShadow.position.y - offSetY);

    [completedString addChild:dropShadow];

    return completedString;
}

Попробуем и нарисуем один из них... но у меня есть ощущение, что это будет более сложно... должен быть способ использовать растровые шрифты..??? bmGlyph...

Ответ 2

Мне удалось достичь несколько приемлемого "наброска", не только используя описанные здесь методы "тени", но и добавив еще три "тени тени".

Другими словами, как только у вас будет нижняя тень, добавьте еще три. Одно смещение к вершине, одно смещение вправо и одно смещение влево - так что у меня есть четыре "тени тени" внизу, а главная метка сверху для всего пяти SKLabelNodes просто для создания этого контурного эффекта.

В моем приложении мне нужно оживить этот текст, поэтому я сделал еще один шаг и создал текстуру растрового изображения из этих пяти ярлыков и создал из этой текстуры один SKSpriteNode, что позволило мне удалить пять исходных узлов ярлыков, и анимировать версию растрового изображения.

Можно также отметить, что, создав текстуру из узлов метки, это привело к размытой текстуре, которую я исправил, удвоив размер узлов метки перед созданием текстуры, а затем уменьшив размер сгенерированной текстуры на 50%.

Я прикрепляю изображение, чтобы показать результат. Это может быть не самый элегантный подход, но, похоже, он работает для моей конкретной ситуации. Надеюсь, это поможет!

введите описание изображения здесь

Ответ 3

Я предлагаю MKOutlinedLabelNode.

Пример:

let textNode = MKOutlinedLabelNode(fontNamed: "Helvetica", fontSize: 32)
textNode.borderColor = UIColor.blackColor()
textNode.horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.Center
textNode.fontColor = UIColor.blueColor()
textNode.outlinedText = "Test"

введите описание изображения здесь

Вы также можете проверить ASAttributedLabelNode.

Ответ 4

Это сработало для меня:

http://battleofbrothers.com/sirryan/outline-text-in-spritekit

Здесь код, который я использовал в сочетании с ASAttributedLabelNode (некоторые из них специфичны для меня, такие как имя/размер шрифта /fillcolor/outlinecolor, но, конечно, просто используйте свой собственный):

func outlinedCenteredString(string : String, size: CGFloat) -> NSAttributedString
{
    var myMutableString : NSMutableAttributedString
    var font =  UIFont(name: "Super Mario 256", size: size)!
    var alignment : CTTextAlignment = CTTextAlignment.TextAlignmentCenter
    let alignmentSetting = [CTParagraphStyleSetting(spec: .Alignment, valueSize: Int(sizeofValue(alignment)), value: &alignment)]
    var paragraphRef = CTParagraphStyleCreate(alignmentSetting, 1)

    let textFontAttributes = [
        NSFontAttributeName : font,
        // Note: SKColor.whiteColor().CGColor breaks this
        NSForegroundColorAttributeName: UIColor.yellowColor(),
        NSStrokeColorAttributeName: UIColor.blackColor(),
        // Note: Use negative value here if you want foreground color to show
        NSStrokeWidthAttributeName:-3
        //,NSParagraphStyleAttributeName: paragraphRef
    ]

    myMutableString = NSMutableAttributedString(string: string, attributes: textFontAttributes as [NSObject : AnyObject])

    let para = NSMutableParagraphStyle()
    para.headIndent = 00
    para.firstLineHeadIndent = 00
    para.tailIndent = 0
    para.lineBreakMode = .ByWordWrapping
    para.alignment = .Center
    para.paragraphSpacing = 0
    myMutableString.addAttribute(
        NSParagraphStyleAttributeName,
        value:para, range:NSMakeRange(0,1))
    return myMutableString
}

вместе со следующим, чтобы использовать эту функцию:

    let hintSize = CGFloat(80.0)
    let hintLabel = ASAttributedLabelNode(size:CGSizeMake(playableRect.size.width*0.9, hintSize))

    hintLabel.attributedString = outlinedCenteredString("Touch the Rope to Release the Wood", size: hintSize)

    hintLabel.position =
        CGPointMake(
            size.width/2.0,
            ((size.height - playableRect.size.height)/2.0) + hintSize/2.0
    )

    hintLabel.zPosition = kHintZPosition
    addChild(hintLabel)

Ответ 5

Так как iOS 11 SKLabelNode имеет attributedText свойство. Вам нужно указать strokeColor, strokeWidth и не забывать font и foregroundColor.

Ответ 6

Что касается описания:

Короткий ответ: у вас есть ваша работа, вырезанная для вас.
Длинный ответ: у вас действительно есть ваша работа, вырезанная для вас.

Мы делали это в проекте, и основным подходом было создание UILabel и рендеринг его текстуре, которая входит в спрайт.
Чтобы получить схему на UILabel, вы можете использовать это: Как сделать отображаемый текст в UILabel? и сделать это в UIImage (чтобы вы могли сделать текстуру с помощью [SKTexture textureWithImage: img]), используйте это: Как создать образ из UILabel? Это связано с множеством проблем, главным из которых является медленный, жадный рендеринг, который в значительной степени решался путем предварительного рендеринга, когда это возможно, для статического текста.

Я не думаю, что вы сможете сделать это с эффектом node из-за точности, которую, как правило, требуют шрифты. Оглядываясь назад, я подумал бы дважды, прежде чем идти по этому пути.

Ответ 7

Использовать ООП! Я реализовал это как новый компонент, потомок SKNode, который содержит два SKLabelNodes, один для самого текста и другой для его тени:

final class TgSKLabelWithShadow: SKNode
{
    private var lblText: SKLabelNode!
    private var lblShadow: SKLabelNode!

    var text: String?
        {     get { return lblText.text }
        set { lblText.text   = newValue
              lblShadow.text = newValue   } }

    var fontColor: UIColor?
        { get { return lblText.fontColor     }
          set { lblText.fontColor = newValue } }
    // define additional getters/setters, if necessary.


    init(     position: CGPoint,
              alignment: SKLabelHorizontalAlignmentMode,
              text: String,
              fontName: String,
              fontSize: CGFloat,
              fontColor: UIColor,
              shadowColor: UIColor,
              shadowOffSet: CGPoint)
    {
        super.init()
        self.position = position

        lblShadow = SKLabelNode(text: text)
        lblShadow.fontName  = fontName
        lblShadow.fontColor = shadowColor
        lblShadow.fontSize  = fontSize
        lblShadow.horizontalAlignmentMode = alignment
        lblShadow.position = shadowOffSet
        self.addChild(lblShadow)  // add shadow first

        lblText = SKLabelNode(text: text)
        lblText.fontName  = fontName
        lblText.fontColor = fontColor
        lblText.fontSize  = fontSize
        lblText.horizontalAlignmentMode = alignment
        self.addChild(lblText)  // on top of shadow
    }

    required init?(coder aDecoder: NSCoder)
    {
        fatalError("TgSKLabelWithShadow - init(coder:) has not been implemented")
    }
}

Создайте и добавьте родительский элемент (другой node или сцену) так:

   ndInfo2 = TgSKLabelWithShadow(
        position: CGPoint(x: size.width/2, y:   size.height - 170),
        alignment : .Center,
        text: "ndInfo2: ???",
        fontName: "Avenir",
        fontSize: 40,
        fontColor: colorText,
        shadowColor: UIColor.blueColor(),
        shadowOffSet: CGPoint(x:1, y:-1))
    addChild(ndInfo2)

Схема? Ну, ничто не мешает вам вложить еще один SKLabelNode, чтобы установить контур. (можно было бы рассчитать его немного больше, чем метка.) Обратите внимание, что порядок добавления дочерних меток является релевантным.

Этот код был протестирован и активно используется в приложении Apple TV, которое я сейчас создаю. С уважением, Тед.

Ответ 8

Я создал класс, наследующий от SKSpriteNode, где он создает необходимые SKLabelNode и 4 теневые метки в соответствии с параметрами, переданными конструктору.

Вам нужно вызвать метод update(), когда вы изменили какое-либо общедоступное свойство. (BorderSize более 6-7 выглядит забавным.)

import Foundation
import SpriteKit

class LFOutlinedLabel : SKSpriteNode {

    private let skewX : [CGFloat] = [-1, 1, 1,-1]
    private let skewY : [CGFloat] = [-1,-1, 1, 1]

    private var label : SKLabelNode = SKLabelNode()
    private var shadows : [SKLabelNode] = []

    public var borderOpacity : CGFloat = 1
    public var borderSize: CGFloat = 1
    public var borderColor: UIColor = UIColor.black
    public var text : String = "?"
    public var fontName : String = Fonts.OptimaExtraBlack.rawValue
    public var fontColor: UIColor = UIColor.white
    public var fontSize : CGFloat = 40

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        //self.setup()
    }

    override init(texture: SKTexture!, color: UIColor, size: CGSize) {
        super.init(texture: texture, color: color, size: size)
        //self.setup()
    }

    convenience init(size: CGSize, font: String, fSize: CGFloat, fColor: UIColor, bSize: CGFloat, bColor: UIColor, bOpacity: CGFloat)
    {
        self.init(texture: nil, color: UIColor.clear, size: size)
        self.fontName = font
        self.fontSize = fSize
        self.fontColor = fColor
        self.borderSize = bSize
        self.borderColor = bColor
        self.borderOpacity = bOpacity
        self.setup()
    }

    // create shadow labels
    private func setup() {
        if shadows.count == 0 {
            let width = self.size.width / 2
            let height = self.size.height / 2
            for j in 0...3 {
                let shadow = SKLabelNode(text: self.text)
                addChild(shadow)
                shadow.verticalAlignmentMode = .center
                shadow.horizontalAlignmentMode = .center
                shadow.zPosition = 999
                shadow.position = CGPoint(x: width + (skewX[j] * borderSize) , y: height + (skewY[j] * borderSize))
                shadow.text = self.text
                shadow.fontSize = self.fontSize
                shadow.fontName = self.fontName
                shadow.fontColor = borderColor
                shadows.append(shadow)
            }
            let label = SKLabelNode(text: self.text)
            addChild(label)
            label.verticalAlignmentMode = .center
            label.horizontalAlignmentMode = .center
            label.zPosition = 1000
            label.position = CGPoint(x: width , y: height )
            label.text = self.text
            label.fontSize = self.fontSize
            label.fontName = self.fontName
            label.fontColor = fontColor
            self.label = label
        }
    }

    public func update(){
        let width = self.size.width / 2
        let height = self.size.height / 2

        self.label.fontSize = fontSize
        self.label.fontName = fontName
        self.label.fontColor = fontColor
        self.label.verticalAlignmentMode = .center
        self.label.horizontalAlignmentMode = .center
        self.label.text = text
        self.label.position = CGPoint(x: width  , y: height )

        for i in 0...3 {
            shadows[i].verticalAlignmentMode = .center
            shadows[i].horizontalAlignmentMode = .center
            shadows[i].fontColor = borderColor
            shadows[i].fontSize = fontSize
            shadows[i].alpha = borderOpacity
            shadows[i].fontName = fontName
            shadows[i].text = text
            shadows[i].position = CGPoint(x: width + (skewX[i] * borderSize) , y: height + (skewY[i] * borderSize) )
        }
    }
}

последний код можно найти на https://gist.github.com/detaybey/214b23731a3b4d0344ce58643795f4b7