元件-實體-系統 (ECS \CES)遊戲程式設計模型
一般來說,我們實現遊戲實體都是採用物件導向的方法進行程式設計。每一個實體都是一個物件,並且需要一個基於類的例項化系統,允許實體通過多型來擴充套件。但是,這樣的方法,往往導致系統中出現大量的類,造成類爆炸的情況出現。隨著新的實體出現,我們發現很難在類繼承圖中新增新的實體,特別是當這個實體需要很多不同型別的功能的時候。你可以看下下面的一個簡單的類圖繼承。一個靜態的敵人,並不能夠很好的繼承出來。
為了解決這樣的問題,遊戲開發人員想出了通過組合而不是繼承的方法來進行實體的構建。一個實體,就是一群元件的聚合,通過這樣的方式,它具有以下物件導向方法所不具有的好處:
1.容易新增新的複雜的實體型別
2.容易定義新的實體資料
3.更加的高效率
下面是如何實現實體的一種方式。注意,這裡的元件都是純粹的資料,沒有任何的方法,在下面會詳細解釋為什麼這麼做。
元件
一個元件可以使用C中的結構體來進行設計。它沒有方法,只是用來儲存一些資料,並不在它之上進行動作。一個經典的實現方式是,每一個不同的元件都繼承至一個抽象的Componet類,通過這樣的方法我們能夠在執行時動態的新增元件,識別元件。每一個元件都描述了實體的某個屬性特徵。當他們單獨存在的時候,實際上是沒有任何意義的,但是當多個元件通過系統的方式組織在一起,就能夠發揮強大的力量。我們可以使用空的元件來對實體進行標記,從而能夠在執行時動態的識別它。
例子
- Position(x,y)
- Velocity(x,y)
- Physics(body)
- Sprite(images, animations)
- Heath(value)
- Character(name, level)
- Player(empty)
實體
一個實體指的是存在於你的遊戲世界中的物體。實體在程式碼上就是一個元件的列表。由於實體的結構實在是太簡單了,所以很多實現都沒有專門的設計一個實體的資料結構。相反的,一個實體就是一個ID,所有組成這個實體的元件將會被這個ID給標記,從而明確的知道哪些元件是屬於哪個實體的。如果你想的話,你可以在執行時,動態的將元件從實體中移除或者增加一個或多個你感興趣的元件。比如說,如果玩家發出了一個冰系魔法,將敵人凍住,你只要簡單的將它的速度元件移除,那麼敵人就靜止住了。
例子
- Rock(Position, Sprite)
- Crate(Position,Sprite,Health)
- Sign(Position,Sprite,Text)
- Ball(Position,Velocity,Physics,Sprite)
- Enemy(Position,Velocity,Sprite,Character,Input,AI)
- Player(Position,Velocity,Sprite,Character,Input,Player)
系統
注意,我在上面沒有提到任何和遊戲邏輯相關的話題。遊戲邏輯是系統需要進行的工作。一個系統就是對所有相關聯的元件記性操作,比如說,同一個實體的元件。舉個例子,人物的移動系統可能會對位置(Position),速度(Velocity),碰撞(Collider),和輸入(Input)進行操作。每一個系統,都會在每一幀中按照邏輯上的順序進行更新。如果要讓一個角色跳起來,我們只要檢測下Input中的keyJump按鍵是否被按下,如果是,那麼系統就會檢視下載Collider中是否有一個接觸了地面,如果是,就將這個實體的Velocity的y速度設定一下,讓這個物體跳起來。
由於系統只會對相關聯的元件進行操作,所以元件就定義了一個實體所應該具有的行為。比如說,如果一個實體有一個Position元件,但是沒有Velocity元件,那麼我們就知道,這個物體是靜止不動的,系統就不會對這個實體的Position元件進行操作了。當我們對這個實體增加了一個Velocity元件的時候,系統就會使用Velocity元件來對物體進行移動。這樣的行為可以使用被標記的元件來進行,被標記的元件能夠重複的使用在不同的上下文中。對一個實體,增加一個空的Player元件,將會為這個實體打上了Player的標籤,那麼PlayerControl系統,就會尋找帶有這個標籤的所有元件,然後使用Input中的資料,進行操作。
例子
- Movememt(Position, Velocity) - 將速度增加到位置上去
- Gravity (Velocity) - 使用重力來對速度進行加速
- Render(Position, Sprite) - 繪製精靈
- PlayerControl(Input, Player) - 更具Input中的資料控制Player
- BotControl(Input, AI) - 更具AI代理和輸入的資料控制
結論
使用了CES系統之後,我們就可以避免使用大量的類了。實體就是你遊戲中存在的物體,它隱式的使用一系列的元件進行定義,這些元件都是純粹的資料,只有系統才能夠操作他們。
相關文章
- 系統程式設計 - I/O模型程式設計模型
- 關於Unity2018的實體元件系統(通用名稱ECS)Unity元件
- 【系統設計】設計一個限流元件元件
- [譯] 原子設計:如何設計元件系統元件
- 軟體系統的設計和實現
- 系統程式設計程式設計
- 支付系統設計:支付系統的賬戶模型模型
- SAP CRM系統訂單模型的設計與實現模型
- DeFi/GameFi鏈遊NFT遊戲系統設計開發專案模型GAM遊戲模型
- (Python程式設計 | 系統程式設計 | 並行系統工具 | 程式退出)Python程式設計並行
- observejs改善元件程式設計體驗JS元件程式設計
- ET介紹——元件式設計(最佳化版的ECS)元件
- 3D遊戲程式設計與設計6——物理系統與碰撞3D遊戲程式設計
- 作業系統實驗(一)-Shell程式設計作業系統程式設計
- 作業系統實驗1 Shell程式設計作業系統程式設計
- 貝殼_程式設計實踐_銀行系統程式設計
- 動作遊戲系統設計概述遊戲
- 遊戲中的技能系統設計遊戲
- 程式設計體系結構(09):分散式系統架構程式設計分散式架構
- 支付系統訂單模型該如何設計?模型
- 遊戲分享系統設計第二步:分享系統的設計遊戲
- 分散式系統程式設計分散式程式設計
- 計算機系統004 - 硬體元件概況計算機元件
- Socket程式設計模型程式設計模型
- 遊戲系統設計的基石:體驗樹(量化、視覺化玩家體驗)遊戲視覺化
- 分散式佇列程式設計:模型、實戰分散式佇列程式設計模型
- Linux系統程式設計—共享記憶體之mmapLinux程式設計記憶體
- Java併發程式設計:Java記憶體模型Java程式設計記憶體模型
- 元件庫設計實戰系列:複雜元件設計元件
- 程式設計師程式設計能力層次模型程式設計師模型
- 小程式元件化程式設計元件化程式設計
- ECS控制檯診斷系統
- 計算機系統007 - 硬體元件之CPU計算機元件
- 計算機系統006 - 硬體元件之RAM計算機元件
- 快捷簡易統計圖表模型設計與實現模型
- 程式設計作業——系統管理程式設計
- 系統程式設計——管道通訊程式設計
- Linux系統程式設計【4】——檔案系統Linux程式設計