You may want to avoid using an SKCropNode
to build your arcs. From Apple's documentation,
Use clipping and effect nodes sparingly. Both are very powerful, but can be expensive, especially when nested
together within the node tree.
Alternatively, you can construct an arc-shaped core graphics path and then create a shape node from the path. You can then create a physics body using the CG path.
To build the arc-shaped path,
- Add an inner arc from the starting angle to the ending angle
- Add a line from the inner arc's ending point to the outer arc's ending point
- Add the outer arc from the ending angle to the starting angle
- Close the path (which connects the arcs starting points)
Extending CGPath
to construct the arc path is not necessary, but often it's more convenient to use. Once extended, the new class method can be called from anywhere in your code. Here's an example:
extension CGPath {
static func arcWithWidth(arcWidth:CGFloat, start:CGFloat, end:CGFloat, radius:CGFloat, clockwise:Bool) -> CGPath {
// The radius parameter specifies the middle of the arc; adjust this as needed
let innerRadius:CGFloat = radius - arcWidth / 2.0
let outerRadius:CGFloat = radius + arcWidth / 2.0
// Note the arc is upside down because CGPath uses UIKit coordinates
let path = UIBezierPath()
// Add inner ring.
path.addArcWithCenter(CGPointZero, radius: innerRadius, startAngle: start, endAngle: end, clockwise: clockwise)
let x = outerRadius * cos(end)
let y = outerRadius * sin(end)
// Connect the inner to the outer ring
path.addLineToPoint(CGPointMake(x, y))
// Add outer ring
path.addArcWithCenter(CGPointZero, radius: outerRadius, startAngle: end, endAngle: start, clockwise: !clockwise)
path.closePath()
return path.CGPath
}
}
With the extension, you can create the top and bottom arcs:
// Top arc
var path = CGPath.arcWithWidth(20, start:0, end: CGFloat(M_PI), radius: 100, clockwise: true)
let topArc = SKShapeNode(path: path)
topArc.position = view.center
topArc.fillColor = SKColor.redColor()
topArc.strokeColor = SKColor.clearColor()
// Add a physics body to the top half
topArc.physicsBody = SKPhysicsBody(polygonFromPath: path)
topArc.physicsBody?.affectedByGravity = false
addChild(topArc)
// Bottom arc
path = CGPath.arcWithWidth(20, start:0, end: CGFloat(M_PI), radius: 100, clockwise: false)
let bottomArc = SKShapeNode(path: path)
bottomArc.position = view.center
bottomArc.fillColor = SKColor.blueColor()
bottomArc.strokeColor = SKColor.clearColor()
addChild(bottomArc)