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头文件中,示例代码如下:

  1. #ifndef __HELLOWORLD_SCENE_H__
  2. #define __HELLOWORLD_SCENE_H__
  3. #include "cocos2d.h"
  4. #include "SettingScene.h"
  5. #include "SystemHeader.h"
  6. class HelloWorld : public cocos2d::Layer
  7. {
  8. public:
  9. … …
  10. CREATE_FUNC(HelloWorld);
  11. };
  12. #endif // __HELLOWORLD_SCENE_H__

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

  1. #include "HelloWorldScene.h"
  2. USING_NS_CC;
  3. using namespace CocosDenshion;
  4. bool HelloWorld::init()
  5. {
  6. ... ...
  7. return true;
  8. }
  9. void HelloWorld::menuItemSettingCallback(Ref* pSender)
  10. {
  11. auto sc = Setting::createScene();
  12. auto reScene = TransitionJumpZoom::create(1.0f, sc);
  13. Director::getInstance()->pushScene(reScene);
  14. if (UserDefault::getInstance()->getBoolForKey(SOUND_KEY)) {                      ①
  15. SimpleAudioEngine::getInstance()->playEffect("sound/Blip.wav");
  16. }
  17. }
  18. void HelloWorld::menuItemHelpCallback(Ref* pSender)
  19. {
  20. MenuItem* item = (MenuItem*)pSender;
  21. log("Touch Help %p", item);
  22. if (UserDefault::getInstance()->getBoolForKey(SOUND_KEY)) {                      ②
  23. SimpleAudioEngine::getInstance()->playEffect("sound/Blip.wav");
  24. }
  25. }
  26. void HelloWorld::menuItemStartCallback(Ref* pSender)
  27. {
  28. MenuItem* item = (MenuItem*)pSender;
  29. log("Touch Start %p", item);
  30. if (UserDefault::getInstance()->getBoolForKey(SOUND_KEY)) {                      ③
  31. SimpleAudioEngine::getInstance()->playEffect("sound/Blip.wav");
  32. }
  33. }
  34. void HelloWorld::onEnter()
  35. {
  36. Layer::onEnter();
  37. log("HelloWorld onEnter");
  38. }
  39. void HelloWorld::onEnterTransitionDidFinish()
  40. {
  41. Layer::onEnterTransitionDidFinish();
  42. log("HelloWorld onEnterTransitionDidFinish");
  43. //播放
  44. if (UserDefault::getInstance()->getBoolForKey(MUSIC_KEY)) {                      ④
  45. SimpleAudioEngine::getInstance()->playBackgroundMusic("sound/Jazz.mp3", true);
  46. }
  47. }
  48. void HelloWorld::onExit()
  49. {
  50. Layer::onExit();
  51. log("HelloWorld onExit");
  52. }
  53. void HelloWorld::onExitTransitionDidStart()
  54. {
  55. Layer::onExitTransitionDidStart();
  56. log("HelloWorld onExitTransitionDidStart");
  57. }
  58. void HelloWorld::cleanup()
  59. {
  60. Layer::cleanup();
  61. log("HelloWorld cleanup");
  62. //停止
  63. SimpleAudioEngine::getInstance()->stopBackgroundMusic("sound/Jazz.mp3");
  64. }

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

  1. #include "SettingScene.h"
  2. USING_NS_CC;
  3. using namespace CocosDenshion;
  4. bool Setting::init()
  5. {
  6. ... ...
  7. UserDefault *defaults  = UserDefault::getInstance();
  8. if (defaults->getBoolForKey(MUSIC_KEY)) {                                    ①
  9. musicToggleMenuItem->setSelectedIndex(0);                                ②
  10. } else {
  11. musicToggleMenuItem->setSelectedIndex(1);                                ③
  12. }
  13. if (defaults->getBoolForKey(SOUND_KEY)) {                                    ④
  14. soundToggleMenuItem->setSelectedIndex(0);                                ⑤
  15. } else {
  16. soundToggleMenuItem->setSelectedIndex(1);                                ⑥
  17. }
  18. return true;
  19. }

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

  1. void Setting::menuSoundToggleCallback(Ref* pSender)
  2. {
  3. auto soundToggleMenuItem = (MenuItemToggle*)pSender;
  4. log("soundToggleMenuItem %d", soundToggleMenuItem->getSelectedIndex());
  5. UserDefault *defaults  = UserDefault::getInstance();
  6. if (defaults->getBoolForKey(SOUND_KEY)) {                                    ①
  7. defaults->setBoolForKey(SOUND_KEY, false);                               ②
  8. } else {
  9. defaults->setBoolForKey(SOUND_KEY, true);                                ③
  10. SimpleAudioEngine::getInstance()->playEffect("sound/Blip.wav");                  ④
  11. }
  12. }

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

  1. void Setting::menuMusicToggleCallback(Ref* pSender)
  2. {
  3. auto musicToggleMenuItem = (MenuItemToggle*)pSender;
  4. log("musicToggleMenuItem %d", musicToggleMenuItem->getSelectedIndex());
  5. UserDefault *defaults  = UserDefault::getInstance();
  6. if (defaults->getBoolForKey(MUSIC_KEY)) {                                    ①
  7. defaults->setBoolForKey(MUSIC_KEY, false);
  8. SimpleAudioEngine::getInstance()->stopBackgroundMusic();
  9. } else {
  10. defaults->setBoolForKey(MUSIC_KEY, true);
  11. SimpleAudioEngine::getInstance()->playBackgroundMusic("sound/Synth.mp3");
  12. }                                                                           ②
  13. }

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

  1. void Setting::onEnter()
  2. {
  3. Layer::onEnter();
  4. log("Setting onEnter");
  5. }
  6. void Setting::menuOkCallback(Ref* pSender)                                  ①
  7. {
  8. Director::getInstance()->popScene();
  9. if (UserDefault::getInstance()->getBoolForKey(SOUND_KEY)) {                      ②
  10. SimpleAudioEngine::getInstance()->playEffect("sound/Blip.wav");
  11. }
  12. }
  13. void Setting::onEnterTransitionDidFinish()                                      ③
  14. {
  15. Layer::onEnterTransitionDidFinish();
  16. log("Setting onEnterTransitionDidFinish");
  17. if (UserDefault::getInstance()->getBoolForKey(MUSIC_KEY)) {                      ④
  18. //播放
  19. SimpleAudioEngine::getInstance()->playBackgroundMusic("sound/Synth.mp3", true);
  20. }
  21. }
  22. void Setting::onExit()
  23. {
  24. Layer::onExit();
  25. log("Setting onExit");
  26. }
  27. void Setting::onExitTransitionDidStart()
  28. {
  29. Layer::onExitTransitionDidStart();
  30. log("Setting onExitTransitionDidStart");
  31. }
  32. void Setting::cleanup()
  33. {
  34. Layer::cleanup();
  35. log("Setting cleanup");
  36. //停止
  37. SimpleAudioEngine::getInstance()->stopBackgroundMusic("sound/Synth.mp3");
  38. }

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

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

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

Cocos2d-x使用UserDefault数据持久化实例:保存背景音乐和音效设置的更多相关文章

  1. Cocos2d-x实例:设置背景音乐与音效-设置场景实现

    设置场景(Setting),Setting.h文件代码如下: #ifndef __Setting_SCENE_H__ #define __Setting_SCENE_H__ #include &quo ...

  2. 深入理解iPhone数据持久化(手把手教你iphone开发 – 基础篇)

    在所有的移动开发平台数据持久化都是很重要的部分:在j2me中是rms或保存在应用程序的目录中,在symbian中可以保存在相应的磁盘目录中和数据库中.symbian中因为权限认证的原因,在3rd上大多 ...

  3. Swift使用NSKeyedArchiver进行数据持久化保存的经验

    iOS提供了几种数据持久化保存的方法,有NSKeyedArchiver,Property List,NSUserDefaults和CoreData.我学习下来,觉得保存应用内的诸如列表,记录这些东西, ...

  4. iOS数据持久化-OC

    沙盒详解 1.IOS沙盒机制 IOS应用程序只能在为该改程序创建的文件系统中读取文件,不可以去其它地方访问,此区域被成为沙盒,所以所有的非代码文件都要保存在此,例如图像,图标,声音,映像,属性列表,文 ...

  5. iOS之数据持久化方案

    概论 所谓的持久化,就是将数据保存到硬盘中,使得在应用程序或机器重启后可以继续访问之前保存的数据.在iOS开发中,有很多数据持久化的方案,接下来我将尝试着介绍一下5种方案: plist文件(属性列表) ...

  6. iOS的数据持久化

    所谓的持久化,就是将数据保存到硬盘中,使得在应用程序或机器重启后可以继续访问之前保存的数据.在iOS开发中,有很多数据持久化的方案,接下来我将尝试着介绍一下5种方案: plist文件(属性列表) pr ...

  7. iOS开发中的4种数据持久化方式【二、数据库 SQLite3、Core Data 的运用】

                   在上文,我们介绍了ios开发中的其中2种数据持久化方式:属性列表.归档解档.本节将继续介绍另外2种iOS持久化数据的方法:数据库 SQLite3.Core Data 的运 ...

  8. iOS开发中的4种数据持久化方式【一、属性列表与归档解档】

    iOS中的永久存储,也就是在关机重新启动设备,或者关闭应用时,不会丢失数据.在实际开发应用时,往往需要持久存储数据的,这样用户才能在对应用进行操作后,再次启动能看到自己更改的结果与痕迹.ios开发中, ...

  9. iOS - OC 数据持久化

    1.Sandbox 沙箱 iOS 为每个应用提供了独立的文件空间,一个应用只能直接访问为本应用分配的文件目录,不可以访问其他目录,每个应用自己独立的访问空间被称为该应用的沙盒.也就是说,一个应用与文件 ...

随机推荐

  1. PPTP + FreeRADIUS + MySQL 安装与配置

    原文地址:http://www.zhukun.net/archives/5375 PPTP + FreeRADIUS + MySQL 安装与配置 2012/03/29Linux运维centos.Fre ...

  2. 教你50招提升ASP.NET性能(二十):认识你的循环

    (31)Know your loops 招数31: 认识你的循环 for is the fastest way of iterating over a collection, foreach is a ...

  3. cocos2d 制作动态光晕效果基础 —— blendFunc

    转自:http://blog.csdn.net/yang3wei/article/details/7795764 最近的项目要求动态光晕的效果. 何谓动态光晕?之前不知道别人怎么称呼这个效果, 不过在 ...

  4. PostgreSQL的 initdb 源代码分析之十二

    继续分析 /* Now create all the text config files */ setup_config(); 将其展开: 实质就是,确定各种参数,分别写入 postgresql.co ...

  5. windows 下实现函数打桩:拦截API方式

    windows 下实现函数打桩:拦截API方式            近期由于工作须要,開始研究函数打桩的方法. 由于不想对project做过多的改动,于是放弃了使用Google gmock的想法. ...

  6. EasyUI改动DateBox和DateTimeBox的默认日期格式

    近期整理Easyui控件的时候,对Easyui的DateBox控件和DateTimeBox控件进行了梳理,而我之所以将EasyUI的DateBox控件和DateTimeBox控件放在一起,归为一类,是 ...

  7. CSS3/jQuery自己定义弹出窗体

    简单演示一下,精简了演示效果和css样式文件,更利于在项目中的实际应用 引入style.css   index.js <!DOCTYPE HTML PUBLIC "-//W3C//DT ...

  8. 架构师之路(39)---IoC框架

    1 IoC理论的背景     我们都知道,在採用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,全部的对象通过彼此的合作,终于实现系统的业务逻辑.   图1:软件系统中耦合的对象 假设 ...

  9. head first c&lt;11&gt;初探网络编程上

    server连接网络四部曲. 为了与外界沟通,c程序用数据流读写字节.比較经常使用的数据流有标准输入.标准输出.文件等. 假设想写一个与网络通信的程序.就须要一种新的数据流----------套接字. ...

  10. C语言连接MySQL数据库(课程设计总结)

    刚结束课程设计,也预示着假期立即就要到来了.本次课程设计并不算难,无非就是让做一个XXX系统,实现用户的注冊.登录.菜单管理.超级用户等等一些功能,到如今为止已经做过好几个了,所以基本流程都熟悉了! ...