Search code examples
swiftsprite-kitgeometrycgpath

Add sprites over a circular CGPath Swift


How can I spawn a sprite repeatedly over the coordinates of a circular path?

So I have a circular path and I want the sprite to appear every 30º for example (so in that case I would end up having the same sprite 12 times). The problem is that it doesn't matter what I do I cant get it to do so. Recently I found an article were it was shown how to do a clock, I used that sample code but I'm still stuck, I don't know what to replace drawRect for or if I have any other errors. I would appreciate any help.

import SpriteKit
import UIKit

class GameScene: SKScene {

override func didMoveToView(view: SKView) {
    /* Setup your scene here */

        func degree2radian(a:CGFloat)->CGFloat {
            let b = CGFloat(M_PI) * a/180
            return b
        }


    func circleCircumferencePoints(sides:Int,x:CGFloat,y:CGFloat,radius:CGFloat,adjustment:CGFloat=0)->[CGPoint] {
        let angle = degree2radian(360/CGFloat(sides))
        let cx = x
        let cy = y
        let r  = radius
        var i = sides
        var points = [CGPoint]()
        while points.count <= sides {
            let xpo = cx - r * cos(angle * CGFloat(i)+degree2radian(adjustment))
            let ypo = cy - r * sin(angle * CGFloat(i)+degree2radian(adjustment))
            points.append(CGPoint(x: xpo, y: ypo))
            i--;
        }
        return points
    }

    func pointsLocation(#x:CGFloat, #y:CGFloat, #radius:CGFloat, #sides:Int) {
        let points = circleCircumferencePoints(sides,x,y,radius)
        let path = CGPathCreateMutable()


        for p in enumerate(points) {


            CGPathMoveToPoint(path, nil, p.element.x, p.element.y)
            let blueDot = SKSpriteNode(imageNamed: "arrow.png")
            blueDot.position.x = p.element.x
            blueDot.position.y = p.element.y
            addChild(blueDot)
            CGPathCloseSubpath(path)

    class View: UIView {


        override func drawRect(rect: CGRect)


            let rad = CGRectGetWidth(rect)/3.5

            pointsLocation(x: CGRectGetMidX(rect), y: CGRectGetMidY(rect), radius: rad, sides: 8)


    }




override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    /* Called when a touch begins */

        }

override func update(currentTime: CFTimeInterval) {
    /* Called before each frame is rendered */
}
}

Solution

  • You code has a lot of syntax errors. That's why it doesn't work. After correcting the errors, the logic you used works.

    class GameScene: SKScene,SKPhysicsContactDelegate {
    
        override func didMoveToView(view: SKView) {
    
            pointsLocation(x: 100, y: 100, radius: 50, sides: 12)
        }
    
        func degree2radian(a:CGFloat)->CGFloat {
            let b = CGFloat(M_PI) * a/180
            return b
        }
    
        func circleCircumferencePoints(sides:Int,x:CGFloat,y:CGFloat,radius:CGFloat,adjustment:CGFloat=0)->[CGPoint] {
            let angle = degree2radian(360/CGFloat(sides))
            let cx = x
            let cy = y
            let r  = radius
            var i = sides
            var points = [CGPoint]()
            while points.count <= sides {
                let xpo = cx - r * cos(angle * CGFloat(i)+degree2radian(adjustment))
                let ypo = cy - r * sin(angle * CGFloat(i)+degree2radian(adjustment))
                points.append(CGPoint(x: xpo, y: ypo))
                i--;
            }
            return points
        }
    
    
    
        func pointsLocation(#x:CGFloat, y:CGFloat, radius:CGFloat, sides:Int) {
            let points = circleCircumferencePoints(sides,x: x,y: y,radius: radius)
            let path = CGPathCreateMutable()
    
    
            for p in enumerate(points) {
    
                let blueDot = SKSpriteNode(imageNamed: "arrow.png")
                blueDot.position.x = p.element.x
                blueDot.position.y = p.element.y
                addChild(blueDot)
    
            }
        }
    
        override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
            /* Called when a touch begins */
    
        }
    
        override func update(currentTime: CFTimeInterval) {
            /* Called before each frame is rendered */
        }
    
    }