激情六月丁香婷婷|亚洲色图AV二区|丝袜AV日韩AV|久草视频在线分类|伊人九九精品视频|国产精品一级电影|久草视频在线99|在线看的av网址|伊人99精品无码|午夜无码视频在线

高校合作1:010-59833514 ?咨詢電話:400-810-1418 服務(wù)與監(jiān)督電話:400-810-1418轉(zhuǎn)接2

基于ECS的游戲引擎架構(gòu)設(shè)計「譯」

發(fā)布時間:2024-03-08 12:57:33 瀏覽量:276次

摘要

游戲編程設(shè)計和組織是困難而復雜的,為了簡化開發(fā)進程,會使用被稱為游戲引擎的游戲框架(framework),該框架包含了一組實用工具。本項的目的是探索游戲引擎設(shè)計和開發(fā)一個模塊化和可擴展的游戲引擎。本文中的設(shè)計是面向?qū)ο?OOP)的以及兩個實體組件系統(tǒng)(ECS)。OOP設(shè)計常用于計算機科學,使用對象層次來共享函數(shù)功能,ECS設(shè)計基于繼承之上的組合的概念,ECS中對象包含特性而不是繼承它們(特性)。然而,設(shè)計都有它們的弱點,例如OOP設(shè)計中的可擴展性問題,該問題來自于層次結(jié)構(gòu)的緊耦合性,在層次結(jié)構(gòu)的根附近進行的更改需要進行有效的代碼重構(gòu)。ECS解決了耦合問題,然而,問題存在于跨系統(tǒng)通信和共享組件。使用了兩個ECS設(shè)計來解決這個問題,分別是Cupcake 和 Artemis。通過一個簡單的游戲應(yīng)用來測試和分析設(shè)計的功能性。結(jié)合使用Cupcake 和 Artemis的優(yōu)點,本該提出了一個能最小化架構(gòu)問題的新ECS設(shè)計。

1 介紹

游戲開發(fā)是一個復雜的進程,它可能需要圖形、聲音、物理、網(wǎng)絡(luò)、AI以及輸入,一個常見的實踐是使用已經(jīng)實現(xiàn)一種技術(shù)的現(xiàn)有的庫來節(jié)省時間和精力。即便如此,將幾種技術(shù)結(jié)合到一個系統(tǒng)中可能也是一項艱巨的任務(wù)。游戲引擎通過提供制作游戲所需的框架和技術(shù)解決了這個問題。這使得游戲開發(fā)者可以跳過技術(shù)的實現(xiàn)來專注于游戲開發(fā)。

開發(fā)游戲引擎時遇到的最大問題是如何表示游戲?qū)ο?,游戲?qū)ο罂梢詮臎]有控制或交互的簡單2D圖像到具有控制、聲音、動畫和AI的異常復雜3D對象。在概念上,l很容易將游戲?qū)ο罄斫鉃楸硎居螒蛑芯哂卸鄠€功能的實體。

當試圖組織一個能夠處理特性組合的體系結(jié)構(gòu)時,問題就出現(xiàn)了。

一種常見的方法是使用面向?qū)ο蟮木幊?OOP)體系結(jié)構(gòu),然而,由于繼承和層次結(jié)構(gòu)的本質(zhì),在表示游戲?qū)ο髸r出現(xiàn)了困難。作為解決面向?qū)ο蟮挠螒驅(qū)ο髥栴}的答案,實體組件系統(tǒng)(ECS)變得非常流行。

本文將討論OOP的缺點、ECS的優(yōu)點、ECS的變體,并提出一種更加模塊化的ECS設(shè)計。

2 面向?qū)ο缶幊?OOP)

面向?qū)ο缶幊淌且环N可重用和模塊化的程序設(shè)計,它將信息表示為包含數(shù)據(jù)和邏輯的對象。面向?qū)ο蟮囊粋€獨特而實用的特點是繼承,這允許架構(gòu)創(chuàng)建共享特性和結(jié)構(gòu)的層次結(jié)構(gòu),這有助于促進代碼重用和組織。

游戲?qū)ο蟮膶哟谓Y(jié)構(gòu)會是什么樣子?OOP聽起來正是游戲引擎需要的代碼重用和組織。圖1是一個表示車輛和花盆的層次結(jié)構(gòu)的示例。當路徑如前面所示一樣簡單時,這就可以實現(xiàn),然而,當游戲?qū)ο箝_始共享功能時,問題就出現(xiàn)了。

2.1 OOP的問題

當涉及到層次結(jié)構(gòu)中的共享特性時,設(shè)計架構(gòu)就變得非常困難。圖1對于帶有聲音的靜態(tài)對象或者帶有聲音和控件(比如播放器外觀)的非渲染對象會發(fā)生什么變化?圖2顯示了添加了游戲?qū)ο蟮臐撛趯哟谓Y(jié)構(gòu)樹,我們的樹開始在特征和路徑上顯示冗余。添加到游戲?qū)ο蟮墓δ芙M合越多,層次結(jié)構(gòu)就會變得越復雜,這使得代碼難以管理和組織。

圖2-冗余的OOP層次結(jié)構(gòu)

這種復雜層次結(jié)構(gòu)的一個主要問題是處理游戲?qū)ο螅茈y創(chuàng)建一個函數(shù)來接受持有特定功能的各種類型的游戲?qū)ο?。諸如函數(shù)重載之類的解決方案很難維護,因為包含特定功能的每種類型的對象都需要自己的函數(shù)。這將強制所有不同組合使用非直觀的層次結(jié)構(gòu)或代碼重用。

這個復雜層次結(jié)構(gòu)的更糟糕的問題是可擴展性,每個子類都在很大程度上依賴于父類的結(jié)構(gòu)。如果沒有大規(guī)模的代碼重構(gòu),添加新特性或更改當前特性可能是困難的,也可能是不可能的。

3 實體組件系統(tǒng)

繼承之上的組合是解決面向?qū)ο蟮膶哟谓Y(jié)構(gòu)問題的一種方法。這個概念通過組合而不是繼承來增加功能,使系統(tǒng)更加模塊化和獨立。例如,使用ECS,車輛對象包含用于聲音或控制等特性的對象,而不是創(chuàng)建層次結(jié)構(gòu)鏈。這使得車輛對象更具動態(tài)性,因為更改特性就像添加或刪除對象一個簡單,而不需要主要代碼的重構(gòu)。

3.1 架構(gòu)

ECS由三個基本部分組成:實體、組件和系統(tǒng)。實體是與對象關(guān)聯(lián)的唯一id,組件是表示實體信息的數(shù)據(jù),系統(tǒng)在實體上運行邏輯,以利用或更改來自組件的數(shù)據(jù)。

在游戲開發(fā)中,游戲?qū)ο蟊划斪鲗嶓w,功能被表示為組件和系統(tǒng)。這可以看作是一個數(shù)據(jù)庫,其中實體是惟一的id,系統(tǒng)是數(shù)據(jù)庫表,組件是數(shù)據(jù)庫表中的數(shù)據(jù)。

圖3-ECS中的游戲?qū)ο?/p>

圖3顯示了游戲?qū)ο笤贓CS體系結(jié)構(gòu)中的樣子。車輛與一個惟一的id關(guān)聯(lián)。使用這個惟一的id,調(diào)用者通過創(chuàng)建與所需特性關(guān)聯(lián)的組件來附加特性。這允許系統(tǒng)使用組件中提供的數(shù)據(jù)處理實體和應(yīng)用動作。

3.2 優(yōu)點

ECS體系結(jié)構(gòu)的優(yōu)點在于它是獨立的,每個組件只不過是簡單的數(shù)據(jù)點,因此本質(zhì)上是與其他組件隔離的。系統(tǒng)需要特定的組件來運行其邏輯,這使得系統(tǒng)相對解耦,因為實體中包含的不同組件的數(shù)量不會改變系統(tǒng)解釋實體的方式。只要滿足組件需求,系統(tǒng)就會在實體上運行其邏輯。

圖4-實體組件系統(tǒng)(ECS)

圖4顯示了以前層次結(jié)構(gòu)轉(zhuǎn)換為ECS的設(shè)計。關(guān)于渲染系統(tǒng),花盆和揚聲器有什么不同?渲染系統(tǒng)是否關(guān)心揚聲器是否有聲音組件?向屏幕渲染對象是否需要聲音組件?這是ECS系統(tǒng)如何提高隔離性和強化代碼組織的一個例子。一個簡單的表格可以用來查看游戲?qū)ο蟀男┕δ?,而不是遵循一個復雜且長樹。

圖5-添加功能的ECS

ECS架構(gòu)的另一個好處是系統(tǒng)的模塊化和可擴展性。由于系統(tǒng)和組件是相對獨立的,所以很容易添加新特性。例如,向花盆中添加聲音與添加聲音組件一樣簡單。添加諸如爆炸之類的新特性可以與創(chuàng)建新系統(tǒng)和組件一樣簡單。更新的圖5顯示了新特性如何對引擎的總體結(jié)構(gòu)產(chǎn)生較低的影響。

3.3 缺點

雖然ECS系統(tǒng)可以解決OOP帶來的一些問題,但是它們有自己的一些問題,隔離和獨立是ECS系統(tǒng)的正反兩面。當設(shè)計需要共享組件和跨系統(tǒng)通信時,就會出現(xiàn)負面影響。

共享組件的問題是包含關(guān)系和處理順序,該概念促進系統(tǒng)耦合,這與ECS的隔離設(shè)計背道而馳。根據(jù)設(shè)計,共享組件的位置是不確定的,此外,處理實體的順序可能是至關(guān)重要的。例如,在引擎中的移動、碰撞和渲染,流程順序?qū)⒏目梢姷慕Y(jié)果。例如,移動、碰撞和渲染的順序可以創(chuàng)建這樣一種情況:由于尚未處理碰撞,對象將會穿透墻壁。

跨系統(tǒng)通信是ECS的另一個難點??缦到y(tǒng)通信對于事件發(fā)生這一情況是必要的。例如,一個球與地面相撞時應(yīng)該發(fā)出噪音。ECS的問題是碰撞和聲音系統(tǒng)是不同的,彼此是隔離的。解決這個隔離問題的兩種方法是向組件添加狀態(tài)或?qū)崿F(xiàn)消息傳遞系統(tǒng)。無論哪種方式,設(shè)計一種方法在保持系統(tǒng)獨立的同時連接它們都是困難的。

4 CUPCAKE ECS

CUPCAKE ECS架構(gòu)被設(shè)計成一個模塊化的ECS系統(tǒng),其目標是在不影響架構(gòu)的情況下方便地添加或刪除系統(tǒng)。這就要求系統(tǒng)之間是完全獨立的,永遠不要使用或引用任何其他系統(tǒng)。理想情況下,這將創(chuàng)建一個用戶可以插入和添加新特性的引擎,并有望提高代碼重用度和用戶之間的共享。

用戶如何使用Cupcake的一個例子是從基本ECS框架開始。這將包括管理系統(tǒng)、實體的實用工具,以及創(chuàng)建新系統(tǒng)和組件的框架。接下來,用戶將從插件(系統(tǒng))列表中選擇所需的功能。例如,用戶可以選擇一個功能列表,如聲音的FMOD, 3D渲染的OpenGL, 物理的Bullet。最后,安裝腳本將插件和框架編譯成靜態(tài)庫和一組頭文件。結(jié)果將是一個高度可定制的、特定于用戶的引擎。

4.1 架構(gòu)

Cupcake架構(gòu)分為幾個部分:引擎、管理器和系統(tǒng)。圖6顯示了Cupcake的基本架構(gòu)。引擎是所有系統(tǒng)、管理器和實體的頂層接口,它負責運行游戲循環(huán)和管理系統(tǒng)和實體。該引擎通過提供添加和刪除附加實體來管理實體,同時為每個實體維護一個惟一的id,通過提供正在處理的系統(tǒng)和空閑系統(tǒng)兩個列表來管理系統(tǒng),正在處理中的系統(tǒng)由引擎游戲循環(huán)進行處理。

圖6-Cupcake架構(gòu)

系統(tǒng)負責管理組件和實現(xiàn)幾種抽象方法。抽象方法包括init、release和update(用于正在處理的系統(tǒng))。使用于FOD播放聲音的系統(tǒng)的一個例子,是一個包含聲音和位置的組件列表的系統(tǒng)。init函數(shù)將初始化FMOD庫文件,release函數(shù)將釋放所有與系統(tǒng)綁定的資源,如組件和FMOD庫。update函數(shù)用于更新移動對象的聲音位置。

4.2 Cupcake 方案

Cupcake包含與任何具有共享組件和跨系統(tǒng)通信的ECS系統(tǒng)相同的通用問題。為了解決共享組件的問題,Cupcake在引擎外部有一個外部組件集。這些外部組件在創(chuàng)建時被傳遞給系統(tǒng),這允許多個系統(tǒng)之間具有相同的組件集,而不需要任何方法來保持數(shù)據(jù)的同步。此外,它還保持了系統(tǒng)之間的獨立性。共享組件的一個例子是渲染和物理系統(tǒng)的位置,通過引用相同的組件列表,物理系統(tǒng)對位置所做的任何更改都將自動用于渲染。

采用外部消息系統(tǒng)解決了系統(tǒng)間的交叉通信問題。此消息傳遞系統(tǒng)由句柄、觸發(fā)器和消息組成。觸發(fā)器是針對特定條件在每個循環(huán)中執(zhí)行的一段邏輯,根據(jù)這些條件,將向消息系統(tǒng)發(fā)送一條消息。消息句柄是為系統(tǒng)創(chuàng)建的對象,用于消息捕獲和基于消息的邏輯執(zhí)行。例如,一個玩家的移動需要三個部分,基于玩家輸入執(zhí)行的觸發(fā)器,當觸發(fā)器注冊了一個玩家輸入(事件)時,它將向系統(tǒng)發(fā)送適當?shù)膍ove消息,比如向前移動,然后,這個向前移動的消息句柄被物理系統(tǒng)捕獲,然后物理系統(tǒng)將被調(diào)用,根據(jù)該句柄移動玩家。

4.3 分析

Cupcake系統(tǒng)通過提高系統(tǒng)的獨立性和采用數(shù)據(jù)驅(qū)動架構(gòu),保持了實體組件系統(tǒng)的基礎(chǔ)本質(zhì)。解決常見ECS問題的方法是有效的,但是還有改進的余地。

共享組件是解決共享數(shù)據(jù)問題的一個相對簡單的解決方案。外部共享組件的問題是包含共享組件的內(nèi)容的模糊表示。除非明確指示,否則不清楚調(diào)用者應(yīng)該在何處生成或獲取共享組件。通過要求調(diào)用者被指示這個外部列表應(yīng)該從哪里來,暴露了一個脆弱的設(shè)計。它允許調(diào)用者為相同的組件創(chuàng)建重復列表,這將達不到共享組件的目的。

事實證明,外部消息傳遞系統(tǒng)工作得相對較好。消息傳遞系統(tǒng)的外部性有助于提高系統(tǒng)獨立性,并允許調(diào)用者定制消息的行為。外部消息傳遞系統(tǒng)的問題在于其與引擎的集成性較弱,創(chuàng)建一個關(guān)于如何處理跨系統(tǒng)通信的標準會更有用。通過將消息傳遞集成到引擎中,系統(tǒng)更有可能圍繞標準消息傳遞系統(tǒng)進行設(shè)計。

最后,Cupcake的一個缺陷是引擎中去除了實體。由于組件存儲在系統(tǒng)中,所以沒有簡單的方法可以從系統(tǒng)中刪除實體。調(diào)用者必須手動地從各個系統(tǒng)中釋放組件來刪除實體。這就留下了一個問題––允許在設(shè)計系統(tǒng)時不實現(xiàn)在特定實體上釋放數(shù)據(jù)的函數(shù)。

5 ARTEMIS ECS 框架

由Gamadu創(chuàng)建的Artemis ECS框架是為游戲開發(fā)而設(shè)計的,該設(shè)計與Cupcake很相似。實體是惟一的id,組件是數(shù)據(jù),系統(tǒng)使用數(shù)據(jù)來處理邏輯。Artemis框架最初是用Java編寫的,但是本文將使用C來適配Artemis框架,從Java到C,有幾個特性沒有實現(xiàn),所以該分析只對C++而而言是準確的。

5.1 架構(gòu)

Artemis框架包含一個中心化的World對象,該對象是這個框架的接口。World對象包含所有manager并運行游戲循環(huán),此框架中使用的manager用于系統(tǒng)、實體、組(group)和標記(tag)。系統(tǒng)和實體的manager類似于Cupcake,它們用于管理實體或系統(tǒng)。組和標記管理器是簡單的系統(tǒng),用于將實體組織在一起并向特定實體添加標記,通過將一些字符串關(guān)聯(lián)到一組實體或單個實體來實現(xiàn)的。

Artemis中的實體管理器是惟一的,因為它將所有組件存儲在引擎中,這是通過一個二維數(shù)組完成的,其中第一個標識符是組件類型,第二個標識符是實體id。實體管理器還為每個活動實體管理惟一的id。

Artemis中的系統(tǒng)要管理需要處理的實體列表,這是通過為每個組件類型分配標識符來實現(xiàn)的。使用組件類型,系統(tǒng)可以通過過濾只處理有效的實體。為了訪問數(shù)據(jù),調(diào)用者必須創(chuàng)建組件mapper,以便從實體管理器獲取組件。

5.2 分析

Artemis有一個獨特的解決方案來解決共享組件問題,通過將組件附加到實體管理器,這使得所有系統(tǒng)都可以訪問組件,這也使得組件在使用它們的系統(tǒng)之間自動同步。此外,它還消除了誰包含共享組件的歧義問題,因為所有組件都存儲在同一個位置。這在調(diào)用者需要刪除實體時非常有用,因為實體管理器可以搜索組件列表并刪除與實體關(guān)聯(lián)的所有數(shù)據(jù)。

Artemis的一個問題是缺乏跨系統(tǒng)的通信,系統(tǒng)之間唯一共享的是可以用作消息的組件。然而,由于創(chuàng)建和刪除組件的開銷很大,因此這可能是一種開銷很大的消息傳遞方法。

最后,Artemis最大的限制是組件和系統(tǒng)類型的限制,與組件和系統(tǒng)關(guān)聯(lián)的惟一id是用位(bit)完成的,比特數(shù)被限制在32個,這就產(chǎn)生了一個問題,當用戶超過組件或系統(tǒng)限制時,過濾就會失效。新組件分配了未定義的類型,這樣就允許將無效實體傳遞給系統(tǒng)(譯注:言外之意是有問題的)。

6 提出的架構(gòu)

本文提出的ECS系統(tǒng)架構(gòu)是Cupcake和Artemis的結(jié)合,Cupcake解決了跨系統(tǒng)通信問題,并保持了系統(tǒng)的獨立性。通過在實體管理器中本地化所有組件,Artemis解決了共享組件的問題。這兩種技術(shù)的結(jié)合解決了ECS的問題,同時保持了模塊化。

6.1 架構(gòu)

這個架構(gòu)像Cupcake和Artemis將有一個中心接口對象稱為引擎(engine),引擎將負責管理器和游戲循環(huán)。引擎所包含的管理器是系統(tǒng)、實體、資源和消息。引擎還負責使用系統(tǒng)管理器處理“正在處理的系統(tǒng)”的每個游戲循環(huán)。

圖7-引擎對象

系統(tǒng)和實體管理器的工作方式與Artemis相同,其中組件存儲在實體管理器中。組件類型將具有唯一id,以便允許系統(tǒng)過濾組件類型,通過使用組件id,系統(tǒng)可以創(chuàng)建具有適當組件的有效實體列表并處理它們。

新增的資源管理器存儲組件可能共享的信息。對象的mesh是多個組件共享數(shù)據(jù)的一個例子,例如,如果游戲中存在50個相同的敵人,那么為每個實體創(chuàng)建重復的mesh數(shù)據(jù)將會非常昂貴。資源管理器將處理在實體之間共享完全相同數(shù)據(jù)這一理想情況。

消息管理器將負責跨系統(tǒng)通信,與Cupcake一樣,它將由調(diào)用者創(chuàng)建的處理程序(handler)組成,這些處理程序捕獲消息并在系統(tǒng)中執(zhí)行邏輯。系統(tǒng)將負責向消息處理程序發(fā)送消息,而不是觸發(fā)器。

7 使用ECS的項目

在這個項目中,實現(xiàn)了兩個不同的ECS系統(tǒng),并在一個簡單的游戲環(huán)境中使用。Cupcake引擎是用C編寫的,用于測試應(yīng)用程序Cron。使用基于Artemis框架的C開發(fā)了用于CPE 476項目Carrota的引擎。

7.1 Cron

圖8-Cupcake測試應(yīng)用

開發(fā)Cupcake引擎時,創(chuàng)建了一個測試應(yīng)用程序來測試引擎的功能。圖8顯示了示例測試應(yīng)用程序。球體代表玩家,用戶可以在其中使用控件移動對象。此外,位置音頻是基于球的位置。這些立方體代表了物理作用于它們的測試對象,它們播放恒定的音頻。這是用來確保3D音頻正常工作。

7.2 Carrota

圖9-Carrota兔子

圖10-Carrota商店菜單

圖11-Carrota甜甜圈

利用Artemis框架為CPE 476項目開發(fā)了ECS引擎,使用該引擎創(chuàng)建一個FPS防御游戲。該引擎的特性包括:2D/3D/文本呈現(xiàn)、聲音、碰撞、物理、動畫、framebuffer對象和陰影,其中每個功能都是相對獨立。

8 未來的工作

在未來的工作中,將提出的ECS方案繼續(xù)發(fā)展和完善,首先構(gòu)建框架,然后實現(xiàn)功能。希望能夠?qū)崿F(xiàn)支持3D渲染和實時圖形的功能,最終目標是創(chuàng)建一個冗長的框架,其中包含多個可以跨引擎共享的特性。

參考文獻

  • [1] Entity-Component-System-Revisited, http://flohofwoe.blogspot.com/2013/07/entity- component-system-revisited.html?m=1: July 6th, 2013.
  • [2] Randy Gaul, Component Based Engine Design, http://www.randygaul.net/2013/05/20/component- based-engine-design/: May 20th, 2013.
  • [3] Ted Brown, Fast Entity Component System, http://www.openprocessing.org/sketch/18023: January 18th, 2011.
  • [4] Bob Nystrom, Component, http://gameprogrammingpatterns.com/component.html
  • [5] Gamadu, Artemis Entity System Framework, http://gamadu.com/artemis/
  • [6] Alec Thomas, EntityX, https://github.com/alecthomas/entityx/tree/master/entityx: May 15th, 2014.
  • [7] Entity System Wiki, http://entity-systems.wikidot.com/

翻譯原文:
https://pdfs.semanticscholar.org/829b/9107c32bb20965400d22a6dad14f56b9b7b5.pdf

熱門課程推薦

熱門資訊

請綁定手機號

x

同學您好!

您已成功報名0元試學活動,老師會在第一時間與您取得聯(lián)系,請保持電話暢通!
確定