1

I am making a game in which a sprite is rotating around a big circle and I want that when touches began the sprite moves to another circle that is in the center of the screen and now the sprite rotatate around it, and when the touches began occurs again the sprite return to the big circle. In my code the sprite moves to the -sprite.position.x * 2 so that makes that the sprite move to the oposite side of the big circle. How can I solve that?

Alex
  • 69
  • 1
  • 7
  • This may be what you're looking for http://stackoverflow.com/questions/38167139/how-to-make-player-move-to-opposite-side-while-is-in-a-path/38174527?noredirect=1#comment63784281_38174527 – Epsilon Jul 05 '16 at 22:18
  • But how do I make to first make the sprite move to the center and then return? – Alex Jul 05 '16 at 23:46
  • Change the sprite's `x` position to set the radius of the rotation – Epsilon Jul 06 '16 at 05:54
  • The problem is that if I am on the center and then return to the original path when I try to move again to the center the sprite moves out of the scene – Alex Jul 06 '16 at 06:05
  • Did you implement the code in the link that I provided? – Epsilon Jul 06 '16 at 06:59
  • yes, I implement it – Alex Jul 06 '16 at 12:29

1 Answers1

2

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. Add the sprite to the container
  5. Set the sprite's x position to the radius of the circular path
  6. Rotate the container

If you want to move the sprite to the another circle with a different radius,

  1. change the sprite's x position
  2. move the container's position (optional)

If you want to change the direction of the rotation,

  1. reverse the container's rotation

Here's an example:

// Define circle
struct Circle {
    var position:CGPoint
    var radius:CGFloat
}

class GameScene: SKScene {
    // 1. Create container node
    let node = SKNode()
    // 2. Create a sprite
    let sprite = SKSpriteNode(color:SKColor.blueColor(),size:CGSizeMake(10,10))
    var rotation:CGFloat = CGFloat(M_PI)
    var circles:[Circle] = []

    override func didMoveToView(view: SKView) {
        scaleMode = .ResizeFill

        circles.append(Circle(position: view.center, radius: 80))
        circles.append(Circle(position: view.center, radius: 40))
        // 3. Add the container to the scene
        addChild(node)

        // 4. Add the sprite to the container
        node.addChild(sprite)
        // 5. Set the sprite's x position to the radius of the circular path
        if let circle = nextCircle() {
            node.position = circle.position
            sprite.position = CGPoint(x:circle.radius, y:0)
            // 6. Rotate the container
            rotate()
        }
    }

    // Rotate the container
    func rotate() {
        let action = SKAction.rotateByAngle(rotation, duration: 4)
        node.runAction(SKAction.repeatActionForever(action),withKey: "rotate")
    }

    // 9. Reverse the container's rotation
    func reverse() {
        rotation = -rotation
    }

    // Stop rotating the container
    func stopRotation() {
        if node.actionForKey("rotate") != nil {
            node.removeActionForKey("rotate")
        }
    }

    // Returns the next circle's parameters and rotates the array
    func nextCircle() -> Circle? {
        guard let circle = circles.first else {
            return nil
        }
        // Move the current circle to the back of the queue
        circles.append(circles.removeAtIndex(0))
        return circle
    }

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        /* Change the sprite's x-position  */
        if sprite.actionForKey("move") == nil {
            stopRotation()
            // 7. change the sprite's x position
            // 8. move the container's position (optional)
            if let circle = nextCircle() {
                let radius = CGPoint(x:circle.radius, y:0)
                let moveCenter = SKAction.moveTo(circle.position, duration: 3)
                let move = SKAction.moveTo(radius, duration: 3)
                let rotate = SKAction.runBlock {
                    self.rotate()
                }
                sprite.runAction(SKAction.sequence([move, rotate]), withKey: "move")
                node.runAction(moveCenter, withKey: "move")
            }
        }
    }
}
Epsilon
  • 1,016
  • 1
  • 6
  • 15
  • Thanks epsilon, ans what if I want that the rotation of the second path is faster? what can I do? – Alex Jul 07 '16 at 03:33
  • 1
    You can do that by changing `rotateByAngle`'s `duration` parameter, where a smaller value results in a faster rotation. – Epsilon Jul 07 '16 at 07:31
  • But that make that because if the ball is the the big path it seems much more faster, I know is the same suration, but I would prefer that if the ball is in the small path it goes even faster – Alex Jul 07 '16 at 12:54
  • 1
    You'll need to have different durations for the larger and smaller circles. With the same duration, the two objects rotate about the center point with difference angular velocities. The object with the larger circle has a higher angular velocity (w=2*pi*r/t), so it travels a longer distance in the same amount of time. – Epsilon Jul 07 '16 at 17:35
  • Ooo I get it, and how can I do de that? – Alex Jul 10 '16 at 01:20
  • 1
    You can pass a duration value into the `rotate` method that is smaller for the smaller circle and larger for the larger circle. – Epsilon Jul 16 '16 at 02:58