2

在我的 2d 游戏中,我有以下代码负责游戏实体控制(飞行飞机)。就手机而言,一切似乎都运行良好,但不幸的是,我得到了一些信息,在 Android 平板电脑上,转向完全不可靠(轴被弄乱了,或者根本不工作)。不幸的是,我没有自己的平板电脑,所以我无法更仔细地研究它。那么..以下代码有什么问题?(为了清楚起见,我只放了与传感器相关的代码)

// ...
private float[] accelerometerValues;
private float[] magneticFieldValues;
private float[] R;
private float[] I;
private float[] outR;
private float[] sensorValues;

private Sensor accelerometer;
private Sensor magneticField;
// ...

// ... sensor initialization
    sensorManager = (SensorManager)activity.getSystemService(Context.SENSOR_SERVICE);
    if(sensorManager == null)
        return;
    accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 
    magneticField = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
// ...

// ... onPause() sensor is being unregistered
public void onResume() {
    if(!sensorManager.registerListener(sensorListener, accelerometer, SensorManager.SENSOR_DELAY_GAME) ||
       !sensorManager.registerListener(sensorListener, magneticField, SensorManager.SENSOR_DELAY_GAME))
// ...

    // ...
    sensorListener = new SensorEventListener() {
        public void onAccuracyChanged(Sensor arg0, int arg1) {              
        }
        public void onSensorChanged(android.hardware.SensorEvent event) {
            synchronized(InputMgr.this) {
                switch(event.sensor.getType()) {
                case Sensor.TYPE_ACCELEROMETER:
                    System.arraycopy(event.values, 0, accelerometerValues, 0, 3);
                    break;
                case Sensor.TYPE_MAGNETIC_FIELD:
                    System.arraycopy(event.values, 0, magneticFieldValues, 0, 3);
                    break;
                }
            }
        }
    };  
    // ...  

    // used somewhere in the game
public void getSensorValues(float values[]) {
    synchronized(InputMgr.this) {
        SensorManager.getRotationMatrix(R, I, accelerometerValues, magneticFieldValues);
        SensorManager.remapCoordinateSystem(R, SensorManager.AXIS_Y, SensorManager.AXIS_X, outR);
        SensorManager.getOrientation(outR, sensorValues);
        System.arraycopy(sensorValues, 0, values, 0, sensorValues.length);
    }
}
4

2 回答 2

3

这不会让你振作起来,但我有一个类似的问题。我可以看到一个 TYPE_MAGNETIC_FIELD 传感器,我可以向它添加一个事件侦听器,但我从未从中获取任何数据。其他传感器工作正常。这是在 Galaxy Tab 7 上。

onSensorChanged(SensorEvent event) 从不触发案例 Sensor.TYPE_MAGNETIC_FIELD:

因此,我没有从磁场传感器获得数据。

如果你解决了,请告诉我们 =)

于 2012-10-31T05:17:14.863 回答
2

在默认方向为横向(-> 大多数平板电脑)的设备上,传感器值有点“错误”(我不知道为什么)。所以你需要抓住这些设备并重新映射你的旋转矩阵。

要检查矩阵是否需要重新映射,可以使用以下代码:

public boolean needToRemapOrientationMatrix;

// compute once (e.g. in onCreate() of your Activity):
Display display = ((WindowManager)getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int orientation;
if(display.getWidth() < display.getHeight()) orientation = Configuration.ORIENTATION_PORTRAIT;
else if(display.getWidth() > display.getHeight()) orientation = Configuration.ORIENTATION_LANDSCAPE;
else orientation = Configuration.ORIENTATION_SQUARE;
int rotation = display.getRotation();
needToRemapOrientationMatrix =
    (orientation==Configuration.ORIENTATION_LANDSCAPE && (rotation==Surface.ROTATION_0 || rotation==Surface.ROTATION_180)) ||
    (orientation==Configuration.ORIENTATION_PORTRAIT && (rotation==Surface.ROTATION_90 || rotation==Surface.ROTATION_270));

当您读取传感器值时,如果需要,重新映射矩阵:

public void getSensorValues(float values[]) {
    synchronized(InputMgr.this) {
        SensorManager.getRotationMatrix(R, I, accelerometerValues, magneticFieldValues);

        if(needToRemapOrientationMatrix)
            SensorManager.remapCoordinateSystem(R, SensorManager.AXIS_MINUS_Y, SensorManager.AXIS_X, R);

        SensorManager.remapCoordinateSystem(R, SensorManager.AXIS_Y, SensorManager.AXIS_X, outR);
        SensorManager.getOrientation(outR, sensorValues);
        System.arraycopy(sensorValues, 0, values, 0, sensorValues.length);
    }
}

这对我有用,我希望它有所帮助。

于 2012-07-02T15:10:43.373 回答