SpriteKit,sprite在使用加速度计返回前景时移动得非常快

时间:2014-07-10 22:51:40

标签: ios iphone objective-c 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)];
        }
}

感谢Ray Wenderlich!

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

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

这也很好用。

我遇到的问题是当应用程序变为背景然后再回到前台时。当前往后台时我有加速度计停止并且当它到达前景时开始备份。但是,如果我在应用程序背景的同时倾斜iPhone,然后回到应用程序,我的精灵就会在整个地方拍摄。这几乎就像加速度计在后台运行时保存在缓存中的数据并立即全部完成!

为了解决这个问题,我试图使用accelerometerUpdateInterval。我NSLog了这个值,它变成了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

ops,猜测我不需要额外的当前时间阅读!!谢谢你的帮助。

编辑#3 [解决方案]

感谢Theis'帮助我终于搞清楚了。我最终记录了加速度计的所有数据,发现当它立即进入后台时它并没有停止。我通过使用通知来暂停我的游戏。

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willResignActive)name:UIApplicationWillResignActiveNotification object:nil];

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

2 个答案:

答案 0 :(得分:1)

我不认为让它进入后台,恢复然后回到游戏没有在最后一次阅读和你回来之后得到的第一个之间进行插值是很有意义的。在游戏术语中它基本上意味着用户可以无限快速地“移动”设备。也就是说,用户可以向左倾斜设备,然后将其放在后台。在背景中向右倾斜并再次打开。加速度计数据现在有了巨大的增长,这意味着巨大的跳跃。解决这个问题的一种方法是让加速度计不设置移动物理对象的速度,但是有一个影响速度的中间变量。

答案 1 :(得分:0)

感谢Theis'帮助我终于搞清楚了。我最终记录了加速度计的所有数据,发现当它立即进入后台时它并没有停止。我使用通知暂停了我的游戏。

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willResignActive)name:UIApplicationWillResignActiveNotification object:nil];

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