從零開(kāi)始學(xué)游戲編程
開(kāi)發(fā)游戲可能是學(xué)習(xí)編程的理由中最吸引人的一條了。但如何從零開(kāi)始入門(mén),達(dá)到能夠開(kāi)發(fā)游戲的編程水平,是困擾無(wú)數(shù)勇敢少年們的傳統(tǒng)難題。作為一名游戲設(shè)計(jì)師,我沒(méi)有系統(tǒng)地學(xué)習(xí)過(guò)編程。從5年前開(kāi)始,我有了自己從頭完整開(kāi)發(fā)游戲的念頭,于是斷斷續(xù)續(xù)地看了很多書(shū),試過(guò)了很多入門(mén)方法和開(kāi)發(fā)環(huán)境,但直到近半年才找到正確的門(mén)路,F(xiàn)在我在Unity開(kāi)發(fā)環(huán)境下獨(dú)立制作游戲原型和利用成型的框架完善游戲功能已不成問(wèn)題。
本文會(huì)介紹如何從零開(kāi)始學(xué)習(xí)游戲開(kāi)發(fā)編程的方法,希望能為和我一樣掙扎在編程大門(mén)之外的游戲開(kāi)發(fā)愛(ài)好者們提供幫助。不過(guò)事先要說(shuō)明的是,這種學(xué)習(xí)思路是為了幫助你在做游戲的過(guò)程中逐漸學(xué)習(xí)編寫(xiě)程序,不適用于其他領(lǐng)域,但作為一種入門(mén)方法,它能讓你在半年到一年的學(xué)習(xí)之后,做到獨(dú)立制做小游戲(或原型)。
門(mén)外漢學(xué)編程的難點(diǎn)
介紹學(xué)習(xí)方法之前,我們先看看門(mén)外漢學(xué)編程最常遇到的問(wèn)題。
第一,程序員們經(jīng)常說(shuō)程序語(yǔ)言只是編程工具,但市面上常見(jiàn)的教程都喜歡從語(yǔ)法、算法和程序語(yǔ)言的使用思想開(kāi)始教學(xué),而不是把編程語(yǔ)言當(dāng)做解決實(shí)際問(wèn)題的工具來(lái)入手。因此,初學(xué)者經(jīng)常耗費(fèi)很大精力才能理解書(shū)上寫(xiě)的算法和思想,卻完全不知道理解之后能用來(lái)做什么。
第二,很多編程教程雖然配有實(shí)例,但一方面例子的學(xué)習(xí)難度曲線增加得很快,剛看完一個(gè)“Hello World”實(shí)例,下一個(gè)例子可能就變成教你如何分配內(nèi)存(真實(shí)的故事,我的一本學(xué)習(xí)Objective-C的教程就是這樣的)。另一方面初學(xué)者在對(duì)開(kāi)發(fā)流程不熟悉的情況下,很難做到舉一反三,從一個(gè)實(shí)例里總結(jié)出做另外三個(gè)游戲的方法,我經(jīng)常遇見(jiàn)看了三個(gè)不同類(lèi)型的游戲?qū)嵗,放下?shū)后卻連一個(gè)游戲都做不出來(lái)的情況。
第三,很多編程教程為了提高普適性,在使用現(xiàn)成架構(gòu)方面都很保守,導(dǎo)致了很多重復(fù)造輪子的教程出現(xiàn)。例如在前幾年Cocos2D(一個(gè)用于iOS平臺(tái)游戲開(kāi)發(fā)的游戲引擎)還沒(méi)有現(xiàn)在這么火時(shí),幾乎所有的iOS游戲開(kāi)發(fā)教程講的都是如何使用OpenGLES來(lái)制作游戲圖像,而這些底層架構(gòu)的實(shí)現(xiàn)對(duì)初學(xué)者來(lái)說(shuō)是根本不可能完成的任務(wù)。
因此,適合初學(xué)者的學(xué)習(xí)方針是:從實(shí)際需求出發(fā);“怎么做”優(yōu)于“為什么”(為什么可以在入門(mén)之后再慢慢理解);使用允許你偷懶的工具或架構(gòu)(需要做的越少越好)。這些要求其實(shí)很容易滿足,答案恰恰在看起來(lái)和編程關(guān)系不大的領(lǐng)域——可視化編程工具里(Visual Programming Tools)。
可視化編程游戲引擎讓你先做再想
可視化編程泛指一切使用可視化元素的操作代替文本輸入的程序設(shè)計(jì)方式,大體上就是像畫(huà)流程圖一樣通過(guò)連接若干“盒子”和“箭頭”來(lái)實(shí)現(xiàn)程序邏輯。這個(gè)概念在游戲開(kāi)發(fā)工具上的應(yīng)用越來(lái)越流行,近年來(lái)還有井噴趨勢(shì),從老牌的GameMaker、RPGMaker、TorqueGameBuilder、到新興的GameSalad、Construct 2和Unity都是其中的代表。盡管這些工具和引擎各有不同的開(kāi)發(fā)方式,但它們都能讓初學(xué)者在完全不懂編程語(yǔ)法和復(fù)雜算法的情況下快速實(shí)現(xiàn)自己的游戲設(shè)計(jì)。
我之前的態(tài)度是寧可抱著“看也看不懂,看懂了也不會(huì)做”的書(shū)苦學(xué)XNA(一個(gè)微軟發(fā)布的使用C#的游戲開(kāi)發(fā)架構(gòu))和Cocoa(蘋(píng)果發(fā)布的使用Objective-C的應(yīng)用開(kāi)發(fā)架構(gòu)),也不屑于使用GameMaker、GameSalad之類(lèi)的圖形界面開(kāi)發(fā)工具。認(rèn)為這些工具屬于“業(yè)余型”,就算能做出游戲來(lái)也是旁門(mén)左道,不能修煉內(nèi)功。
直到有一次參加了柏林獨(dú)立游戲BIG Jam的活動(dòng),接觸了很多非常優(yōu)秀的游戲開(kāi)發(fā)者。他們大部分人都把GameMaker和Flash這些簡(jiǎn)單的工具當(dāng)做制作獨(dú)立游戲的最佳選擇。原因是他們多年以前開(kāi)始學(xué)習(xí)游戲開(kāi)發(fā)時(shí)使用的就是這些工具,常年的使用經(jīng)驗(yàn)讓他們能在最短的時(shí)間里用這些工具實(shí)現(xiàn)想法。而使用這些工具從頭到尾制作了大量游戲的經(jīng)歷,也在他們以后學(xué)習(xí)用編程語(yǔ)言開(kāi)發(fā)游戲時(shí)打下了很好的基礎(chǔ)。
從那之后,為了快速開(kāi)發(fā)原型,我開(kāi)始物色入門(mén)級(jí)的可視化編程游戲引擎。HTML5游戲引擎Construct 2偶然進(jìn)入了我的視線;ㄊ畮追昼妼W(xué)習(xí)教程實(shí)例之后,我很快用幾個(gè)小時(shí)做出了一個(gè)一直在構(gòu)思的游戲想法(當(dāng)然想法本身就很簡(jiǎn)單,而且制作過(guò)程中碰到實(shí)現(xiàn)困難的設(shè)計(jì)都進(jìn)行了進(jìn)一步簡(jiǎn)化)。說(shuō)來(lái)慚愧,盡管在主機(jī)游戲業(yè)從業(yè)多年,這次使用Construct 2的開(kāi)發(fā)過(guò)程中我第一次感覺(jué)到對(duì)游戲開(kāi)發(fā)的整個(gè)過(guò)程和架構(gòu)有了初步認(rèn)識(shí)。
首先,可視化編程工具里一般都有一個(gè)現(xiàn)成的游戲場(chǎng)景(任何游戲開(kāi)發(fā)過(guò)程中都需要一個(gè)畫(huà)布或一個(gè)攝像機(jī)來(lái)描述玩家可以看到的圖像范圍),然后你需要把游戲中需要的各個(gè)元素(一般稱(chēng)為Actor,例如主角、敵人、子彈等,這就是編程語(yǔ)言里對(duì)象的概念)放進(jìn)場(chǎng)景里,然后通過(guò)關(guān)聯(lián)邏輯模塊來(lái)讓它們快速互動(dòng)起來(lái)。Construct 2的邏輯模塊使用了非常貼近編程語(yǔ)言的按行號(hào)從上到下的執(zhí)行順序。而且你將從教程中學(xué)習(xí)到,原來(lái)游戲開(kāi)始運(yùn)行后每一幀都會(huì)按順序執(zhí)行一遍所有的邏輯,這就是游戲開(kāi)發(fā)的基本框架中最常說(shuō)的主游戲循環(huán)(Main Game Loop)。
除此之外,用戶使用邏輯模塊時(shí)不用擔(dān)心語(yǔ)法錯(cuò)誤和算法的設(shè)計(jì),一般這類(lèi)引擎里都會(huì)提供大量現(xiàn)成的算法模塊可供挑選。只要專(zhuān)注于設(shè)計(jì)游戲邏輯,其他事情可以說(shuō)都是軟件自動(dòng)幫你完成。在觀看教程和其他范例項(xiàng)目時(shí)也一目了然,學(xué)習(xí)別人的設(shè)計(jì)思想更加容易。
通過(guò)使用Construct 2獨(dú)立完成了第一個(gè)游戲原型后,我學(xué)到了相似的游戲元素可以共享一部分屬性(編程語(yǔ)言里使用類(lèi)和繼承的概念);學(xué)到了所有活動(dòng)的游戲元素都需要在每一幀的循環(huán)里進(jìn)行驅(qū)動(dòng),每幀只運(yùn)動(dòng)一小段距離;還學(xué)到了應(yīng)該在主游戲循環(huán)的什么位置判斷是否Game Over,以及Game Over時(shí)進(jìn)入另一個(gè)循環(huán)來(lái)等待玩家重新開(kāi)始游戲等內(nèi)容。
這段經(jīng)歷讓我認(rèn)識(shí)到有能力從頭到尾制作游戲(或者原型)對(duì)于游戲開(kāi)發(fā)的理解有多么重要。但有一個(gè)問(wèn)題出現(xiàn)了—如果可視化工具那么好用,那為什么還要繼續(xù)學(xué)習(xí)編程呢?我當(dāng)時(shí)也光顧著高興了,并沒(méi)有從可視化編程工具轉(zhuǎn)到真正編寫(xiě)代碼的計(jì)劃,直到……
由需求出發(fā)向編寫(xiě)代碼的轉(zhuǎn)型
直到我打算做個(gè)稍大一點(diǎn)的戰(zhàn)略游戲項(xiàng)目,才開(kāi)始在各種游戲開(kāi)發(fā)工具中碰壁。接連嘗試了Construct 2、GameMaker、Stencyl,可不管哪一個(gè)工具都無(wú)法很容易地提供我所需要的數(shù)據(jù)結(jié)構(gòu)。重新審視了需求的增加和工具的局限性之后,我才決定開(kāi)始學(xué)習(xí)Unity下的C#編程。在請(qǐng)教了團(tuán)隊(duì)里的程序員和有針對(duì)性地學(xué)習(xí)了一部分?jǐn)?shù)據(jù)結(jié)構(gòu)知識(shí)后,我終于在Unity中搭建出了設(shè)計(jì)需要的基本游戲結(jié)構(gòu)。并在之后開(kāi)始正式學(xué)習(xí)Unity的C#腳本,一步步地掌握了C#里類(lèi)的繼承、列表和字典的使用與委托等難以讀懂,學(xué)了也不知道怎么用的概念。
剛開(kāi)始在Unity開(kāi)發(fā)環(huán)境里獨(dú)立制作游戲原型時(shí),我也感覺(jué)從零開(kāi)始獨(dú)立完成所有的代碼非常和困難。但幸運(yùn)的是,Unity引擎有個(gè)特點(diǎn),就是有一個(gè)內(nèi)容非常豐富的插件市場(chǎng),其中最流行的插件類(lèi)型之一就是可視化編程插件。這些插件(PlayMaker、uScript、Antares Universe等)將Unity游戲開(kāi)發(fā)的常用功能打包成函數(shù)塊,并按需求類(lèi)別歸納成組,只要花一點(diǎn)時(shí)間閱讀手冊(cè)就相當(dāng)于掌握了Unity里大部分的常用函數(shù)功能。之后用戶通過(guò)連接不同函數(shù)塊的輸入輸出接口來(lái)實(shí)現(xiàn)完整的游戲邏輯。
當(dāng)時(shí)我為了開(kāi)發(fā)一個(gè)動(dòng)畫(huà)狀態(tài)很多的動(dòng)作游戲原型,購(gòu)買(mǎi)了PlayMaker插件,并且使用這個(gè)插件強(qiáng)大的狀態(tài)和動(dòng)畫(huà)控制功能第一次學(xué)習(xí)了有限狀態(tài)機(jī)的制作和使用。之后又經(jīng)身邊的程序員指點(diǎn)了解到有限狀態(tài)機(jī)在游戲開(kāi)發(fā)中的運(yùn)用非常廣泛,不光是控制動(dòng)畫(huà),還可以用來(lái)控制菜單和不同條件下需要不同處理方式的很多游戲邏輯。
就像之前的Construct 2一樣,我也只在一個(gè)項(xiàng)目中使用了PlayMaker的狀態(tài)機(jī)。在了解了有限狀態(tài)機(jī)的基本工作方式后,我在之后的項(xiàng)目中都使用了團(tuán)隊(duì)里的程序員開(kāi)發(fā)的純代碼的有限狀態(tài)機(jī)系統(tǒng)(開(kāi)源的exUnity,還包括其他Unity下的游戲開(kāi)發(fā)實(shí)用架構(gòu)),完成了從可視化編程到代碼編程的轉(zhuǎn)型。
這就是Unity下的可視化編程插件很適合用來(lái)學(xué)習(xí)編程的原因:和其他較為簡(jiǎn)單的工具的區(qū)別在于,Unity使用JavaScript和C#作為腳本語(yǔ)言,這個(gè)環(huán)境下的可視化編程插件只是把C#函數(shù)和腳本打包成了可視化的邏輯塊,并沒(méi)有改變其設(shè)計(jì)思路。
對(duì)于初學(xué)者來(lái)說(shuō),用可視化插件組裝起來(lái)的游戲邏輯和用C#手動(dòng)編寫(xiě)的游戲程序幾乎是一一對(duì)應(yīng)的,有時(shí)甚至能精確到函數(shù)段落(例如Antares Universe里的函數(shù)塊就和Unity的全部函數(shù)功能一一對(duì)應(yīng))。在已熟悉整個(gè)設(shè)計(jì)流程的情況下,只需查閱Unity官方的腳本參考手冊(cè),就能完成從可視化編程到文本編程的翻譯。我經(jīng)過(guò)可視化工具的啟發(fā),很快就發(fā)現(xiàn)插件有些臃腫和煩瑣,也無(wú)法實(shí)現(xiàn)一些需求實(shí)現(xiàn)。在接下來(lái)的兩個(gè)原型中就越來(lái)越多地開(kāi)始手動(dòng)編寫(xiě)代碼,對(duì)工具的依賴(lài)越來(lái)越小,直到完全拋棄。
現(xiàn)在可以回答前面提出的“為什么有了不用編程就能開(kāi)發(fā)游戲的工具,還要學(xué)習(xí)編程”的問(wèn)題了。如果你的所有設(shè)計(jì)需求都可以被可視化游戲開(kāi)發(fā)工具完成,那么確實(shí)不需要進(jìn)一步學(xué)習(xí)編程。但如果有的需求無(wú)論如何都不能用其他工具完成,那么自己寫(xiě)代碼來(lái)實(shí)現(xiàn)就是唯一的出路,這時(shí)你有強(qiáng)烈的需求和目標(biāo),就可以通過(guò)詢問(wèn)或搜索“怎么做”來(lái)學(xué)習(xí)編程并滿足需求。我的程序員好友經(jīng)常說(shuō):“能否學(xué)會(huì)編程其實(shí)只取決于你的需求是否強(qiáng)烈,不得其門(mén)而入、或半途而廢的都是需求不夠明確或不夠強(qiáng)烈的人。”
可視化編程工具對(duì)于游戲開(kāi)發(fā)者來(lái)說(shuō)就是一個(gè)篩選需求的過(guò)程:在硬啃編程書(shū)籍時(shí),感覺(jué)自己有100個(gè)需求,但都不知道從哪開(kāi)始學(xué)習(xí)、如何去實(shí)現(xiàn);使用可視化工具,可以輕松實(shí)現(xiàn)90個(gè)需求,剩下10個(gè)就被放大并明確化了。接下來(lái)依靠上網(wǎng)學(xué)習(xí)或向他人請(qǐng)教,終究也能自己實(shí)現(xiàn)(個(gè)別超出能力的需求不要強(qiáng)求,請(qǐng)別人做或者放棄都比鉆牛角尖要好)。
可視化編程工具能夠培養(yǎng)我們由淺入深的思考習(xí)慣。先盡可能地用簡(jiǎn)單的邏輯去實(shí)現(xiàn)設(shè)計(jì),如果用“盒子”和“箭頭”無(wú)法完成,那么你在尋求代碼上的解決方案時(shí),就回答了“為什么要用這樣的程序設(shè)計(jì)思想”的問(wèn)題。經(jīng)歷了這個(gè)過(guò)程,你對(duì)“為什么”的理解會(huì)比一開(kāi)始就去看專(zhuān)門(mén)講解“為什么”的大部頭程序書(shū)籍深刻許多。而通過(guò)實(shí)踐理解了需求和程序設(shè)計(jì)之間的關(guān)系后,再去系統(tǒng)地閱讀程序設(shè)計(jì)教程效果會(huì)好得多。
可視化編程雖然依賴(lài)于工具,但也能幫助你時(shí)刻把“程序語(yǔ)言即工具”的概念裝在腦袋里。之后無(wú)論換什么引擎,用哪種語(yǔ)言,首先應(yīng)該問(wèn)自己:“這個(gè)工具能幫我做什么?我要怎樣做才能實(shí)現(xiàn)需求?”另外,程序設(shè)計(jì)和畫(huà)流程圖之間的距離沒(méi)有想象中那么大,通過(guò)反復(fù)用可視化編程工具畫(huà)“流程圖”的過(guò)程,能夠從實(shí)踐中學(xué)習(xí)各種游戲設(shè)計(jì)的實(shí)現(xiàn)方法,當(dāng)你能準(zhǔn)確地畫(huà)出邏輯完美的流程圖時(shí),離你寫(xiě)出同樣邏輯完美的程序距離已不遠(yuǎn)了。更重要的是,在這個(gè)過(guò)程中你實(shí)現(xiàn)了自己的想法,創(chuàng)造出了和書(shū)上的例程完全不同的東西,對(duì)于增強(qiáng)信心和進(jìn)一步明確自己的學(xué)習(xí)需求的作用都是巨大的。
想學(xué)寫(xiě)程序,就要做程序員的朋友
最后講下如何從身邊的程序員那里獲得幫助。初學(xué)者想要學(xué)寫(xiě)代碼,有個(gè)程序員朋友能讓你獲益良多。當(dāng)你遇到難題時(shí),請(qǐng)把詢問(wèn)的重點(diǎn)集中在需求思路和關(guān)鍵字上,而不是一味求代碼。高手提供了思路以后自己實(shí)現(xiàn),或通過(guò)關(guān)鍵字自己尋求解決方案,都更有助于水平的提高。
從可視化編程到代碼的轉(zhuǎn)化中,也可以嘗試使用程序員寫(xiě)的功能庫(kù)或常用的架構(gòu)。前文中提到不要重復(fù)造輪子,當(dāng)拋棄可視化編程工具時(shí),就要用現(xiàn)成的功能庫(kù)來(lái)代替。在選用功能庫(kù)時(shí),自己信任的程序員推薦的東西總會(huì)是一個(gè)非常不錯(cuò)的選擇,他能告訴你一個(gè)庫(kù)的優(yōu)缺點(diǎn)并且在使用過(guò)程中提供技術(shù)支持。
我在學(xué)寫(xiě)代碼的過(guò)程中,先是自己用最簡(jiǎn)單的方式實(shí)現(xiàn)功能,然后一邊不斷閱讀和學(xué)習(xí)同個(gè)獨(dú)立開(kāi)發(fā)團(tuán)隊(duì)里程序員的項(xiàng)目結(jié)構(gòu)和代碼,再使用程序員設(shè)計(jì)或慣用的架構(gòu)來(lái)組織自己的代碼,這樣既能最快地完成工作,又能逐漸養(yǎng)成較好的編程習(xí)慣和深入理解程序設(shè)計(jì)思想。
本文由站河南北大青鳥(niǎo)校區(qū)整編而成,如需了解更多IT資訊類(lèi)的文章、新聞、課程和學(xué)習(xí)技巧、就業(yè)案例、招生詳情等問(wèn)題,可以對(duì)在線咨詢老師進(jìn)行一對(duì)一問(wèn)答!
推薦資訊
- 鄭州的網(wǎng)絡(luò)工程師培訓(xùn)... 2013-08-05
- 致鄭州北大青鳥(niǎo)百度貼吧吧友的一... 2015-08-18
- 孩子成績(jī)不好怎么辦?學(xué)個(gè)什么技... 2022-02-08
- 鄭州學(xué)編程哪個(gè)學(xué)校好?... 2020-01-08
- 計(jì)算機(jī)培訓(xùn)從零開(kāi)始,打造高薪人... 2012-11-24
熱點(diǎn)資訊
- 在內(nèi)卷和AI之下計(jì)算機(jī)專(zhuān)業(yè)是不是... 2024-05-10
- 選擇IT行業(yè)的理由是什么呢?什么... 2022-07-16
- 初中畢業(yè)生們?yōu)槭裁赐扑]你選擇職... 2022-05-18
- 上班996,生病ICU,不加班的程序... 2019-04-16
- 鄭州北大青鳥(niǎo)培訓(xùn)機(jī)構(gòu)6種方法帶你... 2019-04-02