How to move SKSpriteNode up and down around its starting value in Swift?
I am currently working on a game that has an SKSpriteNode. I want this node location to move up and down all the time. It should be set to y first, for example. 500. Then it has to move 200 pixels down (500 + 200 = 700) and then it has to move 400 pixels up (700-400 = 300), so it is created both up and down, which constantly moves between 500 + 200 and 500 -200, I hope I made it clear. First, how do I get this effect, and second, where can I inject it? Should I be using a custom function? I program with fast (beginner fast)
source to share
I wrote a sample code that you can adapt for your own purposes:
First, you need π to calculate the fluctuations:
// Defined at global scope.
let π = CGFloat(M_PI)
Second, it's extensible SKAction
so you can easily create actions that will oscillate the node:
extension SKAction {
// amplitude - the amount the height will vary by, set this to 200 in your case.
// timePeriod - the time it takes for one complete cycle
// midPoint - the point around which the oscillation occurs.
static func oscillation(amplitude a: CGFloat, timePeriod t: Double, midPoint: CGPoint) -> SKAction {
let action = SKAction.customActionWithDuration(t) { node, currentTime in
let displacement = a * sin(2 * π * currentTime / CGFloat(t))
node.position.y = midPoint.y + displacement
}
return action
}
}
The drive is displacement
given from the equation of simple harmonic motion to move. See here for more info (they've been rearranged a bit, but it's the same equation).
Third, putting it all together, in SKScene
:
override func didMoveToView(view: SKView) {
let node = SKSpriteNode(color: UIColor.greenColor(),
size: CGSize(width: 50, height: 50))
node.position = CGPoint(x: size.width / 2, y: size.height / 2)
self.addChild(node)
let oscillate = SKAction.oscillation(amplitude: 200,
timePeriod: 1,
midPoint: node.position)
node.runAction(SKAction.repeatActionForever(oscillate))
}
If you needed to oscillate a node along the x-axis, I would recommend adding an argument angle
to the method oscillate
and using sin
and cos
to determine how much the node should oscillate on each axis.
Hope it helps!
source to share