Sprite kit 勾勒字体轮廓或去除阴影的最佳方法是什么?
我在Sprite工具包中找不到对dropshadow或字体轮廓的任何支持。对于dropshadow,我猜我可以创建第二个SKLabelNode并将其偏移到另一个之后 是否有某种方法可以利用SKEffectNode作为轮廓或dropshadow?是否可能使SKLabelNode成为SKEffectNode的子节点 更新:Sprite kit 勾勒字体轮廓或去除阴影的最佳方法是什么?,sprite-kit,Sprite Kit,我在Sprite工具包中找不到对dropshadow或字体轮廓的任何支持。对于dropshadow,我猜我可以创建第二个SKLabelNode并将其偏移到另一个之后 是否有某种方法可以利用SKEffectNode作为轮廓或dropshadow?是否可能使SKLabelNode成为SKEffectNode的子节点 更新: 我能够使用第一个节点后面的第二个SKLabelNode获得一个像样的dropshadow,即黑色和偏移。仍然对其他可能的选项感兴趣,但这似乎很有效。关于概述: 简短的回答:你的工
我能够使用第一个节点后面的第二个SKLabelNode获得一个像样的dropshadow,即黑色和偏移。仍然对其他可能的选项感兴趣,但这似乎很有效。关于概述: 简短的回答:你的工作很适合你。
长回答:你的工作真的很适合你 我们已经在一个项目中这样做了,基本的方法是创建一个UILabel,并将其渲染成一个进入精灵的纹理。
要将轮廓添加到UILabel上,可以使用以下方法: 要将其渲染为UIImage(您可以使用[SKTexture textureWithImage:img]生成纹理),请使用以下命令: 这带来了一大堆问题,其中最主要的是缓慢、贪婪的渲染,这在很大程度上是通过尽可能为静态文本预渲染到文件来解决的
我不认为你能通过一个效果节点来实现这一点,因为字体往往需要精确性。回想起来,在走这条路之前,我会三思而后行。这很可能是您正在做的事情,但它很有效而且很简单
- (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…这对我很有用:
以下是我与ASAttributedLabelNode一起使用的代码(其中一些代码对我来说是特定的,比如字体名/size/fillcolor/outlinecolor,但当然只使用您自己的代码):
使用此功能时,请同时执行以下操作:
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)
我不仅使用了这里描述的“2SklabelNode”dropshadow技术,而且还添加了三个“DropShadows”,从而获得了某种程度上可以接受的“轮廓” 换言之,一旦底部阴影就位,再添加三个。一个向顶部偏移,一个向右侧偏移,一个向左侧偏移-因此我在下面有四个“放置阴影”,主标签位于顶部,总共有五个SKLabelNodes,仅用于创建此轮廓效果 在我的应用程序中,我必须设置这个文本的动画,所以我更进一步,用这五个标签创建了一个位图纹理,并用这个纹理创建了一个SKSpriteNode,这样我就可以删除五个原始标签节点,并设置位图版本的动画 还值得注意的是,通过从标签节点创建纹理,它会导致模糊纹理,我通过在创建纹理之前将标签节点的大小加倍,然后将生成的纹理的大小减小50%来修复模糊纹理 我附上一张图片,向您展示结果。这可能不是最优雅的方法,但它似乎适合我的特殊情况。希望这有帮助 使用OOP! 我已经将其实现为一个新组件,一个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")
}
}
实例化并添加到父节点(另一个节点或场景),如下所示:
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来建立一个轮廓。(可以计算出它比标签稍大。)注意,添加子标签的顺序是相关的
这段代码已经过测试,目前正在我正在构建的苹果电视应用程序中积极使用。谢谢你,特德。我建议你
例如:
let textNode = MKOutlinedLabelNode(fontNamed: "Helvetica", fontSize: 32)
textNode.borderColor = UIColor.blackColor()
textNode.horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.Center
textNode.fontColor = UIColor.blueColor()
textNode.outlinedText = "Test"
您也可以签出。我创建了一个继承自SKSpriteNode的类,它根据传递给构造函数的参数创建必要的SKLabelNode和4个阴影标签 更改任何公共属性时,都需要调用update()方法。(大于6-7的边框看起来很有趣。)
最近的代码可以在中找到,因为iOS 11 SKLabelNode已经发布。您需要指定
strokeColor
,strokeWidth
,并且不要忘记font
和foregroundColor
,进一步说明Kelin的优点,下面是它的Swift 4代码:
var label: SKLabelNode!
let attStr: NSMutableAttributedString = NSMutableAttributedString(string: "MyDefaultText")
let myFont: UIFont = UIFont(name: "FontName", size: 7)!
attStr.mutableString.setString("MyText")
attStr.addAttribute(.font, value: myFont, range: NSMakeRange(0, attStr.length))
attStr.addAttribute(.foregroundColor, value: UIColor.white, range: NSMakeRange(0, attStr.length))
attStr.addAttribute(.strokeColor, value: UIColor.red, range: NSMakeRange(0, attStr.length))
attStr.addAttribute(.strokeWidth, value: -3.0, range: NSMakeRange(0, attStr.length))
label.attributedText = attStr
PS:要同时获得笔划和填充,需要对
.strokeWidth
应用负值,这意味着笔划向外。.strokeWidth
的正值将向内发送笔划,并导致填充颜色(.foregroundColor
)消失 Erica Sadun曾基于SKEffectNode
我最近不得不创建她的Swift4版本ShadowLabelNode
:
我现在可以用两个SklabelNode得到一个不错的dropshadow,其中一个是offset和黑色。对于SKEffectNode,您可以使用shouldRasterize选项来缓存它。我将对答案进行编辑以尽可能多地反映。为什么不像你说的那样用两个SKLabel来制作阴影呢?是的,就像我说的,我已经试过了,它对阴影效果很好。我在寻找我可能没有想到或不知道的提纲和阴影投影选项。我不清楚你的答案如何提供提纲选项。转换成图像并不能给我一个轮廓。还是我在这里遗漏了什么?UILabel是否支持dropshadow/outline?好的,我会研究一下。我将把这个问题留一段时间,希望有其他选择。我使用SpriteKit管理了一个令人满意的dropshadow,如果可能的话,我希望避免使用UILabel解决方案。我确实找到了dropshadow,就像您在这里看到的一样。这个提纲我还没想好怎么做。我想我
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) )
}
}
}
var label: SKLabelNode!
let attStr: NSMutableAttributedString = NSMutableAttributedString(string: "MyDefaultText")
let myFont: UIFont = UIFont(name: "FontName", size: 7)!
attStr.mutableString.setString("MyText")
attStr.addAttribute(.font, value: myFont, range: NSMakeRange(0, attStr.length))
attStr.addAttribute(.foregroundColor, value: UIColor.white, range: NSMakeRange(0, attStr.length))
attStr.addAttribute(.strokeColor, value: UIColor.red, range: NSMakeRange(0, attStr.length))
attStr.addAttribute(.strokeWidth, value: -3.0, range: NSMakeRange(0, attStr.length))
label.attributedText = attStr