真的没有办法设置 SKLabelNode 的样式吗?
Is there really no way to style SKLabelNode?
真的没有办法给SKLabelNode设置样式吗?我的意思是除了改变字体和颜色之外。我知道我可以通过在第一个 SKLabelNode 后面创建第二个 SKLabelNode 来添加投影之类的操作(已经有点老套了)。出于显而易见的原因,为我的字体创建图像也很糟糕。似乎很奇怪,您无法摆脱无聊的平面文本。
我的意思是..即使 spritekit 节点数也有很酷的渐变样式...这是怎么做到的?!
好的,所以我在这里尝试重新创建渐变效果。我已经尝试了混合模式的每一种组合,以及颜色和 colorBlendFactor 的多种组合。
阿尔法
相乘
添加
这是代码
let testNode = SKLabelNode(text: "hey there")
testNode.fontSize = 30
testNode.color = SKColor.blueColor()
testNode.colorBlendFactor = 1
testNode.fontName = "Helvetica-Bold"
testNode.blendMode = SKBlendMode.Multiply
testNode.colorBlendFactor = 0.6
testNode.position = CGPoint(x: self.size.width/2, y: self.size.height/2)
self.addChild(testNode)
SKLabelNode 没有任何方法或 属性 可以让您实现渐变样式。正如评论中的 link 所述,SpriteKit 确实有一个 SKBitmapFont private class,但这对你没有帮助。
您可以推出自己的解决方案或尝试字形设计器:https://71squared.com/glyphdesigner
使用着色器非常简单。将文本文件添加到名为 "TheShader.fsh":
的项目中
void main()
{
float yPos = gl_FragCoord.y - labelBase;
float gradient = yPos / u_sprite_size.y; // ranges from 0 at base to 1 at top
vec4 color = SKDefaultShading(); // the current label color
color = vec4(gradient + color.r, gradient + color.g, gradient + color.b, color.a);
color.rgb *= color.a; // set background to alpha 0
gl_FragColor = color;
}
现在在 SKScene 中创建一个 SKEffectNode,将其着色器设置为 "TheShader",并将您的标签添加为效果节点的子节点。标签将使用垂直渐变绘制,范围从底部的标签字体颜色到顶部的白色。
override func didMoveToView(view: SKView)
{
makeGradientLabel("318 nodes 60.0 fps", labelPosition: CGPoint(x: CGRectGetMidX(frame), y: CGRectGetMidY(frame)))
}
func makeGradientLabel(labelText: String, labelPosition: CGPoint)
{
let myShader = SKShader(fileNamed: "TheShader")
let labelBase = SKUniform(name: "labelBase", float: Float(labelPosition.y))
myShader.addUniform(labelBase)
let effectNode = SKEffectNode()
effectNode.shader = myShader
effectNode.shouldEnableEffects = true
addChild(effectNode)
let theLabel = SKLabelNode(fontNamed: "Courier")
theLabel.fontSize = 36
theLabel.fontColor = SKColor.blueColor()
theLabel.text = labelText
theLabel.position = labelPosition
effectNode.addChild(theLabel)
}
如果移动标签,则需要更新 labelBase uniform,以便着色器知道它在哪里:
labelBase.floatValue = Float(theLabel.position.y)
经过反复试验,我成功了:
{
const CGFloat LABELFONTSIZE = 100;
SKColor* fontcolor = [SKColor redColor];
UIFont* font = [AppDelegate fontOfType:Fonttype_main size:LABELFONTSIZE]; // LABELFONTSIZE not used here but whatever.
SKLabelNode* label = [SKLabelNode labelNodeWithFontNamed:font.fontName];
label.fontColor = fontcolor;
label.verticalAlignmentMode = SKLabelVerticalAlignmentModeTop;
self.labelScore = label;
//label.zPosition = Z_HUD;
label.fontSize = LABELFONTSIZE;
self.score = 0;
const CGPoint LABELPOSITION = CGPointMake(self.size.width * 0.5, self.size.height);
label.position = LABELPOSITION;
#define USESHADER
#ifdef USESHADER
SKShader* myShader = [SKShader shaderWithFileNamed:@"TheShader"];
NSAssert(myShader, @"myShader was nil!");
SKEffectNode* effectNode = [SKEffectNode node];
effectNode.zPosition = Z_HUD;
effectNode.shader = myShader;
effectNode.shouldEnableEffects = YES;
[self addChild:effectNode];
[effectNode addChild:label];
#else
label.zPosition = Z_HUD;
[self addChild:label];
#endif
[label runAction:[SKAction repeatActionForever:[SKAction sequence:@[
[SKAction moveByX:0 y:-300 duration:3.0],
[SKAction moveByX:0 y:300 duration:3.0],
]]]];
}
TheShader.fsh:
void main()
{
float gradient = v_tex_coord.y;
//vec4 color = SKDefaultShading(); // the current label color THIS DOES NOT WORK ON IOS 9.2 AND EARLIERISH (MAYBE IT DOES ON IOS 8) WORKS ONLY ON IOS 9.3 BETA AT THIS MOMENT!
vec4 color = texture2D(u_texture, v_tex_coord);
color = vec4(color.r + gradient, color.g + gradient, color.b + gradient, color.a);
color.rgb *= color.a; // set background to alpha 0
gl_FragColor = color;
}
它基于 Loengard 的回答,但没有使用任何制服。着色器 did/does 中的一些内容不适用于许多 iOS 9 版本,包括截至目前的最新 iOS 9.3 beta (20160115)。
上面这段代码运行良好,它甚至不关心标签在屏幕上的位置;我将标签 up/and 向下动画以确认这一点。
真的没有办法给SKLabelNode设置样式吗?我的意思是除了改变字体和颜色之外。我知道我可以通过在第一个 SKLabelNode 后面创建第二个 SKLabelNode 来添加投影之类的操作(已经有点老套了)。出于显而易见的原因,为我的字体创建图像也很糟糕。似乎很奇怪,您无法摆脱无聊的平面文本。
我的意思是..即使 spritekit 节点数也有很酷的渐变样式...这是怎么做到的?!
好的,所以我在这里尝试重新创建渐变效果。我已经尝试了混合模式的每一种组合,以及颜色和 colorBlendFactor 的多种组合。
阿尔法
相乘
添加
这是代码
let testNode = SKLabelNode(text: "hey there")
testNode.fontSize = 30
testNode.color = SKColor.blueColor()
testNode.colorBlendFactor = 1
testNode.fontName = "Helvetica-Bold"
testNode.blendMode = SKBlendMode.Multiply
testNode.colorBlendFactor = 0.6
testNode.position = CGPoint(x: self.size.width/2, y: self.size.height/2)
self.addChild(testNode)
SKLabelNode 没有任何方法或 属性 可以让您实现渐变样式。正如评论中的 link 所述,SpriteKit 确实有一个 SKBitmapFont private class,但这对你没有帮助。
您可以推出自己的解决方案或尝试字形设计器:https://71squared.com/glyphdesigner
使用着色器非常简单。将文本文件添加到名为 "TheShader.fsh":
的项目中void main()
{
float yPos = gl_FragCoord.y - labelBase;
float gradient = yPos / u_sprite_size.y; // ranges from 0 at base to 1 at top
vec4 color = SKDefaultShading(); // the current label color
color = vec4(gradient + color.r, gradient + color.g, gradient + color.b, color.a);
color.rgb *= color.a; // set background to alpha 0
gl_FragColor = color;
}
现在在 SKScene 中创建一个 SKEffectNode,将其着色器设置为 "TheShader",并将您的标签添加为效果节点的子节点。标签将使用垂直渐变绘制,范围从底部的标签字体颜色到顶部的白色。
override func didMoveToView(view: SKView)
{
makeGradientLabel("318 nodes 60.0 fps", labelPosition: CGPoint(x: CGRectGetMidX(frame), y: CGRectGetMidY(frame)))
}
func makeGradientLabel(labelText: String, labelPosition: CGPoint)
{
let myShader = SKShader(fileNamed: "TheShader")
let labelBase = SKUniform(name: "labelBase", float: Float(labelPosition.y))
myShader.addUniform(labelBase)
let effectNode = SKEffectNode()
effectNode.shader = myShader
effectNode.shouldEnableEffects = true
addChild(effectNode)
let theLabel = SKLabelNode(fontNamed: "Courier")
theLabel.fontSize = 36
theLabel.fontColor = SKColor.blueColor()
theLabel.text = labelText
theLabel.position = labelPosition
effectNode.addChild(theLabel)
}
如果移动标签,则需要更新 labelBase uniform,以便着色器知道它在哪里:
labelBase.floatValue = Float(theLabel.position.y)
经过反复试验,我成功了:
{
const CGFloat LABELFONTSIZE = 100;
SKColor* fontcolor = [SKColor redColor];
UIFont* font = [AppDelegate fontOfType:Fonttype_main size:LABELFONTSIZE]; // LABELFONTSIZE not used here but whatever.
SKLabelNode* label = [SKLabelNode labelNodeWithFontNamed:font.fontName];
label.fontColor = fontcolor;
label.verticalAlignmentMode = SKLabelVerticalAlignmentModeTop;
self.labelScore = label;
//label.zPosition = Z_HUD;
label.fontSize = LABELFONTSIZE;
self.score = 0;
const CGPoint LABELPOSITION = CGPointMake(self.size.width * 0.5, self.size.height);
label.position = LABELPOSITION;
#define USESHADER
#ifdef USESHADER
SKShader* myShader = [SKShader shaderWithFileNamed:@"TheShader"];
NSAssert(myShader, @"myShader was nil!");
SKEffectNode* effectNode = [SKEffectNode node];
effectNode.zPosition = Z_HUD;
effectNode.shader = myShader;
effectNode.shouldEnableEffects = YES;
[self addChild:effectNode];
[effectNode addChild:label];
#else
label.zPosition = Z_HUD;
[self addChild:label];
#endif
[label runAction:[SKAction repeatActionForever:[SKAction sequence:@[
[SKAction moveByX:0 y:-300 duration:3.0],
[SKAction moveByX:0 y:300 duration:3.0],
]]]];
}
TheShader.fsh:
void main()
{
float gradient = v_tex_coord.y;
//vec4 color = SKDefaultShading(); // the current label color THIS DOES NOT WORK ON IOS 9.2 AND EARLIERISH (MAYBE IT DOES ON IOS 8) WORKS ONLY ON IOS 9.3 BETA AT THIS MOMENT!
vec4 color = texture2D(u_texture, v_tex_coord);
color = vec4(color.r + gradient, color.g + gradient, color.b + gradient, color.a);
color.rgb *= color.a; // set background to alpha 0
gl_FragColor = color;
}
它基于 Loengard 的回答,但没有使用任何制服。着色器 did/does 中的一些内容不适用于许多 iOS 9 版本,包括截至目前的最新 iOS 9.3 beta (20160115)。 上面这段代码运行良好,它甚至不关心标签在屏幕上的位置;我将标签 up/and 向下动画以确认这一点。