1

これを実装する方法を尋ねているわけではありません。それは十分に単純な概念です。私が問題を抱えているのはフロートです。これが私のコードです:

Position += mVelocity;

        if (!Keyboard.GetState().IsKeyDown(Keys.Left) && !Keyboard.GetState().IsKeyDown(Keys.Right) && !Keyboard.GetState().IsKeyDown(Keys.Down) && !Keyboard.GetState().IsKeyDown(Keys.Up))
        {
            if (mVelocity.X != 0.0F)
            {
                if (mVelocity.X > 0.0F)
                    mVelocity.X -= mFriction;
                if (mVelocity.X < 0.0F)
                    mVelocity.X += mFriction;
            }
            if (mVelocity.Y != 0.0F)
            {
                if (mVelocity.Y > 0.0F)
                    mVelocity.Y -= mFriction;
                if (mVelocity.Y < 0.0F)
                    mVelocity.Y += mFriction;
            }
        }


        Console.WriteLine(mVelocity.X + ", " + mVelocity.Y);

mFriction は 0.2F です。

問題は、プレイヤーを正の速度 (X または Y) で動かすと、摩擦が正常に機能し、速度が 0.0 に低下することです。しかし、負の速度で彼を動かすと、摩擦が追加され、何らかの理由で 0.0 で停止せず、停止する前に 0.2 まで上昇します。このため、プレーヤーが動いていて、キーを離すと、反対方向にゆっくりとスライドし始めます。どうしてこれなの?どうすれば修正できますか?

さらに、テスト用に次のコードを試しました。

            if (mVelocity.X == 0.2F)
                mVelocity.X = 0.0F;
            if (mVelocity.Y == 0.2F)
                mVelocity.Y = 0.0F;

しかし、コードを追加しなかった場合とまったく同じ結果が得られます。どうやら、0.2F は 0.2F と等しくありません。これは何ですか?

最後に、デバッグ出力では、プレイヤーが積極的に動いて静止している (おそらく停止している) とき、x と y の両方の速度 (私が彼を動かした方法によって異なります) は 2.980232E-08 です。私はこれを理解していません。彼の速度を 1 に設定し、フレームごとに正確に 0.2 を減算すると、なぜ 1.0、0.8、0.6、0.4、0.2、0.0 以外になるのでしょうか? それに続いて、彼が負の動きから静止している場合、x と y の速度 (これも、私が彼を動かす方法によって異なります) は 0.2 です。-1、-0.8、-0.6、-0.4、-0.2、0.0 にならないのはなぜですか? 0.0 から 0.2 を超える代わりに。

これは私にはほとんど意味がありません。誰かが私のためにこれを解決してくれたら、私は感謝します. 代替ソリューションも受け入れられます。さらにコードや説明が必要な場合は、喜んで提供します。

4

2 に答える 2

5

問題は、不正確さのために等値テストが失敗することです。そのため、たとえば、キャラクターは 1 フレーム余分に動き続けます。

浮動小数点数は基本的に不正確であるため、理論的には 2.0f * 5.0f は必ずしも == 10.0f ではありません。9.999999f または 10.000001f の可能性があります。2 つの浮動小数点数が等しいかどうかをテストしないでください: それらが十分に小さい間隔内にあるかどうかをテストします。つまり:

// test approximate equality between f1 and f2
bool areEqual(float f1, float f2) {
    return Math.Abs(f1 - f2) < EqualityThreshold; // where EqualityThreshold is a small constant
}

http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.htmlもお読みください

于 2012-04-19T04:41:00.093 に答える
1

最低速度のしきい値を使用する必要があります。実生活では、動摩擦と静摩擦の両方があります。前者は私たちに反対する力であり、後者は私たちが克服する力であり、あらゆる動きがまったく発生しません。

そこには動摩擦がありますが、静的なものがありません。

あなたの問題は純粋に浮動小数点の精度であることは理解していますが、堅牢な物理を構築している場合は、2 種類の摩擦と、力と運動に関するその他の規則を念頭に置いてください。

于 2012-04-20T04:09:10.517 に答える