CCScheduler可以算是个计时器,可以根据需要通过此类下的各种方法设定计时来执行回调函数,达到计时控制精灵、动画的作用。官方原例中已经演示了这个类的具体使用方法,这里就记录一下使用方法:
1.setTimeScale
用于减慢或者快进动画,其默认参数值为1.0,低于此值时计时器会放慢,否则加快,下面是代码:
class SchedulerTimeScale : public cocos2d::CCLayer
{
public:
void onEnter();
void onExit();
CCControlSlider* sliderCtl();
void sliderAction(CCObject* pSender, CCControlEvent controlEvent);
CCControlSlider* m_pSliderCtl;
CREATE_FUNC(SchedulerTimeScale);
};
CCControlSlider* SchedulerTimeScale::sliderCtl()
{
//添加一个滑动条用来控制动画速度
CCControlSlider * slider = CCControlSlider::create("sliderTrack2.png","sliderProgress2.png" ,"sliderThumb.png");
//滑动条数值产生变化时调用自定义的sliderAction来执行setTimeScale
slider->addTargetWithActionForControlEvents(this, cccontrol_selector(SchedulerTimeScale::sliderAction), CCControlEventValueChanged);
slider->setMinimumValue(-3.0f);
slider->setMaximumValue(3.0f);
slider->setValue(1.0f);
return slider;
}
void SchedulerTimeScale::sliderAction(CCObject* pSender, CCControlEvent controlEvent)
{
CCControlSlider* pSliderCtl = (CCControlSlider*)pSender;
float scale;
scale = pSliderCtl->getValue();
//这里由导演取得所有动画的计时器并执行setTimeScale
CCDirector::sharedDirector()->getScheduler()->setTimeScale(scale);
}
void SchedulerTimeScale::onEnter()
{
CCLayer::onEnter();
CCSize s = CCDirector::sharedDirector()->getWinSize();
// rotate and jump
CCActionInterval *jump1 = CCJumpBy::create(4, ccp(-s.width+80,0), 100, 4);
CCActionInterval *jump2 = jump1->reverse();
CCActionInterval *rot1 = CCRotateBy::create(4, 360*2);
CCActionInterval *rot2 = rot1->reverse();
CCSequence* seq3_1 = CCSequence::create(jump2, jump1, NULL);
CCSequence* seq3_2 = CCSequence::create(rot1, rot2, NULL);
CCFiniteTimeAction* spawn = CCSpawn::create(seq3_1, seq3_2, NULL);
CCRepeat* action = CCRepeat::create(spawn, 50);
CCRepeat* action2 = (CCRepeat*)action->copy()->autorelease();
CCRepeat* action3 = (CCRepeat*)action->copy()->autorelease();
CCSprite *grossini = CCSprite::create("grossini.png");
CCSprite *tamara = CCSprite::create("grossinis_sister1.png");
CCSprite *kathia = CCSprite::create("grossinis_sister2.png");
grossini->setPosition(ccp(40,80));
tamara->setPosition(ccp(40,80));
kathia->setPosition(ccp(40,80));
addChild(grossini);
addChild(tamara);
addChild(kathia);
grossini->runAction(CCSpeed::create(action, 0.5f));
tamara->runAction(CCSpeed::create(action2, 1.5f));
kathia->runAction(CCSpeed::create(action3, 1.0f));
m_pSliderCtl = sliderCtl();
m_pSliderCtl->setPosition(ccp(s.width / 2.0f, s.height / 3.0f));
addChild(m_pSliderCtl);
}
void SchedulerTimeScale::onExit()
{
// restore scale 还原timeScale的默认值
CCDirector::sharedDirector()->getScheduler()->setTimeScale(1);
CCLayer::onExit();
}
有时需要不同的计时器来各自控制精灵或者动画,这就需要为不同的精灵或者动画关联不同的scheduler了,下面是代码:
//自定义两个Schedulers
class TwoSchedulers : public cocos2d::CCLayer
{
public:
void onEnter();
CCControlSlider* sliderCtl();
void sliderAction(CCObject* sender, CCControlEvent controlEvent);
//这里定义两个Scheduler
cocos2d::CCScheduler *sched1;
cocos2d::CCScheduler *sched2;
//动作管理器用来统一管理所有关联对象的动作
cocos2d::CCActionManager *actionManager1;
cocos2d::CCActionManager *actionManager2;
CCControlSlider *sliderCtl1;
CCControlSlider *sliderCtl2;
CREATE_FUNC(TwoSchedulers);
};
CCControlSlider *TwoSchedulers::sliderCtl()
{
// CGRect frame = CGRectMake(12.0f, 12.0f, 120.0f, 7.0f);
CCControlSlider *slider = CCControlSlider::create("sliderTrack2.png","sliderProgress2.png" ,"sliderThumb.png");
//[[UISlider alloc] initWithFrame:frame];
slider->addTargetWithActionForControlEvents(this, cccontrol_selector(TwoSchedulers::sliderAction), CCControlEventValueChanged);
slider->setMinimumValue(0.0f);
slider->setMaximumValue(2.0f);
//slider.continuous = YES;
slider->setValue(1.0f);
return slider;
}
void TwoSchedulers::sliderAction(CCObject* sender, CCControlEvent controlEvent)
{
float scale;
CCControlSlider *slider = (CCControlSlider*) sender;
scale = slider->getValue();
if( sender == sliderCtl1 )
sched1->setTimeScale(scale);
else
sched2->setTimeScale(scale);
}
void TwoSchedulers::onEnter()
{
CCLayer::onEnter();
CCSize s = CCDirector::sharedDirector()->getWinSize();
// rotate and jump
CCActionInterval *jump1 = CCJumpBy::create(4, ccp(0,0), 100, 4);
CCActionInterval *jump2 = jump1->reverse();
CCSequence* seq = CCSequence::create(jump2, jump1, NULL);
CCRepeatForever* action = CCRepeatForever::create(seq);
//
// Center
//
CCSprite *grossini = CCSprite::create("grossini.png");
addChild(grossini);
grossini->setPosition(ccp(s.width/2,100));
grossini->runAction((CCAction*)action->copy()->autorelease());
CCScheduler *defaultScheduler = CCDirector::sharedDirector()->getScheduler();
//
// Left:
//
// Create a new scheduler, and link it to the main scheduler
//创建计时器并且关联到主计时器
sched1 = new CCScheduler();
defaultScheduler->scheduleUpdateForTarget(sched1, 0, false);
// Create a new ActionManager, and link it to the new scheudler
//创建动作管理器并关联到自定义的计时器
actionManager1 = new CCActionManager();
sched1->scheduleUpdateForTarget(actionManager1, 0, false);
for( unsigned int i=0; i < 10; i++ )
{
CCSprite *sprite = CCSprite::create("grossinis_sister1.png");
// IMPORTANT: Set the actionManager running any action
//将精灵加入到动作管理器中统一动作
sprite->setActionManager(actionManager1);
addChild(sprite);
sprite->setPosition(ccp(30+15*i,100));
sprite->runAction((CCAction*)action->copy()->autorelease());
}
//
// Right:
//
// Create a new scheduler, and link it to the main scheduler
sched2 = new CCScheduler();;
defaultScheduler->scheduleUpdateForTarget(sched2, 0, false);
// Create a new ActionManager, and link it to the new scheudler
actionManager2 = new CCActionManager();
sched2->scheduleUpdateForTarget(actionManager2, 0, false);
for( unsigned int i=0; i < 10; i++ ) {
CCSprite *sprite = CCSprite::create("grossinis_sister2.png");
// IMPORTANT: Set the actionManager running any action
sprite->setActionManager(actionManager2);
addChild(sprite);
sprite->setPosition(ccp(s.width-30-15*i,100));
sprite->runAction((CCAction*)action->copy()->autorelease());
}
//创建两个滑动条
sliderCtl1 = sliderCtl();
addChild(sliderCtl1);
sliderCtl1->retain();
sliderCtl1->setPosition(ccp(s.width / 4.0f, s.height - 20));
sliderCtl2 = sliderCtl();
addChild(sliderCtl2);
sliderCtl2->retain();
sliderCtl2->setPosition(ccp(s.width / 4.0f*3.0f, s.height-20));
}
3.暂停、唤醒、移除计时器
void HelloWorld::menuCloseCallback(CCObject* pSender)
{
// "close" menu item clicked
//CCDirector::sharedDirector()->end();
//这里把关闭按钮执行的代码改成了暂停与唤醒计时器的代码,不过这里是停止、唤醒所有计时器
if (isPause==false){
m_pPausedTargets=CCDirector::sharedDirector()->getScheduler()->pauseAllTargets();
isPause=true;
CC_SAFE_RETAIN(m_pPausedTargets);
}else{
CCDirector::sharedDirector()->getScheduler()->resumeTargets(m_pPausedTargets);
isPause=false;
}
//这句用来移除所有计时器
//CCDirector::sharedDirector()->getScheduler()->unscheduleAll();
}
在官方interval test 一例中还使用Schedule做了计时器:
//开始计时,这个是CCNode中的函数,用于每秒执行一次回调函数,也可以后面加延时调用的参数
schedule(schedule_selector(HelloWorld::gameTimer));
里面还有个更常用的相当于暂停、继续游戏的方法:
void IntervalLayer::onPause(CCObject* pSender)
{
if(CCDirector::sharedDirector()->isPaused())
CCDirector::sharedDirector()->resume();
else
CCDirector::sharedDirector()->pause();
}