cocos2d-x 菜鸟学习笔记十(计时器-CCScheduler)

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();
}

2.scheduleUpdateForTarget

有时需要不同的计时器来各自控制精灵或者动画,这就需要为不同的精灵或者动画关联不同的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(); 

}

关于CCScheduler,其它还有很多方法,说是说不完了,得到源代码和官方原例中里自己研究了……
源代码下载: http://download.csdn.net/detail/cyistudio/5467885


你可能感兴趣的:(cocos2d-x)