MeV
MeV

Reputation: 3958

accelerometer data not correct, delayed for few seconds

I am creating a very simple game using Swift and SpriteKit and I am moving a ball on the screen using the accelerometer data (acceleration x,y).

I would say the code works fine but I have noticed that sometimes (often right when I open the app) the accelerometer data is not correct and delayed for few seconds.

Why is that happening?

I am using the following code to read the accelerometer data:

if motionManager.accelerometerAvailable == true {
        motionManager.startAccelerometerUpdatesToQueue(NSOperationQueue.currentQueue(), withHandler:{
            data, error in
            self.accX = CGFloat(data.acceleration.x)
            self.accY = CGFloat(data.acceleration.y)
        })
}

And the function update to apply some impulse to the ball:

override func update(currentTime: CFTimeInterval) {
    var impulse = CGVectorMake(accX, accY)
    var obj = childNodeWithName("ball") as SKSpriteNode
    obj.physicsBody?.applyImpulse(impulse)
}

Am i missing something?

Thank you

Upvotes: 0

Views: 247

Answers (2)

MeV
MeV

Reputation: 3958

I have given priority to both functions and the issue seems fixed.

let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
dispatch_async(dispatch_get_global_queue(priority, 0)) {
    // do some task
    dispatch_async(dispatch_get_main_queue()) {
        // code with priority
    }
}

Upvotes: 0

mogelbuster
mogelbuster

Reputation: 1076

With any accelerometer data, it is a good idea to run it through a filter to smooth out any irregular spikes. Here is my favorite:

double filteredAcceleration[3];
memset(filteredAcceleration, 0, sizeof(filteredAcceleration));
CMAccelerometerData *newestAccel = motionManager.accelerometerData;
filteredAcceleration[0] = (filteredAcceleration[0]*(1.0-alpha)) + (newestAccel.acceleration.x*alpha);
filteredAcceleration[1] = (filteredAcceleration[1]*(1.0-alpha)) + (newestAccel.acceleration.y*alpha);
filteredAcceleration[2] = (filteredAcceleration[2]*(1.0-alpha)) + (newestAccel.acceleration.z*alpha);

alpha can be any value from 0 to 1. The closer to 1 the more responsive it will be, the closer to zero the more smooth it will be. My favorite value on the iPhone is 0.2 It is a good compromise for smooth yet responsive for a game like doodle jump, or possibly moving a ball around.

I don't know why the accelerometer data is incorrect/delayed on startup, my guess would be that the hardware has to wake up and calibrate itself, but regardless of the why, if you implement a filter, it will smooth out these irregularities, and they won't be nearly as noticeable.

Upvotes: 1

Related Questions