【问题标题】:What is wrong with my accelerometer code?我的加速度计代码有什么问题?
【发布时间】:2013-06-27 01:17:19
【问题描述】:

我一直在尝试学习 XNA,虽然我无法访问书籍,但我一直依靠 MSDN 和教程来指导我,我现在可以绘制精灵并改变它们的位置并使用 Intersect 和我现在正在尝试为 Windows Phone 7 和 8 手机准备一个基本的加速度计。

我有一些积木和一个球。我希望能够通过向上/向下/向左/向右倾斜手机来移动(或滚动)球。

如果您在下面看到,绿点表示球可以移动的区域。虽然深灰色块只是边界,如果球碰到它们就会反弹(稍后,我不关心这部分)。

我的问题是,如何让球正确响应倾斜运动?

要尝试获得非常基本的倾斜动作,我有:

    protected override void Initialize()
    {
        // TODO: Add your initialization logic here

        Accelerometer accelerometer = new Accelerometer();
        accelerometer.CurrentValueChanged += accelerometer_CurrentValueChanged;
        accelerometer.Start();

        base.Initialize();
    }

    void accelerometer_CurrentValueChanged(object sender, SensorReadingEventArgs<AccelerometerReading> e)
    {

            this.squarePosition.X = (float)e.SensorReading.Acceleration.Z * GraphicsDevice.Viewport.Width + GraphicsDevice.Viewport.Width / 2.0f;

            if (Window.CurrentOrientation == DisplayOrientation.LandscapeLeft)
            {
                this.squarePosition.X = +(float)e.SensorReading.Acceleration.X * GraphicsDevice.Viewport.Width + GraphicsDevice.Viewport.Width / 2;
            }
            else
            {
                this.squarePosition.X = (float)e.SensorReading.Acceleration.X * GraphicsDevice.Viewport.Width + GraphicsDevice.Viewport.Width / 2;
            }
        }

但这绝对令人震惊。非常紧张,就像,物体不断地跳来跳去,好像它正在癫痫发作什么的,我什至不确定这是不是正确的处理方式。

【问题讨论】:

  • 我从来没有为加速度计写过代码,所以我帮不了你太多。不过,有些事情困扰着我:afaik,加速度计检测到速度的变化。因此,您不应在每次加速度计值更改时更新位置:您应该在 XNA Update 方法中根据加速度计的最新值更改位置。这样,如果您倾斜手机然后停止移动,球将继续以平稳的运动移动。或者你可以使用陀螺仪:msdn.microsoft.com/en-us/library/windowsphone/develop/…
  • 另外,您正在为squarePosition.X 分配一个从加速度计的 Z 轴读取的值,然后用从 X 轴读取的值覆盖它。我认为这两个任务之一应该是为squarePosition.Y 而不是

标签: c# .net xna windows-phone accelerometer


【解决方案1】:

您遇到的主要问题是将加速度与位置直接联系起来,而不是使用加速度来影响速度和使用速度来影响球的位置。你已经做到了,球的位置是你倾斜了多少,而不是加速基于你倾斜了多少。

目前,只要加速度计读数发生变化,球的位置就会设置为读数。您需要将球的加速度分配给读数,并通过该加速度定期增加速度,并通过该速度定期增加球的位置。

XNA 可能具有执行此操作的内置方法,但我不知道 XNA,因此我可以向您展示在没有框架/库帮助的情况下我将如何做到这一点:

// (XNA probably has a built-in way to handle acceleration.)
// (Doing it manually like this might be informative, but I doubt it's the best way.)
Vector2 ballPosition; // (when the game starts, set this to where the ball should be)
Vector2 ballVelocity;
Vector2 ballAcceleration;

...

void accelerometer_CurrentValueChanged(object sender, SensorReadingEventArgs<AccelerometerReading> e) {
    var reading = e.SensorReading.Acceleration;
    // (below may need to be -reading.Z, or even another axis)
    ballAcceleration = new Vector2(reading.Z, 0);
}

// (Call this at a consistent rate. I'm sure XNA has a way to do so.)
void AdvanceGameState(TimeSpan period) {
    var t = period.TotalSeconds;
    ballPosition += ballVelocity * t + ballAcceleration * (t*t/2);
    ballVelocity += ballAcceleration * t;

    this.squarePosition = ballPosition;
}

如果您不知道 t*t/2 是从哪里来的,那么您可能想要阅读基础物理学。这将有助于理解如何让球以你想要的方式移动。相关的物理学位称为kinematics (videos)。

【讨论】:

    【解决方案2】:

    您需要对输入进行某种平滑处理以消除这种抖动。

    这里有一个 Micrsoft 博客,其中包含一些相关信息:

    http://blogs.windows.com/windows_phone/b/wpdev/archive/2010/09/08/using-the-accelerometer-on-windows-phone-7.aspx

    特别是查看标题为数据平滑处理

    的部分

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-28
      • 1970-01-01
      相关资源
      最近更新 更多