• cocos2dx三种定时器使用


    
       
    cocos2dx三种定时器的使用以及停止schedule。scheduleUpdate。scheduleOnce

    今天白白跟大家分享一下cocos2dx中定时器的用法。

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

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

    1、scheduleUpdate

    增加当前节点后,程序会每帧都会自己主动运行一次默认的Update函数。

    (注:一定是Update函数哦,若想调用其它自己命名的函数则使用schedule)

    看样例,走起。

    首先在HelloWord类的头文件里声明Update函数:

    1. void Update(float dt);   //注意參数类型  
    然后在HelloWorld类源文件里实现函数Update:

    1. void HelloWorld::Update(float dt)  
    2. {  
    3.     CCLOG("baibai");  
    4. }  
    如今我们能够调用了。在须要他不断运行的地方增加调用的代码就ok:

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

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

    2、scheduleUpdate

    能够没隔几秒运行某个自己定义的函数,来看代码:

    首先还是在HelloWorld中声明所要运行的函数:

    1. void Move(float dt);  
    然后在源文件实现:

    1. void HelloWorld::Move(float dt)  
    2. {  
    3.     CCLOG("baibai");  
    4. }  
    如今去运行他。注意參数哦

    1. scheduleOnce(schedule_selector(HelloWorld::Move), 1.0f);//每隔1.0f运行一次。省略參数则表示每帧都要运行  
    
    

    执行之后。baibai每隔1.0f才会被打印一次。

    3、scheduleOnce

    功能:在几秒之后运行,而且仅仅运行一次。

    我们就运行上面所写过的Move函数吧:

    1. scheduleOnce(schedule_selector(HelloWorld::Move), 1.0f); //在1.0f之后运行,而且仅仅运行一次。

        

    执行一下,baibai仅仅是被打印了一次就完了。。。

    ok,定时器的调用已经讲完,大家最好还是自己写一些函数体验一下。

    可是怎么让定时器停止呢?

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

    1. this->unschedule(schedule_selector(HelloWorld::Move));  
    2、停止默认定时器:

    1. this->unscheduleUpdate();  
    3、停止全部定时器:

    1. this->unscheduleAllSelectors();  

    1.概况

    CCNode内部封装了一个

    1. CCScheduler *m_pScheduler;

    正是通过它我们能够非常轻松地完毕一些定时功能,所以定时器是节点所具备的功能。

    定时器分为2种,一种是更新定时器,运行的频率是每帧运行一次,还有一种则是自己定义回调函数的定时器(最小值是一帧)。关于回调函数和函数指针的相关基础可參见http://blog.csdn.net/jackystudio/article/details/11720325


    2.API

    1. //更新定时器,每帧调用1次。每一个节点仅仅能有1个被调度的update函数
    2. void scheduleUpdate(void);
    3. //卸载更新定时器
    4. void unscheduleUpdate(void);
    5. //自己定义定时器,假设反复调用,那调用间隔会更新。而不会再次调用
    6. //interval,调用时间间隔,假设为0,建议使用scheduleUpdate
    7. //repeat,回调函数会被运行repeat+1次,kCCRepeatForever是无限次调用
    8. //delay。第一次运行前的延时
    9. void schedule(SEL_SCHEDULE selector, float interval, unsigned int repeat, float delay);
    10. void schedule(SEL_SCHEDULE selector, float interval);
    11. void scheduleOnce(SEL_SCHEDULE selector, float delay);
    12. void schedule(SEL_SCHEDULE selector);
    13. //卸载自己定义定时器
    14. void unschedule(SEL_SCHEDULE selector);
    15. void unscheduleAllSelectors(void);
    16. //恢复全部定时器和动作,OnEnter调用
    17. void resumeSchedulerAndActions(void);
    18. //暂停全部定时器和动作,OnExit调用
    19. void pauseSchedulerAndActions(void);
    20. //scheduleUpdate每帧调用
    21. virtual void update(float delta);


    3.演示样例

    3.1.更新定时器

    1. //开启定时器
    2. this->scheduleUpdate();
    3. //虚函数update
    4. void HelloWorld::update(float delta)
    5. {
    6. CCLog("%f",delta);
    7. }
    8. //输出,这里设置了60fps,调用间隔1/60s
    9. 0.016667
    10. 0.016676
    11. 0.016657
    12. 0.016669

    3.2.自己定义定时器

    1. //开启定时器,延时2s运行,运行3+1次,运行间隔1s
    2. this->schedule(schedule_selector(HelloWorld::log),1,3,2);
    3. //回调函数
    4. void HelloWorld::log(float dt)
    5. {
    6. CCLog("schedule");
    7. }
    8. //输出
    9. 2.004532
    10. 1.005827
    11. 1.000238
    12. 1.001019

    4.schedule_selector和SEL_SCHEDULE

    看到上面的schedule_selector了吧。这又是个什么玩意?看看它的宏定义。

    1. #define schedule_selector(_SELECTOR) (SEL_SCHEDULE)(&_SELECTOR)
    原来是把函数指针转化为SEL_SCHEDULE型指针,那SEL_SCHEDULE又是什么?

    1. typedef void (CCObject::*SEL_SCHEDULE)(float);
    也没啥,就是定义了一个带有float參数函数指针。所以我们在使用自己定义Schedule的时候,回调函数一定要记得带上一个float參数。它记录了两次运行的间隔。

    假设忘了。但是会出现类型转换错误的异常。这样的方式在callfunc_selector,menu_selector等也以相同的方式出现。


    5.谁来调用回调函数

    但是有没有发现,假设这个回调函数是个全局函数或者static函数也就算了,偏偏它是个成员函数,成员函数须要实例来调用,但是从调用方法来看。好像没传入调用对象?

    1. this->schedule(schedule_selector(HelloWorld::log),1,3,2);

    是的。还记得一开头说的CCNode内部封装的m_pScheduler吗?

    1. CCScheduler *m_pScheduler;
    原来CCNode帮我们实现了:

    1. void CCNode::schedule(SEL_SCHEDULE selector, float interval, unsigned int repeat, float delay)
    2. {
    3. CCAssert( selector, "Argument must be non-nil");
    4. CCAssert( interval >=0, "Argument must be positive");
    5. m_pScheduler->scheduleSelector(selector, this, interval , repeat, delay, !m_bRunning);
    6. }

    原来this这个时候被传入了,同一时候传入的參数还有m_bRunning,m_bRunning表示节点是否在执行中(是否在舞台上)。OnEnter的时候赋值true,OnExit的时候赋值false。所以在执行定时器的时候还必须确保节点有在执行。

    这样确有用起来怪怪的。所以在cocos2d-x v3.0版本号中,參数和函数指针用一个宏打包起来了~

    至于CCSchedule内部是怎么实现的,以及CCTimer的触发回调,有兴趣的就自己看看源代码吧

    版权声明:本文博主原创文章,博客,未经同意不得转载。

  • 相关阅读:
    uml 类图
    Java IO流
    Spring 创建Bean的 三种方式
    linux+jmeter+python基础+抓包拦截
    接口测试
    HDU 1159 Common Subsequence(POJ 1458)
    HDU 1160 FatMouse's Speed
    HDU 4540 威威猫系列故事——打地鼠
    HDU 1087 Super Jumping! Jumping! Jumping!
    HDU 1176 免费馅饼
  • 原文地址:https://www.cnblogs.com/yxwkf/p/4850856.html
Copyright © 2020-2023  润新知