I am trying to create an open circle from a UIBezierPath and turn that into an SKShapeNode which will later be turned into a SKSpriteNode.
I had an problem where I could not figure out how to shrink a Sprite while its line width did not scale down. You can see the solution here: Resize sprite without shrinking contents
I ended up fixing some things and creating a new class to implement a custom SKShapeNode with this functionality:
class ShrinkableShape: SKShapeNode {
let level: Int
let bezierPath: UIBezierPath
let scale: CGFloat
let finalLineWidth: CGFloat
let from: SKSpriteNode
let initialLineWidth = CGFloat(20)
let duration = 0.3
// level would be from 1 to 5 (it is in a for loop)
init(level: Int, from: SKSpriteNode) {
self.level = level
self.from = from
// create the open circle which is (43 * level) + 140
bezierPath = UIBezierPath(arcCenter: CGPoint(x: 0, y: 0), radius: CGFloat(((43 * level) + 140)), startAngle: CGFloat(GLKMathDegreesToRadians(-50)), endAngle: CGFloat(M_PI * 2), clockwise: false)
// calls static function in this class so it is more readable
scale = ShrinkableShape.scaleFrom(level: level) / ShrinkableShape.scaleFrom(level: level + 1)
finalLineWidth = (initialLineWidth / scale)
// inits shape and then sets it up to specific values
super.init()
setup()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setup() {
// set sprite to path, set color, set line width and rotate it
self.path = bezierPath.cgPath
self.strokeColor = UIColor(red:0.98, green:0.99, blue:0.99, alpha:1.00)
self.lineWidth = 20
self.position = from.position
// FOR DEBUG: you will see what this makes in the screenshot
let color = SKShapeNode(rect: self.frame)
color.fillColor = UIColor.red
color.alpha = 0.2
color.position = self.position
self.addChild(color)
}
// Makes the radius from the value given (only 1...5) 183, 226, 269, etc
static func scaleFrom(level: Int) -> CGFloat {
return (CGFloat((level * 43) + 140) * 2.0)
}
}
If you look at the screenshot you can notice the white circle is a little off compared to where it should be aligned (the gray bar and white circle path should be on each other). This only happens when I call the scale function shown in the solution (linked above).
I think it is because of the frame being all messed up. If you see, the frame is very off (and that same issue was the reason for past issues when converting to a texture because the frame was not exact as it should be)
Why does this happen? How do I fix it? Is there a way for me to manually set the correct frame for the SKShapeNode? Any other ideas on how I can do this?
--Edit-- I forgot to mention. The red part in the picture is a debug to see the frame of the SKShapeNode. You can see how it is created in the setup() func. But I included that to show how far off the frame was.
I think part of your problem is the difference between where you have your lines versus where the bitmap edges are as a result of the stroke/outline width you have 'around' those lines.
Perhaps best described visually, whereby Red is what the system sees as the sprite size, whilst yellow is perhaps what you're thinking about. I've greatly exaggerated the line width to show the effect/problem I'm thinking about.