您当前的位置: 首页 > 

鱼儿-1226

暂无认证

  • 0浏览

    0关注

    1100博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

CCScheduler( 定时调度器) | schedule(定时器) & update(定时器)

鱼儿-1226 发布时间:2021-09-01 16:18:50 ,浏览量:0

------------------------------------------------------------

定时调度器 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);  
};  

复制代码

cpp

复制代码

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

复制代码

cpp

复制代码

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

转自:http://blog.csdn.net/zhuzhihai1988/article/details/9088105

-------------------------------------差一点就永远的分割线-----------------------------------------------------------------------------一条不够所以加一条的----------------------------------------

 update 定时器,每一帧都被触发,使用 scheduleUpdate 方法来启用; schedule 定时器,可以设置触发的间隔,使用 schedule 方法来启用。

1.调度器可以随时增删或修改被注册的定时器。具体来看,调度器将 update 定时器与普通定时器分别处理:当某个节点注册 update 定时器时,调度器就会把节点添加到 Updates 容器中,为了提高调度器效率,Cocos2d-x 使用了散列表与链表结合 的方式来保存定时器信息;当某个节点注册普通定时器时,调度器会把回调函数和其他信息保存到 Selectors 散列表中。

Schedule 定时器

首先,什么是定时器呢?或许你有时候会想让某个函数不断的去执行,或许只是执行一次,获取你想让他每隔几秒执行一次,ok,这些都可以统统交给定时器来解决。

cocos2dx中有三种定时器:schedule,scheduleUpdate,scheduleOnce。了解其功能便会发现定时器真是太方便了,废话不多说,我们逐一学习一下。

1、scheduleUpdate

scheduleUpdate,但是这个时候我们需要重写CCObject中的update方法,初始化scheduleUpdate有两种方法:

1,可以在自己的init方法中初始化它。

2,可在onEnter中初始化它,但是一定要CCLayer::onEnter()否则执行不到你的update

加入当前节点后,程序会每帧都会自动执行一次默认的Update函数。(注:一定是Update函数哦,若想调用其他自己命名的函数则使用schedule) 看例子,走起。 首先在HelloWord类的头文件(HelloWord.h)中声明Update函数:

void Update(float dt);   //注意参数类型

然后在HelloWorld类源文件(HelloWorld.cpp)中实现函数Update:

void HelloWorld::Update(float dt)  
{  
    CCLOG("baibai");  
}

现在我们可以调用了,在需要他不断执行的地方加入调用的代码就ok:

this->scheduleUpdate();     //this是当前节点,如layer,所以可以省略啦。 

运行之后你将会看到不断有baibai被打印出来 ... ...

2、schedule

可以没隔几秒执行某个自定义的函数,来看代码: 首先还是在HelloWorld头文件(HelloWord.h)中声明所要执行的函数:

void Move(float dt);  

然后在HelloWorld类源文件(HelloWorld.cpp)中实现函数Update:

void HelloWorld::Move(float dt)  
{  
    CCLOG("moving ...");  
}  

现在去执行他,注意参数哦

this->schedule(schedule_selector(HelloWorld::Move), 2.0f); //每隔2.0f执行一次,省略参数则表示每帧都要执行  

运行之后,"moving ... "每隔1.0f才会被打印一次。

3、scheduleOnce

功能:在几秒之后执行,并且只会执行一次。 我们就执行上面所写的Move函数吧。

this->scheduleOnce(schedule_selector(HelloWorld::Move), 3.0f); //在3.0f之后执行,并且只执行一次。

运行一下,baibai只是被打印了一次就完了。。。 ok,定时器的调用已经讲完了,大家不妨自己写一些函数体验一下。

但是怎么停止定时器呢?

1、停止执行自己定义的函数定时器:

this->unschedule(schedule_selector(HelloWorld::Move));  

2、停止默认定时器:

this->unscheduleUpdate();  

3、停止所有定时器:

this->unscheduleAllSelectors(); 
关注
打赏
1604459285
查看更多评论
立即登录/注册

微信扫码登录

0.0406s