2

私は XNA を学ぼうとしてきました。本にアクセスすることはできませんが、MSDN とチュートリアルに頼って道を案内してきました。今では、スプライトを描画し、その位置を変更し、Intersect を使用できるようになりました。 Windows Phone 7 および 8 の電話用の基本的な加速度計を取得しようとしています。

私はいくつかのブロックとボールを持っています。そして、電話を上下左右に傾けるだけでボールを動かしたり (または転がしたり) できるようにしたいと考えています。

以下に示すように、緑色の点はボールが移動できる領域を表しています。濃い灰色のブロックは、ボールがそれらに触れると跳ね返る単なる境界ですが (後で、この部分についてはまだ心配していません)。

私の質問は、どうすればボールが傾きの動きに正しく反応するようになるかということです。

私が持っている非常に基本的な傾きの動きを試してみるために:

    protected override void Initialize()
    {
        // TODO: Add your initialization logic here

        Accelerometer accelerometer = new Accelerometer();
        accelerometer.CurrentValueChanged += accelerometer_CurrentValueChanged;
        accelerometer.Start();

        base.Initialize();
    }

    void accelerometer_CurrentValueChanged(object sender, SensorReadingEventArgs<AccelerometerReading> e)
    {

            this.squarePosition.X = (float)e.SensorReading.Acceleration.Z * GraphicsDevice.Viewport.Width + GraphicsDevice.Viewport.Width / 2.0f;

            if (Window.CurrentOrientation == DisplayOrientation.LandscapeLeft)
            {
                this.squarePosition.X = +(float)e.SensorReading.Acceleration.X * GraphicsDevice.Viewport.Width + GraphicsDevice.Viewport.Width / 2;
            }
            else
            {
                this.squarePosition.X = (float)e.SensorReading.Acceleration.X * GraphicsDevice.Viewport.Width + GraphicsDevice.Viewport.Width / 2;
            }
        }

しかし、それは絶対に衝撃的です。オブジェクトが発作か何かを起こしているかのように常に飛び回っているように、非常にぎくしゃくしています。これが正しい方法であるかどうかさえわかりません。

ここに画像の説明を入力

4

2 に答える 2

4

あなたが抱えている主な問題は、加速度を使用して速度に影響を与え、速度を使用してボールの位置に影響を与えるのではなく、加速度を位置に直接リンクすることです。ボールの位置が、傾ける量に基づいて加速するのでなく、傾ける量になるようにしました。

現在、加速度計の読み取り値が変化するたびに、ボールの位置が読み取り値に設定されます。ボールの加速度を読み取り値に割り当て、その加速度によって定期的に速度を上げ、その速度によってボールの位置を定期的に上げる必要があります。

XNAにはおそらくこれを行うための組み込みの方法がありますが、私はXNAを知らないので、フレームワーク/ライブラリの助けなしにどのように行うかを示すことができます:

// (XNA probably has a built-in way to handle acceleration.)
// (Doing it manually like this might be informative, but I doubt it's the best way.)
Vector2 ballPosition; // (when the game starts, set this to where the ball should be)
Vector2 ballVelocity;
Vector2 ballAcceleration;

...

void accelerometer_CurrentValueChanged(object sender, SensorReadingEventArgs<AccelerometerReading> e) {
    var reading = e.SensorReading.Acceleration;
    // (below may need to be -reading.Z, or even another axis)
    ballAcceleration = new Vector2(reading.Z, 0);
}

// (Call this at a consistent rate. I'm sure XNA has a way to do so.)
void AdvanceGameState(TimeSpan period) {
    var t = period.TotalSeconds;
    ballPosition += ballVelocity * t + ballAcceleration * (t*t/2);
    ballVelocity += ballAcceleration * t;

    this.squarePosition = ballPosition;
}

その t*t/2 がどこから来たのかわからない場合は、おそらく基本的な物理学を読みたいと思うでしょう。そのボールを思い通りに動かす方法を理解するのに大いに役立ちます。関連する物理学はキネマティクス(ビデオ) と呼ばれます。

于 2013-06-26T17:06:25.027 に答える
1

この種のジッターを除去するには、入力に対して何らかの平滑化を行う必要があります。

これに関する情報が記載された Micrsoft ブログがあります。

http://blogs.windows.com/windows_phone/b/wpdev/archive/2010/09/08/using-the-accelerometer-on-windows-phone-7.aspx

特に、A Look at Data Smoothingというタイトルのセクションを見てください。

于 2013-06-26T16:57:12.217 に答える