cocos2dx 音频模块分析(3):背景音乐部分
我在(2)已经分析了背景音乐文件的预加载preloadBackgroundMusic和播放playBackgroundMusic两个函数, 这里接着分析,还是基于android平台: 1、 //暂停函数,用于音乐的暂停 void SimpleAudioEngine::pauseBackgroundMusic() { //在SimpleAudioEngineJni.cpp源文件中定义 pauseBackgroundMusicJNI(); } //--pauseBackgroundMusicJNI--->>> void pauseBackgroundMusicJNI() { // void pauseBackgroundMusic() JniMethodInfo methodInfo; if (! getStaticMethodInfo(methodInfo, "pauseBackgroundMusic", "()V")) { return; } //通过jni调用java端的函数,调用的是Cocos2dxHelper类中的 /* public static void pauseBackgroundMusic() { Cocos2dxHelper.sCocos2dMusic.pauseBackgroundMusic(); } */ methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID); methodInfo.env->DeleteLocalRef(methodInfo.classID); } 最终调用的是Cocos2dxMusic类中的 public void pauseBackgroundMusic() { //mBackgroundMediaPlayer在(2)中有分析过,创建的MediaPlayer实例 if (this.mBackgroundMediaPlayer != null && this.mBackgroundMediaPlayer.isPlaying()) { this.mBackgroundMediaPlayer.pause(); this.mPaused = true; //是否暂停标志 } } 2、 恢复播放 void SimpleAudioEngine::resumeBackgroundMusic() { resumeBackgroundMusicJNI(); } 其实和上面暂停的调用过程是一样的,就不分析了,直接进入java端看最终调用的函数, public void resumeBackgroundMusic() { //这里只有处于暂停状态时即mPaused变量为true时,才会接着 //上次播放的位置开始播放 if (this.mBackgroundMediaPlayer != null && this.mPaused) { this.mBackgroundMediaPlayer.start(); this.mPaused = false; //把暂停标志位设置false } } 3、 从头开始播放音乐文件 void rewindBackgroundMusicJNI() { // void rewindBackgroundMusic() JniMethodInfo methodInfo; if (! getStaticMethodInfo(methodInfo, "rewindBackgroundMusic", "()V")) { return; } methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID); methodInfo.env->DeleteLocalRef(methodInfo.classID); } --->>//java端函数 //这个函数最终也是会调用playBackgroundMusic函数,但是和playBackgroundMusic有一点不同, //playBackgroundMusic需要传入音乐文件名,可以播放和上一次一样的音乐也可以和是上一次不一样的 //音乐,但是rewindBackgroundMusic函数只有在mBackgroundMediaPlayer不为null时才执行, //也就是必须播放过音乐,且播放的是上次播放的音乐,只不过这次是从头开始播放 public void rewindBackgroundMusic() { if (this.mBackgroundMediaPlayer != null) { playBackgroundMusic(mCurrentPath, mIsLoop); } } 4、停止播放音乐文件 void stopBackgroundMusicJNI() { // void stopBackgroundMusic() JniMethodInfo methodInfo; if (! getStaticMethodInfo(methodInfo, "stopBackgroundMusic", "()V")) { return; } methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID); methodInfo.env->DeleteLocalRef(methodInfo.classID); } --->>>//java端函数: public void stopBackgroundMusic() { if (this.mBackgroundMediaPlayer != null) { mBackgroundMediaPlayer.release(); //不太明白这里为什么有从新创建了MediaPlayer实例 //可能是一些特殊情况下会出现问题? mBackgroundMediaPlayer = createMediaplayer(mCurrentPath); // should set the state, if not, the following sequence will be error // play -> pause -> stop -> resume //为什么设置mPaused标志,直接看上面的英文注释 this.mPaused = false; } } 5、 返回是否处于播放状态 bool isBackgroundMusicPlayingJNI() { // boolean rewindBackgroundMusic() JniMethodInfo methodInfo; jboolean ret = false; if (! getStaticMethodInfo(methodInfo, "isBackgroundMusicPlaying", "()Z")) { return ret; } ret = methodInfo.env->CallStaticBooleanMethod(methodInfo.classID, methodInfo.methodID); methodInfo.env->DeleteLocalRef(methodInfo.classID); return ret; } --->>>//java端函数,没什么东西 public boolean isBackgroundMusicPlaying() { boolean ret = false; if (this.mBackgroundMediaPlayer == null) { ret = false; } else { ret = this.mBackgroundMediaPlayer.isPlaying(); } return ret; } 6、获取播放声音音量值 float getBackgroundMusicVolumeJNI() { // float getBackgroundMusicVolume() JniMethodInfo methodInfo; jfloat ret = -1.0; if (! getStaticMethodInfo(methodInfo, "getBackgroundMusicVolume", "()F")) { return ret; } ret = methodInfo.env->CallStaticFloatMethod(methodInfo.classID, methodInfo.methodID); methodInfo.env->DeleteLocalRef(methodInfo.classID); return ret; } ------->>>//java public float getBackgroundVolume() { if (this.mBackgroundMediaPlayer != null) { return (this.mLeftVolume + this.mRightVolume) / 2; } else { return 0.0f; } } 7、设置声音音量值 void setBackgroundMusicVolumeJNI(float volume) { // void setBackgroundMusicVolume() JniMethodInfo methodInfo; if (! getStaticMethodInfo(methodInfo, "setBackgroundMusicVolume", "(F)V")) { return ; } methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID, volume); methodInfo.env->DeleteLocalRef(methodInfo.classID); } ---->>>java public void setBackgroundVolume(float pVolume) { if (pVolume < 0.0f) { pVolume = 0.0f; } if (pVolume > 1.0f) { pVolume = 1.0f; } this.mLeftVolume = this.mRightVolume = pVolume; if (this.mBackgroundMediaPlayer != null) { this.mBackgroundMediaPlayer.setVolume(this.mLeftVolume, this.mRightVolume); } } 8、 end函数,这个一般在退出游戏是调用,关掉所有的音乐和音效。 void endJNI() { // void end() JniMethodInfo methodInfo; if (! getStaticMethodInfo(methodInfo, "end", "()V")) { return ; } methodInfo.env->CallStaticVoidMethod(methodInfo.classID, methodInfo.methodID); methodInfo.env->DeleteLocalRef(methodInfo.classID); } --->>>//java端函数 public static void end() { Cocos2dxHelper.sCocos2dMusic.end(); //背景音乐文件的处理 Cocos2dxHelper.sCocos2dSound.end(); } ---->>>>/////背景音乐文件的处理 public void end() { if (this.mBackgroundMediaPlayer != null) { this.mBackgroundMediaPlayer.release(); } //把所有的变量恢复初始值 /* private void initData() { this.mLeftVolume = 0.5f; this.mRightVolume = 0.5f; this.mBackgroundMediaPlayer = null; this.mPaused = false; this.mCurrentPath = null; } */ this.initData(); }
时间: 2024-10-08 03:23:26