2. 存儲(chǔ)對(duì)象狀態(tài)
除了對(duì)象的位置,在游戲引擎中還有兩個(gè)與其狀態(tài)相關(guān)的其他屬性。它們是IsNew和Terminate。
IsNew用于指示該對(duì)象自上次更新后是否已添加到游戲引擎中。我們可以通過(guò)該屬性來(lái)確認(rèn)對(duì)象在屏幕上的初始顯示是否正確。對(duì)于新對(duì)象,該屬性會(huì)自動(dòng)被設(shè)置為true,當(dāng)游戲引擎對(duì)它進(jìn)行了一次更新操作后,該屬性就自動(dòng)被設(shè)置為false。
Terminate屬性(我們?cè)?jīng)提到過(guò))用于請(qǐng)求將對(duì)象從仿真環(huán)境中刪除。要請(qǐng)求終止操作的話(huà)只需要將該屬性值設(shè)置為true,當(dāng)游戲發(fā)生下一次更新時(shí),對(duì)象就會(huì)從游戲中刪除。
3. 對(duì)象中的方法
最后,我們需要在引擎中添加兩個(gè)虛函數(shù),供對(duì)象完成操作任務(wù)。
首先是Render,對(duì)象通過(guò)該函數(shù)來(lái)將自身繪制到后臺(tái)緩沖區(qū)中。與CgameEngineBase類(lèi)中的Render方法類(lèi)似,該方法以一個(gè)Graphics對(duì)象作為參數(shù),在該階段實(shí)際并不做任何操作,它將在繼承類(lèi)的對(duì)象中得以使用。
另一個(gè)函數(shù)是Update。您很快就能看到我們可以使許多對(duì)象自主(或部分自主),它們可以控制自己的移動(dòng)位置,在一定程度上與引擎控制系統(tǒng)保持獨(dú)立。因此,引擎將調(diào)用該函數(shù)使對(duì)象可以根據(jù)需要執(zhí)行各種力所能及的操作。再一次,在基類(lèi)中該函數(shù)不包含代碼,但是繼承類(lèi)要對(duì)它進(jìn)行重寫(xiě)。
4.2.3 CGameObjectGDIBase類(lèi)
下面對(duì)CGameObjectGDIBase類(lèi)進(jìn)行概要的介紹:
● 目的 一個(gè)CGameObjectBase類(lèi)的實(shí)現(xiàn),提供GDI圖形所需的功能。
● 類(lèi)型 抽象基類(lèi)。
● 父類(lèi) CgameObjectBase。
● 子類(lèi) 各個(gè)游戲的游戲?qū)ο螅瑒?chuàng)建在獨(dú)立的程序集中。
● 主要功能
● Width和Height 尺寸屬性。
● HasMoved和GetRenderRectangle 判斷移動(dòng)狀態(tài)以及對(duì)象所在的區(qū)域。
雖然我們對(duì)游戲?qū)ο箢?lèi)的討論還不多,但能看到GDI的脈絡(luò)。CGameObjectGDIBase類(lèi)是另一個(gè)抽象類(lèi),其內(nèi)容不是很多,只是添加了一些使GDI渲染引擎能夠高效工作的屬性與方法。
1. 在GDI中設(shè)置對(duì)象的狀態(tài)
首先要添加的是用于跟蹤對(duì)象Width和Height的屬性。這是兩個(gè)很重要的屬性,根據(jù)它們提供的信息就可以得到每個(gè)對(duì)象在屏幕上占用的空間。在本章后文介紹渲染引擎優(yōu)化時(shí)將使用到它。
我們還要添加一個(gè)名為GetRenderRectangle的函數(shù)。對(duì)象根據(jù)自己的位置及尺寸在屏幕上進(jìn)行繪制,該函數(shù)將得到對(duì)象占用的矩形區(qū)域,并返回該矩形,在對(duì)象本身的Render方法中及游戲引擎優(yōu)化中都將使用該函數(shù),在本章后文中將會(huì)看到。在內(nèi)部,對(duì)象也記錄了其先前的位置,每當(dāng)發(fā)生移動(dòng)時(shí),該位置的值都會(huì)進(jìn)行更新。這也對(duì)后面的優(yōu)化有幫助。
2. 對(duì)象移動(dòng)
然后我們添加一個(gè)名為HasMoved的屬性。我們用它來(lái)標(biāo)識(shí)對(duì)象是否往某個(gè)方向移動(dòng)了。移動(dòng)不僅僅包括其位置的變化,還包括對(duì)象是否添加到了游戲引擎中,或者對(duì)象是否被終止。這些條件中的任何一個(gè)如果發(fā)生,都需要在窗體上重繪對(duì)象。
該屬性通過(guò)CheckIfMoved函數(shù)進(jìn)行更新。該函數(shù)檢查對(duì)象中的每一個(gè)相關(guān)的狀態(tài)屬性,如果任何一個(gè)狀態(tài)屬性發(fā)生變化,就認(rèn)為對(duì)象發(fā)生了移動(dòng),而將HasMoved屬性設(shè)置為true,該函數(shù)如程序清單4-6所示。
程序清單4-6 CheckIfMoved 函數(shù)
/// <summary>
/// Determine whether any of our object state has changed in a way that would
/// require the object to be redrawn. If so, set the HasMoved flag to true.
/// </summary>
internal virtual void CheckIfMoved()
{
if (XPos != LastXPos) HasMoved = true;
if (YPos != LastYPos) HasMoved = true;
if (ZPos != LastZPos) HasMoved = true;
if (IsNew) HasMoved = true;
if (Terminate) HasMoved = true;
}
另外,對(duì)任何一個(gè)位置屬性(Xpos、Ypos或ZPos)進(jìn)行修改,都將使HasMoved屬性被設(shè)置為true。