如何在Spritekit中创建渐变?

9
有没有可能在SpriteKit中创建一个渐变填充的盒子?我尝试使用形状节点来填充,但它指出只有纯色才能与skshapenode一起使用。

我回来了.. 并且发现了这个:https://gist.github.com/Tantas/7fc01803d6b559da48d6 - Jonny
请参考以下链接:https://dev59.com/AWMk5IYBdhLWcg3w3xrq#24494346 - Suresh
4个回答

6

这里有一个解决方案。(注意,我正在使用Rubymotion,这是Objective-C / iOS的Ruby绑定,但逻辑完全相同。如果有人想编辑并放置Objective-C等效内容,请随意)

size = CGSizeMake(50,50)
scale = options[:scale] || UIScreen.mainScreen.scale
opaque = options.fetch(:opaque, false)

UIGraphicsBeginImageContextWithOptions(size, opaque, scale)
context = UIGraphicsGetCurrentContext()

gradient = CAGradientLayer.layer
gradient.frame = CGRectMake(0,0,50,50)
gradient.colors = [SKColor.blackColor.CGColor,SKColor.whiteColor.CGColor]
gradient.renderInContext(context)

image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

texture = SKTexture.textureWithCGImage(image.CGImage)
node = SKSpriteNode.alloc.initWithTexture(texture)

谢谢,但这对OSX:Sprite Kit不起作用。它仅限于iOS。 - Jonny
1
UIGraphicsBeginImageContextWithOptions不存在。 - Jonny
我正在使用Rubymotion,希望能看到这段代码的Ruby版本。 - BananaNeil

6

我认为当前的SKShapeNode很难实现此功能,因为它目前仅能处理其基本功能。如果您不想使用预先存在的精灵渐变图像,则一个好的方法是从应用CIFilter(在这种情况下可能是CILinearGradient)到基本框图像上创建SKTexture,然后从该SKTexture创建SKSpriteNode


4

好的,这里是我现在正在使用的东西。我基于AwDogsGo2Heaven的解决方案进行了调整,不过适用于Mac。希望能有一个完全兼容的解决方案。我不太确定如何创建上下文。但似乎可以工作。另外我对比例也不确定。在Retina Mac和非Retina Mac上运行,看不到任何问题,但上下文是使用比例2创建的,可能对于非Retina Mac来说有点过头了。我把它放在SKTexture的一个类别中。

为了使用它,只需调用+(SKTexture*)gradientWithSize:(const CGSize)SIZE colors:(NSArray*)colors

编辑:更新代码并在此处进行更多讨论:Gradient texture has wrong scale on retina Mac


0
Matt的回答是正确的,但我还无法添加渐变。这是我的当前尝试,如果有人知道如何让它工作,请更新线程。
这里是核心图像参考
CIFilter *gradientFilter = [CIFilter filterWithName:@"CILinearGradient"];
//[gradientFilter setDefaults];
CIColor *startColor = [CIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0];
CIColor *endColor = [CIColor colorWithRed:0 green:0 blue:0 alpha:1.0];
CIVector *startVector = [CIVector vectorWithX:0 Y:0];
CIVector *endVector = [CIVector vectorWithX:0.21 Y:0.31];
[gradientFilter setValue:startVector forKey:@"inputPoint0"];
[gradientFilter setValue:endVector forKey:@"inputPoint1"];
[gradientFilter setValue:startColor forKey:@"inputColor0"];
[gradientFilter setValue:endColor forKey:@"inputColor1"];

SKEffectNode *effectNode = [SKEffectNode node];
effectNode.filter = gradientFilter;
effectNode.shouldEnableEffects = YES;

[self addChild:effectNode];
//effectNode.position = CGPointMake(200, 200);

另一种测试您的过滤器的好方法是从WWDC 2013下载演示应用程序CIFunHouse


我能够使用CAGradientLayer创建渐变,并创建UIImage上下文,将该层呈现在上下文中,并从生成的UIImage创建纹理,这很快,而且我没有遇到任何减速(但我只需要为一个按钮创建一个)。 - AwDogsGo2Heaven
1
我已经在上面添加了答案。 - AwDogsGo2Heaven
1
仍然只适用于iOS,而这个问题并不局限于iOS。 - Jonny
1
同时,在tvOS上它会在第一行崩溃。终止应用程序,原因是未捕获的异常'NSUnknownKeyException',原因:'[<CILinearGradient 0x15ddc03a0> setValue:forUndefinedKey:]:此类不符合键值编码规范,无法为键inputImage设置值。' - Jonny
好的,我会尝试处理它。用法不正确。 - Jonny
现在,在iOS 14上,出现了与inputImage错误消息undefined key等等相崩溃的情况。 - user3069232

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接