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
1 #ifndef GAMETIMER_H 2 #define GAMETIMER_H 3 4 class GameTimer 5 { 6 public: 7 GameTimer(); 8 float TotalTime() const;//返回定时器从计时开始到现在的总时间,不包括暂停时间 9 float DeltaTime() const;//返回本次计时与上次计时之间的时间差 10 11 void Reset();//重置 12 void Start();//暂停后恢复计时 13 void Stop();//暂停 14 void Tick();//计时一次,每一帧调用 15 16 private: 17 double m_secondsPerCount;//系统相关,系统两次计数之间的时间差,是定时器把时间转换为s的基准 18 double m_deltaTime;//距离上次计时的时间差 19 20 __int64 m_baseTime;//定时器开始工作的时间点 21 __int64 m_pausedTime;//暂停的总时间 22 __int64 m_stopTime;//暂停的开始时间 23 __int64 m_prevTime;//上次计时的时间点 24 __int64 m_currTime;//本次计时的时间点 25 26 bool m_isStopped;//是否暂停 27 }; 28 29 #endif //GAMETIMER_H
GameTimer.cpp
1 #include "GameTimer.h" 2 #include <windows.h> 3 4 GameTimer::GameTimer() : m_secondsPerCount(0.0), m_deltaTime(-1.0), m_baseTime(0), m_pausedTime(0), 5 m_prevTime(0), m_currTime(0), m_isStopped(false) 6 { 7 __int64 countsPerSec; 8 QueryPerformanceFrequency((LARGE_INTEGER*)&countsPerSec); 9 m_secondsPerCount = 1.0 / countsPerSec; 10 } 11 12 13 float GameTimer::TotalTime() const 14 { 15 if (m_isStopped) 16 { 17 return static_cast<float>((m_stopTime - m_baseTime - m_pausedTime)*m_secondsPerCount); 18 } 19 else 20 { 21 return static_cast<float>((m_currTime - m_baseTime - m_pausedTime)*m_secondsPerCount); 22 } 23 } 24 25 float GameTimer::DeltaTime() const 26 { 27 return static_cast<float>(m_deltaTime); 28 } 29 30 void GameTimer::Tick() 31 { 32 if (m_isStopped) 33 { 34 m_deltaTime = 0.0; 35 return; 36 } 37 //得到这一帧的时间 38 __int64 currentTime; 39 QueryPerformanceCounter((LARGE_INTEGER*)¤tTime); 40 m_currTime = currentTime; 41 42 //两次计时之间的时间 43 m_deltaTime = (m_currTime - m_prevTime) * m_secondsPerCount; 44 45 m_prevTime = m_currTime; 46 47 if (m_deltaTime < 0.0) 48 m_deltaTime = 0.0; 49 } 50 51 void GameTimer::Reset() 52 { 53 __int64 currentTime; 54 QueryPerformanceCounter((LARGE_INTEGER*)(¤tTime)); 55 56 m_baseTime = currentTime; 57 m_prevTime = currentTime; 58 m_stopTime = 0; 59 m_isStopped = false; 60 } 61 62 void GameTimer::Start() 63 { 64 __int64 startTime; 65 QueryPerformanceCounter((LARGE_INTEGER*)&startTime); 66 67 if (m_isStopped) 68 { 69 //更新暂停的总时间 70 m_pausedTime += (startTime - m_stopTime); 71 72 m_prevTime = startTime; 73 74 //不再暂停 75 m_stopTime = 0; 76 m_isStopped = false; 77 } 78 } 79 80 void GameTimer::Stop() 81 { 82 if (!m_isStopped) 83 { 84 __int64 currentTime; 85 QueryPerformanceCounter((LARGE_INTEGER*)¤tTime); 86 87 m_stopTime = currentTime; 88 m_isStopped = true; 89 } 90 }
注释已经很详细了,类中函数和变量的作用也很明显。构造函数主要是获得根机器相关的变量,得到两次计数之间的时间差。
定时第一次工作是应调用Reset()初始化,以后在每一帧中调用Tick()更新计时器的各种变量。通过TotalTime()和DeltaTime()可以得到相关时间信息,用Stop()和Start()
分别暂停和恢复定时器。
转载于:https://www.cnblogs.com/lonelyxmas/p/10812370.html
Directx11学习笔记【七】 游戏定时器的实现相关推荐
- 基于STM32G431嵌入式学习笔记——七、定时器定时
一.题目引入 上述为第13届蓝桥杯省赛节选内容,为了研究定时器的机理并独立书写计时函数,上述内容简化为以下要求: ①按下B4按键,LD1点亮5s后熄灭 ②按下B3按键,LD2以0.1秒为间隔切换亮灭状 ...
- 【K210】K210学习笔记七——使用K210拍摄照片并在MaixHub上进行训练
[K210]K210学习笔记七--使用K210拍摄照片并在MaixHub上进行训练 前言 K210准备工作 K210如何拍摄照片 准备工作 拍摄相关代码定义 用K210拍摄到的照片在MaixHub平台 ...
- window的dos命令学习笔记 七
文章目录 一.dos历史学习笔记(后期整合到这里,我想能学到这里的应该不多了,嘿嘿,加油) 二.执行状态返回值(`%errorlevel%`,和shell中`$?`相似): 三.视窗 1.color ...
- ESP32学习笔记(七) 复位和时钟
ESP32学习笔记(七) 复位和时钟 目录: ESP32学习笔记(一) 芯片型号介绍 ESP32学习笔记(二) 开发环境搭建 VSCode+platformio ESP32学习笔记(三) 硬件资源介绍 ...
- STM32学习笔记(七)---SysTick
STM32学习笔记(七)-SysTick 文章目录 STM32学习笔记(七)---SysTick 一.SysTick简介 二.SysTick功能框图 三.SysTick寄存器 四.SYSTICK使用 ...
- Typescript 学习笔记七:泛型
中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...
- Directx11学习笔记【二】 将HelloWin封装成类
我们把上一个教程的代码封装到一个类中来方便以后的使用. 首先新建一个空工程叫做MyHelloWin,添加一个main.cpp文件,然后新建一个类叫做MyWindow,将于窗体有关的操作封装到里面 My ...
- 吴恩达《机器学习》学习笔记七——逻辑回归(二分类)代码
吴恩达<机器学习>学习笔记七--逻辑回归(二分类)代码 一.无正则项的逻辑回归 1.问题描述 2.导入模块 3.准备数据 4.假设函数 5.代价函数 6.梯度下降 7.拟合参数 8.用训练 ...
- websocket 获取连接id_Swoole学习笔记七:搭建WebSocket长连接 之 使用 USER_ID 作为身份凭证...
Swoole学习笔记七:搭建WebSocket长连接 之 使用 USER_ID 作为身份凭证 2年前 阅读 3678 评论 0 喜欢 0 ### 0.前言 前面基本的WebSocket操作,我们基本都 ...
- ROS学习笔记七:使用rqt_console和roslaunch
ROS学习笔记七:使用rqt_console和roslaunch 本节主要介绍在调试时使用的rqt_console和rqt_logger_level,以及一次性打开多个节点的工具roslaunch. ...
最新文章
- Python如何在以数字命名的文件前补0
- jQuery.width()和jQuery.css('width')的区别
- %matplotlib inline %config InlineBackend.figure_format = “retina为了将图片嵌入notebook及提高分
- 我的Go语言学习之旅二:入门初体验 Hello World
- 计算机图形学Web前端笔记-图形平移放缩原理及实现(two.js鼠标事件适用所有渲染)
- java判断线段是否相交函数_计算几何-判断线段是否相交
- java读写mysql数据库_Java读写MySQL数据库小实例
- IDEA Tomcat控制台中文乱码
- c# mysql清理_C# 中清空sql数据库中的数据
- Android系统签名生成
- 关于gotoxy函数
- 网页抢东西插件_京东秒杀抢购的小脚本和chorme的一个开发者插件
- element 源码学习五 —— Notice 系列组件学习
- 关于机器人方面的sci论文_机器人期刊_SCI
- esxi下搭建软路由
- 新建git分支(歪门邪道)
- Web与排版学上的字体问题【转】
- iOS 3DES加密
- 计蒜客2018 蓝桥杯省赛 B 组模拟赛(一)-H题封印之门
- 【小程序项目开发-- 京东商城】uni-app之商品列表页面 (下)
热门文章
- nvcc fatal : '--ptxas-options=-v': expected a number
- Leetcode之合并区间
- LayaAir UI组件 # Tab 选项卡按钮组
- LayaAir WebSocket 通信
- springboot 对象 空指针_springboot获取getBean方法以及ApplicationContext空指针问题解决...
- 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_05 IO字符流_7_字符输出流的续写和换行...
- CSS外边距合并(塌陷/margin越界)
- easyui datagrid 遇到的坑 cannot read property ·· pageNum bug and so on
- Scrapy 1.4 文档 02 安装指南
- 按钮插件和按钮状态切换