Introduction
When asking to drag a SKPhysicsBody around in Spritekit, we may come up with an idea immediately that just set the touch position as the position of the node. However, this simple method has a couple of problems actually.[1]
Problems
While we are dragging the dynmaic body directly, gravity is still generating effect on it and is going to be dragging the body down. This will have the effect of making the body's position flicker noticeably as it's move around.
If you set the body's position directly, it is a possibility that this body will move through wall or through other objects骂维,which may not be what you want.
Better Solution
There is a better solution to drag a SKPhysicsBody around in Spritekit; that is adding a pin joint at the point player touched and jointing with the body; then moving the joint around.
Here is example:
override func touchesBegan(touches: Set<NSObject>,
withEvent event: UIEvent) {
// We only care about one touch at a time
if let touch = touches.first as? UITouch {
// Work out what node got touched
let touchPosition = touch.locationInNode(self)
let touchedNode = self.nodeAtPoint(touchPosition)
// Make sure that we're touching something that _can_ be dragged
if touchedNode == dragNode || touchedNode.physicsBody == nil {
return
}
// Create the invisible drag node, with a small static body
let newDragNode = SKNode()
newDragNode.position = touchPosition
newDragNode.physicsBody =
SKPhysicsBody(rectangleOfSize:CGSize(width: 10,
height: 10))
newDragNode.physicsBody?.dynamic = false
self.addChild(newDragNode)
// Link this new node to the object that got touched
let newDragJoint = SKPhysicsJointPin.jointWithBodyA(
touchedNode.physicsBody,
bodyB:newDragNode.physicsBody,
anchor:touchPosition)
self.physicsWorld.addJoint(newDragJoint)
// Store the reference to the joint and the node
self.dragNode = newDragNode
self.dragJoint = newDragJoint
}
}
override func touchesMoved(touches: Set<NSObject>,
withEvent event: UIEvent) {
if let touch = touches.first as? UITouch {
// When the touch moves, move the static drag node.
// The joint will drag node.
// The joint will drag the connected
// object with it.
let touchPosition = touch.locationInNode(self)
dragNode?.position = touchPosition
}
}
override func touchesEnded(touches: Set<NSObject>,
withEvent event: UIEvent) {
stopDragging()
}
override func touchesCancelled(touches: Set<NSObject>,
withEvent event: UIEvent) {
stopDragging()
}
func stopDragging() {
// Remove the joint and the drag node.
self.physicsWorld.removeJoint(dragJoint!)
dragJoint = nil
dragNode?.removeFromParent()
dragNode = nil
}
-
this article is an summary of a chapter of iOS Swift Game Development Cookbook ?