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

时间:2012-03-14 15:58:39

标签: android accelerometer libgdx calibration

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

问题在于(0,0)不是很舒服,所以我们的想法是校准它,以便在特定时间点将0,0设置为手机位置。

这让我想到了我的问题,我该怎么做?我试着只读取当前的X和Y值然后减去它。问题在于,当手机保持90度角时,X偏移值为10(这是最大值),因此最终无法移动,因为该值永远不会超过10({{1 }})。 Z轴必须以某种方式在这里发挥作用,我只是不确定如何。

感谢您的帮助,我尝试尽可能地解释,我确实尝试寻找解决方案,但我甚至不知道对于我正在寻找的东西是什么。

2 个答案:

答案 0 :(得分:0)

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

Gdx.input.getAzimuth(), Gdx.input.getPitch(), Gdx.input.getRoll()

缺点是,与北/南/东/西相比,那些以某种方式使用内部指南针为​​您的设备提供旋转。我很快就做了测试,所以我不是100%肯定。可能值得一看。

更复杂的方法涉及一些三角函数,基本上你必须从Gdx.input.getAccelerometerX/Y/Z()计算手机的角度。必须是这样的(沿着手机的长边旋转):

Math.atan(Gdx.input.getAccelerometerX() / Gdx.input.getAccelerometerZ());

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

希望这会让你以某种方式开始。您也可以搜索“Accelerometer to pitch / roll / rotation”等等。

答案 1 :(得分:0)

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

您可以分三个部分来完成:

  1. 捕获表示中性方向的矢量:

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

    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();
    }
    
  3. 每当您需要来自加速度计的输入时,首先通过旋转矩阵运行它们:

    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]
        ...
    }