先把我的思路分享一下:
因为之前有次做游戏中需要一个全局定时器,要求是不随游戏场景切换而停止。第一时间在百度很容易就找到一个源码,GlobalSchedule,但是这份源码实际运行起来是没有效果的,因为每次进入新的场景会清空schedule,导致在AppDelegate中的启动没有任何效果。
于是在朋友的帮助下,我对这份源码进行了改动,原理是onEnter()事件不会被父节点注销,详情可以参考官方对onEnter函数的解析。
代码改动后将计时器启动的代码写在了onEnter事件里。这样运行schedule起来就不会被清除了,可以实现全局定时。
【源码】
github地址:https://github.com/winterfeel/NewGlobalSchedule
GlobalSchedule.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
#ifndef GLOBALSCHEDULE_H_
#define GLOBALSCHEDULE_H_
#include "cocos2d.h"
USING_NS_CC;
/**
* 全局定时器
*/
class GlobalSchedule: public CCNode {
public:
virtual void onEnter();
// 开始全局定时器 fInterval: 时间间隔 ; fDelay: 延迟运行
static void start(float fInterval = 0.0f, float fDelay = 0.0f);
// 停止全局定时器
static void stop();
// 全局定时器暂停
static void pause();
// 全局定时器暂停恢复
static void resume();
// 全局定时器主逻辑实现
void globalUpdate();
private:
// 构造函数私有化,只能通过 start 来启用全局定时器
GlobalSchedule(float fInterval, float fDelay);
~GlobalSchedule();
// 静态变量保持单例
static GlobalSchedule* m_pSchedule;
};
#endif /* GLOBALSCHEDULE_H_ */
|
GlobalSchedule.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
#include "GlobalSchedule.h"
#define SCHEDULE CCDirector::sharedDirector()->getScheduler()
GlobalSchedule* GlobalSchedule::m_pSchedule = NULL;
GlobalSchedule::GlobalSchedule(float fInterval, float fDelay) {
CCLog("GlobalSchedule()");
CCAssert(!m_pSchedule, "已定义,不能重复定义");
//SCHEDULE->scheduleSelector(
// schedule_selector(GlobalSchedule::globalUpdate), this, fInterval,
/// false,
// kCCRepeatForever, fDelay);
this->onEnter();//这里进行了修改,不在这里直接启动计时器,而是在enter里面
m_pSchedule = this;
}
void GlobalSchedule::onEnter()
{
CCNode::onEnter();
schedule(schedule_selector(GlobalSchedule::globalUpdate), 60.0f);//在这里启动计时器
}
GlobalSchedule::~GlobalSchedule() {
CCLog("GlobalSchedule().~()");
unschedule(schedule_selector(GlobalSchedule::globalUpdate));
}
void GlobalSchedule::globalUpdate() {
CCLog("global update");
/*这里是你写的计时器发生代码*/
}
void GlobalSchedule::start(float fInterval, float fDelay) {
new GlobalSchedule(fInterval, fDelay);
}
void GlobalSchedule::stop() {
CCLog("GlobalSchedule().stop()");
CCAssert(m_pSchedule, "未定义");
CC_SAFE_DELETE(m_pSchedule);
}
|
【总结】
我在游戏中用这份源码可以实现即计时,不过在游戏进入后台的时候只能停止,然后进入前台时重新启动,还没有做到暂停、继续。实现起来应该不难,当时不需要就没写,大家可以自己发挥,写一个完善一下,哈哈~