繁体   English   中英

SpriteKit,使用加速计返回到前景时,Sprite移动非常快

[英]SpriteKit, sprite moves very fast when coming back to foreground using accelerometer

在我的Sprite Kit游戏中,角色通过倾斜iPhone来移动。 我已经使用CMMotionManager完成了此任务。 它像一种魅力。

- (void)processUserMotionForUpdate:(NSTimeInterval)currentTime
{
    CMAccelerometerData *data = self.motionManager.accelerometerData;

    //NSLog(@"data is %2@", data);

    if (fabs(data.acceleration.x) > 0.2)
        {
            [self.player.physicsBody applyForce:CGVectorMake(40 * data.acceleration.x, 0)];
        }
}

谢谢雷·温德利希!

我使用以下代码启动和停止加速度计。

[self.motionManager startAccelerometerUpdates];
[self.motionManager stopAccelerometerUpdates];

那也很好。

我遇到的问题是当应用程序后台运行,然后又回到前台时。 进入后台时,加速度计会停止,而进入前景时,我会重新启动。 但是,如果在应用程序有背景的情况下倾斜iPhone,然后又返回到应用程序,则我的精灵会在整个地方拍摄。 这几乎就像加速度计在后台时将数据保存在缓存中并立即将其全部取出一样!

为了解决这个问题,我尝试使用accelerometerUpdateInterval。 我NSLogged的值,它变成了0.010000。 因此,当应用程序进入后台时,我将其设置为一个很高的数字,希望加速度计可以记录更多数据。

self.motionManager.accelerometerUpdateInterval = 11111;

但这没有用。 如果我倾斜手机,当回到应用程序时,角色仍然会四处射击。 如果我保持稳定,则不会发生。 当应用程序进入前台时,我什至将角色的速度设置为零,但这也不起作用。 有谁知道如何处理这个问题? 提前致谢!!

编辑#1

这就是我的更新方法。

-(void)update:(CFTimeInterval)currentTime
{
    // Called before each frame is rendered
    NSTimeInterval delta = currentTime - self.previousUpdateTime;

    if (delta > 0.02)
    {
        delta = 0.02;
    }

    self.previousUpdateTime = currentTime;
    [self.player update:delta];
}

其中previousUpdateTime是一个NSTimeInterval。

编辑#2

根据Theis的建议,我记录了一个从0开始并在每次调用该方法时递增的数字,然后我还记录了该方法被调用的时间,并在将应用程序背景化并使其前台显示时得到以下结果。

2014-07-12 10:42:34.838 ChargedUp[439:60b] number is 245.000000 at , 33078.175972
2014-07-12 10:42:34.855 ChargedUp[439:60b] number is 246.000000 at , 33078.192806
2014-07-12 10:42:34.871 ChargedUp[439:60b] number is 247.000000 at , 33078.209226

回到背景,回来,我得到

2014-07-12 10:42:42.762 ChargedUp[439:60b] number is 248.000000 at , 33086.082453
2014-07-12 10:42:42.798 ChargedUp[439:60b] number is 249.000000 at , 33086.125970
2014-07-12 10:42:42.803 ChargedUp[439:60b] number is 250.000000 at , 33086.142641
2014-07-12 10:42:42.822 ChargedUp[439:60b] number is 251.000000 at , 33086.159510
2014-07-12 10:42:42.837 ChargedUp[439:60b] number is 252.000000 at , 33086.176046

因此,似乎该方法是定期调用的。 我还记录了当前时间的加速度计值。

2014-07-12 10:50:30.367 ChargedUp[452:60b] data is x 0.288071 y -0.562469 z -0.778046 @ 33553.664755 at , 33553.704597
2014-07-12 10:50:30.382 ChargedUp[452:60b] data is x 0.286469 y -0.550476 z -0.794571 @ 33553.684229 at , 33553.721224
2014-07-12 10:50:30.399 ChargedUp[452:60b] data is x 0.292175 y -0.541321 z -0.808090 @ 33553.703698 at , 33553.737901

回到背景,然后回来,我明白了。

2014-07-12 10:50:41.716 ChargedUp[452:60b] data is x -0.241135 y -0.416245 z -0.877899 @ 33565.009330 at , 33565.036282
2014-07-12 10:50:41.756 ChargedUp[452:60b] data is x -0.253601 y -0.390457 z -0.879852 @ 33565.067755 at , 33565.087821
2014-07-12 10:50:41.765 ChargedUp[452:60b] data is x -0.253601 y -0.390457 z -0.879852 @ 33565.067755 at , 33565.104657
2014-07-12 10:50:41.783 ChargedUp[452:60b] data is x -0.246246 y -0.403030 z -0.869965 @ 33565.087311 at , 33565.121255
2014-07-12 10:50:41.799 ChargedUp[452:60b] data is x -0.250214 y -0.405685 z -0.860123 @ 33565.106754 at , 33565.137892

201

哦,猜猜我不需要多余的currentTime阅读!! 感谢你的帮助。

EDIT#3 [解决方案]

得益于Theis的帮助,我终于得以解决。 我最终记录了来自加速度计的所有数据,发现当它立即进入后台时它并没有停止。 我通过使用通知暂停了我的游戏。

[[NSNotificationCenter defaultCenter] addObserver:自我选择器:@selector(willResignActive)名称:UIApplicationWillResignActiveNotification对象:无];

在willResignActive方法中暂停我的游戏。 但是,我将这些通知放置在保存Sprite Kit场景的视图控制器中。 因此,当应用程序实际执行Resign Active时,加速度计实际需要一些时间才能停止。 实际上,直到我触摸了多任务视图中的另一个窗口为止。 所有这些数据都由加速度计保存,然后在返回时使用。 因此,我只需要将通知放置在场景本身中,现在一切正常。 感谢大家的见解。

我认为将其放到后台,继续播放然后再返回游戏,而不会在最后的读数和返回后的第一个读数之间进行插值,这没有多大意义。从游戏的角度讲,这基本上意味着用户可以无限快地“移动”设备。 也就是说,用户可以将设备向左倾斜,然后将其置于背景中。 在后台将其倾斜并重新打开。 加速度计数据现在有了巨大的跳跃,这意味着巨大的跳跃。 解决该问题的一种方法是让加速度计不设置运动的物理对象的速度,而要设置一个中间变量,该变量会随时间影响速度。

得益于Theis的帮助,我终于得以解决。 我最终记录了来自加速度计的所有数据,发现当它立即进入后台时它并没有停止。 我通过使用通知暂停了我的游戏。

[[NSNotificationCenter defaultCenter] addObserver:自我选择器:@selector(willResignActive)名称:UIApplicationWillResignActiveNotification对象:无];

在willResignActive方法中暂停我的游戏。 但是,我将这些通知放置在保存Sprite Kit场景的视图控制器中。 因此,当应用程序实际执行Resign Active时,加速度计实际需要一些时间才能停止。 实际上,直到我触摸了多任务视图中的另一个窗口为止。 所有这些数据都由加速度计保存,然后在返回时使用。 因此,我只需要将通知放置在场景本身中,现在一切正常。 感谢大家的见解。

暂无
暂无

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

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