前言:

  手游项目《天天打蚊子》终于上线,特地写几篇技术分享文章,分享一下其中使用到的技术,其中使用cocos2d-x引擎,首选平台iOS,也请有iPhone或者iPad的朋友帮忙下载好评。十分感谢。

目前完美支持iPhone4、iPhone 4S、iPhone 5、iPad所有版本,iOS 5以上开始支持。

  目前开发团队3个人,本人客户端+服务端,另有1名客户端,1名美术,目前创业刚刚起步,请各位好友支持!

  《天天打蚊子》下载地址:https://itunes.apple.com/cn/app/id681203794

  

一、Cocos2d-x中的数据存储。

1、CCUserDefault数据存储

CCUserDefault头文件:

 class CC_DLL CCUserDefault
{
public:
~CCUserDefault(); // get value methods /**
@brief Get bool value by key, if the key doesn't exist, a default value will return.
You can set the default value, or it is false.
*/
bool getBoolForKey(const char* pKey);
bool getBoolForKey(const char* pKey, bool defaultValue);
/**
@brief Get integer value by key, if the key doesn't exist, a default value will return.
You can set the default value, or it is 0.
*/
int getIntegerForKey(const char* pKey);
int getIntegerForKey(const char* pKey, int defaultValue);
/**
@brief Get float value by key, if the key doesn't exist, a default value will return.
You can set the default value, or it is 0.0f.
*/
float getFloatForKey(const char* pKey);
float getFloatForKey(const char* pKey, float defaultValue);
/**
@brief Get double value by key, if the key doesn't exist, a default value will return.
You can set the default value, or it is 0.0.
*/
double getDoubleForKey(const char* pKey);
double getDoubleForKey(const char* pKey, double defaultValue);
/**
@brief Get string value by key, if the key doesn't exist, a default value will return.
You can set the default value, or it is "".
*/
std::string getStringForKey(const char* pKey);
std::string getStringForKey(const char* pKey, const std::string & defaultValue); // set value methods /**
@brief Set bool value by key.
*/
void setBoolForKey(const char* pKey, bool value);
/**
@brief Set integer value by key.
*/
void setIntegerForKey(const char* pKey, int value);
/**
@brief Set float value by key.
*/
void setFloatForKey(const char* pKey, float value);
/**
@brief Set double value by key.
*/
void setDoubleForKey(const char* pKey, double value);
/**
@brief Set string value by key.
*/
void setStringForKey(const char* pKey, const std::string & value);
/**
@brief Save content to xml file
*/
void flush(); static CCUserDefault* sharedUserDefault();
static void purgeSharedUserDefault();
const static std::string& getXMLFilePath();
static bool isXMLFileExist(); private:
CCUserDefault();
static bool createXMLFile();
static void initXMLFilePath(); static CCUserDefault* m_spUserDefault;
static std::string m_sFilePath;
static bool m_sbIsFilePathInitialized;
};

CCUserDefault.h

  其中包括多种方法(getBoolForKey,getFloatForKey,getIntegerForKey等等),可根据具体需要存储的数据类型进行选择。

具体实现:

  比如在游戏开发过程中,要实现本地存储新手引导中的某一步是否已经访问过,我可以这样:

 bool DataHelper::getIsVisit(EnumNewUserGuid type)
{
const char * key = CCString::createWithFormat("NewUserGuid_%d",type)->getCString();
return CCUserDefault::sharedUserDefault()->getBoolForKey(key, false);
} void DataHelper::setVisit(EnumNewUserGuid type)
{
const char * key = CCString::createWithFormat("NewUserGuid_%d",type)->getCString();
CCUserDefault::sharedUserDefault()->setBoolForKey(key, true);
}

  其中,EnumNewUserGuid为新手引导的步骤的枚举。

  下面将使用CCUserDefault实现音效管理。

2、iOS keychain数据存储

  上篇文章讲到iOS keychain的数据存储方法,本文加上为C++的接口。keychain.h keychain.m文件再贴一次。

 #import <Foundation/Foundation.h>

 @interface Keychain : NSObject
//keychain
+ (NSMutableDictionary *)getKeychainQuery:(NSString *)service;
+ (void)saveData:(NSString *)service data:(id)data;
+ (id)loadData:(NSString *)service;
+ (void)deleteData:(NSString *)service;
@end

keychain.h

 #import "Keychain.h"

 @implementation Keychain

 //keychain
+ (NSMutableDictionary *)getKeychainQuery:(NSString *)service
{
NSMutableDictionary * dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
(id)kSecClassGenericPassword,(id)kSecClass,
service, (id)kSecAttrService,
service, (id)kSecAttrAccount,
(id)kSecAttrAccessibleAfterFirstUnlock,(id)kSecAttrAccessible,
nil];
return dict;
} + (void)saveData:(NSString *)service data:(id)data
{
//Get search dictionary
NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
//Delete old item before add new item
SecItemDelete((CFDictionaryRef)keychainQuery);
//Add new object to search dictionary(Attention:the data format)
[keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(id)kSecValueData];
//Add item to keychain with the search dictionary
SecItemAdd((CFDictionaryRef)keychainQuery, NULL);
} + (id)loadData:(NSString *)service
{
id ret = nil;
NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
//Configure the search setting
//Since in our simple case we are expecting only a single attribute to be returned (the password) we can set the attribute kSecReturnData to kCFBooleanTrue
[keychainQuery setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
[keychainQuery setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
CFDataRef keyData = NULL;
if (SecItemCopyMatching((CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) {
@try {
ret = [NSKeyedUnarchiver unarchiveObjectWithData:(NSData *)keyData];
} @catch (NSException *e) {
CLog(@"Unarchive of %@ failed: %@", service, e);
} @finally {
}
}
if (keyData)
CFRelease(keyData);
return ret;
} + (void)deleteData:(NSString *)service
{
NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
SecItemDelete((CFDictionaryRef)keychainQuery);
} @end

keychain.m

  下面用keychain记录本地账号:

DBInfoAccount.h

 #include "cocos2d.h"

 using namespace cocos2d;

 class DBInfoAccount {

 public:

     int m_iUserID;
CCString * m_pAccountID;
CCString * m_pPassword; DBInfoAccount();
static DBInfoAccount * getInstance();
bool isHasAccount(); //数据存取
void loadData();
static void saveData();
static void reset();
};

DBInfoAccount.mm

 #import "Keychain.h"
#include "DBInfoAccount.h" //#define kAccount @"Account"
#define kAccountAccountID @"Account_Account_ID"
#define kAccountUserID @"Account_UserID"
#define kAccountPassword @"Account_Pwd" static DBInfoAccount * s_pDBInfoAccount = NULL; DBInfoAccount::DBInfoAccount():
m_iUserID()
{
m_pAccountID = new CCString("");
m_pPassword = new CCString("");
} DBInfoAccount * DBInfoAccount::getInstance()
{
if (s_pDBInfoAccount == NULL) {
s_pDBInfoAccount -> loadData();
if (s_pDBInfoAccount == NULL) {
s_pDBInfoAccount = new DBInfoAccount;
}
} return s_pDBInfoAccount;
} bool DBInfoAccount::isHasAccount()
{
return m_pAccountID!= NULL && m_pAccountID -> length()>;
} void DBInfoAccount::loadData()
{
if (s_pDBInfoAccount == NULL) {
NSString * accountID = [Keychain loadData: kAccountAccountID];
NSString * userID = [Keychain loadData: kAccountUserID];
NSString * password = [Keychain loadData: kAccountPassword];
s_pDBInfoAccount = new DBInfoAccount;
const char * c_accountID = [accountID cStringUsingEncoding:NSUTF8StringEncoding];
DWORD c_userID = [userID intValue];
const char * c_password = [password cStringUsingEncoding:NSUTF8StringEncoding]; if (c_accountID != NULL && c_password != NULL) {
s_pDBInfoAccount -> m_pAccountID -> m_sString = c_accountID;
s_pDBInfoAccount -> m_iUserID = c_userID;
s_pDBInfoAccount -> m_pPassword -> m_sString = c_password;
}
}
} void DBInfoAccount::saveData()
{
NSString * accountID = [NSString stringWithCString:s_pDBInfoAccount->m_pAccountID->getCString() encoding:NSUTF8StringEncoding];
NSString * userID = [NSString stringWithFormat:@"%d",s_pDBInfoAccount->m_iUserID];
NSString * password = [NSString stringWithCString:s_pDBInfoAccount->m_pPassword->getCString() encoding:NSUTF8StringEncoding];
[Keychain saveData:kAccountAccountID data: accountID];
[Keychain saveData:kAccountUserID data: userID];
[Keychain saveData:kAccountPassword data: password];
} void DBInfoAccount::reset()
{
[Keychain deleteData:kAccountAccountID];
[Keychain deleteData:kAccountUserID];
[Keychain deleteData:kAccountPassword];
}

  具体用法一目了然,不再赘述。

二、音效管理。

  废话不说,直接上代码:

  void DataHelper::initMusicAndEffect()
{
bool isEffectEnabel = DataHelper::getEffectEnable();
CocosDenshion::SimpleAudioEngine::sharedEngine()->setEffectsVolume(isEffectEnabel); bool isMusicEnable = DataHelper::getMusicEnable();
CocosDenshion::SimpleAudioEngine::sharedEngine()->setBackgroundMusicVolume(isMusicEnable);
}
bool DataHelper::getEffectEnable()
{
return CCUserDefault::sharedUserDefault()->getBoolForKey("Effect_Enable", true);
}
bool DataHelper::getMusicEnable()
{
return CCUserDefault::sharedUserDefault()->getBoolForKey("Music_Enable", true);
}
void DataHelper::setEffectEnable(bool isEnable)
{
CCUserDefault::sharedUserDefault()->setBoolForKey("Effect_Enable", isEnable);
CocosDenshion::SimpleAudioEngine::sharedEngine()->setEffectsVolume(isEnable);
}
void DataHelper::setMusicEnable(bool isEnable)
{
CCUserDefault::sharedUserDefault()->setBoolForKey("Music_Enable", isEnable);
CocosDenshion::SimpleAudioEngine::sharedEngine()->setBackgroundMusicVolume(isEnable);
}

  其中,CocosDenshion::SimpleAudioEngine::sharedEngine()->setEffectsVolume(isEffectEnabel),setEffectsVolume为设置的音效大小(0~1)的方法,这里使用false(0)和true(1)直接设置,实现是否设置为静音。

  至于播放背景音乐和音效,最好使用mp3格式的,iOS和安卓同时支持。

  具体:

 CocosDenshion::SimpleAudioEngine::sharedEngine()->playBackgroundMusic("bg.mp3", true);//播放背景音乐,第二个参数为是否循环播放

 CocosDenshion::SimpleAudioEngine::sharedEngine()->playEffect("anjian.mp3");//播放音效,比如按键声

《天天打蚊子》下载地址:https://itunes.apple.com/cn/app/id681203794

请各位多多支持,给个好评呀!谢谢!或者扫描二维码下载:

游戏视频:

后续cocos2d-x技术文章陆续放出,敬请关注!!

Cocos2d-x手游技术分享(1)-【天天打蚊子】数据存储与音效篇的更多相关文章

  1. Memcache技术分享:介绍、使用、存储、算法、优化、命中率

    1.memcached 介绍 1.1 memcached 是什么? memcached 是以LiveJournal旗下Danga Interactive 公司的Brad Fitzpatric 为首开发 ...

  2. 【恒天云技术分享系列10】OpenStack块存储技术

    原文:http://www.hengtianyun.com/download-show-id-101.html 块存储,简单来说就是提供了块设备存储的接口.用户需要把块存储卷附加到虚拟机(或者裸机)上 ...

  3. Kooboo CMS技术文档之三:切换数据存储方式

    切换数据存储方式包括以下几种: 将文本内容存储在SqlServer.MySQL.MongoDB等数据库中 将站点配置信息存储在数据库中 将后台用户信息存储在数据库中 将会员信息存储在数据库中 将图片. ...

  4. 建一座安全的“天空城” ——揭秘腾讯WeTest如何与祖龙共同挖掘手游安全漏洞

    作者:腾讯WeTest手游安全测试团队商业转载请联系腾讯WeTest获得授权,非商业转载请注明出处. WeTest导读 <九州天空城3D>上线至今,长期稳定在APP Store畅销排行的前 ...

  5. Unity手游引擎安全解析及实践

    近日,由Unity主办的"Unity技术开放日"在广州成功举办,网易移动安全技术专家卓辉作为特邀嘉宾同现场400名游戏开发者分享了网易在手游安全所积累的经验.当下,很多手游背后都存 ...

  6. 龙之谷手游WebVR技术分享

    主要面向Web前端工程师,需要一定Javascript及three.js基础:本文主要分享内容为基于three.js开发WebVR思路及碰到的问题:有兴趣的同学,欢迎跟帖讨论. 目录:一.项目体验1. ...

  7. 手游录屏直播技术详解 | 直播 SDK 性能优化实践

    在上期<直播推流端弱网优化策略 >中,我们介绍了直播推流端是如何优化的.本期,将介绍手游直播中录屏的实现方式. 直播经过一年左右的快速发展,衍生出越来越丰富的业务形式,也覆盖越来越广的应用 ...

  8. 【腾讯Bugly干货分享】手游热更新方案xLua开源:Unity3D下Lua编程解决方案

    本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:http://mp.weixin.qq.com/s/2bY7A6ihK9IMcA0bOFyB-Q 导语 xL ...

  9. UWP 手绘视频创作工具技术分享系列

    开篇先来说一下写这篇文章的初衷. 初到来画,通读了来画 UWP App 的代码,发现里面确实有很多比较高深的技术点,同时也是有很多问题的,扩展性,耦合,性能,功能等等.于是我们决定从头重构这个产品,做 ...

随机推荐

  1. 2. C/C++笔试面试经典题目二

    1. C和C++中struct有什么区别? [参考答案] [解析]C中的struct没有保护行为,没有public,private,protected,内部不能有函数,但可以有函数指针. 2. C++ ...

  2. Linux常用的命令(3)

    1 文件的内容显示 cat 显示全部 more: 分屏幕显示,只能向后翻 less: 分屏幕显示,可以向上翻 head:查看前n行 默认10行 tail:查看后n行 -n -f: 查看文件尾部,不退出 ...

  3. Freeman链码

    [简介] 链码(又称为freeman码)是用曲线起始点的坐标和边界点方向代码来描述曲线或边界的方法,常被用来在图像处理.计算机图形学.模式识别等领域中表示曲线和区域边界.它是一种边界的编码表示法,用边 ...

  4. c语言和c++的相互调用

    1.c与c++编译方式 (1)gcc和g++都可以编译.c文件,也都可以编译.cpp文件.g++和gcc是通过后缀名来辨别是c程序还是c++程序的(这一点与Linux辨别文件的方式不同,Linux是通 ...

  5. Hibernate 环境配置和依赖添加(使用java web和普通javaSE工程)

    1.Hibernate依赖包的添加 File---->Project Structure,按照如图所示操作,导入所依赖的jar包. 2.生成hibernate.hbm.xml的配置文件 (1)点 ...

  6. hdu6437 Videos 费用流

    题目传送门 题目大意: 给出n,每天有n个小时.有m种电影,每个电影有开始时间和结束时间,和01两种种类,k个人,每一部电影只能被一个人看,会获得一个快乐值wi,如果一个人连续看两部相同种类的电影,快 ...

  7. ZOJ - 2042 模运算DP

    解法见网上参考 这种只判断可达性的DP一般用bool 除非int能得到更多的信息 #include<iostream> #include<algorithm> #include ...

  8. 1091 N-自守数 (15 分)

    如果某个数 K 的平方乘以 N 以后,结果的末尾几位数等于 K,那么就称这个数为“N-自守数”.例如 3×92​2​​=25392,而 25392 的末尾两位正好是 92,所以 92 是一个 3-自守 ...

  9. Hibernate复合主键的注解

    [转自] http://blog.csdn.net/happylee6688/article/details/17636801 最近做项目用到了Hibernate框架,采用了纯面向对象的思想,使用OR ...

  10. C++ GUI Qt4编程(05)-2.2GoToCell

    1. 使用Qt设计师创建GoToCell对话框. 2. gotocelldialog.cpp #include <QRegExp> #include "gotocelldialo ...