Cocos2d-x中背景音乐和音效使用实例

时间:2021-07-17 08:49:53

游戏中的音乐和音效是必不可少的,好的音乐可以给我们留下很深的印象也决定了这个游戏的品质。今天我们来学习一下cocos2d-x中如何使用音乐和音效。这些用到的函数都比较简单,现在直接上代码。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
//声音预先处理类的头文件
#ifndef _AUDIO_PRETREAT_H
#define _AUDIO_PRETREAT_H
#include "cocos2d.h"
//使用声音引擎必须包含SimpleAudioEngeim.h头文件
#include "SimpleAudioEngine.h"
 
using namespace cocos2d;
//声音引擎的命名空间
using namespace CocosDenshion;
 
//类AudioPretrea采用单例设计模式
 
//把用到的音乐做为枚举类型
enum MUSIC_TYPE
{
    MUSIC_TYPE_BACKGROUND //背景音乐
};
 
//把用到的音乐做为枚举类型
enum EFFECT_TYPE
{
    EFFECT_TYPE_EFFECT1
};
 
class AudioPretreat
{
private:
    static AudioPretreat * m_audioPretreat;
public:
    //单例设计的时候需要用到的俩个函数
    static AudioPretreat * sharedAudioPretreat();
    static void freeAudioPretreat();
    //可以根据不同的平台获取不同的声音文件
    char * getMusic(MUSIC_TYPE type);
    char * getEffect(EFFECT_TYPE type);
    //在init中完成声音的预先加载
    bool init();
};
 
#endif
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
//声音预先处理类的实现
#include "AudioPretreat.h"
//单例设计模式采用的惯用方式
AudioPretreat * AudioPretreat::m_audioPretreat = NULL;
 
AudioPretreat * AudioPretreat::sharedAudioPretreat()
{
    if(NULL == m_audioPretreat)
    {
        m_audioPretreat = new AudioPretreat();
    }
    return m_audioPretreat;
}
 
//在AppDelegate析构的时候调用这个函数
void AudioPretreat::freeAudioPretreat()
{
    if(m_audioPretreat)
    {
        delete m_audioPretreat;
        m_audioPretreat = NULL;
    }
}
 
//根据不同的平台获得不同的声音文件
char * AudioPretreat::getMusic(MUSIC_TYPE type)
{
    switch(type)
    {
    case MUSIC_TYPE_BACKGROUND:
        //WIN32,ANDROID,IOS都使用MP3格式的背景音乐
#if(CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
    return "background-music.mp3";
#else(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
    return "background-music.mp3";
#endif
    break;
    }
    return NULL;
}
 
//根据不同的平台获得不同的音效文件
char * AudioPretreat::getEffect(EFFECT_TYPE type)
{
    switch(type)
    {
    case EFFECT_TYPE_EFFECT1:
#if(CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
        return "pew-pew-lei.wav";
#else(CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
        return "pew-pew-lei.ogg";
#endif
    }
    return NULL;
}
 
//init函数中完成一些初始化的操作
bool AudioPretreat::init()
{
    bool bRet = false;
    do
    {
        //预先加载声音,参数是声音文件
        SimpleAudioEngine::sharedEngine()->preloadBackgroundMusic(this->getMusic(MUSIC_TYPE_BACKGROUND));
        //加载音效
        SimpleAudioEngine::sharedEngine()->preloadEffect(this->getEffect(EFFECT_TYPE_EFFECT1));
        //设置声音的大小0.0-1.0
        SimpleAudioEngine::sharedEngine()->setBackgroundMusicVolume(0.1f);
        bRet = true;
    }
    while(0);
 
    return bRet;
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
// 下面就来看一下如何使用声音引擎
bool HelloWorld::init()
{
  bool bRet = false;
  do
  {
 
    CC_BREAK_IF(! CCLayer::init());
 
        CCSize size = CCDirector::sharedDirector()->getVisibleSize();
 
        AudioPretreat::sharedAudioPretreat()->init();
 
        //以下是对背景音乐的一些操作
 
        //设置字符串,并且转码
        std::string str1 = "播放背景音乐";
        std::string str2 = "停止背景音乐";
        std::string str3 = "暂停背景音乐";
        std::string str4 = "恢复背景音乐";
        std::string str5 = "重头播放背景音乐";
        std::string str6 = "背景音乐:加";
        std::string str7 = "背景音乐:减";
        GBKToUTF8(str1,"GB2312","UTF-8");
        GBKToUTF8(str2,"GB2312","UTF-8");
        GBKToUTF8(str3,"GB2312","UTF-8");
        GBKToUTF8(str4,"GB2312","UTF-8");
        GBKToUTF8(str5,"GB2312","UTF-8");
        GBKToUTF8(str6,"GB2312","UTF-8");
        GBKToUTF8(str7,"GB2312","UTF-8");
 
        CCMenuItemFont::setFontSize(24);
        CCMenuItemFont::setFontName("Arial");
        CCMenuItemFont * menu1 = CCMenuItemFont::create(str1.c_str(),this,menu_selector(HelloWorld::menu));
        menu1->setTag(1);
        CCMenuItemFont * menu2 = CCMenuItemFont::create(str2.c_str(),this,menu_selector(HelloWorld::menu));
        menu2->setTag(2);
        CCMenuItemFont * menu3 = CCMenuItemFont::create(str3.c_str(),this,menu_selector(HelloWorld::menu));
        menu3->setTag(3);
        CCMenuItemFont * menu4 = CCMenuItemFont::create(str4.c_str(),this,menu_selector(HelloWorld::menu));
        menu4->setTag(4);
        CCMenuItemFont * menu5 = CCMenuItemFont::create(str5.c_str(),this,menu_selector(HelloWorld::menu));
        menu5->setTag(5);
        CCMenuItemFont * menu6 = CCMenuItemFont::create(str6.c_str(),this,menu_selector(HelloWorld::menu));
        menu6->setTag(6);
        CCMenuItemFont * menu7 = CCMenuItemFont::create(str7.c_str(),this,menu_selector(HelloWorld::menu));
        menu7->setTag(7);
 
        CCMenu * leftMenu = CCMenu::create(menu1,menu2,menu3,menu4,menu5,menu6,menu7,NULL);
        leftMenu->alignItemsVerticallyWithPadding(5);
        leftMenu->setPositionX(size.width/4);
        this->addChild(leftMenu);
 
        //以下是对音效的操作
        std::string str11 = "播放音效";
        std::string str12 = "停止音效";
        std::string str13 = "暂停音效";
        std::string str14 = "恢复音效";
        std::string str15 = "从缓存中移除音效";
        std::string str16 = "音效:加";
        std::string str17 = "音效:减";
        GBKToUTF8(str11,"GB2312","UTF-8");
        GBKToUTF8(str12,"GB2312","UTF-8");
        GBKToUTF8(str13,"GB2312","UTF-8");
        GBKToUTF8(str14,"GB2312","UTF-8");
        GBKToUTF8(str15,"GB2312","UTF-8");
        GBKToUTF8(str16,"GB2312","UTF-8");
        GBKToUTF8(str17,"GB2312","UTF-8");
 
        CCMenuItemFont * menu11 = CCMenuItemFont::create(str11.c_str(),this,menu_selector(HelloWorld::menu));
        menu11->setTag(11);
        CCMenuItemFont * menu12 = CCMenuItemFont::create(str12.c_str(),this,menu_selector(HelloWorld::menu));
        menu12->setTag(12);
        CCMenuItemFont * menu13 = CCMenuItemFont::create(str13.c_str(),this,menu_selector(HelloWorld::menu));
        menu13->setTag(13);
        CCMenuItemFont * menu14 = CCMenuItemFont::create(str14.c_str(),this,menu_selector(HelloWorld::menu));
        menu14->setTag(14);
        CCMenuItemFont * menu15 = CCMenuItemFont::create(str15.c_str(),this,menu_selector(HelloWorld::menu));
        menu15->setTag(15);
        CCMenuItemFont * menu16 = CCMenuItemFont::create(str16.c_str(),this,menu_selector(HelloWorld::menu));
        menu16->setTag(16);
        CCMenuItemFont * menu17 = CCMenuItemFont::create(str17.c_str(),this,menu_selector(HelloWorld::menu));
        menu17->setTag(17);
 
        CCMenu * rightMenu = CCMenu::create(menu11,menu12,menu13,menu14,menu15,menu16,menu17,NULL);
        rightMenu->alignItemsVerticallyWithPadding(5);
        rightMenu->setPositionX(size.width*3/4);
        this->addChild(rightMenu);
 
    bRet = true;
  } while (0);
 
  return bRet;
}
 
void HelloWorld::menu(CCObject * sender)
{
    CCNode * node = (CCNode *)sender;
    int tag = node->getTag();
    switch(tag)
    {
    case 1:
        //播放声音,第二个参数代表是否循环播放
        SimpleAudioEngine::sharedEngine()->playBackgroundMusic(
            AudioPretreat::sharedAudioPretreat()->getMusic(MUSIC_TYPE_BACKGROUND),true);
        break;
    case 2:
        SimpleAudioEngine::sharedEngine()->stopBackgroundMusic();
        break;
    case 3:
        //pause和resume成对使用
        SimpleAudioEngine::sharedEngine()->pauseBackgroundMusic();
        break;
    case 4:
        SimpleAudioEngine::sharedEngine()->resumeBackgroundMusic();
        break;
    case 5:
        SimpleAudioEngine::sharedEngine()->rewindBackgroundMusic();
        break;
    case 6:
        //这个函数在win32上没法改变声音的大小,大家用f12跟进函数的时候里边是空,但是在android平台上有实现
        SimpleAudioEngine::sharedEngine()->setBackgroundMusicVolume(
            SimpleAudioEngine::sharedEngine()->getBackgroundMusicVolume()+0.1f);
        break;
    case 7:
        //这个函数在win32上没法改变声音的大小,大家用f12跟进函数的时候里边是空,但是在android平台上有实现
        SimpleAudioEngine::sharedEngine()->setBackgroundMusicVolume(
            SimpleAudioEngine::sharedEngine()->getBackgroundMusicVolume()-0.1f);
        break;
    case 11:
        //第二个参数设为true的话则循环播放,soundID是在HelloWorld的头文件中定义的
        //音效函数不同于背景音乐的是会返回一个ID
        soundID = SimpleAudioEngine::sharedEngine()->playEffect(
            AudioPretreat::sharedAudioPretreat()->getEffect(EFFECT_TYPE_EFFECT1),true);
        break;
    case 12:
        //音效函数大多会传入一个ID,因为游戏中的音效不止一个
        SimpleAudioEngine::sharedEngine()->stopEffect(soundID);
        break;
    case 13:
        SimpleAudioEngine::sharedEngine()->pauseEffect(soundID);
        break;
    case 14:
        SimpleAudioEngine::sharedEngine()->resumeEffect(soundID);
    case 15:
        //从缓存中移除音效,需要传入移除的音效的名字
        SimpleAudioEngine::sharedEngine()->unloadEffect(
            AudioPretreat::sharedAudioPretreat()->getEffect(EFFECT_TYPE_EFFECT1));
    case 16:
        SimpleAudioEngine::sharedEngine()->setEffectsVolume(
            SimpleAudioEngine::sharedEngine()->getEffectsVolume()+0.1);
        break;
    case 17:
        SimpleAudioEngine::sharedEngine()->setEffectsVolume(
            SimpleAudioEngine::sharedEngine()->getEffectsVolume()-0.1);
        break;
    }
}
//编码格式转化函数
int GBKToUTF8(std::string & gbkStr, const char* toCode, const char* fromCode)
{
    iconv_t iconvH;
    iconvH = iconv_open(fromCode, toCode);
 
    if (iconvH == 0)
 
    {
        return -1;
    }
 
    const char* strChar = gbkStr.c_str();
    const char** pin = &strChar;
    size_t strLength = gbkStr.length();
    char* outbuf = (char*) malloc(strLength*4);
    char* pBuff = outbuf;
 
    memset( outbuf, 0, strLength*4);
    size_t outLength = strLength*4;
 
    if (-1 == iconv(iconvH, pin, &strLength, &outbuf, &outLength))
    {
        iconv_close(iconvH);
        return -1;
    }
 
    gbkStr = pBuff;
    iconv_close(iconvH);
 
    return 0;
}

Cocos2d-x中背景音乐和音效使用实例