Search code examples
swiftsprite-kitskshapenode

Round Specific Corners - SKShapeNode


I have a SKShapeNode which needs to have each one of it's corners rounded if a specific condition is met. Reading the answer provided from the link below, this seemed quiet easy, as I would simply use |= to rounded addition corners that required rounding (4x if statements).

How to write a generic UIRectCorner function?

However, this is not working! When I use the below code, I get the error message "Binart operator '|=' cannot be applied to two 'UIRectCorner' operands"

var corners: UIRectCorner = UIRectCorner(rawValue: 0) | UIRectCorner(rawValue: 1)

or

var corners: UIRectCorner = UIRectCorner(rawValue: 0)
corners |= UIRectCorner(rawValue: 1)

I must be doing something wrong, but I can't figure out what? Any help would be much appreciated.


Solution

  • I wrote a very handy extension that I use heavily in all of my SpriteKit games. It takes the existing SKShapeNode and copies all of its relevant properties then removes and makes a new one with whichever corners you specify to be rounded. Note: you should not use this if the shape node has any children as they will not persist through the new creation. So always use this method before adding any children to it.

    shapeNode.roundCorners(topLeft:true,topRight: true,bottomLeft:false,bottomRight:false,radius:20,parent:self)
    
    
    extension SKShapeNode {
        func roundCorners(topLeft:Bool,topRight:Bool,bottomLeft:Bool,bottomRight:Bool,radius: CGFloat,parent: SKNode){
            let newNode = SKShapeNode(rect: self.frame)
            newNode.fillColor = self.fillColor
            newNode.lineWidth = self.lineWidth
            newNode.position = self.position
            newNode.name = self.name
            newNode.fillColor = self.fillColor
            newNode.strokeColor = self.strokeColor
            newNode.fillTexture = self.fillTexture
            self.removeFromParent()
            parent.addChild(newNode)
            var corners = UIRectCorner()
            if topLeft { corners = corners.union(.bottomLeft) }
            if topRight { corners = corners.union(.bottomRight) }
            if bottomLeft { corners = corners.union(.topLeft) }
            if bottomRight { corners = corners.union(.topRight) }
            newNode.path = UIBezierPath(roundedRect: CGRect(x: -(newNode.frame.width / 2),y:-(newNode.frame.height / 2),width: newNode.frame.width, height: newNode.frame.height),byRoundingCorners: corners, cornerRadii: CGSize(width:radius,height:radius)).cgPath
        }
    }