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

天行健 君子當自強而不息

游戲中時間的封裝

時鐘類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>
            国产亚洲精久久久久久| 欧美亚洲一区二区在线| 亚洲综合首页| 亚洲美女毛片| 久久久久久久网| 午夜久久久久久久久久一区二区| 老司机免费视频久久| 香蕉久久一区二区不卡无毒影院| 欧美激情91| 欧美高清免费| 韩日精品视频一区| 亚洲欧美日韩精品一区二区| 这里只有精品电影| 欧美国产日韩视频| 欧美大片国产精品| 亚洲第一黄网| 久久国产婷婷国产香蕉| 香蕉免费一区二区三区在线观看| 欧美日韩国产首页| 亚洲日韩第九十九页| 亚洲高清一二三区| 久久亚洲精品一区| 欧美va天堂| 亚洲高清在线观看一区| 久久免费视频一区| 久久亚洲私人国产精品va媚药| 国产精品亚洲综合久久| 亚洲一区二区三区精品动漫| 亚洲网站在线播放| 欧美色123| 亚洲视频播放| 欧美一区激情| 国产一区二区三区最好精华液| 性久久久久久久| 久久久噜噜噜| 在线观看91精品国产麻豆| 久久五月婷婷丁香社区| 欧美xx视频| 亚洲精品一二区| 欧美日韩三区| 亚洲图色在线| 久久综合伊人77777麻豆| 1204国产成人精品视频| 免费人成网站在线观看欧美高清| 亚洲国产精品日韩| 一区二区三区欧美日韩| 国产精品社区| 久久国产精品久久国产精品 | 亚洲日韩成人| 欧美美女bb生活片| 亚洲小视频在线| 久久视频这里只有精品| 亚洲日本免费| 国产精品日韩欧美一区| 久久精品人人爽| 亚洲精品久久久久久一区二区| 亚洲欧美在线免费观看| 国产在线视频不卡二| 欧美成人tv| 亚洲欧美韩国| 欧美国产日韩精品| 亚洲欧美日韩系列| 精品白丝av| 欧美揉bbbbb揉bbbbb| 欧美一区亚洲二区| 91久久亚洲| 久久久久国产精品麻豆ai换脸| 亚洲精品精选| 国产手机视频精品| 欧美激情一区| 久久av一区二区三区| 亚洲精品中文在线| 美脚丝袜一区二区三区在线观看| 99riav国产精品| 激情综合在线| 国产精品久久久久久久久果冻传媒| 久久久国产精品一区二区中文 | 欧美成人午夜影院| 欧美一级艳片视频免费观看| 亚洲国产精品www| 久久久999成人| 亚洲专区在线视频| 最近看过的日韩成人| 国产午夜精品视频免费不卡69堂| 欧美区视频在线观看| 久久露脸国产精品| 午夜精品久久久久久久男人的天堂| 亚洲精品久久久蜜桃 | 免费不卡在线观看| 欧美亚洲免费高清在线观看| 亚洲美洲欧洲综合国产一区| 亚洲高清三级视频| 国产一区三区三区| 国产目拍亚洲精品99久久精品| 欧美精品久久久久久久久老牛影院| 久久久久久久综合日本| 亚洲欧美综合精品久久成人| 中文有码久久| 亚洲每日更新| 亚洲精品日产精品乱码不卡| 欧美大片18| 欧美国产日本高清在线| 麻豆国产精品777777在线| 久久夜色精品亚洲噜噜国产mv| 午夜精品免费视频| 午夜精彩国产免费不卡不顿大片| 一本一道久久综合狠狠老精东影业| 亚洲国产一区二区三区a毛片| 韩国女主播一区二区三区| 国产日韩亚洲| 国产亚洲精品久久久久动| 国产欧美成人| 国产日韩精品一区观看| 国产视频亚洲精品| 国产一区二区三区的电影 | 亚洲美女在线观看| 日韩亚洲欧美精品| 一区二区久久久久| 亚洲欧美经典视频| 午夜伦理片一区| 久久九九免费| 免费视频一区| 亚洲国产精品一区二区第一页 | 欧美成人高清视频| 欧美精品导航| 国产精品久久久久久久免费软件| 国产精品久久久久久久久久ktv| 国产精品久久久久久一区二区三区 | 国产综合色一区二区三区| 狠狠色伊人亚洲综合成人| 亚洲福利视频免费观看| 亚洲精品一级| 午夜欧美不卡精品aaaaa| 久久久综合网| 欧美激情一区在线观看| 99pao成人国产永久免费视频| 亚洲一区二区综合| 久久精品国产清高在天天线| 蜜桃视频一区| 国产精品乱看| 黑人巨大精品欧美一区二区| 亚洲激情不卡| 午夜精品久久久久久久99水蜜桃 | 亚洲另类在线视频| 亚洲专区国产精品| 久久人体大胆视频| 亚洲精品在线免费| 欧美一区二区三区男人的天堂| 麻豆成人小视频| 欧美视频福利| 亚洲电影自拍| 欧美一级黄色录像| 亚洲第一在线综合网站| 亚洲一区二区三区777| 老色鬼精品视频在线观看播放| 欧美视频在线观看视频极品| 极品尤物av久久免费看| 中文在线一区| 美女尤物久久精品| 亚洲午夜精品| 欧美大片免费久久精品三p| 国产欧美一级| 亚洲视频在线二区| 欧美成人免费全部观看天天性色| 亚洲午夜91| 欧美另类综合| 1024亚洲| 久久看片网站| 午夜精品久久久久久久男人的天堂| 欧美国产第二页| 亚洲国产精品成人综合| 欧美中文字幕视频| 中文在线资源观看网站视频免费不卡| 久久精品欧洲| 国产欧美日韩在线视频| 亚洲一区二区免费视频| 亚洲国产视频a| 久久久综合激的五月天| 国产日本亚洲高清| 亚洲欧美日韩中文播放| 亚洲精品中文字幕在线| 欧美激情一级片一区二区| 一区视频在线| 久久久久久久综合| 欧美一区二区三区视频在线观看 | 欧美日韩国产综合新一区| 亚洲国产电影| 欧美成黄导航| 美乳少妇欧美精品| 亚洲电影激情视频网站| 麻豆av一区二区三区久久| 欧美一区二区在线播放| 国产日韩精品一区观看| 久久国产一区二区三区| 亚洲欧美不卡| 国产日本欧美一区二区三区在线 | 日韩亚洲视频| 欧美午夜精品久久久久久孕妇| 亚洲一级黄色| 亚洲一区欧美二区|