25

Android 游戏My Paper Plane是如何实现倾斜控制的一个很好的例子,但我一直在努力理解如何做类似的事情。

我有以下使用SensorManager 中的getOrientation()的示例。整件事都在这里的 pastebin上。它只是将方向值打印到文本字段。这是最相关的片段:

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.“旋转”用于滚动/转向:

图 1. 俯仰和横滚

(当然,这是手机在横向模式下的等距视图)

当我沿其长轴前后倾斜手机时 - 由 1 显示。 - 我预计只有 1 个值会发生很大变化,但它们似乎都发生了巨大变化。同样,如果我围绕一条从屏幕出来的假想线旋转手机 - 如图 2 所示。 - 我希望只有滚动值会发生变化,但所有值都会发生很大变化。

问题是当我校准我的游戏时——这意味着记录角度 x、y 和 z 的当前值——我后来不知道如何解释传入的更新角度说“好的,看起来你已经倾斜了手机并且你想向左滚 3 度”。这更像是“好吧,你已经移动了手机,你同时在倾斜和滚动”,即使意图只是滚动。有道理?

有任何想法吗?我尝试使用 remapCoordinateSystem 来查看更改轴是否有任何效果。没有喜悦。我想我错过了一些基本的东西:-(

4

1 回答 1

22

你混合了加速器和磁传感器阵列。代码应该是:

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

查看getRotationMatrix(..)

于 2011-01-02T01:54:13.490 回答