Как повторно выполнить действие, когда кнопка постоянно нажата в объекте

У меня есть четыре простых метода, четыре кнопки и один объект.

- (IBAction)left:(id)sender{
    object.center = CGPointMake(object.center.x - 5, object.center.y);
}

- (IBAction)right:(id)sender{
    object.center = CGPointMake(object.center.x + 5, object.center.y);
}
- (IBAction)down:(id)sender{
    object.center = CGPointMake(object.center.x, object.center.y + 5);
}
- (IBAction)up:(id)sender{
    object.center = CGPointMake(object.center.x, object.center.y - 5);
}

Когда я нажимаю кнопку, метод выполняется один раз. Когда кнопка нажата постоянно, это то же самое. Что мне нужно сделать, чтобы при непрерывном нажатии кнопки мой объект продолжал двигаться влево?

3 ответа

Решение

Как сказал @Maudicus, вам, вероятно, нужно что-то сделать с NSTimers, чтобы получить непрерывное нажатие кнопки. Пример, который я собираюсь использовать, - это перемещение объекта на экране (поскольку вы все равно хотите это сделать). Я использовал постепенное перемещение, потому что понятия не имею, пишете ли вы игру на основе сетки, и поэтому вам нужно ровно 5 пикселей движения. Просто вырежьте весь код stepSize и установите его на 5, если вы это делаете.

  1. Напишите функцию обратного вызова таймера, которая проверяет, является ли BOOL устанавливается и, если так, продолжает срабатывать сам:

    - (void)moveObjectLeft:(NSTimer *)timer
    {
        // check the total move offset and/or the X location of the object here
        // if the object can't be moved further left then invalidate the timer
        // you don't need to check whether the button is still being pressed
        //[timer invalidate];
        //return;
    
        // the object moves gradually faster as you hold the button down for longer
        NSNumber *moveOffset = (NSNumber *)[timer userInfo];
        NSUInteger stepSize = 1;
        if(moveOffset >= 40)
            stepSize = 10;
        else if(moveOffset >= 15)
            stepSize = 5;
        else if(moveOffset >= 5)
            stepSize = 2;
    
        // move the object
        object.center = CGPointMake(object.center.x - stepSize, object.center.y);
    
        // store the new total move offset for this press
        moveOffset += stepSize;
        [timer setUserInfo:moveOffset];
    }
    
  2. Создать свойство таймера в текущих классах .h:

    @property (nonatomic, retain) NSTimer *moveTimer;
    
  3. Синтезировать это в вашем .m:

    @synthesize moveTimer;
    
  4. Создайте свой объект таймера, когда кнопка нажата. Либо сделать это в touchesBegan:withEvent: и проверьте, что это событие Touch Down, или подключите событие Touch Down в Интерфейсном Разработчике к IBAction метод.

    NSNumber *moveOffset = [NSNumber numberWithUnsignedInt:0];
    self.moveTimer =
        [NSTimer
         scheduledTimerWithTimeInterval:0.2
         target:self
         selector:@selector(moveObject:)
         userInfo:moveOffset
         repeats:YES];
    
  5. Когда кнопка отпущена (снова используя один из вышеуказанных методов, touchesEnded:withEvent: для Touch Up Inside или, возможно, даже Touch Up Outside, или другой IBAction на обоих этих событиях), аннулируйте таймер извне:

    [self.moveTimer invalidate];
    self.moveTimer = nil;
    

Когда кнопка дает свое событие mousedown, начинайте движение. Когда кнопка вызывает событие mouseup, прекратите движение.

Быть осторожен; Это может показаться забавным, если одновременно нажимать несколько кнопок.

Я думаю, что вам нужно запланировать таймер и повторить метод, который проверяет состояния кнопок.

// предположим, что таймер настроен на тестирование состояний кнопок, запуск controlLoop каждые х секунд

-(void)controlsLoop
{
    if (leftButton.state == UIControlStateSelected || leftButton.state == UIControlStateHighlighted)  {

    }
}

Я никогда не делал этого раньше, так что играйте с этим весело. Я обычно добиваюсь контроля, как вы хотите в Cocos2d,

Может быть, лучше реализовать эти методы

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event

установить направление, в котором вы хотите переместить объект, и при этом иметь таймер, запускающий фактическое движение.

Другие вопросы по тегам