4.2.4 CGameEngineGDIBase類
下面對CGameEngineGDIBase類進行概要的介紹:
● 目的 一個CGameEngineBase類的實現(xiàn),提供GDI圖形所需的功能。
● 類型 抽象基類。
● 父類 CgameEngineBase。
● 子類 各個游戲,創(chuàng)建在獨立的程序集中。
● 主要功能
● Prepare 為執(zhí)行GDI渲染做好準(zhǔn)備。
● Render 提供有效的圖形渲染技術(shù)。
● Present 將生成好的圖形顯示到屏幕上。
抽象引擎對象與抽象游戲?qū)ο蠖家呀?jīng)就位了,現(xiàn)在要為GDI繪制引擎添加功能。CGameEngineGDIBase類仍然被聲明為abstract,但實際的游戲類將從它繼承而來。
該類附加函數(shù)中最有意義的是Render方法。我們來看看該方法以及這里實現(xiàn)方式上的區(qū)別。
1. 渲染
每個對象需要對后臺緩沖區(qū)進行更新時,都會使用Render函數(shù)。我們要進行許多需要的操作:
● 如果后臺緩沖區(qū)尚未執(zhí)行初始化,則進行初始化。
● 清空背景。
● 向后臺緩沖區(qū)中繪制所有對象。
● 使游戲窗體失效,觸發(fā)一個Paint事件,這樣我們就可以將修改了的后臺緩沖區(qū)復(fù)制到窗體中。
我們首先來討論后臺緩沖區(qū),正如上一章中所述,這是一個不顯示在屏幕上的Bitmap對象,我們將在其中繪制所有的圖形對象。它通常維護的是當(dāng)前要顯示的游戲內(nèi)容的圖形。在Render函數(shù)的開始階段,如果對象尚未可用,就會調(diào)用InitBackBuffer來對緩沖區(qū)進行準(zhǔn)備。在本例中,圖形后臺緩沖區(qū)的大小與游戲窗體的大小一致,如程序清單4-7所示。
程序清單4-7 對后臺緩沖區(qū)進行初始化
/// <summary>
/// If not already ready, creates and initialises the back buffer that we
/// use for off-screen rendering.
/// </summary>
private void InitBackBuffer()
{
// Make a new back buffer if needed.
if (_backBuffer == null)
{
_backBuffer = new Bitmap(GameForm.ClientSize.Width, GameForm.ClientSize.Height);
// Ensure we repaint the whole form
ForceRepaint();
}
}
下一步,清空背景。這里有兩種可能的方法:將背景改為純色,或者在移動的圖形背后顯示一個背景圖像。
如果沒有圖像,那么調(diào)用CreateBackgroundImage函數(shù),該函數(shù)為虛函數(shù),繼承游戲類可以對它進行重寫。如果需要背景圖片,可以返回一個包含了背景圖片的Bitmap對象。然后在繪制圖形之前調(diào)用該函數(shù)來清空后臺緩沖區(qū)。
另一方面,如果調(diào)用了該函數(shù)之后還是沒有背景圖像,那么游戲會用一個純色來清除后臺緩沖區(qū)。通過對象的BackgroundColor屬性來指定該顏色。
第三步是將所有的對象都繪制到后臺緩沖區(qū)中。這里先跳過這一步驟的細節(jié),因為我們馬上要在第4.4節(jié)中對它進行深入的介紹。可以這樣說:所有需要重繪的對象都會在后臺緩沖區(qū)中繪制好。
最后,我們調(diào)用窗體的Invalidate方法來觸發(fā)重繪事件。就是靠這種機制,將修改后的后臺緩沖區(qū)中的內(nèi)容繪制到屏幕上,這樣才能被人們看到。當(dāng)該事件被觸發(fā)時,通過傳遞窗體的Graphics實例,在CGameEngineGDIBase.Present方法中會對窗體進行調(diào)用。我們很快就會看到窗體是如何與引擎相聯(lián)系的。