如何根据平移手势速度向 Sprite Kit 节点应用角脉冲

Posted

技术标签:

【中文标题】如何根据平移手势速度向 Sprite Kit 节点应用角脉冲【英文标题】:How can I apply an angular impulse to a Sprite Kit node based on a pan gesture velocity 【发布时间】:2014-10-27 15:51:38 【问题描述】:

我在这里要做的是围绕其锚点旋转 SKSpriteNode,并使其速度和方向与平移手势相匹配。因此,如果我的平移手势围绕精灵顺时针旋转,那么精灵就会顺时针旋转。

我的代码遇到的问题是,它适用于精灵下方从左到右/从右到左的平移,但当我尝试垂直平移时根本不行,如果我这样做会使精灵旋转错误的方式在精灵上方平移。

这是我到目前为止所得到的 -

let windmill = SKSpriteNode(imageNamed: "Windmill")

override func didMoveToView(view: SKView) 
    /* Setup gesture recognizers */
    let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: "handlePanGesture:")
    self.view?.addGestureRecognizer(panGestureRecognizer)

    windmill.physicsBody = SKPhysicsBody(circleOfRadius: windmill.size.width)
    windmill.physicsBody?.affectedByGravity = false
    windmill.name = "Windmill"
    windmill.position = CGPoint(x: self.frame.size.width / 2, y: self.frame.size.height / 2)
    self.addChild(windmill)


func handlePanGesture(recognizer: UIPanGestureRecognizer) 
    if (recognizer.state == UIGestureRecognizerState.Changed)
    
        pinwheel.physicsBody?.applyAngularImpulse(recognizer.velocityInView(self.view).x)
    

我知道它不与垂直平底锅一起旋转的原因是我只得到 x 值,所以我想我需要以某种方式将它们组合起来。

我也尝试过使用 applyImpulse:atPoint:,但这会导致整个精灵被扫走。

【问题讨论】:

【参考方案1】:

以下步骤将根据平移手势旋转节点:

    存储从节点中心到平移手势起始位置的向量 形成一个从节点中心到平移手势结束位置的向量 确定两个向量叉积的符号 计算平移手势的速度 使用速度和方向向节点施加角脉冲

这是一个如何在 Swift 中执行此操作的示例...

// Declare a variable to store touch location
var startingPoint = CGPointZero

// Pin the pinwheel to its parent
pinwheel.physicsBody?.pinned = true
// Optionally set the damping property to slow the wheel over time
pinwheel.physicsBody?.angularDamping = 0.25

声明平移处理方法

func handlePanGesture(recognizer: UIPanGestureRecognizer) 
    if (recognizer.state == UIGestureRecognizerState.Began) 
        var location = recognizer.locationInView(self.view)
        location = self.convertPointFromView(location)
        let dx = location.x - pinwheel.position.x;
        let dy = location.y - pinwheel.position.y;
        // Save vector from node to touch location
        startingPoint = CGPointMake(dx, dy)
    
    else if (recognizer.state == UIGestureRecognizerState.Ended)
    
        var location = recognizer.locationInView(self.view)
        location = self.convertPointFromView(location)

        var dx = location.x - pinwheel.position.x;
        var dy = location.y - pinwheel.position.y;

        // Determine the direction to spin the node
        let direction = sign(startingPoint.x * dy - startingPoint.y * dx);

        dx = recognizer.velocityInView(self.view).x
        dy = recognizer.velocityInView(self.view).y

        // Determine how fast to spin the node. Optionally, scale the speed
        let speed = sqrt(dx*dx + dy*dy) * 0.25

        // Apply angular impulse
        pinwheel.physicsBody?.applyAngularImpulse(speed * direction)
    

【讨论】:

以上是关于如何根据平移手势速度向 Sprite Kit 节点应用角脉冲的主要内容,如果未能解决你的问题,请参考以下文章

Sprite-Kit:节点不会向左移动

iOS 7 Sprite Kit 动画速度变化

Sprite Kit iOS 中的慢动作

sprite kit:如何根据距离改变 skaction 持续时间?

Sprite kit:删除特定节点而不是所有节点

如何确定节点出现在 sprite kit 中的顺序