`

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.win32\Debug.win32目录下看看是否成功生成了UserDefault.xml文件。

 

 

更多内容请关注最新Cocos图书《Cocos2d-x实战 C++卷》
本书交流讨论网站:http://www.cocoagame.net
更多精彩视频课程请关注智捷课堂Cocos课程:http://v.51work6.com
欢迎加入Cocos2d-x技术讨论群:257760386


《Cocos2d-x实战 C++卷》现已上线,各大商店均已开售:

京东:http://item.jd.com/11584534.html

亚马逊:http://www.amazon.cn/Cocos2d-x%E5%AE%9E%E6%88%98-C-%E5%8D%B7-%E5%85%B3%E4%B8%9C%E5%8D%87/dp/B00PTYWTLU

当当:http://product.dangdang.com/23606265.html

互动出版网:http://product.china-pub.com/3770734

 

《Cocos2d-x实战 C++卷》源码及样章下载地址:

源码下载地址:http://51work6.com/forum.php?mod=viewthread&tid=1155&extra=page%3D1 

样章下载地址:http://51work6.com/forum.php?mod=viewthread&tid=1157&extra=page%3D1

欢迎关注智捷iOS课堂微信公共平台
分享到:
评论

相关推荐

    魔塔游戏(某教程的实例,已改成cocos2d-x 3.2)

    5. **持久化数据**:由于魔塔游戏具有保存和读取进度的需求,开发者需要利用cocos2d-x的数据存储功能,如SQLite或XML文件,来保存玩家的状态和游戏进度。 6. **界面设计**:Resources中的资源文件用于构建游戏的...

    cocos2dx水浒卡牌源码

    9. **持久化存储**:玩家的进度、卡牌收集等数据需要保存,cocos2d-x提供了UserDefault接口进行简单数据的本地存储,更复杂的可以采用SQLite或XML/JSON格式的文件存储。 10. **性能优化**:对于大型游戏,性能优化...

    《Cocos2dx高级开发教程制作自己的《捕鱼达人》》PDF

    8. **游戏保存与加载**:使用Cocos2d-x的数据持久化功能,保存玩家的游戏进度和成就。 9. **网络同步**:如果要实现多人在线对战,需要学习网络编程,使用Socket通信或者WebSocket进行实时数据交换。 10. **发布与...

    精通Cocos2d-x游戏开发(进阶卷)源代码

    9. **数据持久化**:使用SQLite、XML、JSON等格式存储游戏数据,实现进度保存和读取。 10. **性能优化**:学习如何分析和优化游戏性能,包括内存管理、渲染效率提升、代码结构优化等。 11. **多平台适配**:了解...

    知易Cocos2D-iPhone 游戏开发教程006

    4. **声音与音乐**:教程可能涵盖如何在Cocos2D-iPhone中集成音频资源,包括背景音乐和音效的播放控制。 5. **场景切换与过渡**:在游戏过程中,场景切换是常见的操作,Cocos2D-iPhone提供了一系列的过渡效果,使得...

    Cocos2d-JS开发之旅

    书中会介绍HTML5的Canvas API,它是绘制游戏场景的基础,还会讲解如何利用Web Audio API处理游戏音效,以及如何利用Web Storage和IndexedDB进行数据持久化。 关于微信小游戏,它是微信平台上的一个轻量级游戏应用,...

    cocos2dx游戏开发实战

    6. **音频管理**:掌握如何播放背景音乐和音效,使用Cocos2d-x的音频引擎进行音频控制。 7. **游戏逻辑**:通过实例讲解游戏逻辑的编写,如计分系统、游戏状态管理、角色行为控制等。 8. **游戏对象管理**:理解...

    iOS实例开发源码——jeremyflores-cocosMNC-e4c399d.zip

    10. **持久化数据**:学习如何使用plist、sqlite或者其他方式存储游戏数据,以实现进度保存和加载。 通过研究这个项目源码,开发者不仅可以深化对Cocos2d-x框架的理解,还能学习到iOS应用的开发实践,包括Xcode集成...

    cocos学习资料

    8. **数据持久化**:游戏进度、玩家分数等信息需要保存,Cocos2d-x提供了一些数据存储的接口,如UserDefault类,可以实现简单的本地数据存储。 9. **网络通信**:尽管这是单机版,但为了实现排行榜等功能,开发者...

    割绳子游戏代码

    5. 图形渲染:Cocos2d-x使用精灵(Sprite)来绘制2D图像,如游戏中的糖果、绳子和背景。开发者可以方便地加载、显示和更新精灵,实现动态画面。 6. 声音与音频:割绳子游戏中,割绳子的声音、糖果落地的音效以及Om ...

    cocos2dx 完整商业版三消类游戏源码

    8. **数据持久化**:游戏进度、分数、排行榜等信息需要保存到本地,cocos2dx提供了UserDefault类来进行简单数据存储。 9. **性能优化**:由于可能涉及大量元素的更新和渲染,了解如何优化内存使用、减少不必要的...

    TheCars:cocos2d-js 引擎的简单游戏

    cocos2d-js提供了简单的本地存储API,如`cc.sys.localStorage`,可以用来保存和读取玩家的分数、等级等信息。 9. **性能优化**:为了确保游戏在各种设备上流畅运行,开发者需要关注性能优化。这包括合理使用纹理 ...

    cocos2d 游戏开发与实战 第二版 源代码

    9. **存档与数据持久化**:学习如何保存和加载游戏进度,使用plist、sqlite或其他存储方式。 10. **网络通信**:如果项目涉及在线功能,你可能还会接触到HTTP请求、JSON解析等内容。 11. **性能优化**:理解并实践...

    iOS实例开发源码——jlake-cocosShooter-d40d86d.zip

    Cocos2d-x使用层(Layer)的概念来组织游戏逻辑,每个层可以包含多个精灵和其他游戏对象,通过组合这些元素,开发者可以构建出复杂的游戏场景。 项目中可能包含了以下关键文件和目录: 1. `proj.ios_mac`: 这是iOS...

    Cocos2d_for_iPhone_1_Game_Development_Cookbook代码

    8. **存档和加载**:游戏进度的保存和读取是游戏持久化的关键。Cocos2d提供了数据存储接口,你可以在代码集合中找到相关的实现。 9. **粒子系统**:粒子系统用于创建各种视觉特效,如火、烟雾、火花等。Cocos2d的...

    消灭星星源码及资源

    6. **数据持久化**:学习如何保存和读取玩家的进度和分数,通常会涉及到文件操作和JSON解析。 7. **关卡设计**:理解关卡布局和难度设置,以及如何将关卡数据加载到游戏中。 通过研究源码,开发者还可以学习到软件...

    cocos 2d 小游戏 打砖块

    9. **音效与音乐**:Cocos2d支持播放音效和背景音乐,例如球击中砖块的声音、游戏胜利或失败的提示音等,这增强了游戏的沉浸感。 10. **状态机**:游戏可能有多个状态,如开始、游戏进行中、暂停、游戏结束等。使用...

    iPhone & iPad cocos2d游戏开发实战完整版

    为了实现游戏的持久化,cocos2d提供了数据存储的接口,如偏好设置和文件系统操作。开发者将学习如何使用这些工具来保存用户数据,比如得分、等级和解锁的成就。 最后,书中的实战部分将带领读者逐步构建一个完整的...

    iOS实例开发源码——haqu-tower-defense-9947372.zip

    10. **持久化存储**:保存游戏进度、玩家数据,可以使用Core Data、SQLite或UserDefaults。 11. **错误处理和日志**:良好的错误处理机制是必备的,如使用`try-catch`语句或自定义错误类。NSLog或CocoaLumberjack...

    iOS实例开发源码——JohnnySheng-SpaceGame-c2342f0.zip

    7. **存储与数据持久化**:游戏进度、用户数据通常需要保存在本地,CoreData或SQLite是常见的数据存储解决方案。 8. **发布与更新**:发布到App Store需要遵循Apple的审核指南,同时,热更新技术如JSPatch可以帮助...

Global site tag (gtag.js) - Google Analytics