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

天行健 君子當自強而不息

游戲中時間的封裝

時鐘類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>
            欧美日韩在线播| 亚洲欧美国产毛片在线| 老司机午夜精品视频| 亚洲国产成人porn| 亚洲电影毛片| 欧美区一区二| 亚洲影院在线观看| 久久精品国产亚洲5555| 亚洲人www| 99精品久久久| 亚洲激情午夜| 欧美精品在线看| 欧美在线免费视频| 美女久久网站| 午夜精品一区二区三区四区 | 日韩午夜电影在线观看| 国产精品久久国产精麻豆99网站| 欧美在线影院| 麻豆精品一区二区综合av| 亚洲午夜精品视频| 久久精品国产成人| 亚洲一区二区三| 久久久91精品国产一区二区三区| 一区二区三区日韩精品| 欧美一区二区三区日韩| 亚洲伦伦在线| 欧美在线亚洲综合一区| 在线视频一区二区| 久久这里只有| 欧美亚洲三级| 欧美日韩精选| 亚洲美洲欧洲综合国产一区| 亚洲自啪免费| 一区二区三区日韩精品| 久久亚裔精品欧美| 欧美一二三区精品| 欧美人与禽性xxxxx杂性| 久久网站免费| 欧美午夜精品久久久久久浪潮| 葵司免费一区二区三区四区五区| 国产精品成人一区二区网站软件 | 久久狠狠一本精品综合网| 一本一本大道香蕉久在线精品| 久久精品国产欧美激情| 午夜亚洲福利| 欧美色视频在线| 这里只有精品视频在线| 老妇喷水一区二区三区| 欧美在线精品免播放器视频| 欧美日韩另类综合| 亚洲欧洲日本国产| 91久久亚洲| 美国成人直播| 麻豆av一区二区三区久久| 国产三级欧美三级| 亚洲自拍三区| 先锋影音久久| 国产精品伊人日日| 亚洲宅男天堂在线观看无病毒| 一区二区免费看| 欧美日韩不卡视频| 日韩天堂在线观看| 中日韩午夜理伦电影免费| 欧美日本精品| 在线亚洲国产精品网站| 亚洲欧美另类中文字幕| 国产精品日韩在线一区| 亚洲欧美一区二区三区久久| 久久福利电影| 国产在线视频不卡二| 久久噜噜噜精品国产亚洲综合| 老**午夜毛片一区二区三区| 亚洲第一中文字幕| 欧美福利一区| 亚洲美女色禁图| 亚洲欧美激情诱惑| 国产亚洲人成网站在线观看| 亚洲国内在线| 亚洲无线视频| 国产日本欧美在线观看| 久久久亚洲欧洲日产国码αv| 欧美电影美腿模特1979在线看 | 欧美视频一区在线| 亚洲女优在线| 欧美va亚洲va国产综合| av成人免费观看| 国产精品男人爽免费视频1 | 一区二区三区精品在线| 久久爱www久久做| 亚洲国产精品va在线看黑人动漫| 蜜桃av噜噜一区| 在线视频你懂得一区二区三区| 久久精品麻豆| 亚洲精品在线免费| 国产精品亚洲一区二区三区在线| 久久久777| 一区二区日韩欧美| 久久综合网hezyo| 一本大道久久a久久综合婷婷| 国产九九视频一区二区三区| 麻豆国产精品一区二区三区| 亚洲香蕉网站| 亚洲国产精品悠悠久久琪琪| 欧美在线免费观看| aa亚洲婷婷| 精品粉嫩aⅴ一区二区三区四区| 欧美日产国产成人免费图片| 久久精品视频一| 中国女人久久久| 欧美黄在线观看| 欧美一区二区三区在线观看视频| 亚洲美女视频在线观看| 黄色精品一区| 国产精品青草综合久久久久99| 欧美成年人网站| 欧美在线视频免费观看| 99re热这里只有精品免费视频| 欧美ab在线视频| 久久精品水蜜桃av综合天堂| 亚洲午夜黄色| 亚洲毛片在线| 亚洲黄色大片| 亚洲电影第1页| 国际精品欧美精品| 国产欧美日韩高清| 国产精品豆花视频| 欧美日韩午夜剧场| 欧美精品久久久久久| 欧美99久久| 日韩一级大片| 亚洲欧洲精品一区二区三区不卡| 欧美 日韩 国产一区二区在线视频| 香蕉免费一区二区三区在线观看| 亚洲午夜久久久久久尤物| 亚洲精品一区二区三区在线观看 | 在线亚洲自拍| 日韩一级片网址| 亚洲精品欧美极品| 亚洲精品一区二区三| 99这里只有久久精品视频| 亚洲精品久久久久久久久久久久久 | 欧美日韩大陆在线| 欧美日韩国产麻豆| 欧美日韩国产免费| 国产精品扒开腿做爽爽爽视频| 国产精品video| 国产精品国产福利国产秒拍| 国产精品久久久久久久第一福利 | 欧美久久久久久久久久| 欧美日韩亚洲不卡| 国产精品久久久久毛片大屁完整版| 欧美午夜不卡视频| 国产精品青草综合久久久久99| 国产精品美女久久久久aⅴ国产馆| 国产精品一区二区三区观看| 国产婷婷成人久久av免费高清 | 国产日韩精品在线| 国内久久婷婷综合| 亚洲欧洲一区二区三区久久| 一本久久青青| 欧美一级视频精品观看| 久久综合九九| 亚洲剧情一区二区| 亚洲欧美日韩在线观看a三区| 久久黄色网页| 欧美精品国产| 国产精品日产欧美久久久久| 激情六月婷婷综合| 在线性视频日韩欧美| 久久久久久久久久久一区 | 亚洲欧美区自拍先锋| 久久久综合免费视频| 欧美日韩国产一级| 国内精品一区二区| 一区二区精品在线| 久久天天狠狠| 亚洲激情一区| 欧美一区久久| 欧美精品一区二区三区视频| 国产日韩精品在线观看| 亚洲日本视频| 久久精品国产一区二区电影| 亚洲激情综合| 欧美一级大片在线免费观看| 欧美精品在线一区二区| 好吊视频一区二区三区四区| 亚洲视频成人| 亚洲国产欧美日韩| 欧美影院成人| 国产精品久久久久9999吃药| 最新日韩在线| 久久综合给合| 亚洲欧美日韩爽爽影院| 欧美日韩精品系列| 亚洲国产精品一区二区尤物区| 午夜精品区一区二区三| 最新国产精品拍自在线播放| 久久夜色精品| 狠狠色狠狠色综合系列| 欧美综合国产|