问题
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:
- Store a vector from the center of the node to the starting location of the pan gesture
- Form a vector from the center of the node to the ending location of the pan gesture
- Determine the sign of the cross product of the two vectors
- Calculate the speed of the pan gesture
- 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