Search code examples
ios7sprite-kitskshapenodeskcropnode

iOS 7 iPad SpriteKit - Use irregular SKShapeNode as mask for SKCropNode


Does anyone know how to crop an image with spritekit for iOS using an irregular shape node? The problem is when I do an skcrop on it, the shape has 2 layers, and thus the cropping fails. To crop one must use a single layer. Any idea how to rasterize a shape first, before the scene is loaded? I've tried skeffectnode and shouldRasterize on it but that fails too, most likely because it contains 2 children as well, or the rasterization is occuring after the scene is loaded. I've also tried converting the shape to a texture, but that fails for the same reasons as the skeffectnode does. I've looked at other possible solutions on stack overflow, and none seem to work or are very limited to squares, so I'm thinking this is a bug that must exist only in iOS7, so please don't say this is a duplicate without letting me check out the duplicate first to make sure that it really is one.

Right now all signs point to not using an skshapenode with a fill to crop an image.


Solution

  • I basically kept wrapping it until it worked. End all be all solution seemed to be creating an SKEffectNode and adding my SKShapeNode as a child of SKEffectNode. That wasn't enough though. I also had to wrap the SKEffectNode in an SKSpriteNode. Then finally, add the SKSpriteNode as the maskNode of SKCropNode. See the code below. I have additional settings that may be helpful to the solution as well.

            SKCropNode *cropNode = [[SKCropNode alloc] init];
    
            SKEffectNode*rasterEffectNode = [SKEffectNode node];
            [rasterEffectNode addChild:ballShape];
            rasterEffectNode.shouldRasterize = true;
            ballShape.lineWidth = 0;
            ballShape.antialiased = true;
            [ballShape setStrokeColor:[SKColor clearColor]];
            ballShape.fillColor = [SKColor blackColor];
    
            SKSpriteNode*spriteWrapperFix = [SKSpriteNode node];
            [spriteWrapperFix addChild:rasterEffectNode];
            [cropNode setMaskNode:spriteWrapperFix];
            [cropNode addChild:sprite];
            [container addChild:cropNode];