從Scratch學好程式設計

你寫的程式是不是一個廣播接一個廣播,最後不知道接到哪裡?
你寫的程式是不是一定要從頭開始測試,浪費很多時間?
你寫的程式出問題時,請別人幫你 debug,別人看了半天卻說沒辦法幫你?

通常我們做 Scratch 專案都是小遊戲,贏了、輸了遊戲就結束了,但貓咪盃的比賽,通常遊戲要做兩關,而且又要兩位同學一起合作,如果兩個人分開寫程式,卻沒有說好怎麼合作,當兩個人的程式放在一起時,一定會出很多問題。例如:用了相同名字的變數或廣播、兩個人的程式都是『當綠旗被點擊』開始合在一起後同時都動了起來。

先來看看,你的程式流程是不是會像這樣:

  1. 第一個角色是開場動畫的角色,綠旗按下後自己動了起來,並發了一個「開場動畫」的廣播讓其他角色也動了起來。

  2. 開場的最後,出現一個開始遊戲的角色,這個角色被點擊之後發出一個「第一關開始」的廣播

  3. 接著第一關相關的角色動了起來,主角被擊敗後發出「第一關過關」的廣播,敵人被擊敗後發出「第一關再玩一次」的廣播。

  4. 「第一關過關」被另一個角色處理,這個角色發出「第二關開始」的廣播。

  5. 「第一關再玩一次」 被另一個角色處理,這個角色發出「第一關開始」的廣播。

  6. 第二關的程式流程跟第一關類似,主角被擊敗後發出「第二關過關」的廣播,敵人被擊敗後發出「第二關再玩一次」的廣播。

  7. 「第二關過關」的廣播被最後結尾動畫的角色處理,而處理「第二關再玩一次」的角色又是另一個。

我說的都累了,如果今天叫你再做一個第三關,你這樣做是不是會讓你的程式更加複雜下去。

細心的人,會在廣播前面加上編號,幫助追蹤程式 (trace code) 的流程,但我相信兩個禮拜後,你一定還是會忘了這些流程,因為這整個流程跨越了太多角色甚至有可能不同的角色會發出同樣的廣播,增加了流程的分支,讓流程更複雜。那~要怎麼做?

終於要講重點了:

  1. 善用「狀態」變數,把遊戲的各種狀態歸納起來,狀態可以是第幾關,也可以是每個關卡遊戲的狀態,如:遊戲中、死掉重來、過關、沒命結束。

  2. 找一個角色做流程主控,並依照「狀態」變數的值來發出各種廣播,指揮其他角色做事。有時還可以善用『廣播並等待』來減少主控程式的複雜度。

  3. 其他角色『當綠旗被點擊』下的程式只有『隱藏』加初始化,如:定位、尺寸設定。這些角色聽命於主控角色發出的廣播做事,並限制少數幾個角色能改變「狀態」變數。

說那麼多,例子勒?打磚塊

傑夫老師用下面這樣的控制流程架構,就能很簡單的將這個打磚塊遊戲做出三關來。狀態變數就是關卡,用 Level 變數記錄,當 Level = 4 的時候就是過關,但當 Level = 9 的時候,就是沒接到球,遊戲結束。

主控程式

主控程式

球的程式如下,從收到「Game Start」廣播後球開始移動,直到碰到死線或磚塊全部打完為止,如果是磚塊全部打完便將 Level 變數 +1;如果是碰到死線便將 Level 變數設為 9。然後球就沒事了,但因為 Level 變數有了變化,主控程式就繼續下去了。

球的程式

球的程式

而磚塊的程式如下,就是在收到各個「Level X」廣播時開始準備磚塊,各個磚塊分身產生後就等著被球打,被打到後將磚塊數量 -1,不做任何多餘的事。

磚塊程式

磚塊程式

就這樣,不用一節課的時間,三關卡的打磚塊就做好了,因為第三關根本不用做,只要複製貼上再小小修改就搞定了,要做第四關也不是問題。而程式要追蹤 (trace) 只要看主控程式就好,還可以要測第幾關就測試第幾關。

利用這樣的架構,小小修改後(改成三關各自有「Game Start」或不用「Game Start」了),就可以把這三關做成三個獨立的遊戲,這三個獨立的遊戲只要掌握〝過關把 Level 變數 +1、 失敗把 Level 變數設為 9、關卡結束各角色程式也結束〞的原則,就能變成不同的遊戲了。而且,兩位同學就能各做各的遊戲,然後輕易的整合在一起了。

當然這不是唯一的控制流程方式,也不是只有這種程式架構,但傑夫老師認為能夠寫出這樣的程式才稱得上是懂程式設計,因為程式有了可讀性、好維護、易擴展,就不再是單單的寫程式。

程式只會越寫越長,就跟著傑夫老師從 Scratch 學好程式設計吧,Bye now~