5

Update: It looks like iOS 10 has fixed this issue. I upgraded to Swift 3 and Xcode 8 and everything is working as expected.


I've run into this issue a couple times now and I can't tell if it's a bug in SKCropNode or if I'm just misusing it. Perhaps there's some bit of documentation I'm missing to explain why this is happening?


I have a crop node with a 100x100 rectangle shape as the mask. If I place a blue circle inside it, it gets cropped properly.

// Create a crope node with a small square.
let cropNode = SKCropNode()
let cropNodeMask = SKShapeNode(rect: CGRect(x: 0, y: 0, width: 100, height: 100))
cropNodeMask.fillColor = UIColor.whiteColor()
cropNode.maskNode = cropNodeMask
self.addChild(cropNode)

// Create a blue circle and put it in the crop node.
let blueCircle = SKShapeNode(circleOfRadius: 110)
blueCircle.fillColor = UIColor.blueColor()
blueCircle.strokeColor = UIColor.clearColor()
cropNode.addChild(blueCircle)

enter image description here


Now, when I place that same circle inside of an otherwise empty SKNode and place that container inside the same crop node, cropping fails.

// Create a crope node with a small square.
let cropNode = SKCropNode()
let cropNodeMask = SKShapeNode(rect: CGRect(x: 0, y: 0, width: 100, height: 100))
cropNodeMask.fillColor = UIColor.whiteColor()
cropNode.maskNode = cropNodeMask
self.addChild(cropNode)

// Create a container to hold the circle.
let container = SKNode()
cropNode.addChild(container)

// Create a blue circle and put it in the container.
let blueCircle = SKShapeNode(circleOfRadius: 110)
blueCircle.fillColor = UIColor.blueColor()
blueCircle.strokeColor = UIColor.clearColor()
container.addChild(blueCircle)

enter image description here


But a sprite in that same container seems to be cropped fine.

// Create a crope node with a small square.
let cropNode = SKCropNode()
let cropNodeMask = SKShapeNode(rect: CGRect(x: 0, y: 0, width: 100, height: 100))
cropNodeMask.fillColor = UIColor.whiteColor()
cropNode.maskNode = cropNodeMask
self.addChild(cropNode)

// Create a container to hold the sprite.
let container = SKNode()
cropNode.addChild(container)

// Create a spaceship and add it to the container.
let spaceshipNode = SKSpriteNode(imageNamed: "Spaceship")
spaceshipNode.anchorPoint = CGPointZero
container.addChild(spaceshipNode)

enter image description here

Brent Traut
  • 5,614
  • 6
  • 29
  • 54

1 Answers1

4

SKShapeNode is bugged, best to avoid it at all costs. Use it to create your shapes, then convert it to a texture for use with SKSpriteNode

Knight0fDragon
  • 16,609
  • 2
  • 23
  • 44
  • Uh oh. Spoke too soon. I removed all SKShapeNodes from my project in favor of sprites and my content is still escaping the crop. I suspect it's when I have nested crop nodes, although I haven't boiled it down to a simple repro yet. – Brent Traut Sep 05 '16 at 04:08
  • It looks like your answer is partially correct. SKCropNode and SKShapeNode interact poorly, but in this case it's definitely SKCropNode's fault because it also seems to fail with child SKCropNodes. Similar conclusion on [this answer](http://stackoverflow.com/a/26558228/1181827). – Brent Traut Sep 05 '16 at 04:53
  • SKCropNodes inside SKCropNodes produce a different result, alpha transparent cropping( no longer becomes just a on off issue, now if your alpha is 25% it will take that into account when cropping. Has to do with the blending functions) – Knight0fDragon Sep 05 '16 at 08:19
  • I'm using fully opaque or fully transparent pixels in my masks though. Blending shouldn't matter. – Brent Traut Sep 05 '16 at 08:45
  • The math and functions still apply regardless if you use it or not – Knight0fDragon Sep 05 '16 at 08:46