`
810364804
  • 浏览: 773621 次
文章分类
社区版块
存档分类
最新评论

【Cocos2d-X游戏实战开发】捕鱼达人之单例对象的设计(二)

 
阅读更多

本系列学习教程使用的是cocos2d-x-2.1.4(最新版为cocos2d-x-2.1.5)

博主发现前两个系列的学习教程被严重抄袭,在这里呼吁大家请尊重开发者的劳动成果,

转载的时候请务必注明出处:http://blog.csdn.net/yangyu20121224/article/details/11180135

经过上一篇文章对整个框架进行简单的分析了之后,我们可以开始着手开发了。这里

采用增量开发的方式,每一次项目的更新都完成其中一部分功能,同时保持其可扩展

性。功能的复杂性逐轮递增。

一、创建项目

1、首先打开cocos2d-x-2.1.4目录下的“cocos2d-win32.vc2010.sln”文件,这里根据大家使用的VS版本而定。

2、打开之后,会看到左边的解决方案中有很多的项目文件,我们会在此基础上新建项目,这样的做的好处是我们不

需要在额外的关联cocos2d的类库,避免了编译项目时发生异常。大家也可以参考我之前总结过的一篇文章《解决

Cocos2d-X新建项目运行报错的问题

3、右击解决方案“Solution'cocos2d-win32.vc2010'”,点击“Add”->“New Project”。

4、新建项目名为“MyFishingJoy”,并且保存在“E:\Cocos2D-X Projects”文件夹下,这里视个人习惯而定。

5、点击"OK"按钮进入下一步,去掉Box2D前面默认的勾选项,因为我们在此项目中没有用到物理引擎。

6、点击“Finish”按钮,整个项目就新建好了。

写到这里,可能有些读者会觉得我很啰嗦,一个简单新建项目的过程就写了好几个步骤。但是博主写这个教程的时

候就考虑到针对大部分的读者,当然也包括很多刚刚接触Cocos2D-X的朋友们,也有很多都是从Java直接转过来

的,以前都没接触过C++,但是博主认为这不并不影响我们对于Cocos2D-X游戏引擎的学习以及对游戏开发的热情和

痴迷。虽然Cocos2D-X已经这一切都封装的非常好了,但是开发的难度还是很大的,尤其是对于刚刚入门的初学者

来说。所以博主这里只想写更详细一点,最好能详细到每一个步骤,每一个方法,让更多的人知道,其实开发游戏

也是soeasy!(不过对于这些简单的操作步骤,只会出现一次,在今后的教程中并不会重复出现)

二、创建数据

创建好项目之后,我们首先要做的不是急着写场景、写逻辑,而是为这些场景适配数据,所以我们先完成动态数

据FishingJoyData和静态数据StaticData两个类。根据上一篇文章的分析可以知道,这两个类在整个游戏过程中只可

能出现一个实例,并且贯穿着整个游戏过程。因为,我们不妨把它们设计为单例。

单例(singleton)是软件开发过程中常用的一个设计模式。它通过控制一个全局变量,以便拥有某些独占性资

源,并达到便于管理和访问的作用,但是其缺点也很致命。它在整个程序运行周期内几乎不会被释放。同时,滥用单

例会使代码耦合性增大,不易于扩展。因此,单例模式一直备受争议。

Cocos2D-X是一个很好地运用了单例的例子。在引擎内部,有许多单例,它们都以shared为开头出现,例如:

CCDirector *pDirector = CCDirector::sharedDirector();
CCTextureCache *sharedTextureCache = CCTextureCache::sharedTextureCache(); 


仿照Cocos2D-X的做法,我们也同样设计这两个数据类单例,即实现以下功能:

<1> 将类的构造函数、析构函数和初始化函数都设为私有,禁止外部创建的新的实例。

<2> 统一使用shared*接口访问唯一的实例,并在该接口中使用延迟初始化,在需要时才创建实例。

<3> 实现purge函数,在必要时调用,以清理不必要的内存。

最后别忘了,在Cocos2D-X中,所有的对象类都必须继承自CCObject或其子类。

三、项目编码

1、新建StaticData

<1> 首先我们要新建一个类,右击该项目,点击“Add”->“Class”。

<2>在弹出的对话框中,选择“C++ Class”。

<3>然后在接下来的对话框中,取名为“staticData”,继承自CCObject类。

<4>点击“Finish”按钮,在目录中可以看到刚刚新建好的“StaticData.h”和“StaticData.cpp”这两个文件

2、对StaticData编码

<1> StaticData.h头文件。定义这个类的作用主要是通过它可以很方便的读取“.plist”数据文件,根据键值来调用

外部的静态存储数据,以后更改数据也会非常的方便,比如图片的存放路径,金币的初始数量等等

#ifndef __FishingJoy__StaticData__
#define __FishingJoy__StaticData__

#include "cocos2d.h"

#define STATIC_DATA_STRING(key) StaticData::sharedStaticData()->stringFromKey(key)
#define STATIC_DATA_INT(key) StaticData::sharedStaticData()->intFromKey(key)
#define STATIC_DATA_FLOAT(key) StaticData::sharedStaticData()->floatFromKey(key)
#define STATIC_DATA_BOOLEAN(key) StaticData::sharedStaticData()->booleanFromKey(key)
#define STATIC_DATA_POINT(key) StaticData::sharedStaticData()->pointFromKey(key)
#define STATIC_DATA_RECT(key) StaticData::sharedStaticData()->rectFromKey(key)
#define STATIC_DATA_SIZE(key) StaticData::sharedStaticData()->sizeFromKey(key)

class StaticData : public cocos2d::CCObject
{
public:
	static StaticData* sharedStaticData();

    /**
     *	@brief	 外部访问接口
	 *
     *	@param 	key 	对应的static_data.plist中的Key
     *	@return	对应的Value
     */
    const char* stringFromKey(std::string key);
    int intFromKey(std::string key);
    float floatFromKey(std::string key);
    bool booleanFromKey(std::string key);
    cocos2d::CCPoint pointFromKey(std::string key);
    cocos2d::CCRect rectFromKey(std::string key);
    cocos2d::CCSize sizeFromKey(std::string key);
    
    /**
     *	@brief	 内存不足时调用
     */
    void purge();
    
    CC_SYNTHESIZE_READONLY(std::string, _staticDataPath, StaticDataPath);

protected:
    cocos2d::CCDictionary* _dictionary;
private:
    StaticData();
    ~StaticData();
    bool init();
};

#endif


<2> StaticData.cpp文件。

#include "StaticData.h"

USING_NS_CC;

using namespace std;

//定义文件的路径
#define STATIC_DATA_PATH "static_data.plist"

//定义StaticData对象
static StaticData* _sharedStaticData = NULL;

//得到StaticData单例对象
StaticData* StaticData::sharedStaticData()
{
    if(_sharedStaticData == NULL){
        _sharedStaticData = new StaticData();
        _sharedStaticData->init();
    }
    return _sharedStaticData;
}

StaticData::StaticData()
{
    _staticDataPath = STATIC_DATA_PATH;
}

StaticData::~StaticData()
{
    CC_SAFE_RELEASE_NULL(_dictionary);
}

//初始化
bool StaticData::init()
{
    _dictionary = CCDictionary::createWithContentsOfFile(_staticDataPath.c_str());
    CC_SAFE_RETAIN(_dictionary);
    return true;
}

//根据键值得到String类型数据
const char* StaticData::stringFromKey(string key)
{
    return _dictionary->valueForKey(key)->getCString();
}

//根据键值得到int类型数据
int StaticData::intFromKey(string key)
{
    return _dictionary->valueForKey(key)->intValue();
}

//根据键值得到float类型数据
float StaticData::floatFromKey(string key)
{
    return _dictionary->valueForKey(key)->floatValue();
}

//根据键值得到bool类型数据
bool StaticData::booleanFromKey(string key)
{
    return _dictionary->valueForKey(key)->boolValue();
}

//根据键值得到point类型数据
cocos2d::CCPoint StaticData::pointFromKey(string key)
{
    return CCPointFromString(_dictionary->valueForKey(key)->getCString());
}

//根据键值得到rect类型数据
cocos2d::CCRect StaticData::rectFromKey(string key)
{
    return CCRectFromString(_dictionary->valueForKey(key)->getCString());
}

//根据键值得到size类型数据
cocos2d::CCSize StaticData::sizeFromKey(string key)
{
    return CCSizeFromString(_dictionary->valueForKey(key)->getCString());
}

//当内存不足时调用
void StaticData::purge()
{
    CC_SAFE_RELEASE_NULL(_sharedStaticData);
}


通过上面的代码,我们就可以很轻松地获得plist的数据,并转换成我们想要的数据类型。为了更快速地写代码,

我们还定义了一系列接口将重复性的操作进行封装,同时使用宏定义,使代码更加的简洁。

在其init方法中,调用CCDictionary接口,读取“static_data.plist”文件,保存在缓存中。通过把plist读取到

CCDictionary后,我们得到是一个键为string类型、值为CCObject对象的字典。具体来说,值类型有3种:CCString、

CCArray和CCDictionary。对于简单的键值对,我们使用CCString来保存数据(包括字符串类型与数值类型),而对

于数组与字典,则采用后两种类型来保存。

我们来看看static_data.plist中的数据:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>default_gold</key>
	<string>200</string>
</dict>
</plist>

可以看到,里面的数据都是以键值对的方式存储的,所以读取出来非常的方便,也易于管理。如果需要添加新的数

据的话,直接打开static_data.plist文件,以key-string的方式添加即可。


3、新建FishingJoyData

<1> 照着上面的方法,我们在新建一个FishingJoyData类。

<2>点击“Finish”按钮,在目录中可以看到刚刚新建好的这两个文件

4、对FishingJoyData编码

<1> FishingJoyData.h头文件。该类的作用主要是对玩家的数据进行持久化存储,其实就是对CCUserDefault相关操

作的封装。

#ifndef __FishingJoy__FishingJoyData__
#define __FishingJoy__FishingJoyData__

#include "cocos2d.h"

class FishingJoyData : public cocos2d::CCObject
{
public:
    static FishingJoyData* sharedFishingJoyData();
    CC_SYNTHESIZE(int , _gold, Gold);
    CC_SYNTHESIZE(bool, _isBeginner, IsBeginner);
    CC_SYNTHESIZE(float, _soundVolume, SoundVolume);
    CC_SYNTHESIZE(float, _musicVolume, MusicVolume);
    
    //内存不足时调用
    void purge();
    
    //将数据从内存保存到外部文件中
    void flush();
    
    //对Gold的操作
    void alterGold(int delta);

    //重置游戏数据为默认数值
    void reset();

protected:
    FishingJoyData();
    ~FishingJoyData();
    bool init();
};

#endif 


<2> FishingJoyData.cpp文件。

#include "FishingJoyData.h"
#include "StaticData.h"

USING_NS_CC;

//定义FishingJoyData对象
static FishingJoyData* _sharedFishingJoyData = NULL;

//得到FishingJoyData单例对象
FishingJoyData* FishingJoyData::sharedFishingJoyData()
{
    if(_sharedFishingJoyData==NULL){
        _sharedFishingJoyData = new FishingJoyData();
        _sharedFishingJoyData->init();
    }
    return _sharedFishingJoyData;
}

//当内存不足时调用
void FishingJoyData::purge()
{
    CC_SAFE_RELEASE_NULL(_sharedFishingJoyData);
}

FishingJoyData::FishingJoyData()
{
    
}

FishingJoyData::~FishingJoyData()
{
    this->flush();
}

//初始化
bool FishingJoyData::init()
{
	//判断该玩家是否是第一次登录
    _isBeginner = CCUserDefault::sharedUserDefault()->getBoolForKey("beginner",true);

    if(_isBeginner == true){
        this->reset();
        this->flush();
        this->setIsBeginner(false);
    }else{
        _isBeginner = CCUserDefault::sharedUserDefault()->getBoolForKey("beginner");
        _soundVolume = CCUserDefault::sharedUserDefault()->getFloatForKey("sound");
        _musicVolume = CCUserDefault::sharedUserDefault()->getFloatForKey("music");
        _gold = CCUserDefault::sharedUserDefault()->getIntegerForKey("gold");
        CCUserDefault::sharedUserDefault()->purgeSharedUserDefault();
    }
    return true;
}

//重置游戏数据
void FishingJoyData::reset()
{
    int gold = STATIC_DATA_INT("default_gold");
    this->setGold(gold);
    this->setIsBeginner(true);
    this->setMusicVolume(1);
    this->setSoundVolume(1);
    this->flush();
}

//更新金币的数量
void FishingJoyData::alterGold(int delta)
{
    this->setGold(this->getGold()+delta);
}

//存储数据
void FishingJoyData::flush()
{
    CCUserDefault::sharedUserDefault()->setFloatForKey("sound", this->getSoundVolume());
    CCUserDefault::sharedUserDefault()->setBoolForKey("beginner", this->getIsBeginner());
    CCUserDefault::sharedUserDefault()->setIntegerForKey("gold", this->getGold());
    CCUserDefault::sharedUserDefault()->setFloatForKey("music", this->getMusicVolume());
    CCUserDefault::sharedUserDefault()->flush();
    CCUserDefault::sharedUserDefault()->purgeSharedUserDefault();
}

让我们一起来分析上面的这段代码:

<1>大多数游戏对于初学者都会有相应的新手引导,因此,除了金币数量、音乐音效和音量大小外,我们还需要一个

尔值,用于判断玩家是否为初学者。

<2> 在CCUserDefault的get*ForKey系列方法中,有两个参数:一个是字符串类型的键值,另一个是默认参数,它表

示找不到对应键值时返回的值。

<3> 在FishingJoyData类中,每次对CCUserDefault进行操作后,都会调用purgeSharedUserDefault()将其删除。这

是因为FishingJoyData和CCUserDefault中都保存着游戏的数据。因此,只在与外部文件交互时,我们才打开

CCUserDefault,保存数据,然后删除CCUserDefault,以此避免重复占用游戏数据,而对内存造成浪费。

<4>最后,别忘了在程序进入后台时调用flush方法,及时保存游戏数据。

关于CCUserDefault的详细讲解可以参考:http://blog.csdn.net/yangyu20121224/article/details/10857813

完成了游戏数据的封装,大家是不是觉得有些枯燥无味?尽管数据操作并不复杂,但没有看得见的图片和效果,总

是让人兴奋不起来的。但是,有了数据的铺垫,那么接下来我们制作场景的过程会更加的得心应手。



源码下载地址(百度云)

分享到:
评论

相关推荐

    【Cocos2d-X游戏实战开发】捕鱼达人之单例对象的设计(二)源码

    【Cocos2d-X游戏实战开发】捕鱼达人之单例对象的设计(二)源码 教程地址:http://blog.csdn.net/yangyu20121224/article/details/11180135

    【cocos2d-x IOS游戏开发-捕鱼达人9-13】鱼群产生

    9、【cocos2d-x IOS游戏开发-捕鱼达人9】鱼与动画 资源引用页: 10、【cocos2d-x IOS游戏开发-捕鱼达人10】鱼的产生和移动 资源引用页: 11、【cocos2d-x IOS游戏开发-捕鱼达人11】鱼的产生和移动:完善 资源引用页...

    【cocos2d-x IOS游戏开发-捕鱼达人4-8】章节代码

    4、【cocos2d-x IOS游戏开发-捕鱼达人4】基本游戏框架 资源引用页: 5、【cocos2d-x IOS游戏开发-捕鱼达人5】C++中函数代理与信号插槽机制 资源引用页: 6、【cocos2d-x IOS游戏开发-捕鱼达人6】实现开始菜单 资源...

    Cocos2d-x实战:JS卷——Cocos2d-JS开发

    资源名称:Cocos2d-x实战:JS卷——Cocos2d-JS开发内容简介:本书是介绍Cocos2d-x游戏编程和开发技术书籍,介绍了使用Cocos2d-JS中核心类、瓦片地图、物理引擎、音乐音效、数据持久化、网络通信、性能优化、多平台...

    精通COCOS2D-X游戏开发 基础卷_2016.4-P399-13961841.pdf

    精通COCOS2D-X游戏开发 精通COCOS2D-X游戏开发 精通COCOS2D-X游戏开发 精通COCOS2D-X游戏开发 精通COCOS2D-X游戏开发

    Cocos2D-X游戏开发技术精解

    资源名称:Cocos2D-X游戏开发技术精解内容简介:Cocos2D-X是一款支持多平台的 2D手机游戏引擎,支持iOS、Android、BlackBerry等众多平台。当前,很多移动平台流行的游戏,都是基于Cocos2D-X开发的。 《Cocos2D-X...

    cocos2d-x游戏开发实战精解

    本光盘是《Cocos2d-x游戏开发实战精解》一书的配书光盘,内容介绍如下。 (1)本书教学视频:该文件夹收录了本书的配套多媒体教学视频,可用暴风影音等视频播放器播放。 (2)本书源文件:该文件夹收录了本书涉及...

    【Cocos2d-X游戏实战开发】捕鱼达人之开始场景的创建(三)源码

    【Cocos2d-X游戏实战开发】捕鱼达人之开始场景的创建(三)源码 教程地址:http://blog.csdn.net/yangyu20121224/article/details/11397899

    Cocos2d-x高级开发教程

    书中汇聚了热门手机游戏《捕鱼达人》开发的实战经验,作者从最基础的内容开始,逐步深入地介绍了Cocos2d-x的相关知识点。此外,书中的教学资源获得《捕鱼达人》手机游戏的授权,读者可以从一流游戏开发中高起点地...

    大富翁手机游戏开发实战基于Cocos2d-x3.2引擎

    资源名称:大富翁手机游戏开发实战基于Cocos2d-x3.2引擎内容简介:李德国编著的《大富翁手机游戏开发实战(基于 Cocos2d-x3.2引擎)》使用Cocos2d-x游戏引擎技术,带领读者一步一步从零开始进行大富翁移动游戏的开发...

    Cocos2d-x高级开发教程制作自己的《捕鱼达人》

    Cocos2d-x高级开发教程:制作自己的《捕鱼达人》 图书简介: 《Cocos2d-x高级开发教程:制作自己的《捕鱼达人》》是国内第一本全面深入讲解Cocos2d-x进阶内容的图书,Cocos2d-x创始人王哲作序推荐,《捕鱼达人》开发...

    Cocos2d-x 3.x游戏开发实战pdf含目录

    Cocos2d-x 3.x游戏开发实战pdf含目录,内容详细,强烈推荐给大家。

    Cocos2D-X游戏开发技术精解.pdf

    《Cocos2D-X游戏开发技术精解》详细介绍如何使用Cocos2D-X引擎开发自己的移动平台游戏。全书共15章,主要内容包括:Cocos2D-X引擎简介;如何建立跨平台的开发环境;引擎的核心模块——渲染框架;如何实现动态画面和...

    【cocos2d-x IOS游戏开发-捕鱼达人14-17】炮弹的实现

    【cocos2d-x IOS游戏开发-捕鱼达人14】炮弹切换界面 【cocos2d-x IOS游戏开发-捕鱼达人15】炮弹攻击效果1 【cocos2d-x IOS游戏开发-捕鱼达人16】炮弹攻击效果2 【cocos2d-x IOS游戏开发-捕鱼达人17】炮弹攻击判定

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

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

    Cocos2d-x-3.x游戏开发之旅

    Cocos2d-x-3.x游戏开发之旅-钟迪龙著 全新pdf版和附书代码(代码为工程文件,可复制) 附带目录标签

    cocos2d-x实战项目

    cocos2d-x实战项目 01.cocos2d-x原理及环境配置.rar 03.cocostudio使用方法及UI控制.rar 04.XML文件读取与骨骼动画.rarcocos2d-x实战项目 01.cocos2d-x原理及环境配置.rar 03.cocostudio使用方法及UI控制.rar 04.XML...

    COCOS2D-X 捕鱼达人 (VS2010 C++)

    cocos2d-x2.25引擎建立的捕鱼达人,参照了《Cocos2d-x高级开发教程:制作自己的〈捕鱼达人〉》一书并做了改动。将代码导入cocos2d的projects文件夹内自创的工程文件夹里的proj.win32文件夹,resoutses则放在对应工程...

    Cocos2d-x游戏引擎实战开发炸弹超人

    Cocos2d-x 是一个支持多平台的 2D 手机游戏引擎

    Cocos2d-x游戏编程——C++篇 .iso

    Cocos2d-x游戏编程——C++篇(电子工业出版社,徐飞 著)书本配套的光盘代码,

Global site tag (gtag.js) - Google Analytics