How to create a Gradient in Spritekit?

前端 未结 4 725
长发绾君心
长发绾君心 2021-02-08 22:35

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.

相关标签:
4条回答
  • 2021-02-08 22:50

    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.

    0 讨论(0)
  • 2021-02-08 23:04

    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

    0 讨论(0)
  • 2021-02-08 23:05

    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.

    0 讨论(0)
  • 2021-02-08 23:08

    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)
    
    0 讨论(0)
提交回复
热议问题