我没有在Sprite Kit中找到任何支持Drophadow或字体轮廓的内容。对于Drophadow,我猜我可以创建第二个SKLabelNode并将其偏移到另一个之后。
是否有某种方法可以将SKEffectNode用于轮廓或阴影?可能使SKLabelNode成为SKEffectNode的子项?
更新:
我能够使用第一个后面的第二个SKLabelNode得到一个体面的阴影,即黑色和偏移。仍然对其他潜在的选择感兴趣,但这似乎运作良好。
答案 0 :(得分:17)
这很可能是你正在做的,但它很有效,而且很简单。
- (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 ......
答案 1 :(得分:5)
由于iOS 11 SKLabelNode有attributedText
property。您需要指定strokeColor
,strokeWidth
并且不要忘记font
和foregroundColor
。
答案 2 :(得分:4)
我已经能够达到一个可以接受的"大纲"通过不仅使用" 2 SKLabelNode"这里描述的阴影技术,还可以添加三个"阴影"。
换句话说,一旦你有底部阴影,再添加三个。一个偏向顶部,一个向右偏移,一个向左偏移 - 所以我有四个"阴影"在下面,主要标签位于顶部,共有五个SKLabelNodes,用于创建此轮廓效果。
在我的应用程序中,我必须为此文本设置动画,所以我更进了一步,从这五个标签创建了一个位图纹理,并从这个纹理创建了一个SKSpriteNode,这样我就可以删除五个原始标签节点,并为位图版本设置动画。
值得注意的是,通过从标签节点创建纹理,它会导致模糊的纹理,我通过加倍标签节点的大小来修复> em>创建纹理,然后将生成的纹理的大小减少 50%。
我附上图片以显示结果。它可能不是最优雅的方法,但它似乎适用于我的特殊情况。希望这有帮助!
答案 3 :(得分:2)
示例:
let textNode = MKOutlinedLabelNode(fontNamed: "Helvetica", fontSize: 32)
textNode.borderColor = UIColor.blackColor()
textNode.horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.Center
textNode.fontColor = UIColor.blueColor()
textNode.outlinedText = "Test"
您还可以查看ASAttributedLabelNode。
答案 4 :(得分:1)
这对我有用:
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 :(得分:1)
除了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:要同时获取笔划和填充,您需要将否定值应用于{{1这意味着笔划向外。 .strokeWidth
的正值会向内发送笔触并导致填充色(.strokeWidth
)消失!
答案 6 :(得分:0)
关于概述:
简短的回答:你已经为你裁掉了工作 答案很长:你真的为你做了工作。
我们一直在项目中这样做,基本方法是创建一个UILabel并将其渲染为一个进入精灵的纹理。
要将轮廓绘制到UILabel上,您可以使用:
How do I make UILabel display outlined text?
并将其呈现为UIImage(您可以使用[SKTexture textureWithImage:img]创建纹理),使用此:
How to create an image from UILabel?
这带来了一大堆问题,其中最主要的是缓慢,贪婪的渲染,这在很大程度上通过预渲染到静态文本的文件来解决。
我认为你不能用效果节点来解决这个问题,因为字体往往需要精确度。回想起来,在走这条路之前我会三思而后行。
答案 7 :(得分:0)
使用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来建立一个轮廓。 (可以将其计算为略大于标签。)请注意,添加子标签的顺序是相关的。
此代码已经过测试,并且正在我正在制作的Apple TV应用中正在使用。亲切的问候,特德。
答案 8 :(得分:0)
我创建了一个继承自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
找到答案 9 :(得分:0)
Erica Sadun曾经基于SKEffectNode
here
我最近不得不为她的ShadowLabelNode
创建一个Swift4版本:
https://gist.github.com/Bersaelor/d6ea241278665173485e8aabafbe9047