The Game Loop
来源:互联网 发布:天谕最萌萝莉捏脸数据 编辑:程序博客网 时间:2024/05/06 20:57
The Game Loop
Game loop是一种循环系统,不断调用刷新场景中的objects并绘制到显示器上。通常情况下,在程序启动后不久就初始化并执行game loop,而且一直运行到程序结束。有各种各样的game loop设计,图10.8描述了一种最基础的设计。
图10.8 A basic game loop.
从代码的角度看,这种game loop设计与列表10.2的相同
列表10.2 A Basic Game Loop in C++
void Game::Run(){Initialize();while (isRunning){mGameClock.UpdateGameTime(mGameTime);Update(mGameTime);Draw(mGameTime);}Shutdown();}void Game::Exit(){isRunning = false;}
其中,Game::Initialize()函数表示window和Direct3D的initialization(实际代码上分成两个函数),与具体game的初始化步骤一样执行。Game::Update()函数执行所有与渲染无关的操作。例如,Update()函数可能会处理键盘和鼠标的输入,旋转一个objcet或者更新object的坐标位置。相反,Draw()函数处理所有与图形渲染相关的指令。这两个方法用于场景中所有objects的updating和drawing。
Time
代码中调用了UpdateGameTime()函数,以及对应的成员变量mGameTime,该变量作为调用Update()和Draw()函数的参数。这些变量和函数都与time相关,在游戏和图形编程中是非常重要的。与时间相关的最值得关注的两个信息是:时钟开始时间和上一次game loop迭代持续的时间。后一个时间通常用于游戏的frame rate。Game loop迭代一次称为一帧(frame),frame rate表示一秒内执行的帧的数量。在GameClock和GameTime类中封装了elapsed-time数据,以及对应的函数。图10.9显示了这两种类型的类结构图。列表10.3列出了类GameClock的头文件。
Figure 10.9 Class diagrams for the GameClock and GameTime classes.
Listing 10.3 The GameClock.h Header File
#pragma once#include <windows.h>#include <exception>namespace Library{ class GameTime; class GameClock { public: GameClock(); const LARGE_INTEGER& StartTime() const; const LARGE_INTEGER& CurrentTime() const; const LARGE_INTEGER& LastTime() const; void Reset(); double GetFrequency() const; void GetTime(LARGE_INTEGER& time) const; void UpdateGameTime(GameTime& gameTime); private: GameClock(const GameClock& rhs); GameClock& operator=(const GameClock& rhs); LARGE_INTEGER mStartTime; LARGE_INTEGER mCurrentTime; LARGE_INTEGER mLastTime; double mFrequency; };}
GameClock类封装了调用获取高精度定时器的Windows API,该定时器是通过获取CPU执行频率计算得到的。通过调用QueryPerformanceFrequency()函数确定frequency,该函数通过修改一个LARGE_INTEGER(一个64位的整形数,或者long long)的参数值,返回获取的结果。把获取到的frequency值存储到GameClock类成员变量中,用于后续的elapsed-time计算。
通过调用QueryPerformanceCounter()函数,可以得到高精度定时器当前的状态。为了计算一次game loop迭代的持续时间(elapsed time),需要调用QueryPerformanceCounter()函数两次,一次是在循环的开始(在调用Update()函数之前),一次是在循环的结束(在调用Draw()函数之后)。使用下面的公式计算elapsed time(精确到秒):
timeelapsed = (stopTime − startTime) / frequency
要计算从程序启动到现在所经过的总的elapsed time,可以把每一帧的elapsed time相加或者保存最开始调用QueryPerformanceCounter()函数得到的结果,再使用上面的公式计算。列表10.4列出了GameClock类的实现代码。
列表10.4 The GameClock.cpp File
#include "GameClock.h"#include "GameTime.h"namespace Library{ GameClock::GameClock() : mStartTime(), mCurrentTime(), mLastTime(), mFrequency() { mFrequency = GetFrequency(); Reset(); } const LARGE_INTEGER& GameClock::StartTime() const { return mStartTime; } const LARGE_INTEGER& GameClock::CurrentTime() const { return mCurrentTime; } const LARGE_INTEGER& GameClock::LastTime() const { return mLastTime; } void GameClock::Reset() { GetTime(mStartTime); mCurrentTime = mStartTime; mLastTime = mCurrentTime; } double GameClock::GetFrequency() const { LARGE_INTEGER frequency; if (QueryPerformanceFrequency(&frequency) == false) { throw std::exception("QueryPerformanceFrequency() failed."); } return (double)frequency.QuadPart; } void GameClock::GetTime(LARGE_INTEGER& time) const { QueryPerformanceCounter(&time); } void GameClock::UpdateGameTime(GameTime& gameTime) { GetTime(mCurrentTime); gameTime.SetTotalGameTime((mCurrentTime.QuadPart - mStartTime.QuadPart) / mFrequency); gameTime.SetElapsedGameTime((mCurrentTime.QuadPart - mLastTime.QuadPart) / mFrequency); mLastTime = mCurrentTime; }}
在GameClock类的实现代码中,成员变量mStartTime存储了用于计算总的elapsed time的计数值,该变量在Reset()函数中进行赋值。成员变量mCurrentTime和mLastTime用于存储再次调用QueryPerformanceCounter()的结果,并用于计算第一帧的elapsed time。UpdateGameTime()函数封装了elapsed-time的计算,而不是直接把这些计算代码放在Game::Run()函数中。Frequency是在GameClock初始化时获取的。GameTime类没有什么特别的函数;只是简单地提供了访问和修改成员变量mElapsedGameTime和mTotalElapsedGameTime的函数接口。所有源码都可以在本书的配套网站上找到。
Game Loop Initialization
Game类是渲染引擎的核心,并且封装了game loop。Game loop的初始化阶段,执行调用三个虚拟函数:InitializeWindow(), InitializeDirectX(), and Inititialize();这三个函数分别执行以下操作,为应用程序创建一个用于绘制的窗口,设置并初始化DirectX,执行通用组件的初始化(很快就会讨论到)。Game类设计成用于被其他类继承的基类(尽管正式地说,该类不是一个抽象基类,因为包含了一个完整的实现定义),因此所有的虚函数都可以由派生类自己实现。但是基类Game还是为每一个虚函数提供了通用的实现方法。
0 0
- 5-The Game Loop
- The Game Loop
- The standard C# / Windows Forms game loop
- Game Loop
- Game Loop - Game Programming Patterns
- 3-A Basic Game Loop
- Craftyjs系列7-Game Loop
- Android Game Development - A Basic Game Loop
- Structuring the Main Loop
- the beginning of the loop
- The Game
- The Game
- The Game
- The Game
- 二,游戏的game loop搭建
- The Managed DirectX Render Loop
- The JavaScript Event Loop: Explained
- The JavaScript Event Loop: Explained
- 手游研发系列【1】—— csv解析方案
- 程序员==java基础===集合
- js(十六)——原型创建对象和继承
- 多数投票算法 Majority Vote Algorithm
- linux 计划任务
- The Game Loop
- const
- Json
- ubuntu SSH配置解决方法
- 滑动条缩放图片
- XML CDATA是什么
- 内核线程
- 自定义属性的简单用法
- 从相册中获取图片