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

天行健 君子當自強而不息

游戲中時間的封裝

時鐘類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>
            亚洲伊人第一页| 欧美一区二区免费视频| 欧美1区视频| 另类av导航| 一区二区三区久久| 一片黄亚洲嫩模| 国产午夜精品全部视频在线播放 | 欧美日韩另类国产亚洲欧美一级| 日韩视频在线观看| 亚洲视频专区在线| 狠狠色狠狠色综合日日小说| 欧美1区2区3区| 国产精品va在线| 久久一区二区三区四区| 欧美成人午夜77777| 亚洲一区二区三区在线观看视频 | 欧美91视频| 亚洲午夜精品一区二区三区他趣| 亚洲综合三区| 亚洲另类在线视频| 午夜精品久久久久久久| 亚洲人成网站999久久久综合| 99亚洲伊人久久精品影院红桃| 国产视频精品va久久久久久| 亚洲国产免费| 国产欧美精品在线| 亚洲国产你懂的| 国内精品嫩模av私拍在线观看 | 亚洲理论电影网| 国产在线不卡视频| 一区二区三区.www| 在线观看日韩专区| 亚洲免费一在线| 亚洲午夜一级| 蜜臀a∨国产成人精品| 香蕉成人久久| 欧美日韩在线三级| 欧美激情视频一区二区三区在线播放 | 99精品欧美一区二区蜜桃免费| 国产婷婷色综合av蜜臀av| 亚洲精品欧美在线| 亚洲动漫精品| 性做久久久久久久久| 亚洲五月六月| 欧美日本不卡高清| 免费一区二区三区| 国内精品模特av私拍在线观看| 亚洲性夜色噜噜噜7777| 一区二区三区视频免费在线观看 | 久久国产精品第一页| 午夜国产不卡在线观看视频| 欧美精品亚洲一区二区在线播放| 欧美电影免费网站| 亚洲电影免费观看高清| 久久精品一二三| 久久欧美中文字幕| 国产一区再线| 久久久久国产精品一区三寸 | 亚洲免费在线观看视频| 欧美日韩精品福利| 亚洲美女啪啪| 亚洲小说春色综合另类电影| 欧美日韩日韩| 99re6这里只有精品| 中文在线资源观看网站视频免费不卡| 欧美激情中文字幕乱码免费| 最新日韩欧美| 亚洲午夜一二三区视频| 欧美性猛片xxxx免费看久爱| 亚洲视频网站在线观看| 欧美一区二区大片| 黄色欧美成人| 欧美福利精品| 日韩一级大片在线| 欧美亚洲日本一区| 国内外成人免费激情在线视频| 欧美一区午夜视频在线观看| 美女网站在线免费欧美精品| 亚洲精品日本| 欧美午夜a级限制福利片| 亚洲欧美另类久久久精品2019| 久久久久久久久一区二区| 亚洲福利在线视频| 欧美精品性视频| 午夜精品久久久久久久99黑人| 老司机一区二区三区| 999在线观看精品免费不卡网站| 欧美日韩一区二区视频在线观看| 亚洲欧美国产精品va在线观看| 久热精品在线| 中日韩视频在线观看| 国产欧美一区二区三区沐欲| 免播放器亚洲一区| 一区二区激情小说| 蜜桃伊人久久| 亚洲一区综合| 伊人久久亚洲影院| 欧美日韩亚洲一区二区| 欧美在线免费观看| 99re66热这里只有精品3直播| 久久久久九九九| 999亚洲国产精| 精品不卡视频| 国产精品久久一区二区三区| 米奇777超碰欧美日韩亚洲| 中文精品视频| 亚洲国产日韩欧美综合久久| 久久国产手机看片| 99国产精品国产精品久久| 国产亚洲福利| 国产精品高潮呻吟| 麻豆国产va免费精品高清在线| 亚洲调教视频在线观看| 亚洲电影成人| 久久一区欧美| 亚洲影院免费| 一本色道综合亚洲| 亚洲人www| 亚洲第一精品影视| 国产欧美日韩在线观看| 欧美日韩专区| 欧美日韩a区| 欧美aa在线视频| 久久―日本道色综合久久| 亚洲欧美美女| 亚洲午夜久久久久久久久电影院 | 国产亚洲成av人在线观看导航| 欧美日韩国产va另类| 蜜臀av在线播放一区二区三区| 欧美一区国产在线| 香蕉亚洲视频| 香蕉成人伊视频在线观看| 一区二区三区日韩| 9国产精品视频| 日韩网站免费观看| 一本久道久久综合婷婷鲸鱼| 亚洲精品国产精品乱码不99按摩| 欧美成人一二三| 欧美福利视频| 亚洲国产综合91精品麻豆| 欧美国产精品专区| 亚洲人午夜精品免费| 亚洲欧洲免费视频| 日韩系列在线| 国产精品99久久久久久久女警| 在线中文字幕一区| 亚洲影院污污.| 欧美亚洲视频| 久久免费99精品久久久久久| 另类亚洲自拍| 欧美精品在线观看一区二区| 欧美日韩午夜精品| 国产精品入口麻豆原神| 国产欧美日韩免费| 在线免费一区三区| 亚洲精品视频在线播放| 亚洲婷婷在线| 欧美诱惑福利视频| 欧美福利视频在线| 亚洲精品免费一区二区三区| 亚洲一本大道在线| 久久xxxx| 欧美久久电影| 国产伦精品一区二区三区高清| 好看的av在线不卡观看| 在线看成人片| 亚洲午夜伦理| 久久综合婷婷| 99视频一区二区| 久久精品视频在线播放| 欧美精品18+| 国产精品日本一区二区| 在线欧美电影| 亚洲欧美另类国产| 欧美v国产在线一区二区三区| 99精品免费网| 久久亚洲一区二区| 欧美性理论片在线观看片免费| 精品成人乱色一区二区| 日韩午夜电影在线观看| 久久精品国产欧美亚洲人人爽| 亚洲黄色毛片| 久久久国产精品亚洲一区| 欧美日韩一本到| 亚洲高清视频在线观看| 欧美一级电影久久| 亚洲欧洲另类| 久热这里只精品99re8久| 国产精品一区二区三区成人| 亚洲乱码一区二区| 欧美成年人网站| 国产精品视频1区| 一区二区三区|亚洲午夜| 开元免费观看欧美电视剧网站| 亚洲网站在线看| 欧美精品手机在线| 亚洲国产日韩美| 久久久久久穴| 亚洲欧美日韩国产一区二区三区| 欧美日韩免费一区二区三区视频|