I have two arcs that form a circle(SKCropNode
), each with a different color. I know I can give the whole circle a circleOfRadius
, but I was wondering if it was possible to give just one arc a physics body to fit the shape of the arc.
Help much appreciated.
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,
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)