Sprite-kit:如何在圆形路径上定位精灵

时间:2016-03-30 21:53:30

标签: ios swift sprite-kit

所以我正在试验Sprite-kit,以建立主角可以跟随并收集硬币的圆形路径。我已经成功地定位了我的角色,让他沿着我的圆形路径前进。

我想要实现的目标如下:

  • 红球是主角[完成]
  • 白色多边形是硬币

schema

// Adding the big circle
let runway = SKSpriteNode(imageNamed: "runway")
runway.position = CGPointMake(CGRectGetMidX(frame), CGRectGetMidY(frame))
addChild(runway)
// Adding the player
player = SKSpriteNode(imageNamed: "player")
player.position = CGPointMake( CGRectGetMidX(frame) , (CGRectGetMidY(frame) + runway.size.width/2) )
// Calculating the initial position of the player and creating a circular path around it
let dx = player.position.x - frame.width / 2
let dy = player.position.y - frame.height / 2

let radian = atan2(dy, dx)
let playerPath = UIBezierPath(
    arcCenter: CGPoint(x: CGRectGetMidX(frame), y: CGRectGetMidY(frame)),
    radius: (runway.frame.size.width / 2) - 20,
    startAngle: radian,
    endAngle: radian + CGFloat(M_PI * 4.0),
    clockwise: true)

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

我现在的问题是,如何将我的硬币放在同一条路上? 有没有办法使用相同的路径生成他们的位置,还是我应该为每个硬币创建一个特定的路径并每次提取路径currentPoint

有没有更简单的方法来解决我的问题?

由于

2 个答案:

答案 0 :(得分:1)

就像我说的那样,你需要知道路径的中心在哪里(在你的情况下是CGPoint(x: frame.midX, y:frame.midY),它是屏幕的中心")你必须知道半径(您在创建路径时已经计算过它)并且您需要一个角度,即从中心(frame.midX,frame.midY)到圆周上的点(coinX,coinY)的光线使用正x轴进行计算:

import SpriteKit

class GameScene: SKScene {

    let player = SKSpriteNode(color: .purpleColor(), size: CGSize(width: 30, height: 30))

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

        // Adding the big circle
        let runway = SKSpriteNode(color: .orangeColor(), size: CGSize(width: 150, height: 150))
        runway.position = CGPointMake(CGRectGetMidX(frame), CGRectGetMidY(frame))
        addChild(runway)
        // Adding the player

        player.position = CGPointMake( CGRectGetMidX(frame) , (CGRectGetMidY(frame) + runway.size.width/2) )
        addChild(player)
        // Calculating the initial position of the player and creating a circular path around it
        let dx = player.position.x - frame.width / 2
        let dy = player.position.y - frame.height / 2

        let radius = (runway.frame.size.width / 2) - 20.0

        let radian = atan2(dy, dx)
        let playerPath = UIBezierPath(
            arcCenter: CGPoint(x: CGRectGetMidX(frame), y: CGRectGetMidY(frame)),
            radius: radius,
            startAngle: radian,
            endAngle: radian + CGFloat(M_PI * 4.0),
            clockwise: true)

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

        let numberOfCoins = 8
        for i in 0...numberOfCoins {

            let coin = SKSpriteNode(color: .yellowColor(), size: CGSize(width: 10, height: 10))

            let angle = 2 * M_PI / Double(numberOfCoins) * Double(i)

            let coinX = radius * cos(CGFloat(angle))
            let coinY = radius * sin(CGFloat(angle))

             coin.position = CGPoint(x:coinX + frame.midX, y:coinY + frame.midY)
            addChild(coin)
        }
    }
}

只是旁注:在Sprite-Kit中,0弧度的角度指定正x轴。并且正角度是逆时针方向。来源 - Building Your Scene

答案 1 :(得分:1)

Whirlwind发布的答案是有效的,但需要迁移以使用Xcode 11。

以下是该答案的更新版本,以及显示其实际效果的动画。

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

    // Adding the big circle
    let runway = SKSpriteNode(color: .orange, size: CGSize(width: 150, height: 150))
    runway.position = CGPoint(x: frame.midX, y: frame.midY)
    addChild(runway)
    // Adding the player

    player.position = CGPoint(x: frame.midX, y: frame.midY + runway.size.width / 2)
    addChild(player)
    // Calculating the initial position of the player and creating a circular path around it
    let dx = player.position.x - frame.width / 2
    let dy = player.position.y - frame.height / 2

    let radius = (runway.frame.size.width / 2) - 20.0

    let radian = atan2(dy, dx)
    let playerPath = UIBezierPath(
        arcCenter: CGPoint(x: frame.midX, y: frame.midY),
        radius: radius,
        startAngle: radian,
        endAngle: radian + CGFloat(.pi * 4.0),
        clockwise: true)

    let follow = SKAction.follow(playerPath.cgPath, asOffset: false, orientToPath: true, speed: 200)
    player.run(SKAction.repeatForever(follow))

    let numberOfCoins = 8
    for i in 0...numberOfCoins {

        let coin = SKSpriteNode(color: .yellow, size: CGSize(width: 10, height: 10))

        let angle = 2 * .pi / Double(numberOfCoins) * Double(i)

        let coinX = radius * cos(CGFloat(angle))
        let coinY = radius * sin(CGFloat(angle))

         coin.position = CGPoint(x:coinX + frame.midX, y:coinY + frame.midY)
        addChild(coin)
    }
}

它的实际效果:

enter image description here