Cocos2d-x使用UserDefault数据持久化实例:保存背景音乐和音效设置
UserDefault可以实现数据的存储,但是它的使用不能泛滥,具体讲一般情况下不会使用它保存大量的数据,它没有SQL语句那样的灵活。UserDefault除了保存游戏设置外,还有可以长期保持游戏精灵等对象的状态。
我们通过一个实例介绍一下在游戏项目中如何使用UserDefault。如图所示,在Setting场景中可以设置是否播放背景音乐和音效,现在我们将它完善将选择的状态保存到UserDefault中。
我们需要定义两个宏作为键,其中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头文件添加到HelloWorldScene.h和SettingScene.h头文件中,示例代码如下:
- #ifndef __HELLOWORLD_SCENE_H__
- #define __HELLOWORLD_SCENE_H__
- #include "cocos2d.h"
- #include "SettingScene.h"
- #include "SystemHeader.h"
- class HelloWorld : public cocos2d::Layer
- {
- public:
- … …
- CREATE_FUNC(HelloWorld);
- };
- #endif // __HELLOWORLD_SCENE_H__
下面我们看看HelloWorld场景HelloWorldScene.cpp主要代码如下:
- #include "HelloWorldScene.h"
- USING_NS_CC;
- using namespace CocosDenshion;
- bool HelloWorld::init()
- {
- ... ...
- return true;
- }
- void HelloWorld::menuItemSettingCallback(Ref* pSender)
- {
- auto sc = Setting::createScene();
- auto reScene = TransitionJumpZoom::create(1.0f, sc);
- Director::getInstance()->pushScene(reScene);
- if (UserDefault::getInstance()->getBoolForKey(SOUND_KEY)) { ①
- SimpleAudioEngine::getInstance()->playEffect("sound/Blip.wav");
- }
- }
- void HelloWorld::menuItemHelpCallback(Ref* pSender)
- {
- MenuItem* item = (MenuItem*)pSender;
- log("Touch Help %p", item);
- if (UserDefault::getInstance()->getBoolForKey(SOUND_KEY)) { ②
- SimpleAudioEngine::getInstance()->playEffect("sound/Blip.wav");
- }
- }
- void HelloWorld::menuItemStartCallback(Ref* pSender)
- {
- MenuItem* item = (MenuItem*)pSender;
- log("Touch Start %p", item);
- if (UserDefault::getInstance()->getBoolForKey(SOUND_KEY)) { ③
- SimpleAudioEngine::getInstance()->playEffect("sound/Blip.wav");
- }
- }
- void HelloWorld::onEnter()
- {
- Layer::onEnter();
- log("HelloWorld onEnter");
- }
- void HelloWorld::onEnterTransitionDidFinish()
- {
- Layer::onEnterTransitionDidFinish();
- log("HelloWorld onEnterTransitionDidFinish");
- //播放
- if (UserDefault::getInstance()->getBoolForKey(MUSIC_KEY)) { ④
- SimpleAudioEngine::getInstance()->playBackgroundMusic("sound/Jazz.mp3", true);
- }
- }
- void HelloWorld::onExit()
- {
- Layer::onExit();
- log("HelloWorld onExit");
- }
- void HelloWorld::onExitTransitionDidStart()
- {
- Layer::onExitTransitionDidStart();
- log("HelloWorld onExitTransitionDidStart");
- }
- void HelloWorld::cleanup()
- {
- Layer::cleanup();
- log("HelloWorld cleanup");
- //停止
- SimpleAudioEngine::getInstance()->stopBackgroundMusic("sound/Jazz.mp3");
- }
上述第①、②、③行代码中UserDefault::getInstance()->getBoolForKey(SOUND_KEY)是获得sound_key键值,通过取出布尔值判断是否播放音效。第④行代码UserDefault::getInstance()->getBoolForKey(MUSIC_KEY)是获得music_key键值,通过取出布尔值判断是否播放背景音乐。
下面我们再看看Setting场景SettingScene.cpp中的init()主要代码如下:
- #include "SettingScene.h"
- USING_NS_CC;
- using namespace CocosDenshion;
- bool Setting::init()
- {
- ... ...
- UserDefault *defaults = UserDefault::getInstance();
- if (defaults->getBoolForKey(MUSIC_KEY)) { ①
- musicToggleMenuItem->setSelectedIndex(0); ②
- } else {
- musicToggleMenuItem->setSelectedIndex(1); ③
- }
- if (defaults->getBoolForKey(SOUND_KEY)) { ④
- soundToggleMenuItem->setSelectedIndex(0); ⑤
- } else {
- soundToggleMenuItem->setSelectedIndex(1); ⑥
- }
- return true;
- }
上述代码是设置开关菜单的状态,第①~③行代码是设置背景音乐开关菜单,其中第②行代码是设置开关菜单为Off,否则通过第③行代码设置状态为On。第④~⑥行代码是设置音效开关菜单,其中第⑤行代码是设置开关菜单为Off,否则通过第⑥行代码设置状态为On。
SettingScene.cpp中的点击音效开关菜单代码如下:
- void Setting::menuSoundToggleCallback(Ref* pSender)
- {
- auto soundToggleMenuItem = (MenuItemToggle*)pSender;
- log("soundToggleMenuItem %d", soundToggleMenuItem->getSelectedIndex());
- UserDefault *defaults = UserDefault::getInstance();
- if (defaults->getBoolForKey(SOUND_KEY)) { ①
- defaults->setBoolForKey(SOUND_KEY, false); ②
- } else {
- defaults->setBoolForKey(SOUND_KEY, true); ③
- SimpleAudioEngine::getInstance()->playEffect("sound/Blip.wav"); ④
- }
- }
上述代码第①行判断音效开状态为true情况下,通过defaults->setBoolForKey(SOUND_KEY, false)语句设置false,否则通过第③行代码defaults->setBoolForKey(SOUND_KEY, true)语句设置true,同时通过第④行代码播放音效。
SettingScene.cpp中的点击背景音乐开关菜单代码如下:
- void Setting::menuMusicToggleCallback(Ref* pSender)
- {
- auto musicToggleMenuItem = (MenuItemToggle*)pSender;
- log("musicToggleMenuItem %d", musicToggleMenuItem->getSelectedIndex());
- UserDefault *defaults = UserDefault::getInstance();
- if (defaults->getBoolForKey(MUSIC_KEY)) { ①
- defaults->setBoolForKey(MUSIC_KEY, false);
- SimpleAudioEngine::getInstance()->stopBackgroundMusic();
- } else {
- defaults->setBoolForKey(MUSIC_KEY, true);
- SimpleAudioEngine::getInstance()->playBackgroundMusic("sound/Synth.mp3");
- } ②
- }
上述代码第①~②行是设置背景音乐开关菜单。代码与点击音效开关菜单类似,不再解释。还有SettingScene.cpp中的其它主要代码如下:
- void Setting::onEnter()
- {
- Layer::onEnter();
- log("Setting onEnter");
- }
- void Setting::menuOkCallback(Ref* pSender) ①
- {
- Director::getInstance()->popScene();
- if (UserDefault::getInstance()->getBoolForKey(SOUND_KEY)) { ②
- SimpleAudioEngine::getInstance()->playEffect("sound/Blip.wav");
- }
- }
- void Setting::onEnterTransitionDidFinish() ③
- {
- Layer::onEnterTransitionDidFinish();
- log("Setting onEnterTransitionDidFinish");
- if (UserDefault::getInstance()->getBoolForKey(MUSIC_KEY)) { ④
- //播放
- SimpleAudioEngine::getInstance()->playBackgroundMusic("sound/Synth.mp3", true);
- }
- }
- void Setting::onExit()
- {
- Layer::onExit();
- log("Setting onExit");
- }
- void Setting::onExitTransitionDidStart()
- {
- Layer::onExitTransitionDidStart();
- log("Setting onExitTransitionDidStart");
- }
- void Setting::cleanup()
- {
- Layer::cleanup();
- log("Setting cleanup");
- //停止
- SimpleAudioEngine::getInstance()->stopBackgroundMusic("sound/Synth.mp3");
- }
上述代码第①行menuOkCallback是点击Ok菜单回调函数,其中第②行代码是获得sound_key键值,通过取出布尔值判断是否播放音效。第③行代码onEnterTransitionDidFinish函数是在进入层而且过渡动画结束时候调用,第④行代码是获得music_key键值,通过取出布尔值判断是否播放背景音乐。
我们可以运行一下先将状态保存,然后重新运行游戏,看看是否能够保持状态。我们还可以到<Cocos2d-x工程目录>\proj.win32\Debug.win32目录下看看是否成功生成了UserDefault.xml文件。
Cocos2d-x使用UserDefault数据持久化实例:保存背景音乐和音效设置的更多相关文章
- Cocos2d-x实例:设置背景音乐与音效-设置场景实现
设置场景(Setting),Setting.h文件代码如下: #ifndef __Setting_SCENE_H__ #define __Setting_SCENE_H__ #include &quo ...
- 深入理解iPhone数据持久化(手把手教你iphone开发 – 基础篇)
在所有的移动开发平台数据持久化都是很重要的部分:在j2me中是rms或保存在应用程序的目录中,在symbian中可以保存在相应的磁盘目录中和数据库中.symbian中因为权限认证的原因,在3rd上大多 ...
- Swift使用NSKeyedArchiver进行数据持久化保存的经验
iOS提供了几种数据持久化保存的方法,有NSKeyedArchiver,Property List,NSUserDefaults和CoreData.我学习下来,觉得保存应用内的诸如列表,记录这些东西, ...
- iOS数据持久化-OC
沙盒详解 1.IOS沙盒机制 IOS应用程序只能在为该改程序创建的文件系统中读取文件,不可以去其它地方访问,此区域被成为沙盒,所以所有的非代码文件都要保存在此,例如图像,图标,声音,映像,属性列表,文 ...
- iOS之数据持久化方案
概论 所谓的持久化,就是将数据保存到硬盘中,使得在应用程序或机器重启后可以继续访问之前保存的数据.在iOS开发中,有很多数据持久化的方案,接下来我将尝试着介绍一下5种方案: plist文件(属性列表) ...
- iOS的数据持久化
所谓的持久化,就是将数据保存到硬盘中,使得在应用程序或机器重启后可以继续访问之前保存的数据.在iOS开发中,有很多数据持久化的方案,接下来我将尝试着介绍一下5种方案: plist文件(属性列表) pr ...
- iOS开发中的4种数据持久化方式【二、数据库 SQLite3、Core Data 的运用】
在上文,我们介绍了ios开发中的其中2种数据持久化方式:属性列表.归档解档.本节将继续介绍另外2种iOS持久化数据的方法:数据库 SQLite3.Core Data 的运 ...
- iOS开发中的4种数据持久化方式【一、属性列表与归档解档】
iOS中的永久存储,也就是在关机重新启动设备,或者关闭应用时,不会丢失数据.在实际开发应用时,往往需要持久存储数据的,这样用户才能在对应用进行操作后,再次启动能看到自己更改的结果与痕迹.ios开发中, ...
- iOS - OC 数据持久化
1.Sandbox 沙箱 iOS 为每个应用提供了独立的文件空间,一个应用只能直接访问为本应用分配的文件目录,不可以访问其他目录,每个应用自己独立的访问空间被称为该应用的沙盒.也就是说,一个应用与文件 ...
随机推荐
- iPhone Push消息全攻略.1
要做一个iPhone Push消息的需求,从简单test的开始. 1.先添加一个app ID 2.点击Edit来配置push服务. 3.生成两个证书,一个用于开发,一个用于发布. 4.按下图操作创建一 ...
- Failed to load session “ubuntu” -- 12.04
在使用ubuntu 12.04的时候,之前不喜欢Unity桌面,就按照网上提示的安装了Gnome桌面,并且成功了! 可是,最近又想把Unity装回来,心想,这不就是安装一软件的活嘛,很简单!于是就卸载 ...
- 超级终端和SecureCRT进行Console口的连接
国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html 内部邀请码:C8E245J (不写邀请码,没有现金送) 国 ...
- android开发在adapter中使用反射添加元素
android开发中最常用的控件之一就是listview,伴随listview还要有adapter和放入适配器的item.然后假设其中有一部分item的生成符合一定规律,Item item = new ...
- codeforces Gym 100500H H. ICPC Quest 水题
Problem H. ICPC QuestTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100500/a ...
- Android 4.1源码编译找不到资源文件解决办法
我们在Android framework中修改资源文件时,在Android 4.0之前,都是直接在sourcecode/frameworks/base/core/res/res下面添加对应的资源文件, ...
- mysql升级小结和mysql_upgrade的用途
http://blog.itpub.net/15480802/viewspace-1412259/ mysql升级 1 升级方式 分为In-place和out-of-place,前者直接覆盖当前版本, ...
- mydumper原理5
前言 之前介绍了Oracle官方的多线程逻辑导入导出工具mysqlpump,但已经操作过的同学会发现其多线程的单位还是表,换句话说, 单表依然是 单线程导出 .网易早已使用mydumper/myloa ...
- Python的基础--对象 转
对象(Objects)是python中数据的抽象,python中所有的数据均可以用对象或者是对象之间的关系来表示.每个对象均有标识符(identity).类型(type).值(value). 标识 ...
- 高级进程间通信之基于STREAMS的管道
基于STREAMS的管道(简称STREAMS管道,STREAMS pipe)是一个双向(全双工)管道.单个STREAMS管道就能向父.子进程提供双向的数据流. 将http://www.cnblogs. ...