How can I apply an angular impulse to a Sprite Kit node based on a pan gesture velocity

本秂侑毒 提交于 2019-12-21 06:27:21

问题


What I'm looking to do here is to spin a SKSpriteNode around its anchor point and have its speed and direction match a pan gesture. So if my pan gesture is clockwise around the sprite then then sprite spins clockwise.

The problem I have with my code is that it works great for pans below the sprite from left to right/right to left, but not at all when I try and pan vertically and it makes the sprite spin the wrong way if I pan above the sprite.

Here's what I've got so far -

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)
    }
}

I know the reason it's not spinning with vertical pans in that I'm only getting the x value so I figure I need to combine these somehow.

I have also tried this using applyImpulse:atPoint:, but that results in the whole sprite being swept away.


回答1:


The following steps will rotate a node based on a pan gesture:

  1. Store a vector from the center of the node to the starting location of the pan gesture
  2. Form a vector from the center of the node to the ending location of the pan gesture
  3. Determine the sign of the cross product of the two vectors
  4. Calculate the speed of the pan gesture
  5. Apply angular impulse to the node using the speed and direction

Here's an example of how to do that in 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

Declare pan handler method

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)
    }
}


来源:https://stackoverflow.com/questions/26591500/how-can-i-apply-an-angular-impulse-to-a-sprite-kit-node-based-on-a-pan-gesture-v

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!