Cocos2d-x实现计时器与定时器功能

来源:互联网 发布:dhcp 默认端口 编辑:程序博客网 时间:2024/05/24 08:33

笔者最近在写一个计时和定时的功能,上网查看了不少讲述实现计时器定时器的文章,大多都直接采用Cocos2d-x的定时器schedule,通过在schedule方法添加间隔时间的参数去实现计时与定时功能。

但是学过Cocos2d-x定时器schedule的都了解,schedule定时器调用方法是有一定的间隔时间,虽然这个时间间隔很小,只有十几毫秒,一般来说没有太大的影响。但是如果需要计时或者定时的时间较长,那么误差就会增大。比如,假设每次schedule定时器调用方法的时间间隔都固定为0.015s,我们需要计时5分钟即300s(每1s计时一次),结果实际上却是过了304.5s。

为了尽量的消除误差,笔者打算采用schedule定时器与计算系统时间来实现计时和定时功能。
闲话少叙,直接通过代码说话。

计时功能

"HelloWorld.h"#ifndef __HELLOWORLD_SCENE_H__#define __HELLOWORLD_SCENE_H__#include "cocos2d.h"class HelloWorld : public cocos2d::Layer{public:  int oldTime;  //调用schedule定时器前的时间  int num;      //计时  virtual void update(float dt);  //schedule定时器调用的方法  static cocos2d::Scene* createScene();  virtual bool init();  CREATE_FUNC(HelloWorld);};#endif
"HelloWorld.cpp"#include "HelloWorldScene.h"#include "cocostudio/CocoStudio.h"#include "ui/CocosGUI.h"USING_NS_CC;using namespace cocostudio::timeline;Scene* HelloWorld::createScene(){    auto scene = Scene::create();    auto layer = HelloWorld::create();    scene->addChild(layer);    return scene;}bool HelloWorld::init(){    if ( !Layer::init() )    {        return false;    }    struct timeval now;    gettimeofday(&now, NULL);    this->num = 0;    //计时从0开始    CCLOG("%d",this->num);    this->oldTime = now.tv_sec;  //获取调用定时器前的时间    schedule(schedule_selector(HelloWorld::update));    return true;}void HelloWorld::update(float dt) {    struct timeval now;    gettimeofday(&now, NULL);    int nowTime = now.tv_sec;   //获取调用定时器后的时间    if ((nowTime - oldTime) == 1)     //判断调用定时器后的时间(可能调用了几次定时器)是否与调用定时器前的时间相差1s    {        this->num++;        CCLOG("%d",this->num);        this->oldTime = nowTime;   //重新设定调用定时器前的时间    }}

通过上述的方法就可以实现相对误差较少的计时功能了。笔者这里只是简单的实现了一个计时器功能,输出的时间格式是可以优化的,比如输出分秒 (num/60):(num%60),就可以实现完整的计时器功能了

定时功能

"HelloWorld.h"#ifndef __HELLOWORLD_SCENE_H__#define __HELLOWORLD_SCENE_H__#include "cocos2d.h"class HelloWorld : public cocos2d::Layer{public:  int oldTime;  //调用schedule定时器前的时间  int min;      //定时的分钟数  int sec;      //定时的秒数  virtual void update(float dt);  //schedule定时器调用的方法  static cocos2d::Scene* createScene();  virtual bool init();  CREATE_FUNC(HelloWorld);};#endif
"HelloWorld.cpp"#include "HelloWorldScene.h"#include "cocostudio/CocoStudio.h"#include "ui/CocosGUI.h"USING_NS_CC;using namespace cocostudio::timeline;Scene* HelloWorld::createScene(){    auto scene = Scene::create();    auto layer = HelloWorld::create();    scene->addChild(layer);    return scene;}bool HelloWorld::init(){    if ( !Layer::init() )    {        return false;    }    //实现一个2分钟的定时功能    this->min = 2;   //定时分钟数为2min    this->sec = 0;   //定时秒数为0s    struct timeval now;    gettimeofday(&now, NULL);    this->oldTime = now.tv_sec;    CCLOG("%d:%d",this->min,this->sec);    schedule(schedule_selector(HelloWorld::update));    return true;}void HelloWorld::update(float dt) {    struct timeval now;    gettimeofday(&now, NULL);    int nowTime = now.tv_sec;   //获取调用定时器后的时间    if (this->min != 0 || this->sec != 0) { //判断定时是否没有结束        if (nowTime - this->oldTime == 1)         //判断调用定时器后的时间(可能调用了几次定时器)是否与调用定时器前的时间相差1s         {            if (this->sec == 0) {                this->min--;                this->sec = 59;                CCLOG("%d:%d", this->min, this->sec);            }            else if (this->sec != 0) {                this->sec--;                CCLOG("%d:%d", this->min, this->sec);            }            this->oldTime = nowTime;   //重新设定调用定时器前的时间        }    }    else if (this->min == 0 && this->sec == 0) {  //判断定时是否结束        unschedule(schedule_selector(HelloWorld::update));  //取消定时器        CCLOG("end!");    }}

通过上述方法就可以实现一个误差较小的定时功能了。笔者这里只是简单的实现了一个定时器功能,定时的时间可以改变的,可以把整个方法封装成类,定时的时间通过传参去设置,就可以实现一个完整的定时器方法了。

原创粉丝点击