Directx11学习笔记【七】 游戏定时器的实现
原文: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*)&currentTime);
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*)(&currentTime));
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*)&currentTime);
86
87         m_stopTime = currentTime;
88         m_isStopped = true;
89     }
90 }

  注释已经很详细了,类中函数和变量的作用也很明显。构造函数主要是获得根机器相关的变量,得到两次计数之间的时间差。

  定时第一次工作是应调用Reset()初始化,以后在每一帧中调用Tick()更新计时器的各种变量。通过TotalTime()和DeltaTime()可以得到相关时间信息,用Stop()和Start()

分别暂停和恢复定时器。

posted on 2019-05-05 12:57 NET未来之路 阅读(...) 评论(...) 编辑 收藏

转载于:https://www.cnblogs.com/lonelyxmas/p/10812370.html

Directx11学习笔记【七】 游戏定时器的实现相关推荐

  1. 基于STM32G431嵌入式学习笔记——七、定时器定时

    一.题目引入 上述为第13届蓝桥杯省赛节选内容,为了研究定时器的机理并独立书写计时函数,上述内容简化为以下要求: ①按下B4按键,LD1点亮5s后熄灭 ②按下B3按键,LD2以0.1秒为间隔切换亮灭状 ...

  2. 【K210】K210学习笔记七——使用K210拍摄照片并在MaixHub上进行训练

    [K210]K210学习笔记七--使用K210拍摄照片并在MaixHub上进行训练 前言 K210准备工作 K210如何拍摄照片 准备工作 拍摄相关代码定义 用K210拍摄到的照片在MaixHub平台 ...

  3. window的dos命令学习笔记 七

    文章目录 一.dos历史学习笔记(后期整合到这里,我想能学到这里的应该不多了,嘿嘿,加油) 二.执行状态返回值(`%errorlevel%`,和shell中`$?`相似): 三.视窗 1.color ...

  4. ESP32学习笔记(七) 复位和时钟

    ESP32学习笔记(七) 复位和时钟 目录: ESP32学习笔记(一) 芯片型号介绍 ESP32学习笔记(二) 开发环境搭建 VSCode+platformio ESP32学习笔记(三) 硬件资源介绍 ...

  5. STM32学习笔记(七)---SysTick

    STM32学习笔记(七)-SysTick 文章目录 STM32学习笔记(七)---SysTick 一.SysTick简介 二.SysTick功能框图 三.SysTick寄存器 四.SYSTICK使用 ...

  6. Typescript 学习笔记七:泛型

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  7. Directx11学习笔记【二】 将HelloWin封装成类

    我们把上一个教程的代码封装到一个类中来方便以后的使用. 首先新建一个空工程叫做MyHelloWin,添加一个main.cpp文件,然后新建一个类叫做MyWindow,将于窗体有关的操作封装到里面 My ...

  8. 吴恩达《机器学习》学习笔记七——逻辑回归(二分类)代码

    吴恩达<机器学习>学习笔记七--逻辑回归(二分类)代码 一.无正则项的逻辑回归 1.问题描述 2.导入模块 3.准备数据 4.假设函数 5.代价函数 6.梯度下降 7.拟合参数 8.用训练 ...

  9. websocket 获取连接id_Swoole学习笔记七:搭建WebSocket长连接 之 使用 USER_ID 作为身份凭证...

    Swoole学习笔记七:搭建WebSocket长连接 之 使用 USER_ID 作为身份凭证 2年前 阅读 3678 评论 0 喜欢 0 ### 0.前言 前面基本的WebSocket操作,我们基本都 ...

  10. ROS学习笔记七:使用rqt_console和roslaunch

    ROS学习笔记七:使用rqt_console和roslaunch 本节主要介绍在调试时使用的rqt_console和rqt_logger_level,以及一次性打开多个节点的工具roslaunch. ...

最新文章

  1. Python如何在以数字命名的文件前补0
  2. jQuery.width()和jQuery.css('width')的区别
  3. %matplotlib inline %config InlineBackend.figure_format = “retina为了将图片嵌入notebook及提高分
  4. 我的Go语言学习之旅二:入门初体验 Hello World
  5. 计算机图形学Web前端笔记-图形平移放缩原理及实现(two.js鼠标事件适用所有渲染)
  6. java判断线段是否相交函数_计算几何-判断线段是否相交
  7. java读写mysql数据库_Java读写MySQL数据库小实例
  8. IDEA Tomcat控制台中文乱码
  9. c# mysql清理_C# 中清空sql数据库中的数据
  10. Android系统签名生成
  11. 关于gotoxy函数
  12. 网页抢东西插件_京东秒杀抢购的小脚本和chorme的一个开发者插件
  13. element 源码学习五 —— Notice 系列组件学习
  14. 关于机器人方面的sci论文_机器人期刊_SCI
  15. esxi下搭建软路由
  16. 新建git分支(歪门邪道)
  17. Web与排版学上的字体问题【转】
  18. iOS 3DES加密
  19. 计蒜客2018 蓝桥杯省赛 B 组模拟赛(一)-H题封印之门
  20. 【小程序项目开发-- 京东商城】uni-app之商品列表页面 (下)

热门文章

  1. nvcc fatal : '--ptxas-options=-v': expected a number
  2. Leetcode之合并区间
  3. LayaAir UI组件 # Tab 选项卡按钮组
  4. LayaAir WebSocket 通信
  5. springboot 对象 空指针_springboot获取getBean方法以及ApplicationContext空指针问题解决...
  6. 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_05 IO字符流_7_字符输出流的续写和换行...
  7. CSS外边距合并(塌陷/margin越界)
  8. easyui datagrid 遇到的坑 cannot read property ·· pageNum bug and so on
  9. Scrapy 1.4 文档 02 安装指南
  10. 按钮插件和按钮状态切换