9

Is there any possible way to create a gradient filled box in SpriteKit? I've tried filling a shape node with that but it notes that only solid colors work with skshapenode.

AwDogsGo2Heaven
  • 952
  • 11
  • 26
  • I'm back.. and found this: https://gist.github.com/Tantas/7fc01803d6b559da48d6 – Jonny Jan 25 '16 at 08:35
  • Refer this https://stackoverflow.com/questions/18894493/making-a-skscenes-background-transparent-not-working-is-this-a-bug/24494346#24494346 – Suresh Oct 05 '16 at 14:42

4 Answers4

6

I don't think this is possible with current SKShapeNode, which barely handles its basic features currently. A good approach if you don't want to use pre-existing sprite gradient images would be to create an SKTexture from applying a CIFilter (like maybe CILinearGradient in this case) to a basic box image, and then create the SKSpriteNode from that SKTexture.

Matt
  • 4,849
  • 3
  • 26
  • 23
6

Here is a solution. (Note, I am using Rubymotion, a Ruby binding for Objective-C / iOS, however the logic is exactly the same. If someone wants to edit this and put the Objective-C equivalent, go ahead

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)
McKinley
  • 1,123
  • 1
  • 8
  • 18
AwDogsGo2Heaven
  • 952
  • 11
  • 26
4

OK here is something I am using now. I based it on AwDogsGo2Heaven's solution, however adapted for Mac. Would be sweet with one fully compatible solution. I am far from sure how to create contexts. But seems to work. Also I am unsure about the scale. Running on retina mac and non retina mac and can't see any problems but the context is created using scale 2 so might be overkill for non retina macs. I put this in a category on SKTexture.

In order use it, just call +(SKTexture*)gradientWithSize:(const CGSize)SIZE colors:(NSArray*)colors.

Edit: Updated code and more discussion here: Gradient texture has wrong scale on retina Mac

Community
  • 1
  • 1
Jonny
  • 15,955
  • 18
  • 111
  • 232
0

Matt's answer is correct, but I have be unable to add a gradient as yet. This is my currrent attempt, if someone knows how to make it work, please update for thread.

Here is the Core Image Ref

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);

Another good way to test your filters, is download the demo app CIFunHouse from WWDC 2013.

DogCoffee
  • 19,820
  • 10
  • 87
  • 120
  • I was able to create a gradient us CAGradientLayer and creating an UIImage context, rendering that layer on the the context, and creating a texture from the resulting UIImage, it was fast, and I didn't experience any slow down (But I only needed to create one for a button). – AwDogsGo2Heaven Oct 11 '13 at 14:48
  • 1
    I added the answer above. – AwDogsGo2Heaven Oct 13 '13 at 06:24
  • 1
    Still it only works for iOS and this question is not limited to iOS. – Jonny Oct 18 '13 at 03:27
  • 1
    Also it crashes on the first line with tvOS. *Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key inputImage.'* – Jonny Oct 22 '15 at 18:09
  • Ok I'll try to work on it. The usage is not correct. – Jonny Oct 22 '15 at 18:23
  • Now. crashed with inputImage error message undefined key etc etc on iOS 14 too. – user3069232 Jul 09 '21 at 18:53