2015-08-15 100 views
1

使用Swift和Sprite-Kit,我试图在静态SKSpriteNode的位置(称为“pin”)和用户触摸屏幕的任何位置之间创建一条具有真实物理效果的绳索。我通过添加称为ropeNodes的单个SKSpriteNodes并将它们连接到一系列SKPhysicsJointPins来完成此操作。物理效果很好,但是当我尝试旋转每个单独的部分以使它们正确定向时,ropeNodes不再形成直线,也不会旋转到正确的角度。然而,当我删除SKPhysicsJoints时,旋转对每个单独的节点按预期工作。围绕每个ropeNode的anchorPoint移动,似乎只会让事情变得更糟。为什么会发生这种情况,我该如何解决它?在此先感谢(:SKPhysicsJoint使旋转不能正常工作

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) { 
    /* Called when a touch begins */ 

    for touch in (touches as! Set<UITouch>) { 
     let location = touch.locationInNode(self) 
     dx = pin.position.x - location.x 
     dy = pin.position.y - location.y 
     let length = sqrt(pow(dx!, 2) + pow(dy!, 2)) 
     let distanceBetweenRopeNodes = 40 
     let numberOfPieces = Int(length)/distanceBetweenRopeNodes 
     var ropeNodes = [SKSpriteNode]() 

     //adds the pieces to the array and the scene at respective locations 
     for var index = 0; index < numberOfPieces; ++index{ 
      let point = CGPoint(x: pin.position.x + CGFloat((index) * distanceBetweenRopeNodes) * sin(atan2(dy!, -dx!) + 1.5707), y: pin.position.y + CGFloat((index) * distanceBetweenRopeNodes) * cos(atan2(dy!, -dx!) + 1.5707)) 
      let piece = createRopeNode(point) 
      piece.runAction(SKAction.rotateByAngle(atan2(-dx!, dy!), duration: 0)) 
      ropeNodes.append(piece) 
      self.addChild(ropeNodes[index]) 
     } 

     //Adds an SKPhysicsJointPin between each pair of ropeNodes 
     self.physicsWorld.addJoint(SKPhysicsJointPin.jointWithBodyA(ropeNodes[0].physicsBody, bodyB: pin.physicsBody, anchor: 
      CGPoint(x: (ropeNodes[0].position.x + pin.position.x)/2, y: (ropeNodes[0].position.y + pin.position.y)/2))) 
     for var i = 1; i < ropeNodes.count; ++i{ 
      let nodeA = ropeNodes[i - 1] 
      let nodeB = ropeNodes[i] 
      let middlePoint = CGPoint(x: (nodeA.position.x + nodeB.position.x)/2, y: (nodeA.position.y + nodeB.position.y)/2) 
      let joint = SKPhysicsJointPin.jointWithBodyA(nodeA.physicsBody, bodyB: nodeB.physicsBody, anchor: middlePoint) 
      self.physicsWorld.addJoint(joint) 
     } 
    } 
} 

func createRopeNode(location: CGPoint) -> SKSpriteNode{ 
    let ropeNode = SKSpriteNode(imageNamed: "RopeTexture") 
    ropeNode.physicsBody = SKPhysicsBody(rectangleOfSize: ropeNode.size) 
    ropeNode.physicsBody?.affectedByGravity = false 
    ropeNode.physicsBody?.collisionBitMask = 0 
    ropeNode.position = location 
    ropeNode.name = "RopePiece" 
    return ropeNode 
} 

这是发生了什么图像,当我尝试旋转每个单独的ropeNode

enter image description here

+0

迭代他们可能需要一个“演示”节点添加到每个绳段。 _presentation_节点是另一个节点的可视化表示,您可以更改(例如,旋转)而不影响实际节点的物理属性。 – 0x141E

+0

因此,基本上添加没有physicsBody的节点,只有纹理来替代现有的ropeNodes? – Lahav

+0

是的,并将它们的位置设置为与'didSimulatePhysics'中的绳索段相同,并使绳索节点与主体不可见。 – 0x141E

回答

0

经过一番思考,我认为加上演示节点作为孩子是更好的想法,因为你不需要跟踪单独数组中的额外节点。要设置子节点的旋转,只需展开父节点的旋转,然后添加新的旋转角度:

node.zRotation = -node.parent!.zRotation + newRotation 

如果绳段是在容器SKNode,您可以通过

for rope in ropes.children { 
    if let node = rope.children.first { 
     let newRotation = ... 
     node.zRotation = -rope.zRotation + newRotation 
    } 
} 
+0

我基本上做了你所做的。我刚刚添加了'let text = SKSpriteNode(imageNamed:“RopeTexture”) text.runAction(SKAction.rotateByAngle(atan2(-dx !, dy!),duration:0)) ropeNode.addChild(text)'to createRopeNode () 方法 – Lahav