文档章节

Cocos2d-x实现计时与定时

南楼
 南楼
发布于 2017/05/29 12:36
字数 1068
阅读 22
收藏 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
沈阳
程序员
崛起于Springboot2.X之集成Quartz定时调度(29)

1、添加pom依赖 springboot2.0之后,spring-boot-starter中已经包含了quart的依赖,所以只需要添加一个依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-bo......

木九天
07/24
0
0
Cocos2d-X 2.0嵌入MFC的子窗体的方法(1.0姐妹篇)

红孩儿的游戏编程之路 CSDN博客地址:http://blog.csdn.net/honghaier 红孩儿Cocos2d-X学习园地QQ群:249941957 加群写:Cocos2d-x 另本章为我的Cocos2d-x教程一书初稿。望各位看官多提建议!...

长平狐
2012/11/19
378
0
Cocos2d-X 2.0嵌入MFC的子窗体的方法(1.0姐妹篇)

红孩儿的游戏编程之路 CSDN博客地址:http://blog.csdn.net/honghaier 红孩儿Cocos2d-X学习园地QQ群:249941957 加群写:Cocos2d-x 另本章为我的Cocos2d-x教程一书初稿。望各位看官多提建议!...

长平狐
2013/03/19
73
0
Cocos2d-X游戏工具开发之一:将Cocos2d-X嵌入MFC的子窗体方法讲解

[Cocos2d-x相关教程来源于红孩儿的游戏编程之路 CSDN博客地址:http://blog.csdn.net/honghaier] 红孩儿Cocos2d-X学习园地QQ群:249941957 加群写:Cocos2d-x 另本章为我的Cocos2d-x教程一书...

长平狐
2012/11/19
922
0
Android中的倒计时器设计实现 00:00:00格式

功能: 倒计时 类:MainActivity(主类) MyCount(实现倒计时功能的类) AdvancedCountdownTimer(消息机制的抽象类) 代码如下: package com.example.daojishiqi; import android.os.Bund...

zwyandroid
05/25
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Oracle return exit continue

常在循环体中看到下面3种语句: return exit continue 举例说明 啥都没有 -- none begin for i in 1 .. 10 loop if i < 5 then dbms_output.put_line('i < 5, i = ' || to_char......

taadis
59分钟前
2
0
JSONObject 转换时出错 InvocationTargetException

JSONObject 转换时出错java.lang.reflect.InvocationTargetException 一时看不出来是什么问题。 挺奇怪的。 百度参考了一下这个 网页的解决方案 说是类型不对,空? 仔细查看代码,果然是有一...

之渊
今天
3
0
no such module 'pop'问题

在github上 clone 了一个 swift 项目,编译时提示"no such module 'POP'"错误,查了一下居然是因为podfile中指定的最低版本是iOS 11.0,大于我测试手机的iOS版本10.3.3,将Podfile中的最低版...

yoyoso
今天
3
0
redis 系列一 -- 简介及安装

1.简介 redis -- remote dictionary server 远程字典服务 使用 C 语言编写; 高性能的 key-value数据库; 内存数据库,支持数据持久化。 Redis 是一个开源(BSD许可)的,内存中的数据结构存...

imbiao
今天
4
0
nginx log记录请求响应时间

有时为了方便分析接口性能等,需要记录请求的时长,通过修改nginx的日志格式可以做到,如 添加一个新的log_format log_format timed_combined '$remote_addr - $remote_user [$time_local] "...

swingcoder
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部