2016-10-30 7 views
0

Swift3を使用した場合、zRotationの値は、//+ piより小さいか大きくなります(たとえば、約0.5Piのラジアンで7.41137313842773)。これは、以下で説明するアプローチを使用してノードを回転させるときに発生します。誰かが2 Pi以上のzRotationを経験していますか?

コード

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { 
    for touch in touches { 
     newLocation = touch.location(in: self) 
     turnAngle = atan2(newLocation.y - lastLocation.y - mySprite.position.y, newLocation.x - lastLocation.x - mySprite.position.x) 
     mySprite.run(SKAction.rotate(byAngle: turnAngle, duration: 0.1)) 
     lastLocation = newLocation 
     print("mySprite zRotation: \(mySprite.zRotation)") 
    } 
} 

あるIはまた、スプライトのPI/2(絶対)まで回転した時点でスプライトにおけるジッタジャンプに気づきます。これが正常な動作であれば、 -/+ Piまたは0-2Piの間でzRotationを再計算する方法はありますか?

+1

このアクションの実行は多く呼び出され、予期しない結果をもたらす可能性のある移動アクションを積み重ねるので、これはお勧めしません。 zRotationを「手動で」設定するほうが簡単です。頻繁に呼び出される 'touchesMoved'は、回転を円滑にします。 再計算すると、角度を -/+ Piまたは0-2Piの間の等価に変換する関数を意味しますか? –

答えて

1

あなたのコードには、分析する2点があります: SKActionzRotationと思います。


最初のもの()は、一般的に(この問題については)考慮する必要があります。サイクル内で '回転'のようなSKActionを起動する場合は、継続時間があるため、別の起動前にこの操作が完了しているかどうかを確認する必要があります。例:あなたがアクションを使用しているため、誤ったzRotation値が持っている理由zRotationについて、あなたの問題と言えば

extension SKNode 
{ 
    func actionForKeyIsRunning(key: String) -> Bool { 
     return self.action(forKey: key) != nil ? true : false 
    } 
} 

if !self.mySprite.actionForKeyIsRunning(key: "rotation") { 
    self.mySprite.run(SKAction.rotate(byAngle: turnAngle, duration: 0.1),withKey:"rotation") 
} 

。 zRotationはノードプロパティです。アニメーションを実行するノードのプロパティはシミュレーションの各ステップで更新されません。

self.mySprite.zRotation = turnAngle 

または物理体を作成し、角速度を設定する:あなたは、あなたのノードを回転させるzRotationを設定することができます。あなたがアクション

を使用してはならないときにアクションが効率的ですが、コストには

があります:このノートがある場合SKActionとノードのプロパティの詳細については

official Apple docを見ますそれを実行して を実行します。 アニメーションのフレームごとにノードのプロパティを変更し、それらの変更を各フレームの に再計算する必要がある場合は、ノードを直接変更して、 のアクションを使用しないでください。 があなたのゲームでこれを行う可能性がある場所の詳細については、Advanced Scene Processingを参照してください。

+0

こんにちは皆、あなたの素晴らしいフィードバックに感謝します。私は、フレームごとにupdate()を使用するアプローチを変更し、touchesEnded()を使用して、最終結果が「クリーンアップ」され、シーン内で変更が行われることを確認しました。私は+/-ピクチャよりも大きいzRotationの値が(処理能力をオーバーロードしていても)何が行われても起こらないと思う。つまり、私はAppleからの文書化された制限を見つけることができませんでした。私はモジュラスを計算し、2piで割ることによって問題を回避します。これは条件の数を倍増させ(0〜2piの負と正)、問題なく動作します。私はもう少し研究をするつもりです。 –

+0

なぜそれは起こらないのですか? 4 PIは有効な角度であり、2回転を意味し、この値を使用する有効な理由があります – Knight0fDragon

1

@PietroPepeが指摘しているように、アクションを1つずつ積み重ねています。

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { 
    for touch in touches { 

これは、あなたのタッチのライフサイクルを通して複数回タッチが行われることを示しています。クイックタッチの上下操作でも、この方法で少なくとも2回の呼び出しを行うことは非常に可能です。コードの現在の位置に

newLocation = touch.location(in: self) 
    turnAngle = atan2(newLocation.y - lastLocation.y - mySprite.position.y, newLocation.x - lastLocation.x - mySprite.position.x) 

このコードのポイントは、最後の位置からタッチの変更でスプライトの動きを持つことである

mySprite.run(SKAction.rotate(byAngle: turnAngle, duration: 0.1)) 
    lastLocation = newLocation 
    print("mySprite zRotation: \(mySprite.zRotation)") 
} 

}

最後に、この時点で行う語ります1/10秒で表示されます。

ここでシナリオを実行しましょう。画面に触れて移動して放します。

実行に要した時間は4フレームで、これは1タッチベーガン、2タッチモーフィング、1タッチアンドドンを意味します。

私たちのtoucheMovedイベントでは、毎回60度の変化を計算します。

フレームは1/60秒ということに留意してください。

私たちの回転イベントは、0/60から6/60秒、6フレームになるように1/10th秒かかるでしょう。

これは、すべてのフレームが10度移動していることを意味します。

ここでrotateByの2番目のフレームに移動します。

上記の最初のフレームと同じロジックが適用されるため、10度移動する別の一連の回転が適用されます。

これは、スプライトを6度ずつ回転させる2つのイベントを持つことを意味します。

続くようにタイムラインがある:

フレーム:0 1 2 3 4 5 6 7 +10 +10 +10 +10 +10 +10 +10 +10 +10 +10 +10 + 10

ローテーションの終了と開始の間に一貫性のない動作があることに注目してください。これは物事がすべてぎこちないように見える理由です。

ここでは、あなたが探している効果がわかりませんが、これを行う場合は、アクションを使用する代わりにzRotationを設定します。

あなたが遅延効果を探しているなら、あなたが唯一の実行中の1つのアクションを持つようにrun機能にwithKeyパラメータを使用して、スプライトは常に最後の可能なタッチ位置に回転持つようにSKAction.rotateToを使用しています。これは、タッチが最初に開始されたときを、最後にタッチしたときではなく、追跡する必要があることを意味します。あなたはduration:.01 - timeSinceTouchBeganので基本的に、と呼ばれるtouchesMovedイベントの数の間の経過時間を追跡し、あなたの持続時間に時間差を適用する必要があるかもしれないので、これはまた、所望の効果に応じて、少しトリッキー取得