Search code examples
swiftpathsprite-kitmove

How to make player move to opposite side while is in a path?


enter image description here

I want that when touches began the player (red circle) moves to the opposite side of the circular path. I already made that the player follows a path, but I havent find answer to my question on internet.

    override func didMoveToView(view: SKView) {

    player = SKSpriteNode(imageNamed: "circulo")
    player.position = CGPoint(x: self.frame.width / 2, y: self.frame.height / 2 - 170)
    player.color = colorGris
    player.colorBlendFactor = 1
    player.size = CGSize(width: 25, height: 25)
    self.addChild(player)
    player.zPosition = 3

   }
   override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
   /* Called when a touch begins */

    if gameStarted == false {

        gameStarted = true
        moveClockWise()
        movingClockWise = true

    }

       }



   func moveClockWise(){



    let dx = player.position.x - self.frame.width / 2
    let dy = player.position.y - self.frame.height / 2

    let rad = atan2(dy, dx)

    path = UIBezierPath(arcCenter: CGPoint(x:self.frame.width / 2, y: self.frame.height / 2) , radius: 170, startAngle: rad, endAngle: rad + CGFloat(M_PI * 4), clockwise: true)

    let follow = SKAction.followPath(path.CGPath, asOffset: false, orientToPath: true, speed: 200)
    player.runAction(SKAction.repeatActionForever(follow).reversedAction())

}

Solution

  • One of the easiest ways to move an object in a circular path is to

    1. Create a SKNode container
    2. Create a sprite
    3. Add the container to the scene
    4. Set the sprite's x position to the radius of the circular path
    5. Add the sprite to the container
    6. Rotate the container

    If you want to move the sprite to the other side or change the rotation's radius, simply

    1. change the sprite's x position

    If you want to change the direction of the rotation,

    1. reverse the container's rotation

    Example Code:

    // 1) Create the container node 
    let node = SKNode()
    // 2) Create a sprite
    let sprite = SKSpriteNode(color:SKColor.blueColor(),size:CGSizeMake(20,20))
    var rotation:CGFloat = CGFloat(M_PI)
    let radius:CGFloat = 50
    
    override func didMoveToView(view: SKView) {
        scaleMode = .ResizeFill
        node.position = view.center
        // 3) Add the container to the scene
        addChild(node)
        // 4) Set the sprite's x position
        sprite.position = CGPointMake(radius, 0)
        // 5) Add the sprite to the container
        node.addChild(sprite)
        // 6) Rotate the container
        rotate()
    }
    
    // Rotate the container
    func rotate() {
        let action = SKAction.rotateByAngle(rotation, duration: 4)
        node.runAction(SKAction.repeatActionForever(action),withKey: "rotate")
    }
    
    // 8) Reverse the direction of the rotation
    func reverse() {
        rotation = -rotation
    }
    
    // Stop rotating the container
    func stopRotation() {
        if node.actionForKey("rotate") != nil {
            node.removeActionForKey("rotate")
        }
    }
    
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
       /* 7) Change the sprite's x-position  */
        if sprite.actionForKey("move") == nil {
            stopRotation()
            let opposite = -sprite.position.x * 2
            let move = SKAction.moveByX(opposite, y: 0, duration: 3)
            let rotate = SKAction.runBlock {
                self.rotate()
            }
            sprite.runAction(SKAction.sequence([move, rotate]), withKey: "move")
        }
    }