所以我正在试验Sprite-kit,以建立主角可以跟随并收集硬币的圆形路径。我已经成功地定位了我的角色,让他沿着我的圆形路径前进。
我想要实现的目标如下:
// 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
?
有没有更简单的方法来解决我的问题?
由于
答案 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)
}
}
它的实际效果: