文档章节

Cocos2d-x实现计时与定时

南楼
 南楼
发布于 2017/05/29 12:36
字数 1068
阅读 32
收藏 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......

木九天
2018/07/24
0
0
C#开源定时回调库PETimer的使用

PETimer PETimer开源项目GitHub地址:点击跳转 PETimer 1.双端通用:基于C#语言实现的高效便捷计时器,可运行在服务器(.net core/.net framework)以及Unity客户端环境中。 2.功能丰富:PET...

PlaneZhong
01/16
0
0
Android中的倒计时器设计实现 00:00:00格式

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

zwyandroid
2018/05/25
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
388
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
934
0

没有更多内容

加载失败,请刷新页面

加载更多

在 Ubuntu 上为 CentOS 编译 Rust 程序

现在 CentOS 8 还没出来,最新的是 CentOS 7.6,上面搭载的 glibc 版本是 2.17,都已经是 2012 年那时候的版本了。 现在开发者比较常用的桌面 Linux 系统,比如 Ubuntu / Debian / Mint / A...

helloclia
30分钟前
8
0
Android Multimedia框架总结(一)MediaPlayer介绍之状态图及生命周期

前言:从本篇开始,将进入Multimedia框架,包含MediaPlayer, Camera, Surface, MediaRecord, 接下来几篇都是MediaPlayer相关。同样看下Agenda如下: MediaPlayer的状态图 Idle 状态 End 状态...

天王盖地虎626
58分钟前
2
0
IntelliJ IDEA创建第一个Spring boot项目

下载maven:http://maven.apache.org/download.cgi 开发工具:IntelliJ IDEA JDK: Java JDK1.8 ## 1.为了第一个项目初始化速度加快,我们先来配置maven: 添加配置: 选择Build,Execution,Dep...

凌宇之蓝
今天
3
0
Coding and Paper Letter(四十五)

资源整理。 1 Coding: 1.Python库gempy,一种基于Python的开源三维结构地质建模软件,它允许从界面和方向数据隐式(即自动)创建复杂的地质模型。 它还支持随机建模以解决参数和模型的不确定...

胖胖雕
今天
7
0
golang 声明一个指定长度的数组,用于后续添加

很多时候我们需要声明一个指定长度的数组,用于后续添加.在使用go的时候要注意,下面的第一个例子会有报错 "non-constant array bound",应该使用第二个例子. Length 是动态的值 有报错的例子 ...

漫步海边小路
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部