Directx11学习笔记【七】 游戏定时器的实现
无论是在动画还是在一些游戏中,定时器总是必不可少的,游戏的帧数动画的播放等都离不开定时器的控制。这里以dx11龙书中提供的定时器为例,具体看看是怎么实现一个简单但精度高使用方便的定时器的。
这个定时器使用的windows中的高精度计时函数QueryPerformanceCounter和QueryPerformanceFrequency
BOOL QueryPerformanceCounter( LARGE_INTEGER* lpPerformanceCount );
BOOL QueryPerformanceFrequency( LARGE_INTEGER* lpFrequency );
QueryPerformanceCounter函数以计数为单位,因为不同的机器中两次计数之间的差值可能不同,所以就需要QueryPerformanceFrequency函数 返回1s内计数的个数
__int64 countsPerSec;
QueryPerformanceFrequency((LARGE_INTEGER*)&countsPerSec);
m_secondsPerCount = 1.0 / countsPerSec;
通过这样便可以得到系统两次计数之间的时间差,这是定时器把时间转换为秒的基准。
下面看看这个定时器类GameTimer的具体实现
GameTimer.h
#ifndef GAMETIMER_H
#define GAMETIMER_H class GameTimer
{
public:
GameTimer();
float TotalTime() const;//返回定时器从计时开始到现在的总时间,不包括暂停时间
float DeltaTime() const;//返回本次计时与上次计时之间的时间差 void Reset();//重置
void Start();//暂停后恢复计时
void Stop();//暂停
void Tick();//计时一次,每一帧调用 private:
double m_secondsPerCount;//系统相关,系统两次计数之间的时间差,是定时器把时间转换为s的基准
double m_deltaTime;//距离上次计时的时间差 __int64 m_baseTime;//定时器开始工作的时间点
__int64 m_pausedTime;//暂停的总时间
__int64 m_stopTime;//暂停的开始时间
__int64 m_prevTime;//上次计时的时间点
__int64 m_currTime;//本次计时的时间点 bool m_isStopped;//是否暂停
}; #endif //GAMETIMER_H
GameTimer.cpp
#include "GameTimer.h"
#include <windows.h> GameTimer::GameTimer() : m_secondsPerCount(0.0), m_deltaTime(-1.0), m_baseTime(), m_pausedTime(),
m_prevTime(), m_currTime(), m_isStopped(false)
{
__int64 countsPerSec;
QueryPerformanceFrequency((LARGE_INTEGER*)&countsPerSec);
m_secondsPerCount = 1.0 / countsPerSec;
} float GameTimer::TotalTime() const
{
if (m_isStopped)
{
return static_cast<float>((m_stopTime - m_baseTime - m_pausedTime)*m_secondsPerCount);
}
else
{
return static_cast<float>((m_currTime - m_baseTime - m_pausedTime)*m_secondsPerCount);
}
} float GameTimer::DeltaTime() const
{
return static_cast<float>(m_deltaTime);
} void GameTimer::Tick()
{
if (m_isStopped)
{
m_deltaTime = 0.0;
return;
}
//得到这一帧的时间
__int64 currentTime;
QueryPerformanceCounter((LARGE_INTEGER*)¤tTime);
m_currTime = currentTime; //两次计时之间的时间
m_deltaTime = (m_currTime - m_prevTime) * m_secondsPerCount; m_prevTime = m_currTime; if (m_deltaTime < 0.0)
m_deltaTime = 0.0;
} void GameTimer::Reset()
{
__int64 currentTime;
QueryPerformanceCounter((LARGE_INTEGER*)(¤tTime)); m_baseTime = currentTime;
m_prevTime = currentTime;
m_stopTime = ;
m_isStopped = false;
} void GameTimer::Start()
{
__int64 startTime;
QueryPerformanceCounter((LARGE_INTEGER*)&startTime); if (m_isStopped)
{
//更新暂停的总时间
m_pausedTime += (startTime - m_stopTime); m_prevTime = startTime; //不再暂停
m_stopTime = ;
m_isStopped = false;
}
} void GameTimer::Stop()
{
if (!m_isStopped)
{
__int64 currentTime;
QueryPerformanceCounter((LARGE_INTEGER*)¤tTime); m_stopTime = currentTime;
m_isStopped = true;
}
}
注释已经很详细了,类中函数和变量的作用也很明显。构造函数主要是获得根机器相关的变量,得到两次计数之间的时间差。
定时第一次工作是应调用Reset()初始化,以后在每一帧中调用Tick()更新计时器的各种变量。通过TotalTime()和DeltaTime()可以得到相关时间信息,用Stop()和Start()
分别暂停和恢复定时器。
Directx11学习笔记【七】 游戏定时器的实现的更多相关文章
- Directx11学习笔记【九】 3D渲染管线
原文:Directx11学习笔记[九] 3D渲染管线 原文地址:http://blog.csdn.net/bonchoix/article/details/8298116 3D图形学研究的基本内容,即 ...
- Directx11学习笔记【一】 最简单的windows程序HelloWin
声明:本系列教程代码有部分来自dx11龙书及dx11游戏编程入门两本书,后面不再说明 首先,在vs2013中创建一个空的解决方案Dx11Demo,以后的工程都会放在这个解决方案下面.然后创建一个win ...
- Linux学习笔记(七) 查询系统
1.查看命令 (1)man 可以使用 man 命令名称 命令查看某个命令的详细用法,其显示的内容如下: NAME:命令名称 SYNOPSIS:语法 DESCRIPTION:说明 OPTIONS:选项 ...
- (转)Qt Model/View 学习笔记 (七)——Delegate类
Qt Model/View 学习笔记 (七) Delegate 类 概念 与MVC模式不同,model/view结构没有用于与用户交互的完全独立的组件.一般来讲, view负责把数据展示 给用户,也 ...
- Directx11学习笔记【二十二】 用高度图实现地形
本文由zhangbaochong原创,转载请注明出处http://www.cnblogs.com/zhangbaochong/p/5827714.html 在前面我们曾经实现过简单的地形(Direct ...
- Directx11学习笔记【二】 将HelloWin封装成类
我们把上一个教程的代码封装到一个类中来方便以后的使用. 首先新建一个空工程叫做MyHelloWin,添加一个main.cpp文件,然后新建一个类叫做MyWindow,将于窗体有关的操作封装到里面 My ...
- Learning ROS for Robotics Programming Second Edition学习笔记(七) indigo PCL xtion pro live
中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS forRobotics Pro ...
- Typescript 学习笔记七:泛型
中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...
- muduo网络库学习笔记(三)TimerQueue定时器队列
目录 muduo网络库学习笔记(三)TimerQueue定时器队列 Linux中的时间函数 timerfd简单使用介绍 timerfd示例 muduo中对timerfd的封装 TimerQueue的结 ...
- python3.4学习笔记(七) 学习网站博客推荐
python3.4学习笔记(七) 学习网站博客推荐 深入 Python 3http://sebug.net/paper/books/dive-into-python3/<深入 Python 3& ...
随机推荐
- 1.SQL统计某张表的列数。
select count(syscolumns.name) from syscolumns , sysobjects where syscolumns.id ...
- red hat Linux 使用CentOS yum源更新
red hat linux是商业版软件,没有经过注册是无法使用红帽 yum源更新软件的,使用CentOS源更新操作如下: 1.删除red hat linux 原有的yum 源 rpm -aq | gr ...
- Hbase配置中出现的问题总结
在create table的时候出现例如以下问题 1. ERROR: java.io.IOException: Table Namespace Manager not ready yet, try a ...
- linux LNMP自动安装脚本
#!/bin/bashsoft_dir="/home/soft"config_dir="/home/config"httpd="httpd-2.0.5 ...
- SVN的revert和update命令的区别
svn中的revert和update 今天有人问到revert和update的问题. 刚开始还真被问住了. 因为感觉revert和update都可以将本地的copy更新到以前的一个版本,会有什么不同呢 ...
- java获取当前日期时间代码总结
1.获取当前时间,和某个时间进行比较.此时主要拿long型的时间值. 方法如下: 要使用 java.util.Date .获取当前时间的代码如下 代码如下 复制代码 Date date = new ...
- Codeforces Jzzhu and Sequences(圆形截面)
# include <stdio.h> int f[10]; int main() { int x,y,n,j; while(~scanf("%d%d%d",& ...
- 《javascript高级编程》读书笔记(三)变量、范围和内存的问题
第四章:变量.范围和内存的问题 检測类型:typeof是确定一个变量是字符串.数值.布尔值,还是undefined的最佳工具.可是假设变量的值是一个对象或null,typeof仅仅会返回" ...
- cocos2d-x3.0 实现HTTP请求GET、POST
HTTP请求实现 把以下代码拷贝到新创建的project中就能看到效果 HelloWorldScene.h #include "cocos2d.h" /*记得要引头文件*/ #in ...
- hdu3037(lucas定理)
给定n,m,p 表示<=m个豆子放在n棵树上,一共有多少种方案数, 总的方案书mod p 如果将m个豆子放在n棵树上, 可以使用插板法 得到方案数是C(n+m-1,n-1) 那么将0< ...