swift - 如何通过触摸旋转 SpriteNode?

标签 swift xcode sprite-kit skspritenode swift-playground

如何通过触摸在固定点上旋转 SpriteKit 节点。所以当用户拖动他的手指时它会转动。我也希望能够获得 rpm。 (之前有人问过这个问题,但我想知道如何使用 SpriteKit 来做) swift 3 Playground

到目前为止,我已经掌握了它,但有时我会收到 var deltaAngle = angle - startingAngle 的错误!错误 - “在展开可选值时意外发现 nil”

class GameScene: SKScene {
var startingAngle:CGFloat?
var startingTime:TimeInterval?


override func didMove(to view: SKView) {
    let wheel = SKSpriteNode(imageNamed: "IMG_6797.PNG" )

    wheel.position = CGPoint(x: 200, y: 200)

    wheel.name = "wheel"
    wheel.setScale(0.5)
    wheel.physicsBody = SKPhysicsBody(circleOfRadius: wheel.size.width/2)
    // Change this property as needed (increase it to slow faster)
    wheel.physicsBody!.angularDamping = 4
    wheel.physicsBody?.pinned = true
    wheel.physicsBody?.affectedByGravity = false
    addChild(wheel)
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch in touches {
        let location = touch.location(in:self)
        let node = atPoint(location)
        if node.name == "wheel" {
            let dx = location.x - node.position.x
            let dy = location.y - node.position.y
            // Store angle and current time
            startingAngle = atan2(dy, dx)
            startingTime = touch.timestamp
            node.physicsBody?.angularVelocity = 0
        }
    }
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch in touches{
        let location = touch.location(in:self)
        let node = atPoint(location)
        if node.name == "wheel" {
            let dx = location.x - node.position.x
            let dy = location.y - node.position.y


            let angle = atan2(dy, dx)
            // Calculate angular velocity; handle wrap at pi/-pi
            var deltaAngle = angle - startingAngle!
            if abs(deltaAngle) > CGFloat.pi {
                if (deltaAngle > 0) {
                    deltaAngle = deltaAngle - CGFloat.pi * 2
                }
                else {
                    deltaAngle = deltaAngle + CGFloat.pi * 2
                }
            }
            let dt = CGFloat(touch.timestamp - startingTime!)
            let velocity = deltaAngle / dt

            node.physicsBody?.angularVelocity = velocity

            startingAngle = angle
            startingTime = touch.timestamp
        }
    }
}



override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {

    startingAngle = nil
    startingTime = nil
}

最佳答案

这个错误就是它所说的意思。最有可能的是,“wheel”在 touchesBegan 中没有被触摸,但随后在 touchesMoved 中注册,导致 startingAngle 没有被设置为任何东西和 nil。

如果用户没有开始触摸轮子,您可能不希望轮子旋转,所以我会在 touchedMoved 中添加一个守卫

...
let angle = atan2(dy, dx)

guard startingAngle != nil else {return} //Exit the function if starting angle was never set

var deltaAngle = angle - startingAngle!
...

关于swift - 如何通过触摸旋转 SpriteNode?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43146711/

相关文章:

ios - 在静态表格 View 单元格中将文本设置为动态

ios - 将 cocoapods 添加到我的 PodFile

iphone - 获取 UIWebView URL 的查询

swift - 自动换行不适用于 Swift 中的 UILabel

swift - 如何在 SKScene 中使用另一个变量初始化一个变量

ios - 将物理主体保留在 SKScene 的中间?

swift - 如何在 SpriteKit 中为生命栏添加边框?

ios - NavigationBar 标题文本不会随 titleTextAttributes 改变

Swift 数据库检索数据

ios - 如何将 GameCenter 添加到我的应用程序?