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

#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文件。

更多内容请关注最新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课堂微信公共平台

时间: 2024-10-28 09:34:28

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

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

设置场景SettingSetting.h文件代码如下 #ifndef __Setting_SCENE_H__ #define __Setting_SCENE_H__ #include "cocos2d.h" #include "SimpleAudioEngine.h" class Setting : public cocos2d::Layer { bool isEffect; ① public: static cocos2d::Scene* createScene(

Cocos2d-x实例:设置背景音乐与音效- AppDelegate实现

为了进一步了解背景音乐和音效播放的我们通过一个实例给大家介绍一下.如下图所示有两个场景HelloWorld和Setting.在HelloWorld场景点击"游戏设置"菜单可以切换到Setting场景在Setting场景中可以设置是否播放背景音乐和音效设置完成后点击"OK"菜单可以返回到HelloWorld场景.    我们需要在AppDelegate中实现背景音乐播放暂停与继续函数AppDelegate.h文件代码如下 #ifndef _APP_DELEGATE_H

浅谈数据持久化

PS:一些小小的见解,不做之处,还望朋友们多多指导. 数据持久化值得是数据存储方式,在.net中可以利用session.cookie对象保 存用户登录状态,application对象配置应用程序. 这篇文章主要讲解数据的本地存储方案. DataSet类操作讲解 以xml文件保存数据 基于SQLite轻量级数据库保存数 据 基于access数据库保存数据 基于SQLServer数据库保存 1.在讲解数据保存方案前简述一下.net中dataset类,dataset类基本上是内存 中的数据库,其中包含

iOS学习之数据持久化详解

前言 持久存储是一种非易失性存储,在重启设备时也不会丢失数据.Cocoa框架提供了几种数据持久化机制: 1)属性列表: 2)对象归档: 3)iOS的嵌入式关系数据库SQLite3: 4)Core Data. 在iOS开发中,持久化数据的方法也并不限于属性列表.对象归档.SQLite3和Core Data.它们只是四种最常用且简单的方法.其实也可以使用传统C语言I/O调用(比如,fopen())读写数据,也可以使用Cocoa的底层文件管理工具.只不过这两种方法都需要写很多代码,并且没有必要这么做.

iOS中几种数据持久化方案:我要永远地记住你!

概论 所谓的持久化,就是将数据保存到硬盘中,使得在应用程序或机器重启后可以继续访问之前保存的数据.在iOS开发中,有很多数据持久化的方案,接下来我将尝试着介绍一下5种方案: plist文件(属性列表) preference(偏好设置) NSKeyedArchiver(归档) SQLite 3 CoreData 沙盒 在介绍各种存储方法之前,有必要说明以下沙盒机制.iOS程序默认情况下只能访问程序自己的目录,这个目录被称为"沙盒". 1.结构 既然沙盒就是一个文件夹,那就看看里面有什么吧

Android数据持久化之读写SD卡中内容的方法详解

本文实例讲述了Android数据持久化之读写SD卡中内容的方法.分享给大家供大家参考,具体如下: 前面文章里讲的那三个方法:openFileOutput .openFileInput 虽然都能通过流对象OutputStream和InputStream可以处理任意文件中的数据,但与 SharedPreferences 一样,只能在手机内存的指定目录下建立文件,因此,在实际的开发使用中有很大的局限性,那么在这一节中,我们来看一个比较高级的方法来实现数据的持久化--读写SD卡上的内容. --读取ass

Android数据持久化之I/O操作详解

本文实例讲述了Android数据持久化之I/O操作.分享给大家供大家参考,具体如下: 前面文章里我们简单的介绍了File的操作,这一节来说说使用android平台自带对象实现文件的基本操作 主要的两个类:openFileOutput(写)和openFileInput(读) 向文件中写如数据代码如下: //向文件写入内容 try { OutputStream os = openFileOutput("file-io.txt", Context.MODE_PRIVATE); String

iOS - Swift 数据持久化

1.Sandbox 沙箱 iOS 为每个应用提供了独立的文件空间,一个应用只能直接访问为本应用分配的文件目录,不可以访问其他目录,每个应用自己独立的访问空间被称为该应用的沙盒.也就是说,一个应用与文件系统的交互绝大部分都被限制在它自己的应用沙盒内. 1)在新 App 被安装时,安装器会为应用创建一系列角色不同的容器(container). iOS 8.0 之后,bundle 目录和沙盒目录 (Data) 是分开的.iOS 7.0 及以前版本 bundle 目录和沙盒目录 (Data) 是在一起的

详解Android开发数据持久化之文件存储(附源码)

其实我们在社交网络上面所发出的任何信息, 都希望能够保留下来. 那么如何实现呢? 数据持久化 数据持久化, 就是将内存中的瞬时数据保存在存储设备中, 保证即便关机之后, 数据仍然存在. 保存在内存中的数据是瞬时数据, 保存在存储设备中的数据就是处于持久状态的. 持久化技术则是提供了一种机制可以让数据在瞬时状态和持久状态之间进行转换, Android系统中主要提供了3种方式用于简单地实现数据持久化功能, 即文件存储, SharePreference存储, 以及数据库存储. 当然你也可以将数据保存在