Cocos2d проблема с встряхиванием / акселерометром

Так что у меня небольшая предыстория. Я хотел реализовать эффект частиц и звуковой эффект, которые длятся около 3 секунд или около того, когда пользователь встряхивает свое iDevice. Но первая проблема возникла, когда сборка в UIEvent для встряхивания перестала работать. Так что я послушался совета нескольких ветеранов Cocos, чтобы просто использовать какой-нибудь скрипт для получения «жестких» сигналов акселерометра в виде встряхивания. Отлично работал до сих пор.

Проблема в том, что если вы продолжаете встряхивать, частицы просто складываются и звучат снова и снова. В этом нет ничего страшного, кроме случаев, когда вы стараетесь не делать этого. Итак, я надеюсь отключить акселерометр при запуске эффекта частиц / звукового эффекта, а затем снова включить его, как только они закончатся. Теперь я не знаю, следует ли мне делать это по расписанию, NStimer или какой-либо другой функцией. Я открыт для ВСЕХ предложений. вот мой текущий код "встряхивания".

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

    const float violence = 1;
    static BOOL beenhere;
    BOOL shake = FALSE;

    if (beenhere) return;
    beenhere = TRUE;
    if (acceleration.x > violence * 1.5 || acceleration.x < (-1.5* violence))
        shake = TRUE;
    if (acceleration.y > violence * 2 || acceleration.y < (-2 * violence))
        shake = TRUE;
    if (acceleration.z > violence * 3 || acceleration.z < (-3 * violence))
        shake = TRUE;
    if (shake) {
        id particleSystem = [CCParticleSystemQuad particleWithFile:@"particle.plist"];
        [self addChild: particleSystem];

    // Super simple Audio playback for sound effects!

        [[SimpleAudioEngine sharedEngine] playEffect:@"Sound.mp3"];
        shake = FALSE;
    }

    beenhere = FALSE;
}

person Ryan Poolos    schedule 08.01.2011    source источник


Ответы (2)


UIAcceleration имеет свойство timestamp. Я бы изменил ваш код, чтобы сохранить текущую отметку времени при успешном встряхивании в статической переменной (возможно, static NSTimeInterval timestampOfLastShake?). Затем измените if (shake) на if (shake && acceleration.timestamp - 3.0f >= timestampOfLastShake)

результирующий код:

  static NSTimeInterval timestampOfLastShake = 0.0f;
  if (shake && acceleration.timestamp - 3.0f >= timestampOfLastShake ) {
        timestampOfLastShake = acceleration.timestamp;
        id particleSystem = [CCParticleSystemQuad particleWithFile:@"particle.plist"];
        [self addChild: particleSystem];

    // Super simple Audio playback for sound effects!

        [[SimpleAudioEngine sharedEngine] playEffect:@"Sound.mp3"];
        shake = FALSE;
    }
person mackross    schedule 09.01.2011

Вы понимаете, что выполняете проверку ускорения по одной оси и не обеспечиваете повторение ускорения (т. Е. Тряску). Другими словами, если вы уроните телефон, ваш код будет думать, что это кто-то трясет устройство назад и четвертый несколько раз (что и есть встряхивание), и срабатывает много раз в секунду. Итак, либо примените многоосные проверки по времени, либо просто используйте Shake UIEvent. Все, что вам нужно сделать, это в вашем UIView (или еще лучше UIWindow) реализовать - (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event, убедившись, что представление становится первым респондентом. Это позаботится обо всей фильтрации ускорения и т. Д., И приложение не будет подвергаться бомбардировке всем шумом ускорения (вы можете уронить свой телефон на стол, и он не будет принимать это за тряску).

Перейдите сюда, чтобы получить документ: http://developer.apple.com/library/ios/#documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/MotionEvents/MotionEvents.html.

Or:

- (BOOL)canBecomeFirstResponder {
    return YES;
}

// Now call [self becomeFirstResponder]; somewhere, say in viewDidAppear of the controller.   

- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event
{

}

- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
     if (event.subtype == UIEventSubtypeMotionShake) {
    // You've got a shake, do something
     }
}

- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event
{

}
person Ephraim    schedule 21.01.2011