Search code examples
swiftsprite-kitrotationskshapenode

Rotate a SKShapeNode with texture


I'm trying to rotate an SKShapeNode with a texture, but it's not working. Basically, I have a circle with a texture and I'm trying to make it rotate using the same way I have done with an SKSpriteNode:

let spin = SKAction.rotateByAngle(CGFloat(M_PI/4.0), duration: 1)

The problem is that the circle is rotating, but not the texture. I can check this by using this code:

let wait = SKAction.waitForDuration(0.5)
let block = SKAction.runBlock({
                     print(self.circle.zRotation)  
                     })
let sequence = SKAction.sequence([wait, block])
self.runAction(SKAction.repeatActionForever(sequence))

This is the code I have for creating the SKShapeNode:

let tex:SKTexture = SKTexture(image: image)
let circle = SKShapeNode(circleOfRadius: 100 )
circle.position = CGPoint(x: self.frame.width / 2, y: self.frame.height / 2 + 200)
circle.strokeColor = SKColor.clearColor()
circle.glowWidth = 1.0
circle.fillColor = SKColor.whiteColor()
circle.fillTexture = tex
self.addChild(circle)
// Runing the action
circle.runAction(spin)

Please help. Thanks in advance!

PS: I know that using an SKSpriteNode would be better but my goal is to place a square image in a circular frame and I figured that using an SKShapeNode would be perfect. If anyone know how to create a circular SKSpriteNode, feel free to post it in the answers section! :)

This is what I'm trying to achieve (with the capability of rotating it): enter image description here


Solution

  • You can achieve what you want by using SKCropNode and setting its mask property to be a circle texture:

    override func didMoveToView(view: SKView) {
    
         let maskShapeTexture = SKTexture(imageNamed: "circle")
    
         let texture = SKTexture(imageNamed: "pictureToMask")
    
         let pictureToMask = SKSpriteNode(texture: texture, size: texture.size())
    
         let mask = SKSpriteNode(texture: maskShapeTexture) //make a circular mask
    
         let cropNode = SKCropNode()
         cropNode.maskNode = mask
         cropNode.addChild(pictureToMask)
         cropNode.position = CGPoint(x: frame.midX, y: frame.midY)
         addChild(cropNode)
    }
    

    Let's say that picture to mask has a size of 300x300 pixels. The circle you are using as a mask, in that case, has to have the same size. Means the circle itself has to have a radius of 150 pixels (diameter of 300 pixels) when made in image editor.

    Mask node determines the visible area of a picture. So don't make it too large. Mask node has to be a fully opaque circle with transparent background.