2015-08-15 2 views
1

Используя Swift и Sprite-Kit, я пытаюсь создать веревку с реалистичной физикой между местоположением статического SKSpriteNode под названием «pin» и везде, где пользователь коснется экрана. Я делаю это, добавляя отдельные SKSpriteNodes, называемые ropeNodes, и связывая их с серией SKPhysicsJointPins. Физика работает очень хорошо, однако, когда я пытаюсь повернуть каждую отдельную деталь так, чтобы они были ориентированы правильно, ropeNodes больше не образуют прямую линию и не поворачиваются на правильный угол. Однако, когда я удаляю SKPhysicsJoints, вращение работает как предназначено для каждого отдельного Узла. Движение вокруг anchorPoint для каждого отдельного ropeNode только, казалось, еще больше перепутало ситуацию. Почему это происходит, и как я могу его исправить? Заранее спасибо (: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

Итак, в основном добавьте узлы без физического объекта и только текстуру вместо существующих 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!), Продолжительность: 0)) ropeNode.addChild (текст)' to my createRopeNode() – Lahav