1.Cocos2d-x-3.2编写3d打飞机,粒子管理器代码



Cocos2d-x中的一个单例效果:

#ifndef __Moon3d__ParticleManager__

#define __Moon3d__ParticleManager__

#include "cocos2d.h"

USING_NS_CC;

class ParticleManager

{

public:

static ParticleManager* getInstance()//定义获取实例方法,单例设计模式.see notes

{

if ( m_pInstance == nullptr )//如果实例为空,

m_pInstance = new ParticleManager();//创建实例

return m_pInstance;//返回实例

}

private:

ParticleManager();//构造函数

static ParticleManager* m_pInstance;//粒子管理器实例

class CGarbo//内部类,主要作用是退出游戏的时候,清理内存,原理:程序在结束的时候,系统会自动析构所有的全局变量。事实上,系统也会析构所有的类的静态成员变量,就像这些静态成员也是全局变量一样。

{

public:

~CGarbo()//析构函数

{

if (ParticleManager::m_pInstance!= nullptr)//如果实例不为空

{

delete ParticleManager::m_pInstance;//清除单例

}

}

};

static CGarbo m_garbo;//定义内部类变量

public:

std::map<string,ValueMap> m_plistMap;//定义存放粒子数据的集合

void AddPlistData(string strPlist,133); font-family:新宋体; font-size:9.5pt">string strName);//把粒子数据添加到集合里

ValueMap GetPlistData(string strName);//从粒子集合中获取粒子数据

};

#endif /* defined(__Moon3d__ParticleManager__) */

#include "ParticleManager.h"

ParticleManager* ParticleManager::m_pInstance=NULL;//变量初始化

ParticleManager::CGarbo ParticleManager::m_garbo;//变量初始化

ParticleManager()

{

m_plistMap.clear();//构造函数集合清理

}

void ParticleManager::string strName)

{

auto plistData=FileUtils::getInstance()->getValueMapFromFile(strPlist);//获取粒子数据

ValueMap>::iterator it = m_plistMap.begin();//获取集合

m_plistMap.insert(it,133); font-family:新宋体; font-size:9.5pt">pair<ValueMap>(strName,plistData));//把粒子数据存放到集合里

}

ValueMap string strplist)

{

auto plistData=m_plistMap.find(strplist)->second;//获取粒子数据

return plistData;//返回粒子数据

}

说明:

/*****************************************************************************

单例模式也称为单件模式、单子模式,可能是使用最广泛的设计模式。其意图是保证一个类仅有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。有很多地方需要这样的功能模块,如系统的日志输出,GUI应用必须是单鼠标,MODEM的联接需要一条且只需要一条电话线,操作系统只能有一个窗口管理器,一台PC连一个键盘。

单例模式有许多种实现方法,在C++中,甚至可以直接用一个全局变量做到这一点,但这样的代码显的很不优雅。 使用全局对象能够保证方便地访问实例,但是不能保证只声明一个对象——也就是说除了一个全局实例外,仍然能创建相同类的本地实例。

《设计模式》一书中给出了一种很不错的实现,定义一个单例类,使用类的私有静态指针变量指向类的唯一实例,并用一个公有的静态方法获取该实例。

单例模式通过类本身来管理其唯一实例,这种特性提供了解决问题的方法。唯一的实例是类的一个普通对象,但设计这个类时,让它只能创建一个实例并提供对此实例的全局访问。唯一实例类Singleton在静态成员函数中隐藏创建实例的操作。习惯上把这个成员函数叫做Instance(),它的返回值是唯一实例的指针。

定义如下:

[cpp] view plaincopy

class CSingleton

{

private:

CSingleton() //构造函数是私有的

{

}

static CSingleton *m_pInstance;

public:

static CSingleton * GetInstance()

{

if(m_pInstance == NULL) //判断是否第一次调用

m_pInstance = new CSingleton();

return m_pInstance;

}

};

用户访问唯一实例的方法只有GetInstance()成员函数。如果不通过这个函数,任何创建实例的尝试都将失败,因为类的构造函数是私有的。GetInstance()使用懒惰初始化,也就是说它的返回值是当这个函数首次被访问时被创建的。这是一种防弹设计——所有GetInstance()之后的调用都返回相同实例的指针:

CSingleton* p1 = CSingleton :: GetInstance();

CSingleton* p2 = p1->GetInstance();

CSingleton & ref = * CSingleton :: GetInstance();

GetInstance稍加修改,这个设计模板便可以适用于可变多实例情况,如一个类允许最多五个实例。

单例类CSingleton有以下特征:

它有一个指向唯一实例的静态指针m_pInstance,并且是私有的;

它有一个公有的函数,可以获取这个唯一的实例,并且在需要的时候创建该实例;

它的构造函数是私有的,这样就不能从别处创建该类的实例。

大多数时候,这样的实现都不会出现问题。有经验的读者可能会问,m_pInstance指向的空间什么时候释放呢?更严重的问题是,该实例的析构函数什么时候执行?

如果在类的析构行为中有必须的操作,比如关闭文件,释放外部资源,那么上面的代码无法实现这个要求。我们需要一种方法,正常的删除该实例。

可以在程序结束时调用GetInstance(),并对返回的指针掉用delete操作。这样做可以实现功能,但不仅很丑陋,而且容易出错。因为这样的附加代码很容易被忘记,而且也很难保证在delete之后,没有代码再调用GetInstance函数。

一个妥善的方法是让这个类自己知道在合适的时候把自己删除,或者说把删除自己的操作挂在操作系统中的某个合适的点上,使其在恰当的时候被自动执行。

我们知道,程序在结束的时候,系统会自动析构所有的全局变量。事实上,系统也会析构所有的类的静态成员变量,就像这些静态成员也是全局变量一样。利用这个特征,我们可以在单例类中定义一个这样的静态成员变量,而它的唯一工作就是在析构函数中删除单例类的实例。如下面的代码中的CGarbo类(Garbo意为垃圾工人):

[cpp] view plaincopy

class CSingleton

{

private:

CSingleton()

{

}

static CSingleton *m_pInstance;

class CGarbo //它的唯一工作就是在析构函数中删除CSingleton的实例

{

public:

~CGarbo()

{

if(CSingleton::m_pInstance)

delete CSingleton::m_pInstance;

}

};

static CGarbo Garbo; //定义一个静态成员变量,程序结束时,系统会自动调用它的析构函数

public:

static CSingleton * GetInstance()

{

if(m_pInstance == NULL) //判断是否第一次调用

m_pInstance = new CSingleton();

return m_pInstance;

}

};

CGarbo被定义为CSingleton的私有内嵌类,以防该类被在其他地方滥用。

程序运行结束时,系统会调用CSingleton的静态成员Garbo的析构函数,该析构函数会删除单例的唯一实例。

使用这种方法释放单例对象有以下特征:

在单例类内部定义专有的嵌套类;

在单例类内定义私有的专门用于释放的静态成员;

利用程序在结束时析构全局变量的特性,选择最终的释放时机;

使用单例的代码不需要任何操作,不必关心对象的释放。

进一步的讨论

但是添加一个类的静态对象,总是让人不太满意,所以有人用如下方法来重新实现单例和解决它相应的问题,代码如下:

[cpp] view plaincopy

class CSingleton

{

private:

CSingleton() //构造函数是私有的

{

}

public:

static CSingleton & GetInstance()

{

static CSingleton instance; //局部静态变量

return instance;

}

};

使用局部静态变量,非常强大的方法,完全实现了单例的特性,而且代码量更少,也不用担心单例销毁的问题。

但使用此种方法也会出现问题,当如下方法使用单例时问题来了,

Singleton singleton = Singleton :: GetInstance();

这么做就出现了一个类拷贝的问题,这就违背了单例的特性。产生这个问题原因在于:编译器会为类生成一个默认的构造函数,来支持类的拷贝。

最后没有办法,我们要禁止类拷贝和类赋值,禁止程序员用这种方式来使用单例,当时领导的意思是GetInstance()函数返回一个指针而不是返回一个引用,函数的代码改为如下:

[cpp] view plaincopy

class CSingleton

{

private:

CSingleton() //构造函数是私有的

{

}

public:

static CSingleton * GetInstance()

{

static CSingleton instance; //局部静态变量

return &instance;

}

};

但我总觉的不好,为什么不让编译器不这么干呢。这时我才想起可以显示的声明类拷贝的构造函数,和重载 = 操作符,新的单例类如下:

[cpp] view plaincopy

class CSingleton

{

private:

CSingleton() //构造函数是私有的

{

}

CSingleton(const CSingleton &);

CSingleton & operator = (const CSingleton &);

public:

static CSingleton & GetInstance()

{

static CSingleton instance; //局部静态变量

return instance;

}

};

关于Singleton(const Singleton); Singleton & operate = (const Singleton&);函数,需要声明成私有的,并且只声明不实现。这样,如果用上面的方式来使用单例时,不管是在友元类中还是其他的,编译器都是报错。

不知道这样的单例类是否还会有问题,但在程序中这样子使用已经基本没有问题了。

考虑到线程安全、异常安全,可以做以下扩展

[cpp] view plaincopy

class Lock

{

private:

CCriticalSection m_cs;

public:

Lock(CCriticalSection cs) : m_cs(cs)

{

m_cs.Lock();

}

~Lock()

{

m_cs.Unlock();

}

};

class Singleton

{

private:

Singleton();

Singleton(const Singleton &);

Singleton& operator = (const Singleton &);

public:

static Singleton *Instantialize();

static Singleton *pInstance;

static CCriticalSection cs;

};

Singleton* Singleton::pInstance = 0;

Singleton* Singleton::Instantialize()

{

if(pInstance == NULL)

{ //double check

Lock lock(cs); //lock实现线程安全,用资源管理类,实现异常安全

//使用资源管理类,在抛出异常的时候,资源管理类对象会被析构,析构总是发生的无论是因为异常抛出还是语句块结束。

if(pInstance == NULL)

{

pInstance = new Singleton();

}

}

return pInstance;

}

之所以在Instantialize函数里面对pInstance 是否为空做了两次判断,因为该方法调用一次就产生了对象,pInstance == NULL 大部分情况下都为false,如果按照原来的方法,每次获取实例都需要加锁,效率太低。而改进的方法只需要在第一次 调用的时候加锁,可大大提高效率。

*/

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


    本文实践自 RayWenderlich、Ali Hafizji 的文章《How To Create Dynamic Textures with CCRenderTexture in Cocos2D 2.X》,文中使用Cocos2D,我在这里使用Cocos2D-x 2.1.4进行学习和移植。在这篇文章,将会学习到如何创建实时纹理、如何用Gimp创建无缝拼接纹
Cocos-code-ide使用入门学习地点:杭州滨江邮箱:appdevzw@163.com微信公众号:HopToad 欢迎转载,转载标注出处:http://blog.csdn.netotbaron/article/details/424343991.  软件准备 下载地址:http://cn.cocos2d-x.org/download 2.  简介2.1         引用C
第一次開始用手游引擎挺激动!!!进入正题。下载资源1:从Cocos2D-x官网上下载,进入网页http://www.cocos2d-x.org/download,点击Cocos2d-x以下的Download  v3.0,保存到自定义的文件夹2:从python官网上下载。进入网页https://www.python.org/downloads/,我当前下载的是3.4.0(当前最新
    Cocos2d-x是一款强大的基于OpenGLES的跨平台游戏开发引擎,易学易用,支持多种智能移动平台。官网地址:http://cocos2d-x.org/当前版本:2.0    有很多的学习资料,在这里我只做为自己的笔记记录下来,错误之处还请指出。在VisualStudio2008平台的编译:1.下载当前稳
1.  来源 QuickV3sample项目中的2048样例游戏,以及最近《最强大脑》娱乐节目。将2048改造成一款挑战玩家对数字记忆的小游戏。邮箱:appdevzw@163.com微信公众号:HopToadAPK下载地址:http://download.csdn.net/detailotbaron/8446223源码下载地址:http://download.csdn.net/
   Cocos2d-x3.x已经支持使用CMake来进行构建了,这里尝试以QtCreatorIDE来进行CMake构建。Cocos2d-x3.X地址:https://github.com/cocos2d/cocos2d-x1.打开QtCreator,菜单栏→"打开文件或项目...",打开cocos2d-x目录下的CMakeLists.txt文件;2.弹出CMake向导,如下图所示:设置
 下载地址:链接:https://pan.baidu.com/s/1IkQsMU6NoERAAQLcCUMcXQ提取码:p1pb下载完成后,解压进入build目录使用vs2013打开工程设置平台工具集,打开设置界面设置: 点击开始编译等待编译结束编译成功在build文件下会出现一个新文件夹Debug.win32,里面就是编译
分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!http://www.captainbed.net前言上次用象棋演示了cocos2dx的基本用法,但是对cocos2dx并没有作深入的讨论,这次以超级马里奥的源代码为线索,我们一起来学习超级马里奥的实
1. 圆形音量button事实上作者的本意应该是叫做“电位计button”。可是我觉得它和我们的圆形音量button非常像,所以就这么叫它吧~先看效果:好了,不多解释,本篇到此为止。(旁白: 噗。就这样结束了?)啊才怪~我们来看看代码:[cpp] viewplaincopyprint?CCContro
原文链接:http://www.cnblogs.com/physwf/archive/2013/04/26/3043912.html为了进一步深入学习贯彻Cocos2d,我们将自己写一个场景类,但我们不会走的太远,凡是都要循序渐进,哪怕只前进一点点,那也至少是前进了,总比贪多嚼不烂一头雾水的好。在上一节中我们建
2019独角兽企业重金招聘Python工程师标准>>>cocos2d2.0之后加入了一种九宫格的实现,主要作用是用来拉伸图片,这样的好处在于保留图片四个角不变形的同时,对图片中间部分进行拉伸,来满足一些控件的自适应(PS: 比如包括按钮,对话框,最直观的形象就是ios里的短信气泡了),这就要求图
原文链接:http://www.cnblogs.com/linji/p/3599478.html1.环境和工具准备Win7VS2010/2012,至于2008v2版本之后似乎就不支持了。 2.安装pythonv.2.0版本之前是用vs模板创建工程的,到vs2.2之后就改用python创建了。到python官网下载版本2.7.5的,然后
环境:ubuntu14.04adt-bundle-linux-x86_64android-ndk-r9d-linux-x86_64cocos2d-x-3.0正式版apache-ant1.9.3python2.7(ubuntu自带)加入环境变量exportANDROID_SDK_ROOT=/home/yangming/adt-bundle-linux/sdkexportPATH=${PATH}:/$ANDROID_SDK_ROOTools/export
1开发背景游戏程序设计涉及了学科中的各个方面,鉴于目的在于学习与进步,本游戏《FlappyBird》采用了两个不同的开发方式来开发本款游戏,一类直接采用win32底层API来实现,另一类采用当前火热的cocos2d-x游戏引擎来开发本游戏。2需求分析2.1数据分析本项目要开发的是一款游
原文链接:http://www.cnblogs.com/linji/p/3599912.html//纯色色块控件(锚点默认左下角)CCLayerColor*ccc=CCLayerColor::create(ccc4(255,0,0,128),200,100);//渐变色块控件CCLayerGradient*ccc=CCLayerGradient::create(ccc4(255,0,0,
原文链接:http://www.cnblogs.com/linji/p/3599488.html//载入一张图片CCSprite*leftDoor=CCSprite::create("loading/door.png");leftDoor->setAnchorPoint(ccp(1,0.5));//设置锚点为右边中心点leftDoor->setPosition(ccp(240,160));/
为了答谢广大学员对智捷课堂以及关老师的支持,现购买51CTO学院关老师的Cocos2d-x课程之一可以送智捷课堂编写图书一本(专题可以送3本)。一、Cocos2d-x课程列表:1、Cocos2d-x入门与提高视频教程__Part22、Cocos2d-x数据持久化与网络通信__Part33、Cocos2d-x架构设计与性能优化内存优
Spawn让多个action同时执行。Spawn有多种不同的create方法,最终都调用了createWithTwoActions(FiniteTimeAction*action1,FiniteTimeAction*action2)方法。createWithTwoActions调用initWithTwoActions方法:对两个action变量初始化:_one=action1;_two=action2;如果两个a
需要环境:php,luajit.昨天在cygwin上安装php和luajit环境,这真特么是一个坑。建议不要用虚拟环境安装打包环境,否则可能会出现各种莫名问题。折腾了一下午,最终将环境转向linux。其中,luajit的安装脚本已经在quick-cocos2d-x-develop/bin/中,直接luajit_install.sh即可。我的lin
v3.0相对v2.2来说,最引人注意的。应该是对触摸层级的优化。和lambda回调函数的引入(嗯嗯,不枉我改了那么多类名。话说,每次cocos2dx大更新。总要改掉一堆类名函数名)。这些特性应该有不少人研究了,所以今天说点跟图片有关的东西。v3.0在载入图片方面也有了非常大改变,仅仅只是