简体   繁体   English

我的加速度计代码有什么问题?

[英]What is wrong with my accelerometer code?

I have been trying to learn XNA, and while I don't have access to books I've been relying on MSDN and tutorials to guide me along the way and I can now draw sprites and change their position and use Intersect and I am now trying to get a basic Accelerometer going for Windows Phone 7 and 8 phones. 我一直在尝试学习XNA,虽然我无法访问书籍,但我一直依靠MSDN和教程来指导我前进的道路,现在我可以绘制精灵并更改其位置并使用“相交”,我现在试图获得适用于Windows Phone 7和8手机的基本加速度计。

I have some blocks and a ball. 我有一些积木和一个球。 And I want to be able to move the ball (or roll it) by just tilting the phone up/down/left/right. 而且我希望能够仅通过向上/向下/向左/向右倾斜手机来移动球(或滚动球)。

If you see below, the green dots represent areas where the ball can move. 如果您在下面看到,绿点代表球可以移动的区域。 While the dark grey blocks are just boundaries where if the ball touches them it will bounce off of them (at a later time, I'm not concerned about this part yet). 虽然深灰色块只是边界,如果球触碰到它们,它将从它们上反弹(稍后,我还不关心这部分)。

My question is, how do I get the ball to respond correctly to tilt movements? 我的问题是,如何使球正确响应倾斜运动?

To try and get very basic tilt movements I have: 为了获得非常基本的倾斜运动,我有:

    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;
            }
        }

But it's absolutely shocking. 但这绝对令人震惊。 It's very jittery, like, the object is constantly jumping around like it's having a seizure or something, and I am not even sure it this is the correct way to go about this. 这非常令人不安,例如,物体不断发作,就像有癫痫发作一样,我什至不确定这是否是正确的解决方法。

在此处输入图片说明

The main issue you have is directly linking acceleration to position, instead of using the acceleration to affect a velocity and the velocity to affect the ball's position. 您遇到的主要问题是直接将加速度链接到位置,而不是使用加速度影响速度和使用速度影响球的位置。 You've made it so the position of the ball is how much you tilt, instead of accelerating based on how much you tilt. 您已经做到了,所以球的位置就是倾斜的角度,而不是根据倾斜的角度来加速

Currently, whenever the accelerometer reading changes, the ball's position is set to the reading. 当前,只要加速度计的读数发生变化,球的位置就会设置为该读数。 You need to assign the ball's acceleration to the reading, and periodically increase a velocity by that acceleration and also periodically increase the ball's position by that velocity. 您需要将球的加速度分配给读数,并以该加速度周期性地增加速度,并以该速度周期性地增加球的位置。

XNA probably has a built-in way to do this, but I don't know XNA so I can just show you how I would do it without help from a framework/library: 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;
}

If you have no idea where that t*t/2 came from, then you will probably want to read up on basic physics. 如果您不知道t * t / 2的来源,那么您可能会想读一读基础物理学。 It will help a lot with understanding how to make that ball move the way you want. 这将有助于您理解如何使该球以您想要的方式运动。 The relevant bit of physics is called kinematics ( videos ). 物理的相关部分称为运动学视频 )。

You will need to do some kind of smoothing on the input to remove this kind of jitter. 您将需要对输入进行某种平滑处理以消除这种抖动。

There's a Micrsoft Blog with some information about it here: 这里有一个Micrsoft博客,其中包含一些相关信息:

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

In particular, look at the section entitled A Look at Data Smoothing 特别是,请参阅标题为“数据平滑处理”的部分。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM