正文

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

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


 

2. 存儲(chǔ)對象狀態(tài)

除了對象的位置,在游戲引擎中還有兩個(gè)與其狀態(tài)相關(guān)的其他屬性。它們是IsNew和Terminate。

IsNew用于指示該對象自上次更新后是否已添加到游戲引擎中。我們可以通過該屬性來確認(rèn)對象在屏幕上的初始顯示是否正確。對于新對象,該屬性會(huì)自動(dòng)被設(shè)置為true,當(dāng)游戲引擎對它進(jìn)行了一次更新操作后,該屬性就自動(dòng)被設(shè)置為false。

Terminate屬性(我們曾經(jīng)提到過)用于請求將對象從仿真環(huán)境中刪除。要請求終止操作的話只需要將該屬性值設(shè)置為true,當(dāng)游戲發(fā)生下一次更新時(shí),對象就會(huì)從游戲中刪除。

3. 對象中的方法

最后,我們需要在引擎中添加兩個(gè)虛函數(shù),供對象完成操作任務(wù)。

首先是Render,對象通過該函數(shù)來將自身繪制到后臺(tái)緩沖區(qū)中。與CgameEngineBase類中的Render方法類似,該方法以一個(gè)Graphics對象作為參數(shù),在該階段實(shí)際并不做任何操作,它將在繼承類的對象中得以使用。

另一個(gè)函數(shù)是Update。您很快就能看到我們可以使許多對象自主(或部分自主),它們可以控制自己的移動(dòng)位置,在一定程度上與引擎控制系統(tǒng)保持獨(dú)立。因此,引擎將調(diào)用該函數(shù)使對象可以根據(jù)需要執(zhí)行各種力所能及的操作。再一次,在基類中該函數(shù)不包含代碼,但是繼承類要對它進(jìn)行重寫。

4.2.3  CGameObjectGDIBase類

下面對CGameObjectGDIBase類進(jìn)行概要的介紹:

● 目的  一個(gè)CGameObjectBase類的實(shí)現(xiàn),提供GDI圖形所需的功能。

● 類型  抽象基類。

● 父類  CgameObjectBase。

● 子類  各個(gè)游戲的游戲?qū)ο?,?chuàng)建在獨(dú)立的程序集中。

● 主要功能

● Width和Height  尺寸屬性。

● HasMoved和GetRenderRectangle  判斷移動(dòng)狀態(tài)以及對象所在的區(qū)域。

雖然我們對游戲?qū)ο箢惖挠懻撨€不多,但能看到GDI的脈絡(luò)。CGameObjectGDIBase類是另一個(gè)抽象類,其內(nèi)容不是很多,只是添加了一些使GDI渲染引擎能夠高效工作的屬性與方法。

1. 在GDI中設(shè)置對象的狀態(tài)

首先要添加的是用于跟蹤對象Width和Height的屬性。這是兩個(gè)很重要的屬性,根據(jù)它們提供的信息就可以得到每個(gè)對象在屏幕上占用的空間。在本章后文介紹渲染引擎優(yōu)化時(shí)將使用到它。

我們還要添加一個(gè)名為GetRenderRectangle的函數(shù)。對象根據(jù)自己的位置及尺寸在屏幕上進(jìn)行繪制,該函數(shù)將得到對象占用的矩形區(qū)域,并返回該矩形,在對象本身的Render方法中及游戲引擎優(yōu)化中都將使用該函數(shù),在本章后文中將會(huì)看到。在內(nèi)部,對象也記錄了其先前的位置,每當(dāng)發(fā)生移動(dòng)時(shí),該位置的值都會(huì)進(jìn)行更新。這也對后面的優(yōu)化有幫助。

2. 對象移動(dòng)

然后我們添加一個(gè)名為HasMoved的屬性。我們用它來標(biāo)識對象是否往某個(gè)方向移動(dòng)了。移動(dòng)不僅僅包括其位置的變化,還包括對象是否添加到了游戲引擎中,或者對象是否被終止。這些條件中的任何一個(gè)如果發(fā)生,都需要在窗體上重繪對象。

該屬性通過CheckIfMoved函數(shù)進(jìn)行更新。該函數(shù)檢查對象中的每一個(gè)相關(guān)的狀態(tài)屬性,如果任何一個(gè)狀態(tài)屬性發(fā)生變化,就認(rèn)為對象發(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;

}

另外,對任何一個(gè)位置屬性(Xpos、Ypos或ZPos)進(jìn)行修改,都將使HasMoved屬性被設(shè)置為true。


上一章目錄下一章

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