How to limit the movement of two anchored lines so they swing continually like a pendulum

后端 未结 2 1153
囚心锁ツ
囚心锁ツ 2020-12-16 12:36

I have created two lines anchored to a sprite, which are 30˚ apart. I want both lines to swing left and right like a pendulum, always swinging from end to end (in such a way

相关标签:
2条回答
  • 2020-12-16 13:17

    A swift 5 extension version for the good mogelbuster code :

    extension SKAction {
        class func pendulum(withAngle angle:CGFloat, period:TimeInterval, key:String) -> SKAction {
            let initialRotate = SKAction.rotate(byAngle: angle/2, duration: period/2)
            initialRotate.timingMode = .easeOut
            let rotate = SKAction.rotate(byAngle: angle, duration: period)
            rotate.timingMode = .easeInEaseOut
            let rotateForever = SKAction.repeatForever(SKAction.sequence([rotate.reversed(), rotate]))
            return SKAction.sequence([initialRotate, rotateForever])
        }
    }
    

    Usage:

    let pendulum = SKAction.pendulum(withAngle: CGFloat.pi/2, period: 0.5, key: "pendulum")
    self.mynode.run(pendulum)
    
    0 讨论(0)
  • 2020-12-16 13:38

    Here is the practical answer:

    Replace addChild(armRight) with anchorSprite.addChild(armRight). Replace addChild(armLeft) with anchorSprite.addChild(armLeft). Delete armRight.position = anchorSprite.position and delete armLeft.position = anchorSprite.position. Also, unless you use the physics joints for other movements in your code, delete all of them, as my solution does not require joints.

    Now your arms are children of anchorSprite and subjected to its' coordinate system. If you want to rotate both arms in the same direction at the same time, you can run a rotation action on the anchorSprite. If you want the arms to rotate in different directions you will have to run the rotate action on each arm separately. For either situation, you can use this handy function I made just for the bounty on this question :-P

    func runPendulumRotationOnNode(_ node:SKNode, withAngle angle:CGFloat, period:TimeInterval, key:String) {
        let initialRotate = SKAction.rotate(byAngle: angle/2, duration: period/2)
        initialRotate.timingMode = .easeOut
        let rotate = SKAction.rotate(byAngle: angle, duration: period)
        rotate.timingMode = .easeInEaseOut
        let rotateForever = SKAction.repeatForever(SKAction.sequence([rotate.reversed(), rotate]))
        let rotateSequence = SKAction.sequence([initialRotate, rotateForever])
        node.run(rotateSequence, withKey:key)
    }
    

    I have tested it, and it works great! You can call it like this to rotate both arms together:

    runPendulumRotationOnNode(anchorSprite, withAngle:CGFloat.pi/2, period:0.5, key:"")
    

    Or to rotate the arms in opposite directions, you can use it like this:

    runPendulumRotationOnNode(armRight, withAngle:CGFloat.pi/2, period:0.5, key:"")
    runPendulumRotationOnNode(armLeft, withAngle:-CGFloat.pi/2, period:0.5, key:"")
    

    Some minor notes, notice how I use CGFloat.pi, an easy constant for π. Also this function assumes the pendulum is starting at its midpoint in the rotation, so π/2 (90 degrees) will rotate the arms π/4 (45 degrees) in either direction.

    0 讨论(0)
提交回复
热议问题