Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/180.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 为2d游戏校准3d加速度计_Android_Accelerometer_Libgdx_Calibration - Fatal编程技术网

Android 为2d游戏校准3d加速度计

Android 为2d游戏校准3d加速度计,android,accelerometer,libgdx,calibration,Android,Accelerometer,Libgdx,Calibration,我正在做一个2d游戏。手机水平放置,角色上下左右移动以避开障碍物。该字符由手机上的加速计控制。如果玩家不介意手机完全平放时(0,0)(角色静止的点),一切都正常。在这种情况下,可以直接读取Y和X值并使用它们来控制角色。加速计值介于-10和10之间(它们乘以加速度常数以确定角色的移动速度),libgdx是使用的框架 问题是使用(0,0)不是很舒服,所以我们的想法是对其进行校准,以便在特定时间点将0,0设置为手机的位置 这就引出了我的问题,我该怎么做?我试着只读取当前的X和Y值,然后减去它。问题是,

我正在做一个2d游戏。手机水平放置,角色上下左右移动以避开障碍物。该字符由手机上的加速计控制。如果玩家不介意手机完全平放时
(0,0)
(角色静止的点),一切都正常。在这种情况下,可以直接读取Y和X值并使用它们来控制角色。加速计值介于-10和10之间(它们乘以加速度常数以确定角色的移动速度),
libgdx
是使用的框架

问题是使用
(0,0)
不是很舒服,所以我们的想法是对其进行校准,以便在特定时间点将0,0设置为手机的位置

这就引出了我的问题,我该怎么做?我试着只读取当前的X和Y值,然后减去它。问题是,当手机保持90度角时,X偏移值为10(最大值),因此无法移动,因为该值永远不会超过10(
10-10=0
)。Z轴必须在这里发挥作用,我只是不知道如何


感谢您的帮助,我尽可能地解释,我确实尝试过搜索解决方案,但我甚至不知道我要寻找的是什么合适的术语。

对于简单的解决方案,您可以查看以下方法:

Gdx.input.getAzimuth(), Gdx.input.getPitch(), Gdx.input.getRoll()
不利的一面是,与北/南/东/西相比,它们以某种方式使用内部指南针为您的设备提供旋转。我只测试了很短的时间,所以我不是100%确定。也许值得一看

更复杂的方法涉及一些三角学,基本上,您必须从
Gdx.input.getAccelerometrx/Y/Z()
计算手机保持的角度。必须类似(用于沿手机较长一侧旋转):

对于这两种方法,然后存储初始角度,然后再减去它。但是你必须注意范围,我认为
Math.atan(…)
-Pi
Pi
之内


希望这能让你开始。你也可以搜索“加速计俯仰/滚动/旋转”和类似的问题。

这是一个老问题,但我在这里提供答案,因为我在任何地方都找不到Android或LibGDX的好答案。下面的代码基于某人发布的iOS解决方案(对不起,我丢失了参考资料)

您可以通过三个部分完成此操作:

  • 捕获表示中性方向的向量:

    Vector3 tiltCalibration = new Vector3( 
                 Gdx.input.getAccelerometerX(), 
                 Gdx.input.getAccelerometerY(), 
                 Gdx.input.getAccelerometerZ() );
    
  • 将此向量转换为旋转矩阵:

    public void initTiltControls( Vector3 tiltCalibration ) {
        Vector3.tmp.set( 0, 0, 1 );
        Vector3.tmp2.set( tiltCalibration ).nor();
        Quaternion rotateQuaternion = new Quaternion().setFromCross( Vector3.tmp, Vector3.tmp2 );
    
        Matrix4 m = new Matrix4( Vector3.Zero, rotateQuaternion, new Vector3( 1f, 1f, 1f ) );
        this.calibrationMatrix = m.inv();
    }
    
    public void handleAccelerometerInputs( float x, float y, float z ) {
    
        Vector3.tmp.set( x, y, z );
        Vector3.tmp.mul( this.calibrationMatrix );
    
        x = Vector3.tmp.x;
        y = Vector3.tmp.y;
        z = Vector3.tmp.z;
    
        [use x, y and z here]
        ...
    }
    
  • 无论何时需要来自加速计的输入,首先通过旋转矩阵运行它们:

    public void initTiltControls( Vector3 tiltCalibration ) {
        Vector3.tmp.set( 0, 0, 1 );
        Vector3.tmp2.set( tiltCalibration ).nor();
        Quaternion rotateQuaternion = new Quaternion().setFromCross( Vector3.tmp, Vector3.tmp2 );
    
        Matrix4 m = new Matrix4( Vector3.Zero, rotateQuaternion, new Vector3( 1f, 1f, 1f ) );
        this.calibrationMatrix = m.inv();
    }
    
    public void handleAccelerometerInputs( float x, float y, float z ) {
    
        Vector3.tmp.set( x, y, z );
        Vector3.tmp.mul( this.calibrationMatrix );
    
        x = Vector3.tmp.x;
        y = Vector3.tmp.y;
        z = Vector3.tmp.z;
    
        [use x, y and z here]
        ...
    }