0

在我的应用程序中,我实现了 NSTimer 来计算时间。我有滑动检测,当用户在屏幕上滑动时,动画会连续运行。我的问题是当我在屏幕上滑动时(左/右连续) NSTimer 减慢。谁能告诉我如何解决这个问题?

//代码

    gameTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/100
                                                          target:self
                                                        selector:@selector(updateGameTimer)
                                                        userInfo:nil
                                                        repeats:YES];

    -(void)updateGameTimer
    {
        counter++;
        tick++;
        if(tick==100){
            tick = 0;
            seconds += 1;
        }
        if(counter==100){
            counter = 0;
        }
        timerLabel.text = [NSString stringWithFormat:@"%i.%02d",seconds,counter];
    } 


//swipe detection

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
    [super touchesMoved:touches withEvent:event];

    UITouch *touch = [touches anyObject];
    //CGPoint curPt = [touch locationInView:self.view];    
    CGPoint newLocation = [touch locationInView:self.view];
    CGPoint oldLocation = [touch previousLocationInView:self.view];
    gameView.multipleTouchEnabled = true;

    if(newLocation.x-oldLocation.x>0){
        swipe_direction = 1;
        //NSLog(@"left");
    }
    else{
        swipe_direction = 2;
        //NSLog(@"right");

    }

    if(swipe_direction==1){
        //animate images
        //play sound effect
    }
    else if(swipe_direction==2){
       //animate images
       //play sound effect
    }

}
4

2 回答 2

5

NSTimer文档...

定时器不是实时机制;它仅在已添加计时器的运行循环模式之一正在运行并且能够检查计时器的触发时间是否已过时触发。由于典型的运行循环管理的各种输入源,计时器的时间间隔的有效分辨率被限制在 50-100 毫秒的数量级。如果计时器的触发时间发生在长时间调用期间或运行循环处于不监视计时器的模式下,则计时器不会触发,直到运行循环下次检查计时器。因此,定时器触发的实际时间可能是计划触发时间之后的一个重要时间段。

您的计时器分辨率为 10 毫秒,因此如果运行循环没有足够快地完成(低于 10 毫秒),您将开始注意到实时和计数器之间的延迟。

如果您正在实现游戏,开发人员通常会尝试与 CPU 或时钟速度分离。

看看这个答案

或者看看像cocos2d这样的框架是如何实现自己的调度器的。

于 2012-07-23T02:45:22.580 回答
0

从描述中很难看出“减速”是什么意思。由于处理负载,它只是跟不上真实时钟,还是实际上短暂停止?

在某些情况下,问题实际上是当某些 UI 进程发生时,如触摸事件处理或滚动,您处于不同的运行循环模式。在这种模式下,默认NSTimer实例实际上不会被触发,除非你明确告诉 iOS 这样做。

在此处查看其他答案

它可能就像将您的计时器添加到正确的运行循环模式的计时器列表一样简单:

gameTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/100
                                             target:self
                                           selector:@selector(updateGameTimer)
                                            serInfo:nil
                                            repeats:YES];

[[NSRunLoop currentRunLoop] addTimer: gameTimer forMode: NSRunLoopCommonModes];

这是一个简单的一行更改,看看这是否解决了您的问题。比重新设计整个滴答机制要容易得多。试一试!

于 2012-07-23T05:04:14.547 回答