偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

iPhone 游戲開發(fā)教程 游戲引擎 (6)

移動(dòng)開發(fā) iOS 游戲開發(fā)
本文講解的是iPhone 游戲開發(fā)教程 游戲引擎,手機(jī)游戲開發(fā)已經(jīng)成為了一種主流趨勢(shì),先來看內(nèi)容詳解。

iPhone 游戲開發(fā)教程 游戲引擎 (6)是本我要介紹的內(nèi)容,繼續(xù)上一章開始介紹,本節(jié)主要介紹了事件的相關(guān)內(nèi)容,先來看本文詳解。

解決高層次事件

一旦判定了用戶執(zhí)行的物理動(dòng)作,你的代碼必須能將它們轉(zhuǎn)換為游戲邏輯組件可以使用的形式。具體怎么做需要依賴于你的游戲的上下文,但是這里有幾種典型的形式:

如果玩家準(zhǔn)備控制虛擬人偶,在玩家和游戲之間通常會(huì)有連續(xù)的交互。經(jīng)常需要存儲(chǔ)當(dāng)前用戶輸入的表現(xiàn)形式。比如,如果輸入裝置為遙桿,你可能需要在主循環(huán)中記錄當(dāng)前點(diǎn)的x軸坐標(biāo)和y軸坐標(biāo),并修正虛擬人偶的動(dòng)量。玩家和虛擬人偶之間的是緊密地耦合在一起的,所以控制器的物理狀態(tài)代表著虛擬人偶的高層次的狀態(tài)模型。當(dāng)遙桿向前撥動(dòng)時(shí),虛擬人偶向前移動(dòng);當(dāng)“跳躍”按鈕按下時(shí),虛擬人偶跳起。

如果玩家正與游戲地圖進(jìn)行交互,那么需要另外一種間接的方式。比如,玩家必須觸摸游戲地圖中的一個(gè)物體,代碼必須將玩家在屏幕上的觸摸坐標(biāo)轉(zhuǎn)化為游戲地圖的坐標(biāo)以判定用戶到底觸摸到了什么。這可能只是簡(jiǎn)單的將y軸坐標(biāo)減去2D攝像機(jī)坐標(biāo)的偏移量,也可能是復(fù)雜到3D場(chǎng)景中的攝像機(jī)光線碰撞偵測(cè)。

最后,用戶可能進(jìn)行一些間接影響到游戲的動(dòng)作,如暫停游戲、與GUI交互等。這時(shí),一個(gè)簡(jiǎn)單的消息或者函數(shù)會(huì)被觸發(fā),去通知游戲邏輯應(yīng)該做什么。

游戲邏輯

游戲邏輯是游戲引擎中是你的游戲獨(dú)一無二的部分。游戲邏輯記錄著玩家狀態(tài)、AI狀態(tài)、判定什么時(shí)候達(dá)到目的地、并生成所有的游戲規(guī)則。給出兩個(gè)相似的游戲,他們的圖像引擎與物理引擎可能只有細(xì)微差別,但是它們的游戲邏輯可能會(huì)有很大差異。

游戲邏輯與物理引擎緊密配合,在一些沒有物理引擎的小游戲中,游戲邏輯負(fù)責(zé)處理所有物理相關(guān)內(nèi)容。但是,當(dāng)游戲引擎中有游戲引擎的時(shí)候,需要確保兩者的獨(dú)立。達(dá)到此目的的最好方式就是通過物理引擎向游戲邏輯發(fā)送高層次的游戲事件。

高層次事件

游戲邏輯代碼應(yīng)該盡可能僅處理高層次問題。它不應(yīng)該處理當(dāng)用戶觸摸屏幕時(shí)需要以什么順序?qū)⑹裁疵璁嫷狡聊簧?,或者兩個(gè)矩形是否相交等問題。它應(yīng)該處理玩家希望向前移動(dòng),什么時(shí)候一個(gè)新的游戲物體應(yīng)當(dāng)被創(chuàng)建/移除以及當(dāng)兩個(gè)物體相互碰撞后應(yīng)該做什么。

為了維持概念上的距離,處理低層次概念(諸如用戶輸入與物理引擎等)的代碼應(yīng)當(dāng)創(chuàng)建高層次的消息并發(fā)送給游戲邏輯代碼去處理。這不僅能保持代碼的獨(dú)立性與模塊化,還會(huì)對(duì)調(diào)試有所幫助。通過查看高層次消息傳遞的日志,你可以判定是沒有正確處理消息(游戲邏輯代碼的問題),還是沒有在正確的時(shí)機(jī)傳送消息(低層次代碼問題)。

 一個(gè)非常基本的傳遞高層次消息的技術(shù)是寫一個(gè)String并傳遞它。假如玩家按下了上箭頭鍵,它的虛擬人偶必須向上移動(dòng)。

  1. void onPlayerInput( Input inputEvt ) {     
  2.     if(inputEvt.type == IE_KEY && inputEvt.value == KEY_UP ) {     
  3.         g_myApp->sendGameLogicMessage( "player move forward" );     
  4.     }     
  5. }    

雖然上面的代碼對(duì)程序員來說通俗易懂,但對(duì)于電腦來說卻并不高效。它需要更多的內(nèi)存與處理,遠(yuǎn)比實(shí)際需要的多。我們應(yīng)該用提示來替代用戶輸入方法。比起一個(gè)字符串,它使用一個(gè)"type"和"value"。由于可能的事件都是結(jié)構(gòu)化的和有限的,因此我們可以使用整數(shù)和枚舉類型來我們消息中的事件信息。

首先,我們定義一個(gè)枚舉類型來標(biāo)識(shí)事件類型:

  1. enumeration eGameLogicMessage_Types {     
  2.     GLMT_PLAYER_INPUT,     
  3.     GLMT_PROJECTILE_WEAPON,     
  4.     GLMT_GOAL_REACHED,     
  5. };  

 

接著我們?cè)賱?chuàng)建一個(gè)枚舉類型來標(biāo)識(shí)事件的值:

  1. enumeration eGameLogicMesage_Values {     
  2.     GLMV_PLAYER_FORWARD,     
  3.     GLMV_PLAYER_BACKWARD,     
  4.     GLMV_PLAYER_LEFT,     
  5.     GLMV_PLAYER_RIGHT,     
  6.     GLMV_ROCKET_FIRED,     
  7.     GLMV_ROCKET_HIT,     
  8. };    

現(xiàn)在我們定義一個(gè)結(jié)構(gòu)體來存儲(chǔ)我們的消息數(shù)據(jù):

  1. view plaincopy to clipboardprint?struct sGameLogicMessage {     
  2.     short type;     
  3.     short value;     
  4. } Message;    

現(xiàn)在,我們就可以像上一個(gè)例子代碼一樣,用一個(gè)對(duì)象來傳遞我們的消息:

  1. void onPlayerInput( Input inputEvt ) {     
  2.    if(inputEvt.type == IE_KEY && inputEvt.value == KEY_UP ) {     
  3.        Message msg;     
  4.        msg.type = GLMT_PLAYER_INPUT;     
  5.        msg.value = GLMV_PLAYER_FORWARD;     
  6.        g_myApp->sendGameLogicMessage( msg );     
  7.    }     
  8.     

這看起來作了更多的工作,但它運(yùn)行起來會(huì)更有效率。前一個(gè)(壞的)例子用了20個(gè)字節(jié)來傳遞消息(20個(gè)字符各占一個(gè)字節(jié),別忘了終止符)。第二個(gè)例子只用了4個(gè)字節(jié)來傳遞同樣的消息。但是更要的是,當(dāng)sendGameLogicMessage()處理方法的時(shí)候,它只需要分析兩個(gè)switch語句就可以找到正確的響應(yīng),而前一個(gè)例子則組要從字符串進(jìn)行解析,速度很慢。

人工智能

游戲邏輯的另外一個(gè)職責(zé)就是管理AI代理。兩類典型的游戲需要用到AI系統(tǒng):一種是玩家與電腦競(jìng)賽;另外一種是在游戲世界中有半自主系統(tǒng)的敵人。在這兩種情況下,AI代理為游戲世界中的物體的動(dòng)作接受輸入并提供輸出。

在第一種類型游戲里,AI被稱作專家系統(tǒng)。它被期待用來模擬理解游戲規(guī)則的人的行為動(dòng)作,并可以采取具有不同難度的策略來挑戰(zhàn)玩家。AI具有與玩家類似的輸入與輸出,可以近似的模擬玩家的行為。由于人類比現(xiàn)在的AI代理更擅長(zhǎng)處理復(fù)雜信息,有時(shí)為專家系統(tǒng)提供的輸入信息要多于給玩家的,以使AI系統(tǒng)看起來更智能。

例如,在即時(shí)戰(zhàn)略游戲(RTS)中,戰(zhàn)爭(zhēng)迷霧用來限制玩家的視野,但AI敵人可以看見地圖上所有的單位。盡管這樣提高AI對(duì)抗更高智慧玩家的能力,但是如果優(yōu)勢(shì)變的太大,會(huì)讓人覺得AI在作弊。記住,游戲的重要點(diǎn)是讓玩家獲得樂趣,而不是讓AI擊敗他們。

在第二種類型的游戲中,可能有許多AI代理。每一個(gè)都獨(dú)立,其不是非常智能。在某些情況下,AI代理會(huì)直接面對(duì)玩家,而有些可能是中立狀態(tài),甚至還有一些是前面兩種狀態(tài)的結(jié)合。

有些代理可能是完全愚笨的,提供特定的、有限的行為而且并不關(guān)心游戲世界中發(fā)生的事情。在走廊里面來來回回走動(dòng)的敵人就是一個(gè)例子。有些可能是稍微有些愚笨,只有一個(gè)輸入和一個(gè)輸出,比如玩家可以打開和關(guān)閉的門。還有一些可能非常復(fù)雜,甚至懂得將它們的行為組合在一起。為AI代理選擇恰當(dāng)?shù)妮斎朐试S你模仿“意識(shí)”和增加現(xiàn)實(shí)性。

不論AI代理有多么簡(jiǎn)單,一般都會(huì)它們使用狀態(tài)機(jī)。例如,第一個(gè)例子中的完全愚笨的物體必須記錄它在朝哪個(gè)方向走動(dòng);稍微愚笨的物體需要記錄它是開的狀態(tài)還是關(guān)的狀態(tài)。更復(fù)雜的物體需要記錄“中立”與“進(jìn)攻性之間的”動(dòng)作狀態(tài),如巡邏、對(duì)抗與攻擊。

透明的暫停與繼續(xù)

將游戲視作具有主要游戲狀態(tài)的模擬是非常重要的。不要將現(xiàn)實(shí)世界時(shí)間與游戲時(shí)間混淆。如果玩家決定休息會(huì)兒,游戲必須可以暫停。之后,游戲必須可以平滑的繼續(xù),就像任何事情都沒有發(fā)生一樣。由于IPHONE是移動(dòng)設(shè)備,保存與繼續(xù)游戲狀態(tài)變得尤其重要。

IPHONE上,在一個(gè)時(shí)間點(diǎn)只允許一個(gè)應(yīng)用程序運(yùn)行,用戶也希望這些應(yīng)用程序能夠很快載入。同時(shí),他們希望能夠繼續(xù)他們?cè)谇袚Q應(yīng)用程序之前所做的事情。這意味著我們需要具有在設(shè)備上保存游戲狀態(tài),并盡可能快的繼續(xù)游戲狀態(tài)的能力。對(duì)于開發(fā)游戲,一項(xiàng)任務(wù)是要求保持現(xiàn)在的關(guān)卡并可以重新載入它使玩家即使在重新啟動(dòng)應(yīng)用程序后也可以繼續(xù)游戲。你需要選擇保存哪些數(shù)據(jù),并以一種小巧的、穩(wěn)定的格式將其寫到磁盤上。這種結(jié)構(gòu)化的數(shù)據(jù)存儲(chǔ)被稱為序列化。

根據(jù)游戲類型的不同,這可能比聽起來要困難的多。對(duì)于一個(gè)解謎游戲,你將僅需要記錄玩家在哪個(gè)關(guān)卡、以及現(xiàn)在記分板看起來是什么樣的。但是在動(dòng)作類游戲中,除了記錄玩家虛擬人偶之外,你可能還需要記錄關(guān)卡中的每個(gè)物體的位置。在一個(gè)特定時(shí)間點(diǎn),這可能變得難以管理,特別是當(dāng)希望它能夠很快完成。對(duì)于這種情況,你可以在游戲設(shè)計(jì)階段采取一些措施以確保成功。

首先,你必須決定什么東西是在保存游戲狀態(tài)時(shí)必須保存的?;鹧媪W酉到y(tǒng)中的每根小火苗的位置并不重要,但是在粒子系統(tǒng)的位置在大型游戲中可能很重要。如果它們能從關(guān)卡數(shù)據(jù)中獲得,那么游戲中每個(gè)敵人的狀態(tài)可能并不重要。用這種方式進(jìn)一步考慮,如果你可以簡(jiǎn)單的讓玩家的虛擬人偶從check point開始的話,那玩家虛擬人偶的確切狀態(tài)與位置也可能不需要保存。

基于幀的邏輯與基于時(shí)間的邏輯

基于幀的邏輯是指基于單獨(dú)的幀的改變來更新游戲物體。基于時(shí)間的邏輯雖然更復(fù)雜但卻與實(shí)際游戲狀態(tài)更緊密,是隨著時(shí)間的流逝而更新游戲物體。

不熟悉游戲開發(fā)的程序員總是犯了將基于幀的邏輯與基于時(shí)間的邏輯混合的錯(cuò)誤。 它們?cè)诙x上的區(qū)別是微妙的,不過如果處理不得當(dāng),會(huì)造成非常明顯的BUG。

比如,讓我們以玩家移動(dòng)為例。新手程序員可能寫出這樣的代碼:

  1. void onPlayerInput( Input inputEvent ) {     
  2.     if(inputEvt.type == IE_KEY && inputEvt.value == KEY_UP) {     
  3.         //apply movement based on the user input     
  4.         playerAvatar.y += movementSpeed;     
  5.     }     
  6. }   

每當(dāng)玩家按下按鍵,虛擬人偶像前移動(dòng)一點(diǎn)。這是基于幀的邏輯,因?yàn)槊看我苿?dòng)的變化都會(huì)潛在的伴隨著新的幀。事實(shí)上,在這個(gè)的例子中,每次玩家輸入事件都會(huì)發(fā)生移動(dòng)。這或多或少有點(diǎn)像主循環(huán)的迭代。移動(dòng)的可視化影響只有在主循環(huán)的下次迭代中才會(huì)反映,所以任何迭代中間的虛擬人偶移動(dòng)都會(huì)浪費(fèi)計(jì)算。讓我們做一下改進(jìn):

  1. void onPlayerInput( Input inputEvent ) {     
  2.     if(inputEvt.type == IE_KEY && inputEvt.value == KEY_UP) {     
  3.         //save the input state, but don't apply it     
  4.         playerAvatar.joystick = KEY_UP;     
  5.     }     
  6.     if(inputEvt.type == IE_KEY_RELEASE) {     
  7.         playerAvatar.joystick = 0;     
  8.     }     
  9. }     
  10. void Update() {     
  11.     //update the player avatar     
  12.     if( playerAvatar.joystick == KEY_UP ) {     
  13.         playerAvatar.y += movementSpeed;     
  14.     }     
  15. }    

現(xiàn)在我們知道,在鍵被按下的過程中,每次游戲循環(huán)中都只會(huì)被賦予一次速度。但是,這仍然是基于幀的邏輯。

基于幀的邏輯的問題是,幀變化不會(huì)總是以相同的時(shí)間間隔發(fā)生。如果在游戲循環(huán)中,渲染或者游戲邏輯會(huì)比通常耗費(fèi)更多的時(shí)間,它可能會(huì)被推遲到下一次循環(huán)中。所以,有時(shí)你需要有60幀每秒(fps),有時(shí),你只需要30fps。由于移動(dòng)是適用于幀的,有時(shí)你只會(huì)以通常的一半速度來移動(dòng)。

你可以用基于時(shí)間的邏輯來準(zhǔn)確的表達(dá)移動(dòng)。通過記錄自從上次幀更新的時(shí)間,你可以適用部分移動(dòng)速度。用這種方式,你可以以每秒為單位來標(biāo)識(shí)移動(dòng)速度,而不必關(guān)心當(dāng)前幀速率是多少,玩家虛擬人偶的速度是一致的:

  1. void Update( long currTime ) {     
  2.     long updateDT = currTime - lastUpdateTime;     
  3.     //update the player avatar     
  4.     if( playerAvatar.joystick == KEY_UP ) {     
  5.         //since currTime is in milliseconds, we have to divide by 1000     
  6.         // to get the correct speed in seconds.     
  7.         playerAvatar.y += (movementSpeed * updateDT)/1000;     
  8.     }     
  9.     lastUpdateTime = currTime;     
  10. }    

在這個(gè)例子中,移動(dòng)速度的總量將會(huì)是相同的,不管是2fps還是60fps?;跁r(shí)間的邏輯需要一點(diǎn)額外的代碼,但是它可以使程序更精確而不必在乎暫時(shí)的延遲。

當(dāng)然可以用基于幀的邏輯來開發(fā)游戲。重要的是,不要混合它們。比如,如果你的圖形代碼使用基于時(shí)間的邏輯來渲染玩家虛擬人偶的移動(dòng)動(dòng)畫,但是游戲邏輯代碼卻使用基于幀的邏輯在游戲世界中來移動(dòng)它,這樣移動(dòng)的動(dòng)畫將不能玩玩家移動(dòng)的距離完全同步。

如果可能的話,請(qǐng)盡量移除基于幀的邏輯。基于時(shí)間的邏輯將會(huì)對(duì)你有更大的幫助。

游戲邏輯組織結(jié)構(gòu)

游戲邏輯代碼的核心功能就是管理游戲狀態(tài)的規(guī)則與進(jìn)度。根據(jù)你的游戲設(shè)計(jì),這可能意味著任何事情。但是,還是有一些基本模式基于制作的游戲的類型。

游戲邏輯不與任何一個(gè)特定的類相關(guān)聯(lián),它游戲狀態(tài)對(duì)象中表現(xiàn)出來。當(dāng)主游戲狀態(tài)被初始化后,它將會(huì)為關(guān)卡載入與初始化必要的資源。例如猜謎游戲中的一組提示與單詞、玩家虛擬人偶的圖片數(shù)據(jù)以及玩家當(dāng)前所在區(qū)域的圖片數(shù)據(jù)。在游戲循環(huán)中,游戲邏輯將會(huì)接受用戶輸入,運(yùn)行物理模擬,并負(fù)責(zé)處理所有的碰撞結(jié)局消息,模擬AI動(dòng)作,執(zhí)行游戲規(guī)則。最后,當(dāng)應(yīng)用程序需要終止主游戲狀態(tài),它會(huì)釋放釋放所有的游戲資源,并可能將游戲狀態(tài)保存到硬盤驅(qū)動(dòng)器上。

根據(jù)游戲的復(fù)雜度,你可能會(huì)發(fā)現(xiàn)很方便進(jìn)一步分解游戲邏輯。比如,如果你在開發(fā)一款冒險(xiǎn)游戲,你可能有一個(gè)充滿環(huán)境數(shù)據(jù)(地面、建筑、河流、樹等)、可以移動(dòng)、與玩家交互的實(shí)體(玩家虛擬人偶、敵人、非玩家角色、開關(guān)、障礙物等),各種GUI使玩家作出特殊動(dòng)作和顯示重要信息的游戲世界。每種游戲特征都必須有大量的代碼。雖然它們合在一起才能組成完整的游戲,但是你還是可以保持它們的工作模塊化。

你可以創(chuàng)建一個(gè)Level Manager類來處理游戲關(guān)鍵,包括載入和卸載顯示在游戲世界中的物理與圖像數(shù)據(jù)與調(diào)用游戲引擎來偵測(cè)實(shí)體與游戲世界的碰撞。你還可以創(chuàng)建另外一個(gè)類或者一些類來處理游戲世界中存在的實(shí)體。每個(gè)類都載入和卸載渲染那些物體的必要的物理和圖片數(shù)據(jù),以及包括控制它們的AI。

最后,你可能創(chuàng)建另外一個(gè)單獨(dú)的類來處理游戲中用戶交互,以保持代碼與三大概念獨(dú)立。

這個(gè)體系結(jié)構(gòu)適用于任何類型的游戲。首先評(píng)估游戲設(shè)計(jì)的主要特性,接著以某種方式組合,將相近的功能與數(shù)據(jù)組合在一起。

小結(jié):

小結(jié):iPhone 游戲開發(fā)教程 游戲引擎 (6)的內(nèi)容介紹完了,希望本文對(duì)你有所幫助!你應(yīng)該對(duì)創(chuàng)造一個(gè)游戲引擎時(shí)必須完成的任務(wù)有了一個(gè)基本的理解。這將會(huì)幫助我們?cè)谙乱还?jié)創(chuàng)建這些元素,為我們的游戲做準(zhǔn)備。 想要深入了解iPhone  游戲引擎的更多內(nèi)容,請(qǐng)參考以下幾篇文章:

iPhone 游戲開發(fā)教程 游戲引擎 (1)

iPhone 游戲開發(fā)教程 游戲引擎 (2)

iPhone 游戲開發(fā)教程 游戲引擎 (3)

iPhone 游戲開發(fā)教程 游戲引擎 (4)

iPhone 游戲開發(fā)教程 游戲引擎 (5)

責(zé)任編輯:zhaolei 來源: CSDN博客
相關(guān)推薦

2011-07-18 10:53:09

2011-07-18 11:07:12

iPhone 游戲 引擎

2011-07-18 11:39:58

iPhone 游戲 引擎

2011-07-18 11:23:29

iPhone 游戲 動(dòng)畫

2011-07-21 16:48:19

iPhone 游戲

2011-08-09 11:13:07

iPhone游戲網(wǎng)絡(luò)連接測(cè)試游戲

2013-12-04 17:27:10

Android游戲引擎libgdx教程

2015-07-08 16:38:10

Cocos游戲引擎

2015-07-06 17:36:17

Cocos游戲開發(fā)引擎

2015-07-06 17:12:31

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

2011-07-27 13:57:36

iPhone 游戲 Cocos2d

2013-04-19 01:42:02

2011-12-12 13:58:11

TinyCoiOSAndroid

2023-09-14 11:45:11

Godot項(xiàng)目游戲

2012-03-06 10:56:32

HTML 5

2013-12-04 16:28:29

Android游戲引擎libgdx教程

2012-06-23 20:06:21

jQuery

2013-12-06 09:59:53

Android游戲引擎libgdx教程

2015-07-10 10:27:21

Cocos游戲開發(fā)引擎

2011-04-06 15:22:00

虛擬引擎移動(dòng)游戲開發(fā)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)