2012-02-09 7 views
0

オブジェクトの回転を任意の位置に簡単に(徐々に)移動しようとしています。回転角度は、Virtual Thumbstickクラスによって決定され、-1と1の間のX/Y座標を返します。もしthumbscick上に動きがなければ、私は0を指すように戻っています。スプライトの画像。回転イージングアルゴリズムがXNAで動作しない

私が抱えている問題は、このコードでは、連続回転ではなく約1.5回転(-3 * PIと3 * PIの間)しか許されないということです。サムスティックのX/Y座標でMath.Atan2を使用すると、返される角度は-PIとPIの間で制限されますが、連続回転が可能です。また、オブジェクトを一方向に回転させて親指を離すと、その方向から上に回転します。最短ルートで上に戻るようにしたい。

if (VirtualThumbsticks.LeftThumbstick.Length() > .2f) 
{ 
    double rotateTo = Math.Atan2(VirtualThumbsticks.LeftThumbstick.Y, VirtualThumbsticks.LeftThumbstick.X); 

    if (rotateTo > Rotation + Math.PI) rotateTo -= (Math.PI * 2); 
    if (rotateTo < Rotation - Math.PI) rotateTo += (Math.PI * 2); 

    Rotation += (rotateTo - Rotation) * 0.2; 
} 
else 
{ 
    Rotation += (-1.57079 - Rotation) *0.2; 
} 

私が話しているか知っている任意のフラッシュ/ ActionScriptのゲーム開発者がある場合は、私はC#のにそれを適用することができますようチャイムください。

ありがとうございます、皆さん!

EDIT:

このコードのチャンクはAS3で完璧に動作します。私は、問題を引き起こしている私の種類や型キャストに問題がある場合は疑問に思い始めている

function enterFrameHandler(e:Event):void 
{ 
    var curMouseX = Math.round(-(arrow.x - stage.mouseX));//(stage.stageWidth/2)-(stage.mouseX/2); 
    var curMouseY = Math.round(-(arrow.y - stage.mouseY));//(stage.stageHeight/2)-(stage.mouseY/2); 
    var angleTo:Number = Math.atan2(curMouseX, -curMouseY) * TO_DEGREES; 
    if (angleTo > arrow.rotation+180) angleTo -= 360; 
    if (angleTo < arrow.rotation-180) angleTo += 360; 

    tf_angle.text = angleTo.toString(); 
    tf_mouseX.text = curMouseX.toString(); 
    tf_mouseY.text = curMouseY.toString(); 

    arrow.rotation += (angleTo - arrow.rotation) * 0.2; 
} 

。誰かがアイデアを持っている場合、あなたの入力は非常に高く評価されます。

+0

ここで働いていませんか? – Tigran

+0

@Tigran - 回転は連続していません。どちらの方向に1.5回回転して壁に当たってスナップバックします。また、親指を離すとき、それは来た方向から0(この場合は-1.57097)に戻ります。明確にするために質問を再度お読みください。 – ImKevinJones

答えて

0

問題が解決されています。問題は回転値が「正規化」されていないことにあります。基本的には、回転値がMath.PI * 2を超える場合は0に戻らなければなりません。回転値が0を下回る場合は、Math.PI * 2に戻る必要があります。

このページの最後のコメントは私の問題を解決し、回転は正規化されました。

http://forums.create.msdn.com/forums/t/27527.aspx

マイ結果コード:

if (VirtualThumbsticks.LeftThumbstick.Length() > .2f) 
{ 
    float angleTo = (float)Math.Atan2(VirtualThumbsticks.LeftThumbstick.Y, VirtualThumbsticks.LeftThumbstick.X); 

    if (angleTo > Rotation + Math.PI) angleTo -= (float)(Math.PI * 2); 
    if (angleTo < Rotation - Math.PI) angleTo += (float)(Math.PI * 2); 

    accelerationRotation += (angleTo - Rotation) * (float)0.25; 

} 
else 
{ 
    accelerationRotation += ((float)(Math.PI/2) - Rotation) * (float)0.2; 
} 

Rotation = Wrap(accelerationRotation, 0, (float)Math.PI * 2); 

次のようにラップ機能は次のとおりです。

public static float Wrap(float value, float lower, float upper) 
{ 
    unchecked 
    { 
     if (lower >= upper) 
     { 
      throw new ArithmeticException("rotary bounds out of negative or zero size"); 
     } 

     float distance = upper - lower; 

     float times = (float)Math.Floor((value - lower)/distance); 

     return value - (times * distance); 
    } 
} 
0

これは、XMLを使用してC#で書かれているため、動作スクリプトの並列処理は適用されない可能性がありますが、それは可能です。 Flashでは、123456789度の回転変換を格納する利点はほとんどないため、すべてのフレームの最後に回転が調整されます。変換は回転のモジュロ値にリセットされます。

大きな数字が予想され、モジュロ値を使用して相対位置を計算する代わりに、他の数値と比較して、最短ローテーションを計算すると問題に遭遇する可能性があります。

おそらく、これが問題の原因です。そのちょうど推測。

あなたがそれに精通していない奇妙なことに、モジュロ演算子 - 別名パーセント記号 - "%"はあなたに除算の残りを与えます。これは、グリッドアライメントや回転などのループする数値に役立ちます。

例:

21 % 5 = 1; 
720 % 360 = 0; 
+0

入力していただきありがとうございますが、私はそのロジックを私の問題に適用する方法を理解していません。それは、最短ローテーションを計算しながら問題にぶつかることができると私に伝えています。また、 "C#でXMLを使って書かれている"ということを意味するものではありません。 – ImKevinJones

関連する問題