zoukankan      html  css  js  c++  java
  • Cocos2d-x使用UserDefault数据持久化实例:保存背景音乐和音效设置

    UserDefault可以实现数据的存储,但是它的使用不能泛滥,具体讲一般情况下不会使用它保存大量的数据,它没有SQL语句那样的灵活。UserDefault除了保存游戏设置外,还有可以长期保持游戏精灵等对象的状态。


    我们通过一个实例介绍一下在游戏项目中如何使用UserDefault。如图所示,在Setting场景中可以设置是否播放背景音乐和音效,现在我们将它完善将选择的状态保存到UserDefault中。




    设置背景音乐与音效(上图HelloWorld场景、下图Setting场景)

    我们需要定义两个宏作为键,其中SOUND_KEY是音效状态键,MUSIC_KEY是背景音乐播放状态键。
    #define SOUND_KEY "sound_key"
    #define MUSIC_KEY "music_key"
    但是这两个宏是需要在所有使用cpp文件中使用,我们可以创建一个头文件,把这些宏等都声明在这个头文件中,这个头文件SystemHeader.h代码如下:
    #include "SimpleAudioEngine.h"
    #define SOUND_KEY "sound_key"
    #define MUSIC_KEY "music_key"
    其中我们声明了两个宏,还有包含头文件SimpleAudioEngine.h,头文件SimpleAudioEngine.h是文件使用CocosDenshion引擎所需要的。
    在Visual Studio 2012中添加SystemHeader.h文件过程是。首先,打开解决方案中的HelloWorld工程,右键点击Classes,在右键菜单中选择,“添加”→ “新建项”,如图14-8所示。
    在弹出对话框中选择“Visual C++ ”→“头文件(.h) ”, 在下面名称中输入“SystemHeader.h”,然后点击“添加”按钮,添加头文件。


    添加SystemHeader.h文件
    添加SystemHeader.h文件对话框

    在使用的时候,我们需要将SystemHeader.h头文件添加到HelloWorldScene.h和SettingScene.h头文件中,示例代码如下:

    [html] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. #ifndef __HELLOWORLD_SCENE_H__  
    2. #define __HELLOWORLD_SCENE_H__  
    3.   
    4.   
    5. #include "cocos2d.h"  
    6. #include "SettingScene.h"  
    7. #include "SystemHeader.h"  
    8.   
    9.   
    10. class HelloWorld : public cocos2d::Layer  
    11. {  
    12. public:  
    13.     … …  
    14.     CREATE_FUNC(HelloWorld);  
    15. };  
    16.   
    17.   
    18. #endif // __HELLOWORLD_SCENE_H__  



    下面我们看看HelloWorld场景HelloWorldScene.cpp主要代码如下:

    [html] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. #include "HelloWorldScene.h"  
    2.   
    3.   
    4. USING_NS_CC;  
    5. using namespace CocosDenshion;  
    6.   
    7.   
    8. bool HelloWorld::init()  
    9. {  
    10.     ... ...  
    11.     return true;  
    12. }  
    13.   
    14.   
    15. void HelloWorld::menuItemSettingCallback(Ref* pSender)  
    16. {     
    17.     auto sc = Setting::createScene();  
    18.     auto reScene = TransitionJumpZoom::create(1.0f, sc);  
    19.     Director::getInstance()->pushScene(reScene);  
    20.   
    21.   
    22.     if (UserDefault::getInstance()->getBoolForKey(SOUND_KEY)) {                      ①  
    23.         SimpleAudioEngine::getInstance()->playEffect("sound/Blip.wav");  
    24.     }  
    25. }  
    26.   
    27.   
    28. void HelloWorld::menuItemHelpCallback(Ref* pSender)  
    29. {  
    30.     MenuItem* item = (MenuItem*)pSender;  
    31.     log("Touch Help %p", item);  
    32.     if (UserDefault::getInstance()->getBoolForKey(SOUND_KEY)) {                      ②  
    33.         SimpleAudioEngine::getInstance()->playEffect("sound/Blip.wav");  
    34.     }  
    35. }  
    36.   
    37.   
    38. void HelloWorld::menuItemStartCallback(Ref* pSender)  
    39. {  
    40.     MenuItem* item = (MenuItem*)pSender;  
    41.     log("Touch Start %p", item);  
    42.     if (UserDefault::getInstance()->getBoolForKey(SOUND_KEY)) {                      ③  
    43.         SimpleAudioEngine::getInstance()->playEffect("sound/Blip.wav");  
    44.     }  
    45. }  
    46.   
    47.   
    48. void HelloWorld::onEnter()  
    49. {  
    50.     Layer::onEnter();  
    51.     log("HelloWorld onEnter");        
    52. }  
    53.   
    54.   
    55. void HelloWorld::onEnterTransitionDidFinish()  
    56. {  
    57.     Layer::onEnterTransitionDidFinish();  
    58.     log("HelloWorld onEnterTransitionDidFinish");  
    59.   
    60.   
    61.     //播放  
    62.     if (UserDefault::getInstance()->getBoolForKey(MUSIC_KEY)) {                      ④  
    63.         SimpleAudioEngine::getInstance()->playBackgroundMusic("sound/Jazz.mp3", true);  
    64.     }  
    65. }  
    66.   
    67.   
    68. void HelloWorld::onExit()  
    69. {  
    70.     Layer::onExit();  
    71.     log("HelloWorld onExit");  
    72. }  
    73.   
    74.   
    75. void HelloWorld::onExitTransitionDidStart()  
    76. {  
    77.     Layer::onExitTransitionDidStart();  
    78.     log("HelloWorld onExitTransitionDidStart");  
    79. }  
    80.   
    81.   
    82. void HelloWorld::cleanup()  
    83. {  
    84.     Layer::cleanup();  
    85.     log("HelloWorld cleanup");    
    86.     //停止  
    87.     SimpleAudioEngine::getInstance()->stopBackgroundMusic("sound/Jazz.mp3");  
    88. }  



    上述第①、②、③行代码中UserDefault::getInstance()->getBoolForKey(SOUND_KEY)是获得sound_key键值,通过取出布尔值判断是否播放音效。第④行代码UserDefault::getInstance()->getBoolForKey(MUSIC_KEY)是获得music_key键值,通过取出布尔值判断是否播放背景音乐。
    下面我们再看看Setting场景SettingScene.cpp中的init()主要代码如下:

    [html] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. #include "SettingScene.h"  
    2.   
    3.   
    4. USING_NS_CC;  
    5. using namespace CocosDenshion;  
    6.   
    7.   
    8. bool Setting::init()  
    9. {  
    10.     ... ...  
    11.     UserDefault *defaults  = UserDefault::getInstance();  
    12.   
    13.   
    14.     if (defaults->getBoolForKey(MUSIC_KEY)) {                                    ①  
    15.         musicToggleMenuItem->setSelectedIndex(0);                                ②  
    16.     } else {  
    17.         musicToggleMenuItem->setSelectedIndex(1);                                ③  
    18.     }  
    19.   
    20.   
    21.     if (defaults->getBoolForKey(SOUND_KEY)) {                                    ④  
    22.         soundToggleMenuItem->setSelectedIndex(0);                                ⑤  
    23.     } else {  
    24.         soundToggleMenuItem->setSelectedIndex(1);                                ⑥  
    25.     }  
    26.   
    27.   
    28.     return true;  
    29. }  



    上述代码是设置开关菜单的状态,第①~③行代码是设置背景音乐开关菜单,其中第②行代码是设置开关菜单为Off,否则通过第③行代码设置状态为On。第④~⑥行代码是设置音效开关菜单,其中第⑤行代码是设置开关菜单为Off,否则通过第⑥行代码设置状态为On。
    SettingScene.cpp中的点击音效开关菜单代码如下: 

    [html] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. void Setting::menuSoundToggleCallback(Ref* pSender)  
    2. {  
    3.     auto soundToggleMenuItem = (MenuItemToggle*)pSender;  
    4.     log("soundToggleMenuItem %d", soundToggleMenuItem->getSelectedIndex());  
    5.   
    6.   
    7.     UserDefault *defaults  = UserDefault::getInstance();  
    8.     if (defaults->getBoolForKey(SOUND_KEY)) {                                    ①  
    9.         defaults->setBoolForKey(SOUND_KEY, false);                               ②  
    10.     } else {  
    11.         defaults->setBoolForKey(SOUND_KEY, true);                                ③  
    12.         SimpleAudioEngine::getInstance()->playEffect("sound/Blip.wav");                  ④  
    13.     }  
    14.   
    15.   
    16. }  



    上述代码第①行判断音效开状态为true情况下,通过defaults->setBoolForKey(SOUND_KEY, false)语句设置false,否则通过第③行代码defaults->setBoolForKey(SOUND_KEY, true)语句设置true,同时通过第④行代码播放音效。
    SettingScene.cpp中的点击背景音乐开关菜单代码如下: 

    [html] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. void Setting::menuMusicToggleCallback(Ref* pSender)  
    2. {  
    3.     auto musicToggleMenuItem = (MenuItemToggle*)pSender;  
    4.     log("musicToggleMenuItem %d", musicToggleMenuItem->getSelectedIndex());  
    5.   
    6.   
    7.     UserDefault *defaults  = UserDefault::getInstance();  
    8.     if (defaults->getBoolForKey(MUSIC_KEY)) {                                    ①  
    9.         defaults->setBoolForKey(MUSIC_KEY, false);  
    10.         SimpleAudioEngine::getInstance()->stopBackgroundMusic();  
    11.     } else {  
    12.         defaults->setBoolForKey(MUSIC_KEY, true);  
    13.         SimpleAudioEngine::getInstance()->playBackgroundMusic("sound/Synth.mp3");  
    14.     }                                                                           ②  
    15. }  



    上述代码第①~②行是设置背景音乐开关菜单。代码与点击音效开关菜单类似,不再解释。还有SettingScene.cpp中的其它主要代码如下: 

    [html] view plaincopy在CODE上查看代码片派生到我的代码片
     
    1. void Setting::onEnter()  
    2. {  
    3.     Layer::onEnter();  
    4.     log("Setting onEnter");  
    5. }  
    6.   
    7.   
    8. void Setting::menuOkCallback(Ref* pSender)                                  ①  
    9. {  
    10.     Director::getInstance()->popScene();  
    11.   
    12.   
    13.     if (UserDefault::getInstance()->getBoolForKey(SOUND_KEY)) {                      ②  
    14.         SimpleAudioEngine::getInstance()->playEffect("sound/Blip.wav");  
    15.     }  
    16. }  
    17.   
    18.   
    19. void Setting::onEnterTransitionDidFinish()                                      ③  
    20. {  
    21.     Layer::onEnterTransitionDidFinish();  
    22.     log("Setting onEnterTransitionDidFinish");    
    23.   
    24.   
    25.     if (UserDefault::getInstance()->getBoolForKey(MUSIC_KEY)) {                      ④  
    26.         //播放  
    27.         SimpleAudioEngine::getInstance()->playBackgroundMusic("sound/Synth.mp3", true);  
    28.     }  
    29.   
    30.   
    31. }  
    32.   
    33.   
    34. void Setting::onExit()  
    35. {  
    36.     Layer::onExit();  
    37.     log("Setting onExit");    
    38. }  
    39.   
    40.   
    41. void Setting::onExitTransitionDidStart()  
    42. {  
    43.     Layer::onExitTransitionDidStart();  
    44.     log("Setting onExitTransitionDidStart");  
    45. }  
    46.   
    47.   
    48. void Setting::cleanup()  
    49. {  
    50.     Layer::cleanup();  
    51.     log("Setting cleanup");   
    52.     //停止  
    53.     SimpleAudioEngine::getInstance()->stopBackgroundMusic("sound/Synth.mp3");  
    54. }  



    上述代码第①行menuOkCallback是点击Ok菜单回调函数,其中第②行代码是获得sound_key键值,通过取出布尔值判断是否播放音效。第③行代码onEnterTransitionDidFinish函数是在进入层而且过渡动画结束时候调用,第④行代码是获得music_key键值,通过取出布尔值判断是否播放背景音乐。

    我们可以运行一下先将状态保存,然后重新运行游戏,看看是否能够保持状态。我们还可以到<Cocos2d-x工程目录>proj.win32Debug.win32目录下看看是否成功生成了UserDefault.xml文件。

    更多内容请关注国内第一本Cocos2d-x 3.2版本图书《Cocos2d-x实战:C++卷》
    本书交流讨论网站:http://www.cocoagame.net
    更多精彩视频课程请关注智捷课堂Cocos课程:http://v.51work6.com
    欢迎加入Cocos2d-x技术讨论群:257760386
    欢迎关注智捷iOS课堂微信公共平台

  • 相关阅读:
    VC 常见问题百问
    python windows 环境变量
    Check server headers and verify HTTP Status Codes
    Where are the AES 256bit cipher suites? Please someone help
    outlook 如何预订会议和会议室
    安装Axis2的eclipse插件后,未出现界面
    windows 环境变量
    python 时间日期处理汇集
    openldap学习笔记(使用openldap2.3.32)
    set p4 environment in windows
  • 原文地址:https://www.cnblogs.com/iOS-Blog/p/4038559.html
Copyright © 2011-2022 走看看