2

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

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

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

感谢您的帮助,我尽我所能解释,我确实尝试过寻找解决方案,但我什至不知道我正在寻找的正确术语是什么。

4

2 回答 2

1

一个老问题,但我在这里提供答案,因为我在任何地方都找不到适用于 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]
        ...
    }
    
于 2014-03-06T13:27:33.917 回答
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(...)-Piand范围内Pi

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

于 2012-03-14T22:19:15.057 回答