Sine Wave Motion In SpriteKit

前端 未结 3 766
萌比男神i
萌比男神i 2021-01-02 07:25

I want to make sine wave motion from the first point in the screen to the last Point in the screen, independent on the size of the screen.

Here is my code, but it d

3条回答
  •  抹茶落季
    2021-01-02 07:45

    I agree with @Gord, in that I think SKActions are the best way to go. However, there is no need to approximate the sine curve when you can use the sin function.

    Firstly, you need π as it's going to be useful for the calculations:

    // Defined at global scope.
    let π = CGFloat(M_PI)
    

    Secondly, extend SKAction (in Objective-C this would be done with categories) to easily create an SKAction that oscillates the node in question:

    extension SKAction {
        static func oscillation(amplitude a: CGFloat, timePeriod t: CGFloat, midPoint: CGPoint) -> SKAction {
            let action = SKAction.customActionWithDuration(Double(t)) { node, currentTime in
                let displacement = a * sin(2 * π * currentTime / t)
                node.position.y = midPoint.y + displacement
            }
    
            return action
        }
    }
    

    In the code above: amplitude is the height of the oscillation; timePeriod is the time for one complete cycle and the midPoint is the point around which the oscillation occurs. The formula for displacement comes from the equations for Simple Harmonic Motion.

    Thirdly, putting that all together. You can combine the SKAction.oscillation action and SKAction.moveByX to make the sprite move along the path of the curve.

    class GameScene: SKScene {
        override func didMoveToView(view: SKView) {
            let node = SKSpriteNode(color: UIColor.greenColor(), size: CGSize(width: 50, height: 50))
            node.position = CGPoint(x: 25, y: size.height / 2)
            self.addChild(node)
    
            let oscillate = SKAction.oscillation(amplitude: 200, timePeriod: 1, midPoint: node.position)
            node.runAction(SKAction.repeatActionForever(oscillate))
            node.runAction(SKAction.moveByX(size.width, y: 0, duration: 5))
        }
    }
    

提交回复
热议问题