原文鏈接:https://hackernoon.com/build-a-game-engine-from-scratch-in-c
游戲開發一直很能激勵學生學習高級計算機科學。可能有些人認為游戲是孩子們喜歡的,但對于標準的計算機科學課程來說,游戲開發其實是少數幾個能用當中所有知識的領域。
游戲開發涉及標準計算機科學課程中的諸多內容
根據游戲的性質,你可能還需要深入到更具體的專業,比如分布式系統或人機交互。游戲開發是一項嚴肅的工作,是助力計算機科學理念學習的有力工具。
本文將詳細介紹使用C 創建一款簡單游戲引擎所需的一些基本構建模塊,解釋游戲引擎所需的主要組成元素,并就如何從零開始編寫游戲引擎給出一些個人建議。
不過,本文不是一個編程教程,因此也不會深入太多的技術細節或解釋所有這些元素是如何通過代碼粘合在一起的。如果你想找關于如何編寫C 游戲引擎的綜合性教程,可以先看看《用C 和Lua創建一個2D游戲引擎》。
一、游戲引擎是什么?
概括地講,游戲引擎是一套優化視頻游戲開發的軟件工具。這些引擎可以是小而極簡型的,簡單到只提供一個游戲循環和幾個渲染功能;當然,也可以是大而全面型的,類似于IDE應用程序那種,開發人員可以用于編寫腳本、調試、自定義關卡邏輯、人工智能、設計、發布、協作,并最終從頭到尾構建游戲,而無需離開引擎。
游戲引擎和游戲框架通常向用戶公開一組API。這些API允許程序員調用引擎函數,并像執行黑匣子一樣執行艱難的任務。
為了真正理解這些API是如何工作的,讓我們更具體地結合應用說明一下。例如,游戲引擎API公開一個名為“IsColliding()”的函數,開發者可以調用該函數來檢查兩個游戲對象是否發生碰撞,這種情況并不罕見。程序員不需要知道該函數是如何實現的,也不需要知道正確確定兩個形狀是否重疊所需的算法。就我們而言,IsColliding函數僅是一個黑匣子,根據這些對象是否相互碰撞,它會正確地返回true或false。下面是大多數游戲引擎向用戶公開的一個功能示例。
大多數引擎都會抽象碰撞檢測,并簡單地將其作為真/假函數公開
除了編程API,游戲引擎的另一個重要職責是硬件抽象。例如,3D引擎通常構建在一個專用的圖形API上,比如OpenGL、Vulkan或Direct3D。這些API為圖形處理單元(GPU)提供了軟件抽象。
說到硬件抽象,還有一些底層庫(如DirectX、OpenAL和SDL),它們提供對許多其他硬件元素的抽象以及多平臺訪問。這些庫幫助我們訪問和處理鍵盤事件、鼠標移動、網絡連接,甚至音頻等各項功能。
二、游戲引擎的崛起
在游戲行業的早期,游戲是使用定制的渲染引擎構建的。開發代碼是為了從較慢的機器中盡可能多地提升部分系統性能。每個CPU周期都至關重要,因此代碼重用或適用于多種場景的通用函數并不是開發人員能夠負擔得起的。
隨著游戲和開發團隊規模和復雜性擴展,大多數工作室最終都會在開發的多款游戲之間重用某些功能和子程序。工作室開發的內部引擎,基本上都是針對處理低級任務的內部文件和庫的集合。這些功能允許開發團隊的其他成員專注于游戲操作、地圖創建和級別定制等高級細節。
一些流行的經典引擎包括id-Tech、BUIld和AGI等。這些引擎是為了幫助特定游戲的開發而創建的,它們允許團隊的其他成員快速開發新的關卡,添加自定義資源,并動態定制地圖。這些定制引擎也被用來為他們的原創游戲修改或創建擴展包。
Id Software軟件公司(美國得克薩斯州的一家游戲軟件公司)研發了id Tech技術。id Tech技術其實是一系列不同引擎的集合,其中每一個引擎的迭代時期都關聯著一款不同的游戲。于是,開發人員通常會將id Tech 0描述為“Wolfenstein 3D引擎(Wolfenstein3D engine)”,將id Tech 1描述為“末日引擎(Doom engine)”,將id Tech 2描述為“雷神之錘引擎(Quake engine)”,等等。
Build是上世紀90年代游戲引擎歷史中的另一個例子。它由肯·西爾弗曼(Ken Silverman)創建,旨在助力第一人稱射擊游戲定制。與id Tech的情況類似,Build隨著時間而發展,它的不同版本曾經先后幫助程序員開發了《毀滅公爵3D》(Duke Nukem 3D)、《影子武士》(Shadow Warrior)和《血祭》(Blood)等游戲。這三個可以說是使用Build引擎開發的最受歡迎的游戲作品的代表,通常被稱為“三巨頭(The Big Three)”。
肯·西爾弗曼開發的Build引擎正在2D模式下編輯關卡時的情景
上世紀90年代游戲引擎的另一個例子是“瘋狂大樓專用程序腳本創建開發工具(Script Creation Utility for Manic Mansion)”(SCUMM)。SCUMM是盧卡斯藝術公司(LucasArts)開發的一款引擎,它是許多經典點擊式(Point-and-Click)游戲的基礎,《猴島小英雄》(Monkey Island)和《全速狂飆》(Full Throttle)這兩款游戲就使用這個引擎。
《全速狂飆》游戲的對話框和運作都使用SCUMM腳本語言進行管理
隨著機器的發展和功能的不斷增強,游戲引擎也隨之發展。現代引擎配備了功能豐富的工具,這些工具需要快速的處理器速度、驚人的內存量和專用顯卡。
有了備用動力,現代游戲引擎可以用機器循環來換取更多的抽象性。這種權衡意味著,我們可以將現代游戲引擎視為通用工具,以較低的成本和較短的開發時間創建復雜的游戲。
三、為什么要制作游戲引擎?
這并不是一個陌生的問題,不同的游戲程序員也各有各的看法。其回答取決于開發的游戲的性質、業務需求以及其他待考慮因素的影響。
開發者可以使用現有許多免費、強大、專業的商業引擎來創建和部署自己的游戲。那么,既然存在這么多游戲引擎可供選擇,為什么還會有人費心從頭開始制作游戲引擎呢?
我曾經寫了一篇博客文章《自己動手編寫游戲引擎還是使用現成的?》(https://pikuma.com/blog/why-make-a-game-engine)來解釋程序員從頭開始制作游戲引擎的一些原因。在我看來,最主要的原因包括:
學習機會:對游戲引擎工作原理的深層次理解可以讓你成為一名優秀的開發人員。
工作流控制:你可以更好地控制游戲的特殊方面,并調整解決方案以滿足工作流的需求。
定制:能夠根據獨特的游戲需求定制解決方案。
極簡主義:較小的代碼庫可以減少較大游戲引擎帶來的開銷。
創新:你可能需要實現一些全新的或針對其他引擎不支持的非正統硬件。
四、如何制作游戲引擎
下文將繼續討論游戲引擎的一些組件,并指導讀者自己編寫一個游戲引擎。
1.選擇編程語言
開發核心引擎代碼的編程語言是首要選擇。原始匯編語言、C、C ,甚至C#、Java、Lua,還有JavaScript等高級語言都有用來開發引擎。
編寫游戲引擎最流行的語言之一是C 。C 編程語言將速度與使用面向對象編程(OOP)和其他編程范式的能力結合起來,幫助開發人員組織和設計大型軟件項目。
因為在我們開發游戲時,性能通常是非常重要的,而C 具有編譯語言的優勢。使用編譯語言意味著最終的可執行文件將在目標機器的處理器上以本機方式運行。此外還有許多專用的C 庫和開發工具包可用于大多數現代控制臺,如PlayStation或XBox等。
開發者可以使用微軟提供的C 庫訪問XBox控制器
在性能方面,我個人不推薦使用虛擬機、字節碼或任何其他中間層的語言。除了C 之外,一些適合編寫核心游戲引擎代碼的替代品還包括Rust、Odin和Zig等語言。
本文將以C 編程語言構建一個簡單的游戲引擎。
2 . 硬件訪問
在MS-DOS等較舊的操作系統中,我們通常可以直接操作內存地址并訪問映射到不同硬件組件的特殊位置。例如,我要用某種顏色“繪制”一個像素,所要做的就是加載一個特殊的內存地址,其中的數字代表VGA調色板的正確顏色,而顯示驅動程序將該變化轉換為物理像素,并將其轉換到CRT顯示器。
隨著操作系統的發展,它們開始負責保護硬件免受程序員的攻擊。現代操作系統將不允許代碼修改操作系統為進程提供允許地址之外的內存位置。
例如,如果你使用的是Windows、macOS、Linux或BSD,則需要向操作系統請求在屏幕上繪制像素或與任何其他硬件組件對話的正確權限。即使是在操作系統桌面上打開窗口這樣的簡單任務也必須通過操作系統API來執行。
因此,運行進程、打開窗口、在屏幕上渲染圖形、繪制窗口內的像素,甚至從鍵盤讀取輸入事件都是特定于操作系統的任務。
SDL(Simple DirectMedia Layer,即簡易直控媒體層)是一個非常流行的庫,它可以幫助實現多平臺硬件抽象。在游戲開發課堂上時,通過SDL,我無需為Windows操作系統、macOS和使用Linux系統的學生創建三個不同版本的代碼。SDL不僅是不同操作系統的橋梁,也是不同CPU體系結構(英特爾、ARM、蘋果M1等)的橋梁。SDL庫對底層硬件訪問進行抽象,并“翻譯”我們的代碼以便在這些不同的平臺上都能夠正確工作。
下面是使用SDL在操作系統上打開窗口的一小段代碼。為了簡單起見,代碼中沒有添加處理錯誤的部分,但是下面的代碼對于Windows、macOS、Linux、BSD,甚至RaspberryPi,都是通用的。
SDL只是我們可以用來實現這種多平臺硬件訪問的游戲庫的一個例子。SDL是2D游戲和將現有代碼移植到不同平臺和控制臺的熱門選擇方案之一。多平臺庫的另一個流行選擇方案是GLFW,它主要用于3D游戲和3D引擎。GLFW庫可以很好地與OpenGL和Vulkan等加速3D API進行通信。
3 . 游戲主循環
至此,一旦操作系統方案解決,接下來我們就需要創建一個控制整個游戲的主循環。
簡單地說,我們通常希望我們的游戲以每秒60幀的速度運行。根據游戲的不同,幀速率可能會有所不同,但為了讓景物變得更加清晰,在膠片上拍攝的電影通常都是以每秒24幀的速度運行(每秒鐘24幅圖像從你眼前閃過)。
在游戲過程中,游戲循環會持續運行,在循環的每一次過程中,我們的引擎都需要運行一些重要的任務。傳統的游戲循環必須確保:
在不阻塞的情況下處理輸入事件
更新當前幀的所有游戲對象及其屬性
在屏幕上渲染所有游戲對象和其他重要信息
但是,一個原始的C 循環對我們來說還不夠。游戲循環必須與現實世界的時間有某種關系。畢竟,游戲中的敵人應該在任何機器上都是以相同的速度移動,而不管這些機器的CPU時鐘速度如何。
控制這個幀速率并將其設置為固定的FPS數實際上是一個非常有趣的事情。它通常要求我們跟蹤幀與幀之間的時差,并進行一些合理的計算,以確保我們的游戲以至少30 FPS的幀速率順利運行。
4 . 輸入事件處理
很難想象一個游戲不從用戶那里讀取某種輸入事件會是什么情景。所有這些輸入事件可能來自鍵盤、鼠標、游戲板或虛擬現實設備。因此,我們必須在游戲循環中處理不同的輸入事件。
要處理用戶輸入,我們必須請求訪問硬件事件,這必須通過操作系統API執行。我們可以使用一些著名的多平臺硬件抽象庫(SDL、GLFW、SFML等)來處理用戶輸入。
例如,如果我們使用SDL就可以實現輪詢事件,然后僅用幾行代碼就可以處理各種輸入事件。
再強調一次,如果我們使用像SDL這樣的跨平臺庫來處理輸入,我們不必太擔心特定于操作系統的實現。無論我們的目標平臺是什么,C 代碼都應該是相同的。
至此,我們已經有了一個可工作的游戲循環和一種處理用戶輸入的方法。接下來是時候開始考慮在內存中組織游戲對象了。
5 . 在內存中表示游戲對象
在設計游戲引擎時,我們需要設計數據結構來存儲和訪問游戲對象。
程序員在設計游戲引擎時會使用多種技術。一些引擎可能會使用簡單的面向對象方法來處理類和繼承,而其他引擎可能會將它們的對象組織為實體和組件。
如想學習更多關于算法和數據結構的知識,建議嘗試實現這些數據結構。如果你使用的是C ,一個選項是使用STL(標準模板庫),并利用它附帶的許多數據結構(向量、列表、隊列、堆棧、映射、集合等)。C STL在很大程度上依賴于模板,因此這是一個練習使用模板的好機會,同時可以在實際項目中看到它們發揮的作用。
在閱讀過一些游戲引擎架構的內容后,你會發現游戲使用的最流行的設計模式之一是基于實體和組件。實體組件設計將游戲場景中的對象組織為實體(Unity引擎中稱之為“游戲對象”,而Unreal引擎中則稱之為“角色”)和組件(我們可以添加或附加到實體的數據)。
要了解實體和組件是如何協同工作的,請考慮一個簡單的游戲場景。此例中,實體將是我們的主要游戲玩家,還包括敵人、地板、投射物等,而組件將是我們“附加”到實體上的重要數據塊,如位置、速度、剛體碰撞器等。
一種流行的游戲引擎設計模式是將游戲元素組織為實體和組件
我們可以選擇附加到實體的一些組件,例如下面這些:
位置組件:跟蹤實體在世界坐標系中的x-y位置坐標(或3D中的x-y-z)。
速度組件:跟蹤實體在x-y軸(或3D中的x-y-z)上移動的速度。
精靈組件:通常存儲我們應該為特定實體渲染的PNG圖像。
動畫組件:跟蹤實體的動畫速度,以及動畫幀如何隨時間變化。
碰撞器組件:這通常與剛體的物理特性有關,并定義實體的碰撞形狀(邊界框、邊界圓、網格碰撞器等)。
健康組件:存儲實體的當前健康值。這通常只是一個數字,或者在某些情況下是一個百分比值(例如,健康進度條)。
腳本組件:有時我們可以在實體上附加一個腳本組件,它可能是一個外部腳本文件(Lua、Python等),我們的引擎必須在后臺解釋和執行該文件。
上面給出的是一種非常流行的表示游戲對象和重要游戲數據的方法。如今,我們已經有了實體,然后我們就可以將這些不同的組件“插入”到實體中。
目前,市場上已有諸多書籍和文章探討了實現實體組件設計的方式,以及在這個實現中應該使用什么樣的數據結構。我們使用的數據結構和訪問它們的方式對我們的游戲性能有直接的影響。開發人員經常會提到諸如面向數據的設計、實體組件系統(ECS)、數據局部性等想法,這些想法與我們的游戲數據在內存中的存儲方式以及有效訪問數據方式都有密切的關系。
在內存中表示和訪問游戲對象可能是一個復雜的主題。根據我的經驗,你可以手動編寫一個簡單的實體組件來實現,也可以簡單地使用現有的第三方ECS庫(Entity-Component-System,即“實體-組件-系統”的縮寫。此模式遵循組合優于繼承原則,游戲內的每一個基本單元都是一個實體,每個實體又由一個或多個組件構成,每個組件僅僅包含代表其特性的數據)。
當前市場上,有一些流行的現成的ECS庫可供選用,我們可以將它們包含在C 項目中,開始創建實體和附加組件,而不必擔心它們是如何在后臺實現的。C ECS庫的一些例子是EnTT和Flecs。
我個人建議那些認真對待編程的學生至少嘗試一次手動實現一個非常簡單的ECS。我的理由是,即使你的實現并不完美,從頭開始編寫ECS系統也會迫使你考慮底層數據結構以及相應的性能。
一旦完成了定制的臨時ECS實現,我建議你只使用一些流行的第三方ECS庫(EnTT、Flecs等),因為這些都是經過行業多年開發和測試的專業的游戲開發庫,它們可能比我們自己從零開始編寫的要好得多。
總之,一個專業的ECS很難僅憑個人力量從零開始實現。選擇一個經過良好測試的第三方ECS庫,并將其添加到游戲引擎代碼中即可完成你的游戲作品。
6 . 渲染
游戲引擎的復雜性正在慢慢提升。前文已討論了在內存中存儲和訪問游戲對象的方法,接下來我們需要討論如何在屏幕上渲染對象的問題。
第一步是考慮用引擎創建的游戲的性質。我們創建的游戲引擎是否只用來開發2D游戲?如果是這樣,我們需要考慮渲染精靈、紋理、管理層,并可能利用圖形卡加速。2D游戲通常比3D游戲簡單,因為2D數學比3D數學要簡單得多。
如果目標是開發2D引擎,則可以使用SDL幫助進行多平臺渲染。SDL抽象了加速的GPU硬件,可以解碼和顯示PNG圖像,繪制精靈,并在我們的游戲窗口中渲染紋理。
如果目標是開發一個3D引擎,那么則需要定義將一些額外的3D信息(頂點、紋理、著色器等)發送到GPU的方式。如果你想使用對圖形硬件軟件抽象,最流行的選擇方案就是OpenGL、Direct3D、Vulkan和Metal。當然,使用哪種API的決定可能取決于自身的目標平臺。例如,Direct3D會為微軟平臺的應用程序提供支持,而Metal則只適合與蘋果的產品配合使用。
3D應用程序通過圖形管道處理3D數據。該管道將規定引擎必須如何向GPU發送圖形信息(頂點、紋理坐標、法線等)。圖形API和管道還將規定我們應該如何編寫可編程著色器來變換和修改3D場景的頂點和像素。
可編程著色器規定GPU應如何處理和顯示3D對象
每個頂點和每個像素(片段)可以有不同的腳本,它們分別用于控制反射、平滑度、顏色、透明度等。
至于3D對象和頂點,最好將讀取和解碼不同網格格式的任務委托給一些第三方庫來實現。大多數第三方3D引擎都應該了解許多流行的3D模型格式,例如OBJ、Collada、FBX和DAE等一些文件格式。我的建議是首選.OBJ文件格式,因為有不少測試和支持力度良好的庫可以用C 處理OBJ加載。這方面,TinyOBJLoader和AssImp就是許多游戲引擎使用的上佳選擇。
7 . 物理引擎
當我們向引擎中添加實體時,我們可能還希望它們在場景中移動、旋轉和反彈。
游戲引擎的這個子系統稱為物理模擬。這可以手動創建,也可以從現有的現成的物理引擎導入。
在這里,我們還需要考慮想要模擬的物理類型。2D物理通常比3D簡單,但物理模擬的底層部分對2D和3D引擎都非常相似。
如果你只想在項目中包含一個物理庫,那么已有幾個很好的物理引擎可供選擇。對于2D物理引擎,我建議調研一下Box2D和Chipmunk2D這兩款產品。對于專業且穩定的三維物理模擬引擎,品牌相當不錯的包括PhysX和Bullet之類的庫。如果物理穩定性和開發速度對項目至關重要,那么使用第三方物理引擎總是一個不錯的選擇。
BOX2D是一個非常受歡迎的物理庫選項,可以與游戲引擎一起使用
你不需要編寫一個完美的物理模擬,但要確保物體能夠正確加速,并且不同類型的力可以應用到你的游戲物體上。一旦實現基本的物體移動效果,接下來你也可以繼續考慮實現一些簡單的碰撞檢測和碰撞解析。
對于2D剛體物理可參考Box2D源代碼和來自Erin Catto的介紹。如果想尋找一門關于游戲物理的綜合課程可參看《從零開始編寫2D游戲物理》)。
如果想學習3D物理以及物理模擬實現,可參閱大衛·埃伯里(David Eberly)編寫的圖書《游戲物理》(Game Physics)。
8 . 用戶界面設計
一提到Unity或Unreal等現代游戲引擎,我們會想到復雜的用戶界面,其中包含許多面板、滑塊、拖放選項和其他漂亮的UI元素,可以幫助用戶自定義游戲場景。UI允許開發者添加和刪除實體,動態更改組件值,并輕松修改游戲變量。
為了明確起見,我們討論的是用于開發工具的游戲引擎UI,而不是我們向游戲用戶顯示的用戶界面(如對話框屏幕和菜單)。
游戲引擎不一定需要嵌入編輯器,但由于游戲引擎通常用于提高生產力,友好的用戶界面將幫助你和團隊快速自定義游戲場景的關卡等其他方面。
對于初學者來說,從頭開始開發UI框架可能是游戲引擎制作中最煩人的任務之一。你必須創建按鈕、面板、對話框、滑塊、單選按鈕、管理顏色,還需要正確處理UI的事件并始終保持其狀態。向引擎中添加UI工具會增加應用程序的復雜性,并給源代碼管理帶來大量麻煩。
如果你的目標是為引擎創建UI工具,那么我建議使用現有的第三方UI庫,熱門UI備選工具有Dear ImGui、Qt和Nuklear等。
Imgui是一個強大的UI庫,被許多游戲引擎用作編輯工具
Dear ImGui是極佳的選擇之一,它允許我們為引擎工具快速設置用戶界面。ImGui項目使用了一種稱為“即時模式UI”的設計模式,由于它通過利用加速的GPU渲染與3D應用程序進行良好的通信從而被廣泛用于游戲引擎。
總之,如果你想在游戲引擎中添加UI工具,建議使用Dear ImGui。
9 . 腳本開發
隨著我們游戲引擎的不斷發展,一個常見的選擇是使用簡單的腳本語言實現游戲關卡定制。
想法很簡單:我們在原生C 應用程序中嵌入了一種腳本語言,非專業程序員可以使用這種更簡單的腳本語言編寫實體行為、AI邏輯、動畫和游戲的其他重要方面的腳本。
一些流行的游戲腳本語言有Lua、Wren、C#、Python和JavaScript等。所有這些語言的運行級別都比我們的原生C 代碼高得多。無論誰使用腳本語言編寫游戲行為腳本,都不需要擔心內存管理或核心引擎如何工作的其他低級細節。他們要做的就是編寫游戲中對應關卡的腳本,而我們的引擎知道如何解釋腳本并在幕后執行艱難的任務。
Lua是一種快速、小型的腳本語言,可輕松與C/C 項目集成
我最喜歡的腳本語言是Lua。Lua體積小、速度快,非常容易與C和C 本機代碼集成。此外,如果我使用Lua和“現代”C ,我喜歡使用一個名為Sol的包裝庫(https://github.com/ThePhD/sol2)。Sol庫可幫助人們快速熟悉和使用Lua,并提供了許多輔助函數來改進傳統的Lua C-API。
如果我們開發的游戲引擎中支持腳本編程的話,那么接下來可以開始在游戲引擎中討論一些更高級的話題。腳本編程能夠幫助定義人工智能邏輯、自定義動畫幀和運動,以及其他不需要通過原生C 代碼控制,而是可以通過外部腳本輕松管理的游戲行為。
10 . 音頻
接下來,還有一個需要為游戲引擎添加的支持元素是音頻。
如果想要讀寫音頻數據并發出聲音,我們需要通過操作系統訪問音頻設備。再次聲明,由于人們通常不想編寫特定于操作系統的代碼,我建議使用一個多平臺庫來抽象音頻硬件訪問。
SDL等多平臺庫就具有擴展功能,可幫助引擎處理音樂和音效等內容。
但是,我強烈建議只有在確定引擎的其他部分都已經能夠正常協同工作之后,再考慮處理音頻的問題。控制聲音文件發音可能很容易實現,但如果我們過早地開始處理音頻同步問題,即把音頻與動畫、事件和其他游戲元素聯系起來共同考慮,事情往往會變得一團糟。
如果你真正是自己手工編寫代碼,那么由于多線程管理的復雜性,可能會導致音頻處理起來變得很棘手。不過,如果你的目標是編寫一個簡單的游戲引擎,那么我可能更會借助一個專門的庫來處理這一部分功能。
例如,你可以考慮將SDL_Mixer、SoLoud和FMOD等優秀的音頻庫和工具集成到自己開發的游戲引擎中。
《微型戰場》(Tiny Combat Arena)
這款游戲就使用FMOD聲音庫來實現多普勒和壓縮等音頻效果
11 . 人工智能
最后一個子系統是人工智能。我們可以通過腳本來實現人工智能。這意味著,我們可以將人工智能邏輯委托給關卡設計師來編寫腳本。另一個選擇是,在我們的游戲引擎內核的本機代碼中嵌入適當的人工智能系統。
在游戲中,人工智能用于對游戲對象產生響應性、適應性或類似智能的行為。大多數人工智能邏輯被添加到非玩家角色(NPC、敵人)中,以模擬類似人類的智能。
敵人是AI在游戲中應用的一個流行的例子。當敵人追逐地圖上的物體時,游戲引擎可以通過路徑搜索算法或有趣的模仿人類的行為來創建抽象效果。
伊恩·米林頓(Ian Millington)的《游戲人工智能》是一本關于游戲人工智能理論和實現技術的綜合性書籍,值得參考。
五、不要貪多求快
在游戲引擎開發工作中,最困難的部分之一是大多數開發者都不會設定明確的界限,即有一種走不到“終點線”的感覺。換句話說,程序員會啟動一個游戲引擎項目,渲染對象,添加實體,添加組件,但到最后突然發現一切都很糟糕。因此,如果他們不定義某種邊界,就很容易不斷添加越來越多的功能,而忽略了全局。如果這種情況發生,游戲引擎很有可能永遠看不到曙光。
除了缺乏邊界,當看到代碼以閃電般的速度在眼前增長時,我們自己反倒很容易被淹沒。游戲引擎項目的復雜性可能會迅速擴大,幾周內你的C 項目可能會有幾個依賴項,需要復雜的構建系統,而隨著更多功能添加到引擎中,代碼的整體可讀性會不斷下降。
因此,我的首要建議是,在編寫實際游戲時,要始終堅持編寫自己的游戲引擎。開始并完成游戲的第一次迭代時,腦海中要有一個真實的游戲。這將幫助你設定限制,并為你需要完成的工作指出一條清晰的路徑。盡最大的努力堅持下去,而不是反復改變需求。
六、穩扎穩打,專注基礎
大多數學生在項目開始時都感到興奮,但是隨著時間的推移就開始出現焦慮情緒。如果我們從頭開始創建一個游戲引擎,尤其是在使用像C 這樣的復雜語言時,很容易不知所措失去動力。
因此,要學會及時享受某些階段性的小勝利。例如,學會如何成功地在屏幕上顯示PNG紋理,成功地發現了兩個物體之間的碰撞等等。專注并理解基礎知識一直都是非常重要的事情。
對于熱愛編程的朋友來說,路再難走也要堅持走下去!如果你想更好的提升你的編程核心能力(內功)不妨從現在開始!
編程學習書籍分享:
編程學習視頻分享:
整理分享(多年學習的源碼、項目實戰視頻、項目筆記,基礎入門教程)
歡迎轉行和學習編程的伙伴,利用更多的資料學習成長比自己琢磨更快哦!
對于C/C 感興趣可以關注小編在后臺私信我:【編程交流】一起來學習哦!可以領取一些C/C 的項目學習視頻資料哦!已經設置好了關鍵詞自動回復,自動領取就好了!
版權聲明:本文內容由互聯網用戶自發貢獻,該文觀點僅代表作者本人。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如發現本站有涉嫌抄襲侵權/違法違規的內容, 請發送郵件至 舉報,一經查實,本站將立刻刪除。