Frage

I'm trying to make my first game using Spritekit, so i have a sprite that i need to move around using my accelerometer. Well, no problem doing that; movement are really smooth and responsive, the problem is that when i try to rotate my sprite in order to get it facing its own movement often i got it "shaking" like he has parkinson. (:D)

i did realize that this happens when accelerometer data are too close to 0 on one of x, y axes.

So the question: Is there a fix for my pet parkinson?? :D

Here is some code:

-(void) update:(NSTimeInterval)currentTime{
    static CGPoint oldVelocity;
    //static CGFloat oldAngle;

    if(_lastUpdatedTime) {
        _dt = currentTime - _lastUpdatedTime;
    } else {
        _dt = 0;
    }

    _lastUpdatedTime = currentTime;

    CGFloat updatedAccelX = self.motionManager.accelerometerData.acceleration.y;
    CGFloat updatedAccelY = -self.motionManager.accelerometerData.acceleration.x+sinf(M_PI/4.0);


    CGFloat angle = vectorAngle(CGPointMake(updatedAccelX, updatedAccelY));

    _velocity = cartesianFromPolarCoordinate(MAX_MOVE_PER_SEC, angle);


    if(oldVelocity.x != _velocity.x || oldVelocity.y != _velocity.y){
        _sprite.physicsBody.velocity = CGVectorMake(0, 0);
        [_sprite.physicsBody applyImpulse:CGVectorMake(_velocity.x*_sprite.physicsBody.mass, _velocity.y*_sprite.physicsBody.mass)];

        _sprite.zRotation = vectorAngle(_velocity);
        oldVelocity = _velocity;

    }
}

static inline CGFloat vectorAngle(CGPoint v){
    return atan2f(v.y, v.x);
}

i did try to launch the update of the _velocity vector only when updatedAccelX or updatedAccelY are, in absolute value >= of some values, but the result was that i got the movement not smooth, when changing direction if the value is between 0.1 and 0.2, and the problem wasn't disappearing when the value was under 0.1.

i would like to maintain direction responsive, but i also would like to fix this "shake" of the sprite rotation.

I'm sorry for my bad english, and thanks in advance for any advice.

War es hilfreich?

Lösung

You can try a low pass filter (cf. to isolate effect of gravity) or high pass filter (to isolate effects of user acceleration).

    #define filteringFactor 0.1

    - (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {

        //low pass
        accelerX = (acceleration.x * filteringFactor) + (accelerX * (1.0 - filteringFactor));
        //idem …  accelerY
        //idem … accelerZ 

        //or high pass
        accelerX = acceleration.x - ( (acceleration.x * filteringFactor) + (accelerX * (1.0 - filteringFactor)) );
        //idem …  accelerY
        //idem … accelerZ
    }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top