单例类在大部分游戏中应该是必不可少的部分,如整个游戏音乐的开关控制、数据的加载与存储等都需要一个全局访问点来控制,那就需要用到单例类了。
【3.x】
shared***() 改为 getInstance() 。好了,言归正传,为什么我们要用单例来设计游戏呢,参考这句话:
众所周知,游戏开发中离不开游戏数据保存和加载。这些数据包括关卡数据、游戏进行中的状态数据等。这样一些信息很多游戏模块中都需要访问,所以可以为之设置一个单例对象。我武断地认为,客户端游戏开发中,至少需要一个单例对象。因为一个全局的访问点可以方便很多对象之间的交互。
-----------------------------------------------------
下面介绍单例的简单使用方法:
1、声明一个类:
- class TestSingleton : public cocos2d::Layer
- {
- public:
- static TestSingleton* getInstance();//创建一个全局访问点,例如我们常用的Director::getInstance()就是这样一个单例
- void test();//测试单例时用到。
- private:
- static TestSingleton* m_singleton;
- };
- TestSingleton* TestSingleton::m_singleton = nullptr;//m_singleton指向空指针
- TestSingleton* TestSingleton::getInstance()
- {
- //判断m_singleton是否已被实例化, 如果没有,将之实例
- if(nullptr == m_singleton)
- {
- m_singleton = new TestSingleton();//
- }
- return m_singleton;
- }
- void TestSingleton::test()
- {
- CCLOG("test testSingleton success~~");
- }
我直接在HelloWorld这里测试。代码如下:
- bool HelloWorld::init()
- {
- TestSingleton::getInstance()->test();//调用TestSingleton里的test(),看控制台是否输出success
- }
很明显是成功的,我就不贴结果啦。
4、释放
单例这东西用起来一定要谨慎谨慎再谨慎,如非万不得已,尽可能别用吧。因为大家要考虑这么一个问题:单例是什么时候被释放的?按目前实现的方法,单例是直到游戏退出时才释放的!所以当游戏中使用过多的单例是十分浪费空间,或者说根本不能容忍的!
在网上查找了一些释放单例的办法。这篇博客总结了挺多,大家可以按自身申请使用。http://blog.csdn.net/gogogo/article/details/7009862
因为Director也使用到了单例,我看了下,它是在析构函数里将单例置NULL。然后再调用Director::getInstance()->end();后把释放标志_purgeDirectorInNextLoop=true;然后在下一帧执行Director::purgeDirector()方法。其中最后的release()才释放内存。
实例二:
1、cocos2dx中的单例模式
cocos2dx中其实存在很多的单例类,相信大家也都接触过。
例如:CCDirector、SimpleAudioEngine、CCUserDefault、CCSpriteFrameCache等都是用了单例模式,并可以通过shared***()来获取单例对象,如CCDirector::sharedDirector()。
2、创建单例类
2.1、声明.h
1
2
3
4
5
6
7
8
9
10
11
12
13
|
//
class
Global : cocos2d::CCObject {
private
:
static
Global* m_global;
//唯一静态实例对象m_global
public
:
static
Global* shareGlobal();
//获取全局访问点m_global
//其他属性函数的声明
//......
};
//
|
2.2、定义实现.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
//
//初始化单例唯一实例对象m_global
Global* Global::m_global = NULL;
//获取全局访问点
Global* Global::shareGlobal()
{
//判断m_global是否已被实例化,如果没有,将之实例
if
(m_global == NULL) {
m_global =
new
Global();
}
return
m_global;
}
//其他函数的定义实现
//......
//
|