iphone - ccTouchMoved 反复触发声音 & ccTouchEnded 不起作用

标签 iphone objective-c audio 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”事件一起工作。

正如我所说,关键是当用户在屏幕上拖动他/她的手指时应该播放声音。但是当我尝试将 playSound 函数与“ccTouchMoved”联系起来时,声音会在自身上反复循环,而不是一次循环,这使得它很难使用。更改为 ccTouchMoved 后,stopSound 功能不起作用。

我尝试使用 NSTimer 创建某种方式来处理循环,但没有任何成功。

我用常规的 iOS SDK 开始了这个项目,当我发现没有 Cocos2d 就无法处理音高和增益操作时,我发现了自己的局限性。

通过将常规 SDK 包装在 if 语句中,我得到了一切正常工作:
if(![mySound isPlaying]{
    [mySound play];
}

正如我所说,这在常规 SDK 中工作得非常好,但现在当我使用 Cocos2d 时就不行了。

最佳答案

随着手指在屏幕上移动,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 秒内,则只需更新记录的时间戳并继续;但是,如果距离上次触摸的时间过长,您将停止正在播放的声音。

这样您就可以播放无缝的声音,它只创建一次,并且您保持对它的所有权。

希望这可以帮助

关于iphone - ccTouchMoved 反复触发声音 & ccTouchEnded 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7710781/

相关文章:

iphone - ARC 和 Storyboard 的兼容性

iphone - 如何解决发送到类的无法识别的选择器?

javascript - meteor DOMException : Unable to decode audio data

java - 处理中的多声道音频

ios - iOS 播放通知声音的选项

iphone - 无法从应用程序加载器上传应用程序

objective-c - 调试程序化自动布局约束

ios - 视觉 QuartzCore iOS

ios - 在 iOS 中显示和隐藏状态栏+更改 View Controller 之间的状态栏文本颜色

ios - Swift - 在所有设备的相同位置将 subview 添加到 UIImageView