1. 首页菜单

Cocos2d-x 3.x基础学习: 定时器更新schedule/update

2015年03月23日 10:43 0 点赞 0 评论 更新于 2025-11-21 18:13

在大部分游戏中,定时器是不可或缺的。它的作用是每隔一段时间执行相应的刷新函数,以更新游戏的画面、时间、进度、敌人的指令等。Cocos2d-x 为开发者提供了与定时器 schedule 相关的操作。这些操作函数的定义在 CCNode 中,因此基本上大多数的引擎类都可以设置定时器,例如 CCLayerCCSpriteCCMenu 等。

定时器更新的方式

定时器更新的方式主要分为以下三类:

  1. 默认定时器scheduleUpdate()
  2. 自定义定时器schedule()
  3. 一次性定时器scheduleOnce()

相关代码资源:定时器schedule、update.rar

默认定时器:scheduleUpdate()

scheduleUpdate() 是默认定时器,其默认刷新次数与屏幕刷新频率有关。例如,当屏幕刷新频率为 60 帧每秒时,scheduleUpdate() 每秒会执行 60 次刷新。与之对应的刷新函数体是 update(),即每一帧都会执行一次 update() 函数。

相关操作如下:

// 开启默认定时器,刷新间隔为一帧
void scheduleUpdate();

// 给予优先级 priority,priority 越小,优先级越高
void scheduleUpdateWithPriority(int priority);

// update 为 scheduleUpdate 定时器的刷新函数体
virtual void update(float delta);

自定义定时器:schedule()

schedule() 是自定义定时器,它允许开发者自定义指定的刷新函数体、刷新函数体的执行次数、刷新频率以及开始刷新的时间。刷新函数体不一定是 update(),可以由开发者自行定义。

相关操作如下:

// 设置自定义定时器,默认刷新间隔为一帧
// interval : 每隔 interval 秒执行一次
// repeat : 重复次数
// delay : 延迟时间,即创建定时器 delay 秒后开始执行刷新
// 示例:schedule( schedule_selector(HelloWorld::myUpdate), 1.0/60.0 );

// 默认刷新间隔为一帧
void schedule(SEL_SCHEDULE selector);

// 自定义刷新间隔,单位:秒
void schedule(SEL_SCHEDULE selector, float interval);

// 完整参数的自定义定时器设置
void schedule(SEL_SCHEDULE selector, float interval, unsigned int repeat, float delay);

一次性定时器:scheduleOnce()

scheduleOnce() 是一次性定时器,它在等待 delay 秒延迟时间后,只执行一次刷新函数体,之后就不再进行刷新。

相关操作如下:

// 只执行一次,delay 秒后执行
// 示例:scheduleOnce( schedule_selector(HelloWorld::myUpdate), 5.0 );
void scheduleOnce(SEL_SCHEDULE selector, float delay);

定时器的取消、暂停和恢复操作

// 取消默认定时器
void unscheduleUpdate(void);

// 取消自定义函数的定时器
void unschedule(SEL_SCHEDULE selector);

// 取消所有定时器
void unscheduleAllSelectors(void);

// 暂停所有定时器和动作
void pauseSchedulerAndActions(void);

// 恢复所有定时器和动作
void resumeSchedulerAndActions(void);

代码实战

1、在 HelloWorld::init() 中创建五个精灵

创建五个精灵,并使用五种定义定时器的方法,使精灵与定时器一一对应。

// 创建五个精灵
CCSprite* sp = CCSprite::create("Icon.png");
sp->setPosition( ccp(30, mysize.height - 30) );
this->addChild(sp, 0, 100); // tag 标记 100

CCSprite* sp1 = CCSprite::create("Icon.png");
sp1->setPosition( ccp(30, mysize.height - 90) );
this->addChild(sp1, 0, 101); // tag 标记 101

CCSprite* sp2 = CCSprite::create("Icon.png");
sp2->setPosition( ccp(30, mysize.height - 150) );
this->addChild(sp2, 0, 102); // tag 标记 102

CCSprite* sp3 = CCSprite::create("Icon.png");
sp3->setPosition( ccp(30, mysize.height - 210) );
this->addChild(sp3, 0, 103); // tag 标记 103

CCSprite* sp4 = CCSprite::create("Icon.png");
sp4->setPosition( ccp(30, mysize.height - 270) );
this->addChild(sp4, 0, 104); // tag 标记 104

// 定义五个定时器,更新精灵
this->scheduleUpdate();
this->schedule( schedule_selector(HelloWorld::myupdate) );
this->schedule( schedule_selector(HelloWorld::myupdate2), 1.0f );
this->schedule( schedule_selector(HelloWorld::myupdate3), 1.0f, 5, 3.0f);
this->scheduleOnce( schedule_selector(HelloWorld::myupdate4), 5.0f );

2、编写定时器对应的刷新函数体

// scheduleUpdate
void HelloWorld::update(float dt)
{
CCSprite* sp = (CCSprite*)this->getChildByTag(100); // 获取 tag=100 的精灵
sp->setPosition( sp->getPosition() + ccp(1,0) ); // 每帧移动 1
}

// schedule(schedule_selector)
void HelloWorld::myupdate(float dt)
{
CCSprite* sp1 = (CCSprite*)this->getChildByTag(101); // 获取 tag=101 的精灵
sp1->setPosition( sp1->getPosition() + ccp(1,0) ); // 每帧移动 1
}

// schedule(schedule_selector, interval)
void HelloWorld::myupdate2(float dt)
{
CCSprite* sp2 = (CCSprite*)this->getChildByTag(102); // 获取 tag=102 的精灵
sp2->setPosition( sp2->getPosition() + ccp(60,0) ); // 每秒移动 60
}

// schedule(schedule_selector, interval, repeat, delay)
void HelloWorld::myupdate3(float dt)
{
CCSprite* sp3 = (CCSprite*)this->getChildByTag(103); // 获取 tag=103 的精灵
sp3->setPosition( sp3->getPosition() + ccp(60,0) ); // 每秒移动 60
}

// scheduleOnce
void HelloWorld::myupdate4(float dt)
{
CCSprite* sp4 = (CCSprite*)this->getChildByTag(104); // 获取 tag=104 的精灵
sp4->setPosition( sp4->getPosition() + ccp(100,0) ); // 移动 100
}

3、运行结果

运行上述代码后,可以观察到五个精灵根据各自对应的定时器规则进行移动。

4、分析与总结

  • scheduleUpdate()schedule(schedule_selector):这两种方式的效果类似,不同之处在于 schedule() 可以自定义刷新函数体,不一定是 update(),而 scheduleUpdate() 的刷新函数体只能是 update()
  • schedule(schedule_selector, interval):设置了 interval = 1.0,因此每隔 1.0 秒会执行一次 myupdate2()
  • schedule(schedule_selector, interval, repeat, delay):在开始 3.0 秒后才开始执行 myupdate3(),并且之后又重复执行了 5 次,然后停止更新。
  • scheduleOnce(schedule_selector):在开始 5 秒后,只执行了一次 myupdate4(),之后就停止更新。

通过以上的学习和实践,开发者可以熟练掌握 Cocos2d-x 3.x 中定时器的使用方法,从而实现游戏中各种定时更新的需求。