正文

開發(fā)游戲引擎(12)

Windows移動(dòng)游戲開發(fā)實(shí)戰(zhàn) 作者:(美)Adam Dawes


 

3. 運(yùn)行游戲

以上就是游戲進(jìn)行演示所需要的所有代碼。唯一沒有介紹的就是游戲窗體了。這可以通過該類的構(gòu)造函數(shù)、OnPaintBackground方法、Paint事件(在本節(jié)的開始介紹過)來實(shí)現(xiàn)。此外,還要在窗體上添加一個(gè)標(biāo)簽,用來顯示當(dāng)前游戲的幀率。這需要使用一個(gè)Timer控件,并將其設(shè)置為每隔1秒更新一次。

接下來,我們要?jiǎng)?chuàng)建一個(gè)循環(huán)來驅(qū)動(dòng)游戲?qū)嶋H運(yùn)行。一個(gè)簡單的方法就是在窗體上再放一個(gè)Timer控件,為了使時(shí)間間隔盡可能地小,先將其設(shè)置為1。這樣可以運(yùn)行,但可能不是最佳的效果,因?yàn)樵谇耙粋€(gè)間隔結(jié)束和下一個(gè)間隔開始之間總會(huì)有個(gè)小的延時(shí)。

不過我們不采用這種方法,而是創(chuàng)建一個(gè)永久的循環(huán),利用每個(gè)循環(huán)周期來推進(jìn)游戲的運(yùn)行,直到游戲窗體關(guān)閉該循環(huán)才停止,這才能使應(yīng)用程序關(guān)閉。該循環(huán)在RenderLoop函數(shù)中創(chuàng)建,如程序清單4-14所示。

程序清單4-14  通過RenderLoop函數(shù)驅(qū)動(dòng)游戲運(yùn)行

/// <summary>

/// Drive the game

/// </summary>

private void RenderLoop()

{

do

{

// If we lose focus, stop rendering

if (!this.Focused)

{

System.Threading.Thread.Sleep(100);

}

else

{

// Advance the game

_game.Advance();

}

// Process pending events

Application.DoEvents();

// If our window has been closed then return without doing anything 

// more

if (_formClosed) return;

// Loop forever (or at least, until our game form is closed).

} while (true);

}

函數(shù)RenderLoop首先檢查窗體是否實(shí)際獲得了焦點(diǎn)。如果窗體被最小化了,就說明用戶不在游戲中,因此不用將很多CPU時(shí)間花費(fèi)到更新游戲上。如果我們探測到游戲失去了焦點(diǎn),就將線程掛起1/10秒,不做其他處理。在此期間因?yàn)闆]有調(diào)用游戲的Advance函數(shù),所以當(dāng)游戲失去焦點(diǎn)時(shí)可以有效地將它暫停。

假設(shè)游戲擁有焦點(diǎn),那么會(huì)調(diào)用游戲引擎的Advance函數(shù),游戲就會(huì)得到更新。更新時(shí)會(huì)觸發(fā)窗體的Paint事件,因?yàn)橐{(diào)用游戲引擎中所包含的窗體的Invalidate方法。

接下來調(diào)用Application.DoEvents函數(shù),這個(gè)調(diào)用很重要,如果少了它,游戲窗體中所有的事件都將排隊(duì)等待RenderLoop函數(shù)結(jié)束后才開始執(zhí)行。這也就意味著我們將無法處理任何輸入事件或者其他可能發(fā)生的窗體事件,例如窗口大小調(diào)整、最小化、或者關(guān)閉等。

最后檢查窗體是否已經(jīng)關(guān)閉了。在.NET CF 3.5中,可以通過查看窗體的IsDisposed屬性很容易地得到結(jié)果,但是,在.NET CF 2.0中沒有提供該屬性。為了使代碼能夠兼容兩個(gè)版本的框架,我們采用了一種稍微不同的方式,_formClosed變量是一個(gè)類級(jí)別的變量,在窗體的Closed事件中將它設(shè)置為true。這可以觸發(fā)線程退出循環(huán)。

為了啟動(dòng)循環(huán)繪制,我們從窗體的Load事件中調(diào)用它。在調(diào)用之前要確保窗體是可見的,并且要調(diào)用窗體的Show方法及Invalidate方法將它完全重繪。這部分代碼以及對(duì)幀率計(jì)時(shí)器進(jìn)行初始化所用的代碼,如程序清單4-15所示。


上一章目錄下一章

Copyright ? 讀書網(wǎng) ranfinancial.com 2005-2020, All Rights Reserved.
鄂ICP備15019699號(hào) 鄂公網(wǎng)安備 42010302001612號(hào)