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& ...
随机推荐
- Android中Menu的基本使用方法
一. 使用xml定义Menu 菜单资源文件必须放在res/menu文件夹中.菜单资源文件必须使用<menu>标签作为根节点.除了<menu>标签外,还有另外两个标签用于设置菜单 ...
- ThinkPHP---RBAC
一.什么是RBAC 基于角色的访问控制(Role-Based Access Control)作为传统访问控制(自主访问,强制访问)的有前景的代替受到广泛的关注. 在RBAC中,权限与角色相关联,用户通 ...
- URAL1523(dp+树状数组)
题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=41224#problem/B 分析:可以设dp[i][j]表示以i结尾长度为j的 ...
- UVA 5875 DP
题意:给你一堆二维点,每个点有一些分数. 现在要从点(0 , 0 )出发,只能从标号小的点走到大的点,每个人有一个走的距离的限制,问最后能拿到的最高的分数,当然这个人从(0 , 0)出发还得回到( 0 ...
- 从尾到头打印链表--《剑指offer》
题目:非常easy,就是题目,将链表从尾到头打印出来. 可能我们首先想到的是将链表进行遍历,将之前的訪问的数据进行保存,最后进行反向输出,但是保存数据的空间是个问题:或者是我们将整个链表进行反向操作, ...
- Knockout应用开发指南 第二章:监控属性(Observables)
原文:Knockout应用开发指南 第二章:监控属性(Observables) 关于Knockout的3个重要概念(Observables,DependentObservables,Observabl ...
- [POJ 3150] Cellular Automaton (矩阵高速幂 + 矩阵乘法优化)
Cellular Automaton Time Limit: 12000MS Memory Limit: 65536K Total Submissions: 3048 Accepted: 12 ...
- hdu3709(数位dp)
求区间[l,r]内有多少个数的满足: 选一个位为中点,是的左边的数到该位的距离等于右边的位到该位的距离. 比如4139 选择3位中点, 那么左边的距离是 4 * 2 + 1 * 1 , 右边的距 ...
- PowerDesigner 对 Oracle 作 逆向工程
原文 PowerDesigner 对 Oracle 作 逆向工程 目的 PowerDesigner 15对OracleClient 11g进行逆向工程 环境 Win7 64位系统 Oracle 11g ...
- JQuery日记_5.13 Sizzle选择器(六)选择器的效率
当选择表达式不符合高速匹配(id,tag,class)和原生QSA不可用或返回错误时,将调用select(selector, context, results, seed)方法,此方法迭代DO ...