web-dev-qa-db-ja.com

「My Paper Plane」などの傾斜コントロールにSensorManager.getOrientationを使用するにはどうすればよいですか?

Androidゲーム マイペーパープレーン は、チルトコントロールを実装する方法の良い例ですが、同様のことを行う方法を理解するのに苦労してきました。

次の例では、SensorManagerの getOrientation() を使用しています。全体は Pastebin here にあります。テキストフィールドに向きの値を出力するだけです。最も関連性の高いスニペットは次のとおりです。

private void computeOrientation() {
    if (SensorManager.getRotationMatrix(m_rotationMatrix, null,
                                        m_lastMagFields, m_lastAccels)) {
        SensorManager.getOrientation(m_rotationMatrix, m_orientation);

        /* 1 radian = 57.2957795 degrees */
        /* [0] : yaw, rotation around z axis
         * [1] : pitch, rotation around x axis
         * [2] : roll, rotation around y axis */
        float yaw = m_orientation[0] * 57.2957795f;
        float pitch = m_orientation[1] * 57.2957795f;
        float roll = m_orientation[2] * 57.2957795f;

        /* append returns an average of the last 10 values */
        m_lastYaw = m_filters[0].append(yaw);
        m_lastPitch = m_filters[1].append(pitch);
        m_lastRoll = m_filters[2].append(roll);
        TextView rt = (TextView) findViewById(R.id.roll);
        TextView pt = (TextView) findViewById(R.id.pitch);
        TextView yt = (TextView) findViewById(R.id.yaw);
        yt.setText("azi z: " + m_lastYaw);
        pt.setText("pitch x: " + m_lastPitch);
        rt.setText("roll y: " + m_lastRoll);
    }
}

問題は、これが吐き出す値が意味をなさないように見えるか、少なくともユーザーが実行したモーションのタイプを分離する方法がないことです。検出したい2種類のモーションを示す図を描画しました-1.ピッチの「傾斜」と2.ロール/ステアリングの「回転」:

Figure 1. Pitch and roll

(これはもちろん、横長モードの電話の等角のようなビューです)

1で示すように、電話をその長軸に沿って前後に傾けると、値が1つだけ大きく変化すると予想しましたが、すべてが大幅に変化しているようです。同様に、画面から出てくる想像上の線を中心に電話を回転させると(図2を参照)、ロール値のみが変化し、すべての値が大きく変化することを期待しています。

問題は、ゲームを調整するときです-つまり、角度x、y、zの現在の値を記録します-後で、入ってくる更新された角度を解釈して、「わかりました。電話を傾けたようです。左に3度回転したい。」それは、意図が転がりだけであったとしても、「OK、あなたは電話を動かし、そしてあなたは同時にチルティンであり、ローリングである」に似ています。理にかなっていますか?

何か案は? remapCoordinateSystemを使用して、軸を変更しても効果があるかどうかを確認しました。喜びがない。私はこれで基本的な何かが欠けていると思います:-(

24
richq

アクセラレータと磁気センサーアレイを混在させました。コードは次のようになります。

if (SensorManager.getRotationMatrix(m_rotationMatrix, null,
                                    m_lastAccels, m_lastMagFields)) {

チェックアウト getRotationMatrix(..)

22
Peter Knego