文档章节

Cocos2d-x实现计时与定时

南楼
 南楼
发布于 2017/05/29 12:36
字数 1068
阅读 150
收藏 0

「深度学习福利」大神带你进阶工程师,立即查看>>>

笔者最近在写一个计时和定时的功能,上网查看了不少讲述实现计时器定时器的文章,大多都直接采用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!");
    }
}

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

南楼
粉丝 0
博文 7
码字总数 5247
作品 0
沈阳
程序员
私信 提问
加载中
请先登录后再评论。
用vertx实现高吞吐量的站点计数器

工具:vertx,redis,mongodb,log4j 源代码地址:https://github.com/jianglibo/visitrank 先看架构图: 如果你不熟悉vertx,请先google一下。我这里将vertx当作一个容器,上面所有的圆圈要...

jianglibo
2014/04/03
4.3K
3
SQLServer实现split分割字符串到列

网上已有人实现sqlserver的split函数可将字符串分割成行,但是我们习惯了split返回数组或者列表,因此这里对其做一些改动,最终实现也许不尽如意,但是也能解决一些问题。 先贴上某大牛写的s...

cwalet
2014/05/21
9.7K
0
Promises/A 和 when() 实现--When.js

When.js 是 cujojs 的轻量级的 Promises/A 和 when() 实现,从 wire.js 的异步核心和 cujojs 的 IOC 容器派生而来。包含很多其他有用的 Promiss 相关概念,例如联合多个 promiss、mapping 和...

匿名
2013/02/15
7.5K
0
Redis 分片实现--Redis Shard

redis-shard 是 Redis 分区的 Python API ,基于对 key 和 key tag 进行 CRC32 checksum 计算,可参考文章 http://antirez.com/post/redis-presharding.html . 该项目由知乎网开发。 使用限制...

匿名
2012/10/24
5.7K
0
iOS 的 Canvas 和 Audio 实现--Ejecta

Ejecta 是一个快速开源的 JavaScript、Canvas 和 音频实现,适用于 iOS 平台。你可以把它想象成一个只支持显示 Canvas 元素的浏览器,它像一个浏览器却无需浏览器,适用于游戏和动画开发。无...

匿名
2012/10/26
4.4K
0

没有更多内容

加载失败,请刷新页面

加载更多

EasyDL入驻社区果蔬店 离线识别秒级智能结算

传统收银方式高成本低效率 急需转型 500米商圈概念被越来越多的企业关注,在中国,一个社区就有可能成为一个商圈,蕴藏着巨大的商机。而在社区中,果蔬作为人们每天都要采购的高频消费商品,...

百度智能云
06/10
0
0
rabbitmq集群环境安装配置

一、主机清单 2台机器同时执行下面安装步骤 10.0.0.216 shiguang-rabbitmq-01 10.0.0.223 shiguang-rabbitmq-02 注意:请将上面内容加入2台机器 /etc/hosts (集群环境必须要加) 1、安装erlan...

caozhangming
2019/08/09
0
0
【rabbitmq-Php】-发布Publish 与订阅Subscribe

发布/订阅,使用扇型交换机(fanout) composer.json ### composer.json { "require": { "php-amqplib/php-amqplib": ">=2.9.0" }} 发布端(Publish) /** * rabbitmq......

DEPAKIN
27分钟前
13
0
如何在PHP中进行重定向? - How do I make a redirect in PHP?

问题: Is it possible to redirect a user to a different page through the use of PHP? 是否可以通过使用PHP将用户重定向到其他页面? Say the user goes to www.example.com/page.php an......

法国红酒甜
37分钟前
9
0
一周面试了 30 人,通过 2 人,面试面到我心态爆炸…

Java技术栈 www.javastack.cn 打开网站看更多优质文章 因技术团队人员调整及项目组扩编,需要招几个 Java 程序员,3~5年左右,领导要求的是能力要比现有的大部分技术人员要强,并且宁缺勿滥...

Java技术栈
05/24
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部