「學」的部分
只要你能扎紮實實地把上一節的內容學會了,你現在就比很多大學計算機本科專業的大一學生要強了,因為他們可能不怎麼懂Windows編程,而你已經抄了好幾遍代碼了。雖然這種學習方法有點「簡單粗暴」,但是,複雜的內容往往就需要這樣的方法。而且,這個課程是為了激發小孩子的興趣,你不學紮實一點,如何引導小孩?
有了框架之後,我們就可以把遊戲內容寫在窗口之中了。那麼,接下來,我們要直接開始寫遊戲核心內容嗎?
我想,你的答案和我一樣:不是的。因為我們要寫一個3D的小遊戲示例,即便這個示例再簡單,也包含了巨量的知識點,在你不了解這些知識點之前,你面對3D遊戲的核心代碼就和看天書差不多。所以,在開始寫這個3D遊戲示例之前,我們需要用好幾節課的篇幅把這些必須要知道的知識點講清楚了。
這一節作為重要知識點的入門,我設置的比較簡單,只需要懂得一點:為什麼要用DirectX來寫遊戲?
我們慢慢來說。
3D遊戲和2D遊戲有著本質的區別。2D遊戲其實可以看成是一個可以操控的動畫而已,程式設計師只需要按照一定的規律把一些二維的圖片顯示在屏幕上就可以了,而計算機屏幕本就是二維的,是一個一個的像素矩陣,顯示起來其實是很簡單的一件事情,根本就不需要消耗太多的CPU資源。所以,90年代的電腦基本上沒有獨立顯卡,都是集成在主板上的集成顯卡,因為顯示一個二維圖像的任務實在是太輕鬆了。
而3D遊戲呢?問題一下子就複雜起來了。我們的屏幕是二維的,要在一個二維的屏幕上表現出一個三維的東西,真的不是一件容易的事情。就拿最簡單的立方體來講,要讓玩家覺得這個是立方體而不是多邊形,最簡單的方法,是讓玩家可以操控這個立方體。比如玩家可以操控這個立方體朝著各個方向移動,或者可以讓這個立方形任意旋轉等等。
要解決這個問題,乍一看真的沒有什麼頭緒。實際上,曾經的程式設計師剛開始探索3D遊戲的時候,也是沒有頭緒的。但是,程式設計師都比較聰明,會從生活中的方方面面來汲取經驗。
程式設計師前輩們發現,電影和3D遊戲很像,因為電影也是在一個二維的平面(電影布)上展示著三維的世界,而且,觀眾們並不會覺得這是二維的。既然有現成的成功案例,為什麼不借鑑呢?
程式設計師仔細研究了放電影的步驟,就是用一個投影儀把一張一張的膠片投影到電影布上,然後因為視覺暫留的關係,我們就能看到一個「動起來」的畫面了。
把這個過程分解得再細一些:
1.首先我們需要膠片;
2.然後有一臺能投影的儀器;
3.保證1秒鐘能投影24張膠片。
我們類比到電腦遊戲中,程式設計師驚奇地發現,第2和第3點已經不是什麼問題了,因為2D遊戲就是把二維的圖片繪製到計算機屏幕上,也就是說,「投影儀」和24幀不是什麼問題。那麼,程式設計師唯一要解決的,就是這些「膠片」了。
再深入研究一下,這些膠片是怎麼來的呢?
答案很明顯:是通過攝像機拍攝現實的場景得來的。
既然是拍攝來的,那麼,計算機遊戲中,能不能也用拍攝的方法呢?於是乎,程式設計師就寫出了一個比較可行的解決方案:
1.在計算機中創建一個虛擬的3D世界,並把所有需要的東西放進去;
2.用一個虛擬的攝像機,在這個虛擬的3D世界中拍攝並得到一張張的膠片。
在大量程式設計師們的努力下,這個過程被分解成了很多細小的問題,然後逐一都攻破了。雖然3D顯示的問題被解決了,可程式設計師們發現了另一個非常頭疼的問題:計算機完全無法承受這種級別的計算量,真的寫出遊戲的話,計算機根本就帶不動!
創建虛擬3D世界,並用虛擬攝像機拍攝,牽扯到了非常非常多複雜的數學計算,當時的CPU很難快速計算這麼多數據。而且,必須保證1秒鐘可以顯示24張「膠片」,可是,當時都是集成顯卡,面對這個問題是有點吃力的。
所以,在發展了幾年後,獨立顯卡就出來了。為什麼是獨立顯卡呢?因為,這種顯卡有著一部分CPU的功能,可以減輕CPU的負荷。為了功能獨立化,顯卡中的CPU被叫做GPU,這個GPU的性能可能比CPU要好,並且,GPU只計算3D顯示中的那些複雜的、巨量的數學計算。
我們現在能玩到很多非常逼真的3A遊戲,高性能的獨立顯卡功不可沒。舉個簡單的例子,作為家長,你應該知道CS這個遊戲吧?CS是比較老的遊戲了,這個遊戲對電腦性能的要求不是特別高,一般的顯卡就能帶動了。而現在的電腦基本上都是i7、i9的處理器,還有一塊比較不錯的顯卡,運行這個CS是一點兒問題都沒有的。好了,現在假設你拆掉了電腦的顯卡,換上了一塊幾乎沒有計算能力的集成顯卡,那麼,CS遊戲中的所有複雜的數學計算就會一下子壓給CPU。i7處理器計算這些數學計算不是什麼大問題,但由於數量過於龐大,會嚴重影響遊戲的效率,最後顯示到屏幕上就會非常卡。所以,顯卡才是3D遊戲流暢運行的基本。
有了顯卡後,3D遊戲運行已經沒什麼問題了,現在的問題是,3D遊戲編寫過程中的那些數學計算太複雜了。怎麼說呢?一個程式設計師可能要學習好幾個月才能完全學明白這些複雜的數學計算,然後才能在程序代碼中正確地使用這些數學計算。
但是,程式設計師是出了名的懶,如此複雜的東西,而且還是有規律的複雜內容,為什麼不寫成工具呢?把這些數學計算的過程集合起來,寫成一個一個的函數,這樣程式設計師用起來方便,也不容易出錯。這就是DirectX之類「工具」的雛形了。
也就是說,DirectX就是幫我們處理3D遊戲中的那些非常複雜的數學計算的。當然,能處理這些數學問題的工具非常多,DirectX只是其中的一個,另一個非常出名的是OpenGL(優化可能比DirectX要好)。但是,我們為什麼不用OpenGL,而要去用DirectX呢?原因非常簡單——DirectX是微軟提供的。
我們的遊戲要在Windows平臺下運行,當然是用微軟提供的DirectX更好了。
其實,DirectX是微軟提供的一套遊戲開發工具,其中的東西非常多,包含了遊戲開發的方方面面,除了3D方面的內容外,還有圖像顯示、輸入輸出、聲音播放等等功能,非常全面。DirectX中「X」的意思就是代表很多的意思,專門處理3D方面內容的其實叫做Direct3D,處理聲音的是DirectSound,處理輸入的是DirectInput等等。
而OpenGL只是一個3D處理而已,像聲音、輸入等內容還需要額外去找工具,作為程式設計師,當然更喜歡DirectX了。
還有,我們使用的是Visual Studio來寫遊戲,這個也是微軟的,兩者的契合度是非常高的。
總結一下,寫遊戲要DirectX的支持,主要是要利用其中的3D數學計算功能,否則,我們幾乎寫不出效率很高的3D遊戲。
「習」的部分
我們已經安裝了Visual Studio了,這裡我們需要把DirectX安裝上。程式設計師開發用到的DirectX和玩家玩遊戲安裝的DirectX不太一樣,程式設計師的DirectX多了非常多的內容。安裝的步驟也麻煩一些:
1.在微軟官網或者是其他網站上下載一個DirectX SDK;
2.建議把DirectX SDK安裝到根目錄;
3.在Visual Studio中設置DirectX SDK的路徑,方法如下:打開Visual Studio菜單「工具」下面的「選項」,在彈出的對話框中找到「VC++目錄」的項目,分別在「包含文件」和「庫文件」下添加新目錄,指定DirectX SDK的include目錄和lib目錄。DirectX SDK安裝後是一個文件夾,裡面包含了很多目錄,include和lib就是其中的兩個。需要注意的是,lib中可能有x86和x64兩個子目錄,我們要選擇x86的目錄,因為我們寫的是32位的遊戲程序。
DirectX的版本挺多的,我們作為學習,只需要DirectX9.0就可以了,而且,我們的示例程序也是用DirectX 9來寫的。DirectX是一個向下兼容非常完美的工具,現在的電腦基本上都安裝了用戶版本的DirectX 11或者12,運行一個9版本的DirectX程序是完全沒有問題的。
你可能要問,為什麼不用DirectX10以上的版本來寫呢?答案就是——沒必要。9是一個非常成熟的版本,只要熟練掌握了9,你幾乎就能寫出任何類型的3D遊戲了(應該沒有多少人敢說熟練掌握的),而10往上的版本,幾乎是為了大型3A遊戲而開發的,其中有一些高級的功能。我們寫遊戲只是愛好,真的沒必要接觸這些太高級的內容。