2016-07-15 15 views
1

私はこの質問を簡略化するように求められています。SpriteKit joint:体に従います

私はSpriteKitの物理的ジョイント(およびおそらく物理的なボディプロパティ)に苦しんでいます。私はすべての単一のサブクラスと多くの構成を試しましたが、何も動作しないか、何か間違っているような継ぎ目があります。

私はスネークゲームを開発しています。ユーザーは一定速度で前進するはずのヘビの頭をコントロールし、ユーザーはそれを時計回りまたは反時計回りに回すことができます。残りのヘビのすべての部分は頭の後ろにあるべきです - 彼らは頭がある時とまったく同じ道を進むべきです。

私はこのゲームでは、ピンのジョイントがアンカーポイントが要素間の中央にあるアンサーであるべきだと思います。

残念ながら、結果は完全ではありません。構造は完全な円を作るべきですが、そうではありません。私はコードを付けています、そして現在の効果を示すgifです。物理的な身体および/または関節の特性が望ましい効果のためにここに適用されるべきであることを私に何か示唆を与えるのに十分な経験があるか?

enter image description here

マイコード:

class GameScene: SKScene { 
    private var elements = [SKNode]() 

    override func didMove(to view: SKView) { 
     physicsWorld.gravity = CGVector(dx: 0, dy: 0) 

     let dummyTurnNode = SKNode() 
     dummyTurnNode.position = CGPoint(x: size.width/2 - 50, y: size.height/2) 
     let dummyTurnBody = SKPhysicsBody(circleOfRadius: 1) 
     dummyTurnBody.isDynamic = false 
     dummyTurnNode.physicsBody = dummyTurnBody 
     addChild(dummyTurnNode) 

     for index in 0..<5 { 
      let element = SKShapeNode(circleOfRadius: 10) 
      let body = SKPhysicsBody(circleOfRadius: 10) 
      body.linearDamping = 0 
      // body.mass = 0 
      element.physicsBody = body 
      element.position = CGPoint(x: size.width/2, y: size.height/2 - 30 * CGFloat(index)) 
      elements.append(element) 
      addChild(element) 

      let label = SKLabelNode(text: "A") 
      label.fontSize = 10 
      label.fontName = "Helvetica-Bold" 
      element.addChild(label) 

      if index == 0 { 
       element.fillColor = UIColor.blue() 

       body.velocity = CGVector(dx: 0, dy: 30) 

       let dummyTurnJoint = SKPhysicsJointPin.joint(withBodyA: dummyTurnBody, bodyB: body, anchor: dummyTurnNode.position) 
       physicsWorld.add(dummyTurnJoint) 
      } else { 
       body.linearDamping = 1 

       element.fillColor = UIColor.red() 
       let previousElement = elements[index - 1] 
       let connectingJoint = SKPhysicsJointPin.joint(withBodyA: previousElement.physicsBody!, bodyB: body, anchor: CGPoint(x: size.width/2, y: size.height/2 - 30 * CGFloat(index) + CGFloat(15))) 
       physicsWorld.add(connectingJoint) 
      } 
     } 
    } 

    override func update(_ currentTime: TimeInterval) { 
     let head = elements.first!.physicsBody! 
     var velocity = head.velocity 
     velocity.normalize() 
     velocity.multiply(30) 
     head.velocity = velocity 
    } 
} 

extension CGVector { 
    var rwLength: CGFloat { 
     let xSq = pow(dx, 2) 
     let ySq = pow(dy, 2) 
     return sqrt(xSq + ySq) 
    } 

    mutating func normalize() { 
     dx /= rwLength 
     dy /= rwLength 
    } 

    mutating func multiply(_ factor: CGFloat) { 
     dx *= factor 
     dy *= factor 
    } 
} 
+0

あなたはどのSwiftバージョンを使用していますか? –

+0

@AlessandroOrnano 3 –

答えて

2

「残りのすべてのヘビの作品が頭に従うべきである - 彼らは頭がいくつかの時間前だったこととまったく同じパスを移動する必要があります。」

物理学のジョイントでは、自分が何をしていても分散が生じる可能性が高いことに注意してください。たとえそれが完璧に近づいたとしても、フードの下で丸め誤差があり、パスが正確ではありません。

すべての尾部が等しい場合は、別の方法を使用することもできますが、これは私が彗星の尾に行ったことです。基本的には、テールオブジェクトの配列があり、フレーム単位の移動では最後のテールオブジェクトが常にヘッドオブジェクトと同じ位置に移動するという考え方です。頭部オブジェクトがより高いz位置を有する場合、尾部はその下に描かれる。

頭の位置(フレームごとのパス)の配列を格納してテールオブジェクトをそのパスに沿ってフレームごとの更新呼び出しで配置することでアプローチを変える必要がある場合は、ヘビ。

以下の私のコード例を参照してください:これらはあなたが頭のオブジェクトである変数

:あなたの頭のinit関数で

var tails = [SKEmitterNode]() 
var tailIndex = 0 

テールオブジェクトインスタンス化:以下

for _ in 0...MAX_TAIL_INDEX 
     { 
      if let remnant = SKEmitterNode(fileNamed: "FireTail.sks") 
      { 
       p.tails.append(remnant) 
      } 
     } 

コールフレームあたり:

func drawTail() 
{ 
    if tails.count > tailIndex 
    { 
     tails[tailIndex].resetSimulation() 
     tails[tailIndex].particleSpeed = velocity()/4 
     tails[tailIndex].emissionAngle = zRotation - CGFloat(M_PI_2) // opposite direction 
     tails[tailIndex].position = position 
     tailIndex = tailIndex < MAX_TAIL_INDEX ? tailIndex + 1 : 0 
    } 
} 

結果のエフェクトは、scene update()関数から呼び出すと実際は滑らかです。

+0

点と頭を回転させて配列を保持し、後でそれを他のノードに適用することは可能ですが、可能な限りゲームフレームワークの利点を多く取りたいと思います。この解はまた、初期位置のためにいくらかの事前計算を必要とする。ところで、私は丸め誤差が厳しいと思う。私はヘビの体が頭に従うことを望み、ほとんど見えない丸め誤差は私には受け入れられる。 –

関連する問題