6個(gè)月從“菜鳥”到“牛人” iOS游戲開發(fā)者成長(zhǎng)記
這是一個(gè)毫無編程經(jīng)驗(yàn)的“菜鳥”在成長(zhǎng)為 iOS 游戲開發(fā)者后,總結(jié)的成長(zhǎng)史。短短6個(gè)月間,他從 Python 入門,發(fā)展到給 Mac 開發(fā)小游戲,再到自學(xué) Objective-C 和 Cocos2d。除了你可能已經(jīng)讀過無數(shù)次的勵(lì)志元素,文中的書籍、網(wǎng)站推薦以及開發(fā)過程中的經(jīng)驗(yàn)教訓(xùn)總結(jié)很值得打算或剛剛進(jìn)入蘋果開發(fā)領(lǐng)域的新人一看。
我是菜鳥
幾乎剛好是6個(gè)月前,我決定開始從事一項(xiàng)新的職業(yè)。2010年10月之前,我從未接觸過編程。要說有,那也只是在6年級(jí)時(shí)學(xué)過了大概一周的非?;?本、基本、基本的編程知識(shí)。就這些。我不知會(huì)學(xué)成什么樣。2010年10月9日我在微博上寫道:“我究竟想干嗎?我決定學(xué)習(xí)編程,我沒有任何的基礎(chǔ)。唉, 兄弟們,我有些擔(dān)心。”這是一段生涯的開始,我很高興能走上這條路。我不會(huì)回頭。
開端
我將只快速簡(jiǎn)單的給你們講一下我前幾個(gè)月的學(xué)習(xí)過程,因?yàn)檫@段時(shí)間非常的枯燥。我從Invent with Python這本書開始,這是一本對(duì)新手來說非常不錯(cuò)的教程。為了讓你們知道它是如何的初級(jí),我向你們展示這本書里的一段話:
+ 這個(gè)符號(hào)是來告訴計(jì)算機(jī)把2和2相加。做減法用這個(gè)符號(hào) -,做乘法用星號(hào)(*)。
在我學(xué)會(huì)了一些非?;镜闹R(shí)后,我隨意的做了很多文本形式的小游戲,比如劊子手,jotto,猜數(shù)字。我的第一個(gè)比較大一點(diǎn)的小玩意叫做“大齒怪”。這個(gè)游戲的情景是關(guān)于一個(gè)大齒怪(就把它想成一個(gè)怪物吧),禍害村里。它藏在什么地方,你需要去猜它在哪:

也就是在此時(shí)我收到了我的第一張珍貴的粉絲畫的作品。我把這個(gè)游戲發(fā)布在了Reddit上,Michael Hussinger為它制作了這張令人驚嘆的封面畫:
接下來,我轉(zhuǎn)移到了我的第一個(gè)半圖形游戲:”掃雷“。在此時(shí)我才開始真正的理解構(gòu)造一個(gè)靈活的游戲引擎有多么的重要(沒錯(cuò),就像我開發(fā)的這個(gè)游戲引 擎)。這個(gè)游戲仍然是文本形式的,但已經(jīng)有相當(dāng)?shù)撵`活度了,在這個(gè)游戲里,我可以指定布景的大小和地雷的數(shù)量。這樣一來游戲就可以從頭再玩,你可以把地雷 數(shù)量設(shè)置很小而很快能看到游戲的結(jié)果,這樣有趣多了。下面就是這個(gè)游戲:
歡迎使用蘋果iOS
此時(shí),我已經(jīng)感覺到應(yīng)該轉(zhuǎn)向真正的圖形游戲了。我感覺陷入了僵局。我根本不知道從哪里入手。我研究了一下SDL,這個(gè)東西超過了我的接受能力,我很快放棄了。因?yàn)槲抑雷罱K我想做iPhone應(yīng)用程序,我請(qǐng)教了Matt Rix (Trainyard),他給了我一些很好的建議。他建議我從學(xué)C語言開始,然后學(xué)Objective-C,然后Cocos2d。今天說起這些我很快高興,這三種語言我都學(xué)會(huì)了,雖然很基礎(chǔ)。
在學(xué)習(xí)C和Obj-C時(shí),我遇到的大量的挫折,我沒有做出多少游戲。很多次,我真的懷疑是否能渡過難關(guān)、找到出路。很多東西當(dāng)我第一次看到時(shí)愁得我撓掉了很多頭發(fā):結(jié)構(gòu)體,數(shù)組,多維數(shù)組,屬性,表現(xiàn)層,控制層,協(xié)議和代理,內(nèi)存管理,還有很多。很多東西我目前仍然無法理解領(lǐng)會(huì)。但是我堅(jiān)持繼續(xù)下去,我對(duì)很多人都說:讓自己進(jìn)步的唯一方法就是不斷的做游戲。我十分清楚,想成為鋼琴家,練習(xí)時(shí)根本,所以,這也是我需要的(我就持續(xù)這樣下去)。
歡迎使用Cocos2d
一旦我最終把iPhone應(yīng)用的基本知識(shí)攻克下,我立即開始研究Cocos2d。我很緊張,也很興奮?,F(xiàn)在,我不知道自己是太挑剔還是太笨,我感覺 Cocos2d的文檔寫的不太好。所有的類,方法,屬性都列出來了,但卻很難讓人讀懂,它們解釋的不太清楚。一個(gè)例子:每個(gè)”node“(Cocos2d 的主要元素)都有一個(gè)”(BOOL) isRunning“屬性??雌饋矸浅5暮?jiǎn)單,但它似乎能夠表示任何意思。所有的文檔對(duì)這個(gè)屬性的解釋都是:”標(biāo)志這個(gè)node是否在運(yùn)行。嗯,ok … 不用說,Cocos2d里面有很多東西我都十分的困惑。
盡管這些的不滿,我還是非常喜歡Cocos2d。一旦掌握了一些基本知識(shí),我就開始研究它如何能夠容易的做出一個(gè)簡(jiǎn)單游戲,讓它馬上能跑起來。我已經(jīng)知道了如何做音樂和聲效,我還知道一些Photoshop,我就真的開始要讓它輸出一些很酷的結(jié)果了。起初我對(duì)Cocos2d很困惑,我從Ray Wenderlich的一些非常棒的教材開始學(xué)習(xí)。
我開發(fā)的各種暫且算是游戲的游戲
下面的是我的第一個(gè)Cocos2d游戲,它是我直接按照Ray的教材開發(fā)出來的(我在里面還加上了我的音樂和當(dāng)一個(gè)敵人被消滅時(shí)的很傻的音效!):

接著,我仿制了一個(gè)Pong。這個(gè)游戲還可以多人參與:

Pong之后,我受到了鼓舞,決定開發(fā)Tetris。這是個(gè)巨大的錯(cuò)誤。我根本沒有準(zhǔn)備好。我遇到了各種讓人懊惱的錯(cuò)誤和問題,當(dāng)我最終把框架搭起來后,我在微博上寫了這樣的話:“我很驕傲。我為我的Tetris仿品開發(fā)了一個(gè)真正復(fù)雜的類/子類系統(tǒng)。”Noel Llopis很快的告訴我,說我的決定十分的錯(cuò)誤。我搜集了一些教材,試圖好好的修改一下這個(gè)仿Tetris游戲,但太困難了。我決定放棄,但有一天我會(huì)打敗你的,Tetris!
這次Tetris失敗的嘗試之后,我受Tilt to Live的啟發(fā)做了一個(gè)游戲初始原型,我計(jì)劃在這個(gè)游戲里,你需要去收集紅點(diǎn)來獲取積分,而不是像其它游戲里去避開它們?,F(xiàn)在做的這個(gè)里面并沒有加入真正的游戲里面會(huì)有的音樂:

學(xué)習(xí)了更多的Cocos2d之后,我突然來了靈感要做一個(gè)循環(huán)的褶皺紙樣式的背景。于是把一張紙做出褶皺型,以循環(huán)方式填充背景。然后我在上面放了 一個(gè)小圓片,你可以用加速器讓它在上面滾動(dòng)。當(dāng)我弄明白如何讓這個(gè)小圓片滾動(dòng)后,我為自己能做出這個(gè)東西很自豪,因?yàn)檫@牽涉的一些數(shù)學(xué)知識(shí),我并沒有用很 久的時(shí)間就把它能明白了(盡管只是一個(gè)很簡(jiǎn)單的幾何問題)。背景很難看 —— 但很好用:

接著,當(dāng)我看到了即將發(fā)布的游戲Bumpy Road的令人驚訝的海報(bào)后,我受啟發(fā),心想是否能夠也做一個(gè)跟里面的高高低低的路面相似風(fēng)格的游戲元素。很顯然,我的做圖水平很有限,你可以比較一下。
Bumpy Road:

我的版本:

這之后,我想在真正的動(dòng)畫上試試身手。以前從沒有做過動(dòng)畫,先在Photoshop試試。人物的制作很乏味冗長(zhǎng)。即使是畫一條很傻很短的線條也很費(fèi) 勁。但我還是完成了,我把他稱作“狂歡者”。他能做的就是一遍遍的張開和閉上他的大嘴,每次都隨機(jī)的發(fā)出一些哼哼聲。你還可以在屏幕上移動(dòng)他。背景閃動(dòng)不 同的顏色。當(dāng)你觸碰屏幕時(shí),他只能哼哼和張嘴:

然而,“狂歡者”有了一小隊(duì)粉絲。這些粉絲的頭像圖標(biāo)里包括Mario, Link, Samus,等等。事實(shí)上我把這個(gè)游戲發(fā)給了Touch Arcade的Jared(嘿,是他向我要的)。之后,讓我大吃一驚和無比高興的是,Retro Dreamer的Craig Sharpe創(chuàng)作了我的第二張正規(guī)的粉絲的藝術(shù)作品!下面就是Craig為“狂歡者”創(chuàng)作的杰作:

他的作品是如此的優(yōu)秀,我甚至把它放入了我的下一個(gè)游戲里。但起初,我突發(fā)奇想,要做一個(gè)跳桿子的游戲。起初的出發(fā)點(diǎn)只是為了使用一個(gè)簡(jiǎn)單的游戲技 術(shù)測(cè)試一下視差背景的效果,但做下來就做成了這個(gè)游戲。最終的游戲有一個(gè)小屏幕,有記分功能,有重玩功能,有音樂、音效,各種跳躍高桿,有一個(gè)高度指示 器,甚至還有一個(gè)鳴謝頁(yè)面!它是我的功能最全的一個(gè)游戲。我在游戲里畫了一些非常丑陋的精靈,就像你下面看到的:

因?yàn)楫嫷奶?,我詢問Michael Hussinger是否愿意為我做一些簡(jiǎn)單的修改,他同意了!他在二十分鐘內(nèi)就畫出來一個(gè)讓人驚嘆的匹薩伙計(jì)。我估計(jì)花幾個(gè)小時(shí)也畫不出這么好的作品來。他還為游戲中的視差效果畫了一個(gè)漂亮的山作為背景。下面的就是在他的幫助下游戲的樣子,我加上了標(biāo)題和鳴謝頁(yè):

游戲運(yùn)行中!
我的下一個(gè)游戲受Trainyard的啟發(fā)。我想看看是否能做出 一個(gè)地圖,上面畫些網(wǎng)格道路,卡車能跑在上面。看看,制作“狂歡者”有了很好的回報(bào)。所以我稱這個(gè)為“狂歡大巴”。游戲的玩法就是點(diǎn)擊地圖上的一個(gè)地方就 設(shè)定一個(gè)聚會(huì)點(diǎn)(一個(gè)閃爍的,顏色變換的點(diǎn),伴有音樂),然后圖上會(huì)畫出一條路,通向這個(gè)點(diǎn),“狂歡者”會(huì)把他的“狂歡大巴”開到那里。不用說,這是一個(gè) 非常簡(jiǎn)單的游戲。但里面很酷的東西是,當(dāng)他到達(dá)目標(biāo)地點(diǎn)后,音樂聲會(huì)變大,卡車會(huì)開始跳舞,Craig畫的作品會(huì)出現(xiàn)在開車上面左右搖擺!

代碼寫的很亂,有很多問題。我讓弟弟試玩了一下,他式了三次,什么都沒干成,他總是每次都是在錯(cuò)誤的時(shí)間點(diǎn)擊到錯(cuò)誤的地方,這樣游戲根本就不能正常 玩下去。每次我都要從頭開始玩這個(gè)游戲,因?yàn)槲覜]有給它加入“重新開始”的功能。但我還是挺為這個(gè)Trainyard的復(fù)制品感到自豪的。Matt應(yīng)該為 此感謝我。
我的下一個(gè)項(xiàng)目是要做一條蛇。我發(fā)現(xiàn)了這個(gè)如何用flash做出一條蛇, 我只需要把它移植到iPhone上。這個(gè)教材讓我明白了很多如何做這種游戲的內(nèi)幕。之前,我計(jì)劃讓蛇每一幀移動(dòng)一次,但在如何讓蛇尾和蛇身保持一致的問題 上遇到了很多的麻煩。我本打算建一個(gè)數(shù)組存所有歷史動(dòng)作,蛇尾將按照這個(gè)數(shù)組里的信息做它的每個(gè)動(dòng)作,但這樣一來它動(dòng)的太快,讓人很不舒服。這個(gè)教程整個(gè) 顛倒了我的思維,我意識(shí)到蛇其實(shí)根本沒有動(dòng)。這種看起來在移動(dòng)的視覺效果其實(shí)是簡(jiǎn)單的在幀上添加和移去一小段蛇身產(chǎn)生的。這樣,當(dāng)你撿起一 個(gè)蘋果,所需要做的只是告訴程序不要?jiǎng)h除任何片段。事實(shí)上我需要重新寫這個(gè)程序,因?yàn)榻缑嫣y看了,控制的也不好。因?yàn)槲沂且浦策^來的,代碼寫的很亂。但 事實(shí)上作為一個(gè)基本的游戲來,它還是很不錯(cuò)的!

在完成這條蛇之后,我打算制作“狂歡大巴2”:“狂歡者”的周末狂歡。我把上一版升級(jí)了一些。我在里面加入了一些Trainyard里面的速度條, 一個(gè)車站,車可以從里面開車,一些聲音特效(當(dāng)他被碰著時(shí)會(huì)出現(xiàn)很大的汽車相撞的聲音,而且會(huì)喊出“今天沒有活動(dòng)!”),程序也整理的更整潔了。但沒多 久,程序又開始變亂,當(dāng)我要糾正一個(gè)問題時(shí),另外一個(gè)東西又出現(xiàn)了問題。最大的問題是當(dāng)我把速度設(shè)成最大時(shí),卡車會(huì)在路上某個(gè)點(diǎn)崩潰。這是因?yàn)楦抡{(diào)用的 太頻繁,程序來不及在下一次調(diào)用前更新完。盡管我知道這個(gè)問題的原因,如想修復(fù)這個(gè)問題需要重做大量的東西。我想我需要升級(jí)到“狂歡大巴3”:最后的狂歡。

我最近的目標(biāo)是重做Doodle Jump。目前為止一切進(jìn)展順利。里面很多小平臺(tái),移動(dòng)速度會(huì)約來越快,一個(gè)會(huì)跳的小人,一些其它物品(目前為止只有一個(gè)彈簧),自定義音樂和聲效,以及完全從原作里拷貝的背景。目前為止我對(duì)做出的東西很高興。我會(huì)繼續(xù)往里面增加很多的東西。

結(jié)論
練習(xí)給人帶來的進(jìn)步是驚人的。每次當(dāng)寫出一個(gè)新程序,我都會(huì)遇到大量的無法預(yù)知的問題和bug。當(dāng)遇到挫折時(shí),我一般是將問題移到下一次升級(jí)時(shí)解決。這讓我感覺自己就在走一個(gè)while循環(huán):
- while (編程技術(shù)仍然很糟) {
- 練習(xí)時(shí)間++;
- 程序 * 新程序 = [程序 程序類型:游戲];
- if (新程序.做的很好嗎 == 是的 && 練習(xí)時(shí)間 >= 大量) {
- 編程技術(shù)仍然很糟 = 否;
- }
- }
我會(huì)一直這樣制作下去,一轉(zhuǎn)眼就到現(xiàn)在了,我?guī)缀醯炔患跋胫涝?個(gè)月后會(huì)是什么樣。請(qǐng)下次當(dāng)我來述說如何給Casey’s Contraptions制作音樂(和一些聲音)時(shí),請(qǐng)記住一定來看看!

【編輯推薦】





















