ccTouchMoved запускает звук повторно, и ccTouchEnded не работает

#iphone #objective-c #audio #cocos2d-iphone

#iPhone #objective-c #Аудио #cocos2d-iphone

Вопрос:

Я пытаюсь создать приложение, в котором предполагается воспроизведение короткого звукового сэмпла, пока пользователь, использующий приложение, проводит пальцем по экрану. Когда палец (пальцы) отведены от экрана, звук прекратится.

Это текущая функция, которая запускает звук (я пробовал разные методы):

 -(BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event{

NSLog(@"Ja, den börjar...");
return YES; 
}

-(void)ccTouchMoved:(NSSet *)touch withEvent:(UIEvent *)event{

    soundFile = [[CDAudioManager sharedManager] audioSourceForChannel:kASC_Right];
    [soundFile load:@"sound.wav"];
    soundFile.backgroundMusic = NO;
    soundSourceForFile:@"sound.wav"]retain];
}
  

Это функция, которая останавливает звук:

 -(void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event{
    [soundFile stop]; 
}
  

Сначала я начал использовать ccTouchBegan (просто чтобы заставить какой-то звук работать), который плавно зацикливал звук. На этом этапе ccTouchEnded работал вместе с событием «Touch Up Inside».

Как я уже сказал, суть в том, что звук должен воспроизводиться, когда пользователь проводит пальцем по экрану. Но когда я попытался привязать функцию воспроизведения звука к «ccTouchMoved», звук многократно повторяется сам по себе, а не по одному за раз, что делает его адским в использовании. Функция stopSound не работает после того, как я перешел на ccTouchMoved.

Я пытался использовать NSTimer для создания какого-либо способа обработки циклов, но без какого-либо успеха.

Я начал этот проект с обычного iOS SDK и обнаружил свои ограничения, когда узнал, что не могу обрабатывать манипуляции с высотой тона и усилением без Cocos2d.

Я заставил все работать в обычном SDK, обернув его в if-оператор:

 if(![mySound isPlaying]{
    [mySound play];
}
  

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

Ответ №1:

ccTouchMoved будет вызываться непрерывно при перемещении пальца по экрану. Проблема, с которой вы сталкиваетесь, заключается в том, что каждый раз, когда это вызывается, вы загружаете новый звуковой файл, и они перекрываются, потому что они являются вновь созданными отдельными объектами. У вас есть только ссылка на конечный загружаемый звук (на который указывает SoundFile), и вы также не освобождаете память.

Пример:

(при перетаскивании пальца)

 LoadedSoundA created and starts playing
soundfile points to LoadedSoundA
// finger moves
LoadedSoundB created and starts playing
soundfile points to LoadedSoundB
// finger moves
LoadedSoundC created and starts playing
soundfile points to LoadedSoundC
... etc
  

единственный звук, на который у вас есть указатель на данный момент, — это последний созданный звук, поскольку вы каждый раз переназначаете звуковой файл. Таким образом, вы можете «остановить» только звук, который вы создали последним.

Вы также теряете много памяти, поскольку сохраняете все эти звуки и никогда не выпускаете их.

Я бы предложил другую тактику:

В touchesBegan вы должны загрузить звук, включить его в цикл и записать время касания в iVar уровня класса.

Теперь в touchesMoved вы должны получить время текущего касания и посмотреть, достаточно ли оно близко к времени, которое вы записали. Если это в пределах, скажем, 0,5 секунды, просто обновите записанную временную метку и продолжайте; Однако, если с момента последнего касания прошло слишком много времени, вы останавливаете воспроизводимый звук.

Таким образом, у вас воспроизводится плавный звук, он создается только один раз, и вы сохраняете право собственности на него.

Надеюсь, это поможет

Комментарии:

1. Я действительно чувствую, что вы указываете мне правильное направление. Я сделал почти все, что вы предложили выше, начал предварительную загрузку звука и воспроизведение его при касании. Не хотели бы вы помочь med с некоторым синтаксисом, касающимся функции ccTime? У меня возникли некоторые проблемы с тем, КАК я собираюсь это написать. Просто хотел уточнить — я не хочу, чтобы звук воспроизводился, когда я касаюсь фона. Я хочу, чтобы он воспроизводился только во время перемещения пальцев по экрану, а затем останавливался, когда я их снимал. Спасибо, что нашли время.