Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change the radius of SKShapeNode

How can we change the radius of the SKShapeNode without recreating it? In the header file there is only an initialiser with circleOfRadius syntax.

like image 854
Metin Say Avatar asked Jun 20 '14 15:06

Metin Say


2 Answers

If you create the SKShapeNode with a path, you can change the path at any point later. Try this:

class GameScene: SKScene {
    override func mouseDown(theEvent: NSEvent) {
        let location = theEvent.locationInNode(self)
        let node = self.nodeAtPoint(location)
        if let circle = node as? SizeableCircle { // clicking on an existing circle
            circle.radius = Double(arc4random_uniform(100))
        } else { // clicking on empty space
            self.addChild(SizeableCircle(radius: 100.0, position: location))
        }
    }
}

class SizeableCircle: SKShapeNode {

    var radius: Double {
        didSet {
            self.path = SizeableCircle.path(self.radius)
        }
    }

    init(radius: Double, position: CGPoint) {
        self.radius = radius

        super.init()

        self.path = SizeableCircle.path(self.radius)
        self.position = position
    }

    class func path(radius: Double) -> CGMutablePathRef {
        var path: CGMutablePathRef = CGPathCreateMutable()
        CGPathAddArc(path, nil, 0.0, 0.0, radius, 0.0, 2.0 * M_PI, true)
        return path
    }

}

The difference between this and scaling is that anything else that you set (e.g. line width, text child nodes, etc.) will not change unless you make them.

like image 108
Grimxn Avatar answered Sep 27 '22 22:09

Grimxn


Swift 4:

Essentially, you can launch an SKAction for scaleTo or scaleBy with a specific TimeInterval as a duration, anyway I've translate the Grimxn class to the latest swift in case you have to use it for other reasons:

class SizeableCircle: SKShapeNode {

    var radius: Double {
        didSet {
            self.path = SizeableCircle.path(radius: self.radius)
        }
    }

    init(radius: Double, position: CGPoint) {
        self.radius = radius

        super.init()

        self.path = SizeableCircle.path(radius: self.radius)
        self.position = position
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    class func path(radius: Double) -> CGMutablePath {
        let path: CGMutablePath = CGMutablePath()
        path.addArc(center: CGPoint.zero, radius: CGFloat(radius), startAngle: 0.0, endAngle: CGFloat(2.0*Double.pi), clockwise: false)
        return path
    }

}
like image 23
Alessandro Ornano Avatar answered Sep 27 '22 22:09

Alessandro Ornano