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

天行健 君子當自強而不息

游戲中時間的封裝

時鐘類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 閱讀(930) 評論(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>
            国产精品免费一区二区三区观看| 欧美成人一区二区在线| 夜夜狂射影院欧美极品| 99在线精品观看| 欧美黑人多人双交| 99v久久综合狠狠综合久久| 亚洲免费av电影| 欧美一区视频在线| 亚洲欧美三级伦理| 久久综合色天天久久综合图片| 欧美韩国一区| 国产精品日日摸夜夜添夜夜av| 伊人狠狠色j香婷婷综合| 亚洲欧洲久久| 久久激情网站| 亚洲伦伦在线| 麻豆精品在线视频| 国产精品一区二区男女羞羞无遮挡 | 亚洲一区中文字幕在线观看| 久久久精品日韩| 日韩视频免费在线观看| 国产精品久久久久久久9999| 在线欧美日韩| 欧美一区二区三区在线免费观看| 亚洲第一精品福利| 亚洲一区在线直播| 欧美亚洲日本国产| 亚洲乱码国产乱码精品精天堂 | 欧美一区二区三区久久精品| 欧美在线黄色| 99精品久久| 亚洲国产精品一区二区久| 欧美一区二区成人| 91久久久国产精品| 亚洲欧美日韩爽爽影院| 亚洲激情第一页| 欧美第十八页| 国产精品夜夜嗨| 亚洲成人在线视频播放| 欧美在线视频一区二区| 亚洲日本视频| 亚洲国产精品欧美一二99| 国产精品久久777777毛茸茸| 欧美二区不卡| 国内视频一区| 久久久噜噜噜久久久| 午夜精品电影| 在线亚洲电影| 亚洲一区二区三区乱码aⅴ| 欧美日韩美女在线| 亚洲天堂成人在线视频| 亚洲欧美国产精品桃花| 国模私拍一区二区三区| 一区二区三区精品在线| 国产欧美日韩在线观看| 久久久久久久尹人综合网亚洲 | 欧美激情va永久在线播放| 久久男人资源视频| 国产精品天天摸av网| 日韩一本二本av| 99re热这里只有精品视频 | 亚洲一级免费视频| 国产欧美综合在线| 一区二区高清视频| 日韩视频在线观看国产| 嫩草成人www欧美| 亚洲图中文字幕| 欧美日韩国产不卡| 亚洲欧美在线观看| 欧美专区中文字幕| 欧美一区影院| 国产亚洲欧美另类中文 | 亚洲专区一区二区三区| 欧美日本久久| 久久久久99| 国产有码在线一区二区视频| 欧美一二三视频| 久久一区二区三区av| 欧美aⅴ99久久黑人专区| 麻豆久久婷婷| 欧美视频久久| 欧美激情综合色| 亚洲美女性视频| 欧美日韩国产在线一区| 一区二区三区回区在观看免费视频| 在线午夜精品| 国产欧美视频在线观看| 久久爱91午夜羞羞| 亚洲精品资源| 欧美视频久久| 西西人体一区二区| 在线视频欧美精品| 国产精品乱码久久久久久| 亚洲欧美日韩视频一区| 欧美~级网站不卡| 国产精品视频男人的天堂| 午夜日韩福利| 亚洲第一综合天堂另类专| 99日韩精品| 国产一区91精品张津瑜| 久热国产精品| 亚洲影院色无极综合| 麻豆av一区二区三区久久| 99伊人成综合| 黄色一区二区三区四区| 欧美一进一出视频| 亚洲激情视频网站| 亚洲区第一页| 国产欧美一区二区精品性 | 亚洲高清在线观看| 亚洲一区二区三区在线播放| 欧美黑人一区二区三区| 亚洲欧美国产三级| 欧美激情一区在线观看| 欧美一区日韩一区| 亚洲最新在线| 在线观看欧美成人| 国产精品99免费看| 中日韩美女免费视频网址在线观看| 日韩一区二区高清| 国产主播一区二区三区四区| 欧美日韩国产一区| 久久一二三区| 亚洲国产激情| 久久久久欧美精品| 亚洲欧美一级二级三级| 亚洲精品国产视频| 精品粉嫩aⅴ一区二区三区四区| 欧美午夜精品| 欧美韩日一区| 欧美成人r级一区二区三区| 91久久线看在观草草青青| 久久九九久久九九| 欧美一级视频一区二区| 国产日韩一区欧美| 欧美在线视屏| 午夜精品久久久久久99热| 日韩写真视频在线观看| 亚洲第一在线视频| 欧美a级大片| 巨胸喷奶水www久久久免费动漫| 亚洲男同1069视频| 精品成人一区| 国产综合香蕉五月婷在线| 国产精品萝li| 国产精品一区久久久| 国产精品久久9| 国产精品一级久久久| 国产精品久久久久一区二区三区| 欧美日韩免费观看一区二区三区| 欧美成在线观看| 欧美精品videossex性护士| 亚洲少妇自拍| 亚洲亚洲精品在线观看| 中文在线资源观看网站视频免费不卡| 亚洲伦理在线观看| 99re热这里只有精品免费视频| 亚洲美女色禁图| 一本色道**综合亚洲精品蜜桃冫| 亚洲精选一区| 亚洲在线免费观看| 亚洲欧美日韩另类| 欧美在线你懂的| 免费精品99久久国产综合精品| 能在线观看的日韩av| 欧美激情一区二区三区在线视频观看 | 亚洲视频一二| 久久精品毛片| 亚洲午夜极品| 欧美主播一区二区三区美女 久久精品人| 欧美伊久线香蕉线新在线| 久久激情五月丁香伊人| 欧美jizzhd精品欧美喷水| 欧美女激情福利| 国产精品视频区| 一区二区在线观看视频| 日韩视频精品| 欧美一区午夜精品| 欧美顶级大胆免费视频| 一区二区三区黄色| 久久精品女人的天堂av| 欧美激情在线免费观看| 国产精品综合不卡av| 亚洲成色999久久网站| 亚洲婷婷在线| 久久综合成人精品亚洲另类欧美| 亚洲成色777777在线观看影院| 一区二区三区 在线观看视频| 欧美一区永久视频免费观看| 欧美久久久久中文字幕| 国产午夜亚洲精品理论片色戒| 亚洲啪啪91| 久久亚洲图片| 亚洲一本大道在线| 欧美成人一区二区三区| 国产精品亚发布| 99成人精品| 欧美h视频在线| 欧美一级片一区| 欧美视频中文字幕|