青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

天行健 君子當自強而不息

游戲中時間的封裝

時鐘類GE_TIMER可用來取得游戲已進行的時間,計算出兩個時間點之間的時間片大小,從而可在某一時間點處,自動更新某些游戲狀態。此外,還可用來獲取程序的幀頻FSP(Frame Per Second)大小,檢驗3D渲染的速度,即游戲速度。

Windows API函數timeGetTime用來取得游戲開始后的時間,返回的時間值單位為ms(毫秒)。

The timeGetTime function retrieves the system time, in milliseconds. The system time is the time elapsed since Windows was started.

DWORD timeGetTime(VOID);

Parameters

This function does not take parameters.

Return Values

Returns the system time, in milliseconds.

但是這個函數的精度只有10ms左右,如果需要采用更為精確的時間,可使用小于1ms時間精度的Windows API函數QueryPerformanceCounter和QueryPerformanceFrequency,這兩個函數直接使用了Windows 內核的精度非常高的定時器。不同的硬件和操作系統,定時器的頻率稍有不同。

The QueryPerformanceFrequency function retrieves the frequency of the high-resolution performance counter,
if one exists. The frequency cannot change while the system is running.

Syntax

BOOL QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency);

Parameters

lpFrequency
[out] Pointer to a variable that receives the current performance-counter frequency, in counts per second.
If the installed hardware does not support a high-resolution performance counter, this parameter can be zero.

Return Value

If the installed hardware supports a high-resolution performance counter, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. For example,
if the installed hardware does not support a high-resolution performance counter, the function fails. 

The QueryPerformanceCounter function retrieves the current value of the high-resolution performance counter. 

Syntax

BOOL QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount);

Parameters

lpPerformanceCount
[out] Pointer to a variable that receives the current performance-counter value, in counts.

Return Value

If the function succeeds, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. 

Remarks

On a multiprocessor computer, it should not matter which processor is called. However, you can get different results on
different processors due to bugs in the basic input/output system (BIOS) or the hardware abstraction layer (HAL).
To specify processor affinity for a thread, use the SetThreadAffinityMask function.

這兩個函數都使用了結構體LARGE_INTEGER,我們來看看它的結構:

The LARGE_INTEGER structure is used to represent a 64-bit signed integer value.

Note  Your C compiler may support 64-bit integers natively. For example, Microsoft® Visual C++® supports the __int64 sized integer type.
For more information, see the documentation included with your C compiler.

typedef union _LARGE_INTEGER
{
     struct {    DWORD LowPart;    LONG HighPart;  }; 
     struct {    DWORD LowPart;    LONG HighPart;  } u;
     LONGLONG QuadPart;
} LARGE_INTEGER, *PLARGE_INTEGER;

Members

LowPart 
Low-order 32 bits.

HighPart 
High-order 32 bits.


LowPart 
Low-order 32 bits. 
HighPart 
High-order 32 bits.

QuadPart 
Signed 64-bit integer.

Remarks

The LARGE_INTEGER structure is actually a union. If your compiler has built-in support for 64-bit integers,
use the QuadPart member to store the 64-bit integer. Otherwise, use the LowPart and HighPart members to store the 64-bit integer.

看的出來,它實際上是1個聯合體。

提示:要正確編譯運行,需要鏈接winmm.lib。
由于本人水平有限,可能存在錯誤,敬請指出。

源碼下載

好了,現在看看GE_COMMON.h的定義,主要用來包含公用的頭文件和宏定義:

/*************************************************************************************
 [Include File]

 PURPOSE: 
    Include common header files and common macro.
************************************************************************************
*/

#ifndef GAME_ENGINE_COMMON_H
#define GAME_ENGINE_COMMON_H

#define DIRECTINPUT_VERSION 0x0800  // let compile shut up

#include 
<windows.h>
#include 
<tchar.h>
#include 
<string.h>
#include 
<stdio.h>

#include 
<d3d9.h>
#include 
<d3dx9.h>
#include 
<dinput.h>
#include 
<dsound.h>

// defines for small numbers
#define EPSILON_E3  (float)(1E-3)
#define EPSILON_E4  (float)(1E-4)
#define EPSILON_E5  (float)(1E-5)
#define EPSILON_E6  (float)(1E-6)

#define Safe_Release(object) if((object) != NULL) { (object)->Release(); (object)=NULL; }

#define FCMP(a, b) (fabs((a) - (b)) < EPSILON_E3 ? 1 : 0)

#endif

由于浮點數不能直接比較大小,所以定義了1個宏來比較浮點數的大小。

#define FCMP(a, b) (fabs((a) -& nbsp;(b)) < EPSILON_E3 ? 1& nbsp;: 0)

再來看看GE_TIMER.h的定義:

/*************************************************************************************
 [Include File]

 PURPOSE: 
    Encapsulate system time for game.
************************************************************************************
*/

#ifndef GAME_ENGINE_TIMER_H
#define GAME_ENGINE_TIMER_H

class GE_TIMER
{
private:
    
bool _use_large_time;               // flag that indicate whether use large time

    __int64 _one_second_ticks;          
// ticks count in one second
    __int64 _tick_counts_start;         // tick counts at start count time

    unsigned 
long _time_start;          // start time for timeGetTime()

    
int _frame_count;                   // frame count number
    float _fps;                         // frame per second
    float _time1, _time2, _time_slice;  // time flag and time slice

public:
    GE_TIMER();
    
~GE_TIMER();
    
void Init_Game_Time();
    
float Get_Game_Play_Time();
    
void Update_FPS();

    
float Get_FPS() { return _fps; }
};

#endif

并非所有系統都支持內核的定時器讀取,因此要定義一個
_use_large_time來標志是否使用這個高精度的定時器,否則將使用timeGetTime函數進行時間計算。

我們來看看構造函數和析構函數的定義:

//------------------------------------------------------------------------------------
// Constructor, initialize game time.
//------------------------------------------------------------------------------------
GE_TIMER::GE_TIMER()
{
    Init_Game_Time();
}

//------------------------------------------------------------------------------------
// Destructor, do nothing.
//------------------------------------------------------------------------------------
GE_TIMER::~GE_TIMER()

}

看的出來,構造函數只是調用了Init_Game_Time來初始化游戲時間,而析構函數什么都不做。

再來看看
Init_Game_Time的定義:

//------------------------------------------------------------------------------------
// Initialize game time.
//------------------------------------------------------------------------------------
void GE_TIMER::Init_Game_Time()
{
    _frame_count 
= 0;
    _fps 
= 0;
    _time1 
= _time2 = _time_slice = 0;

    
if(QueryPerformanceFrequency((LARGE_INTEGER*&_one_second_ticks))
    {
        _use_large_time 
= true;
        QueryPerformanceCounter((LARGE_INTEGER
*&_tick_counts_start);
    }
    
else
    {
        _use_large_time 
= false;
        _time_start 
= timeGetTime();
    }
}

我們使用Get_Game_Play_Time來取得當前的游戲時間,來看看它的定義:

//------------------------------------------------------------------------------------
// Get time has escaped since game start.
//------------------------------------------------------------------------------------
float GE_TIMER::Get_Game_Play_Time()
{
    __int64 current_tick_counts;

    
if(_use_large_time)
    {
        QueryPerformanceCounter((LARGE_INTEGER
*&current_tick_counts);
        
return ((float) (current_tick_counts - _tick_counts_start) / _one_second_ticks) * 1000
    }

    
return (float)(timeGetTime() - _time_start);
}

分兩種情況進行處理,如果使用高精度時鐘,將計算開始和結束時鐘計數之差,除以時鐘頻率,再乘以1000,即獲得時間片大小,單位為 ms。
否則直接利用timeGetTime函數計算時間片大小。

更新幀頻通過Update_FPS函數來進行,每5幀更新一次。

//------------------------------------------------------------------------------------
// Update FPS.
//------------------------------------------------------------------------------------
void GE_TIMER::Update_FPS()
{
    
// increment frame count by one
    _frame_count++;

    
if(_frame_count % 5 == 1)
        _time1 
= Get_Game_Play_Time() / 1000;
    
else if(_frame_count % 5 == 0)
    {
        _time2 
= Get_Game_Play_Time() / 1000;
        _time_slice 
= (float) fabs(_time1 - _time2);    // calculate time escaped
    }

    
// update fps
    if(! FCMP(_time_slice, 0.0))
        _fps 
= 5 / _time_slice;
}

完整的GE_TIMER.cpp實現如下所示:

/*************************************************************************************
 [Implement File]

 PURPOSE: 
    Encapsulate system time for game.
************************************************************************************
*/

#include 
"GE_COMMON.h"
#include 
"GE_TIMER.h"

//------------------------------------------------------------------------------------
// Constructor, initialize game time.
//------------------------------------------------------------------------------------
GE_TIMER::GE_TIMER()
{
    Init_Game_Time();
}

//------------------------------------------------------------------------------------
// Destructor, do nothing.
//------------------------------------------------------------------------------------
GE_TIMER::~GE_TIMER()

}

//------------------------------------------------------------------------------------
// Initialize game time.
//------------------------------------------------------------------------------------
void GE_TIMER::Init_Game_Time()
{
    _frame_count 
= 0;
    _fps 
= 0;
    _time1 
= _time2 = _time_slice = 0;

    
if(QueryPerformanceFrequency((LARGE_INTEGER*&_one_second_ticks))
    {
        _use_large_time 
= true;
        QueryPerformanceCounter((LARGE_INTEGER
*&_tick_counts_start);
    }
    
else
    {
        _use_large_time 
= false;
        _time_start 
= timeGetTime();
    }
}

//------------------------------------------------------------------------------------
// Get time has escaped since game start.
//------------------------------------------------------------------------------------
float GE_TIMER::Get_Game_Play_Time()
{
    __int64 current_tick_counts;

    
if(_use_large_time)
    {
        QueryPerformanceCounter((LARGE_INTEGER
*&current_tick_counts);
        
return ((float) (current_tick_counts - _tick_counts_start) / _one_second_ticks) * 1000
    }

    
return (float)(timeGetTime() - _time_start);
}

//------------------------------------------------------------------------------------
// Update FPS.
//------------------------------------------------------------------------------------
void GE_TIMER::Update_FPS()
{
    
// increment frame count by one
    _frame_count++;

    
if(_frame_count % 5 == 1)
        _time1 
= Get_Game_Play_Time() / 1000;
    
else if(_frame_count % 5 == 0)
    {
        _time2 
= Get_Game_Play_Time() / 1000;
        _time_slice 
= (float) fabs(_time1 - _time2);    // calculate time escaped
    }

    
// update fps
    if(! FCMP(_time_slice, 0.0))
        _fps 
= 5 / _time_slice;
}

posted on 2007-05-07 21:33 lovedday 閱讀(923) 評論(0)  編輯 收藏 引用 所屬分類: ■ DirectX 9 Program

公告

導航

統計

常用鏈接

隨筆分類(178)

3D游戲編程相關鏈接

搜索

最新評論

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            精品成人国产在线观看男人呻吟| 欧美精品一级| 极品少妇一区二区三区| 亚洲欧美日韩在线高清直播| 中文一区二区| 国产在线精品一区二区夜色| 久久免费的精品国产v∧| 久久精品一区二区三区四区| 在线日韩欧美| 欧美成人自拍| 欧美日韩国产经典色站一区二区三区| 一区二区日韩精品| 亚洲欧美国产精品va在线观看| 国内一区二区三区在线视频| 亚洲电影毛片| 欧美视频精品在线观看| 久久岛国电影| 欧美精品一区二区三区蜜桃| 欧美在线视频日韩| 免费欧美在线视频| 性亚洲最疯狂xxxx高清| 裸体女人亚洲精品一区| 亚洲视频在线免费观看| 久久精品久久99精品久久| 99re6这里只有精品视频在线观看| 亚洲视频一二| 亚洲日本中文字幕免费在线不卡| 亚洲视频一区在线观看| 亚洲国产精品福利| 午夜一区不卡| 亚洲一区二区三区四区在线观看| 欧美专区18| 亚洲在线一区二区三区| 免费一级欧美在线大片| 久久er精品视频| 欧美日韩免费视频| 亚洲成色999久久网站| 国产视频久久久久| 一区二区三区国产精品| 亚洲人成欧美中文字幕| 欧美一区二区在线视频| 亚洲一区二区欧美| 欧美刺激性大交免费视频| 久久久五月婷婷| 国产精品一卡二卡| 夜夜夜久久久| 亚洲最新合集| 欧美精品二区| 亚洲人成免费| 亚洲激情视频在线播放| 久久久久国色av免费看影院| 欧美与黑人午夜性猛交久久久| 欧美日韩一区精品| 亚洲精品日产精品乱码不卡| 91久久精品国产91久久| 久久亚洲精品网站| 久久综合九色99| 国产欧美日本一区视频| 亚洲资源av| 欧美一区二区高清| 国产精品一区二区三区久久久| 一区二区欧美日韩| 亚洲一区bb| 国产精品日韩高清| 欧美一级大片在线观看| 欧美一区二区三区视频在线 | 亚洲天堂成人在线视频| 99综合电影在线视频| 欧美欧美午夜aⅴ在线观看| 91久久嫩草影院一区二区| 日韩天堂av| 欧美日韩精品一区二区天天拍小说 | 欧美14一18处毛片| 亚洲人成在线播放| 亚洲砖区区免费| 国产精品永久免费观看| 久久国产一区二区| 欧美成人黑人xx视频免费观看| 1204国产成人精品视频| 欧美成人精品在线| 一区二区三区精品视频在线观看| 亚洲欧美制服另类日韩| 国产资源精品在线观看| 欧美成年视频| 中文一区二区| 鲁大师成人一区二区三区| 亚洲欧洲一区| 国产精品久久国产精麻豆99网站| 欧美一区1区三区3区公司| 鲁大师成人一区二区三区| 日韩亚洲精品电影| 国产精品一区三区| 美女成人午夜| 亚洲经典在线| 小黄鸭精品密入口导航| 含羞草久久爱69一区| 女仆av观看一区| 亚洲一区二区三区三| 久久香蕉国产线看观看网| 亚洲精品美女免费| 国产免费亚洲高清| 老司机aⅴ在线精品导航| 99在线精品观看| 噜噜噜噜噜久久久久久91| 亚洲午夜国产一区99re久久| 精东粉嫩av免费一区二区三区| 欧美日韩国产影院| 久久成人综合视频| 在线视频欧美日韩精品| 欧美国产1区2区| 欧美一区二区三区精品电影| 亚洲精品美女在线观看播放| 国产一区二区三区高清播放| 欧美日韩一本到| 久久在线免费观看视频| 亚洲小说春色综合另类电影| 亚洲高清视频在线| 久久蜜桃精品| 欧美在线观看网站| 亚洲四色影视在线观看| 91久久久国产精品| 樱花yy私人影院亚洲| 国产模特精品视频久久久久| 欧美三级视频在线| 欧美另类在线播放| 免费日韩精品中文字幕视频在线| 久久福利视频导航| 欧美一级午夜免费电影| 亚洲在线成人精品| 亚洲视频成人| 国产精品99久久久久久人 | 欧美电影资源| 美日韩精品视频| 美女爽到呻吟久久久久| 久久精品视频免费| 欧美制服丝袜第一页| 亚洲欧美日韩国产成人精品影院| 一区二区三区日韩欧美| 一本色道久久精品| aa亚洲婷婷| 亚洲愉拍自拍另类高清精品| 亚洲午夜电影在线观看| 亚洲一区在线免费| 午夜精品一区二区三区在线视 | 欧美一区二区啪啪| 欧美伊人久久大香线蕉综合69| 午夜激情一区| 欧美在线亚洲| 噜噜噜在线观看免费视频日韩| 免费看亚洲片| 欧美日韩在线一区| 国产精品人人做人人爽| 国产亚洲精品v| 亚洲电影免费| 洋洋av久久久久久久一区| 亚洲午夜未删减在线观看| 性色av一区二区三区在线观看| 久久国产精品毛片| 欧美国产成人精品| 99re这里只有精品6| 亚洲一区尤物| 久久精品视频亚洲| 欧美理论在线播放| 国产欧美一区二区在线观看| 一区二区三区在线视频观看| 亚洲精品午夜精品| 亚洲免费中文| 美国十次了思思久久精品导航| 亚洲黄色免费| 亚洲欧美日本伦理| 欧美成人精品一区| 国产嫩草一区二区三区在线观看| 国自产拍偷拍福利精品免费一| 亚洲精品无人区| 欧美一区二区三区视频免费| 亚洲第一久久影院| 亚洲欧美国产不卡| 欧美二区在线播放| 国产视频在线观看一区二区| 亚洲精品免费网站| 久久久精品2019中文字幕神马| 亚洲国产美女| 欧美怡红院视频| 欧美日韩中文字幕精品| 精品999成人| 欧美一级一区| 亚洲美女淫视频| 每日更新成人在线视频| 国产欧美日韩综合精品二区| 一区二区欧美激情| 久热精品视频在线观看一区| 一区二区三区欧美在线| 欧美成人精品影院| 国产欧美日韩视频在线观看| 一片黄亚洲嫩模| 欧美高清hd18日本| 久久精品在线视频| 国产精品丝袜xxxxxxx| 一区二区免费在线视频| 欧美黄色免费|