資訊內容
Scratch第五十二講:開心消消樂(CC哥版)
想免費學編程,就請點擊上面的藍字:跟我學Scratch編程,關注CC哥。
最近實在太忙,所以空了一周,關鍵也是一直在做這個小程序。這個消消樂真的是CC哥自己琢磨著編寫的,沒有參考任何其他人的材料,完全屬于獨創。做完之后還是小得意了一下。雖然還有很多地方沒有去一一細化,好在為了教學,能講明白就行。
先看看CC哥版的消消樂
雖然跟手游上的比還是差很多,不過作為教學已經很夠用了。做這個游戲還是很費了一些腦子。平常我們去看別人的程序代碼,就會覺得不復雜,或者是感覺就應該這樣設計的。其實任何一個程序都有無數種方法去實現,哪種好,哪種不好,還真是很難說清楚。甚至做完了你都不知道你選的方法是不是最好的方法。在這個程序里,CC哥就反復了很多次,嘗試了各種方法,下面就一一給你道來。
設計框架
第一步是要選擇用什么方法來實現這一堆彩球。消消樂的思路就是通過相鄰的彩球的交換,形成三個連起來的彩球,然后消除掉。那么用什么來做這一堆彩球呢?思路上有兩個大的思路:
1:克隆
????克隆就是這些彩球全部通過克隆來做。
2:圖章
????圖章就是用圖章的命令在桌面上畫出應該的彩球。(CC哥前面有個俄羅斯方塊的講座就是全部用圖章來做的。)
用圖章做這個程序的工作量將主要放在畫圖上,和顏色的檢測上。用克隆做程序的主要工作量就放在了克隆體的操作上。每個人習慣不同,我就更喜歡用克隆來做,這個強調的主要是邏輯和算法。用圖章做是個細致活,實在不是CC哥的風格。大家沒事可以自己試試。
我在scratch里選了小球的角色,9個一排,克隆了126個。總共5個造型,隨機分布,看著還不錯吧。
第二步:實現相鄰之間的小球交換
小球交換就有幾種情況:
1:選的球不是相鄰的,那么就不能交換。
2:選的球是同色的,那么也不能交換。
3:選的球交換后,不能形成三個同色球在一起,那么還要換回原地。
第三步:消除同色的小球,上面的小球降落下來。
這里面難點包括:
1:如何檢測上下左右有幾個球是同色的。
2:這些小球是克隆體,如何消除這些特定的克隆體。
3:上面的小球如何降落下來,以及如何在空白位置補充新的小球。
有沒有覺得不好做了?一開始CC哥覺得挺容易的,誰知道做起來還是挺繞的。這一講CC哥不像以前那樣一步一步給大家過代碼,主要講一下CC哥在編程過程中繞的圈子和最終的解決方式吧。如果大家對代碼感興趣,還是老規矩,幫CC哥分享,免費獲取源代碼。
126個球的標簽
做這么多克隆體的管理,就必須要給克隆體打標簽,這個技能CC哥很多講座里都講過了,通過克隆體的私有變量來做。但是這126個球的私有特征都有什么呢?
1:位置,我們要管理球動來動去,自然要標記位置。
2:顏色,這個也是必須標記的。
3:狀態,球也是有狀態的,變動過位置的球跟沒變動過位置的球是有區別的,變動過位置的球就需要檢測位置變動后有沒有同色相鄰球,而沒有變動過位置的球就不需要檢測。
為此,CC哥想到了列表,但是Scratch的列表是一維的,只能有一列,那怎么標記這么多種特征呢?而且位置本身就是個二維的,行和列。
為此,CC哥想到一個方法,用一個5位數字來表示球的信息,第一位是列,第二三位是行,第四位是顏色,第五位是狀態。比如10120,就表示第一列第一排的藍色小球。是不是很完美,一開始CC哥也滿得意的,做到最后就有點蒙圈了。
scratch畢竟不是C語言,稍微一些復雜的數據的處理用這種圖形命令就會寫得非常復雜,不但容易錯,而且錯了也很難檢查出來。
一個計算式屏幕都放不下,寫得CC哥都快崩潰了。尤其是做到消除這一塊時,我就知道這么做肯定不行了,因為通過列表里的狀態信息來控制克隆體,算法實在是太復雜了,所以這條路走不通。
其實一開始我就覺得這么做有些問題,但是一開始也沒法想那么細,每做一步都是一個小成功,當開始發現問題的時候,因為前面已經花了那么多時間,就不想放棄,推倒重來前面不是白做了。最后做到了第三步才發現實在是做不動了,邏輯過于復雜,bug多到根本找不完,解了一個bug,又增加幾個bug。才不得不放棄。這就是我們經常碰到的沉默成本的問題。最后我還是全部推到重來,用了不到半天就把程序全部做完了。前面因為沉默成本,在錯誤的路上埋頭堅持了兩個晚上,想想多么愚蠢呀。
CC哥主要錯在哪里了?就是用列表沒錯,錯在信息標簽做的太復雜。
其實就這么一列數據就夠了,因為方框內就這么126個位置,所以從左到右從上到下個號,只要知道小球的編號,就完全可以算出小球在哪個位置上。所以列表的編號就是位置信息,每個編號就對應了一個克隆體。那么列表的內容只需要放這個克隆體的顏色信息就夠了。而狀態這個完全不需要再加一位進去,只需要把有過位置移動的小球信息單獨再創建個列表就OK了。
對特定小球的控制
這個游戲里面大量的操作都是針對具體的克隆體進行控制,這里面有個特別的技巧,就是消息命令。大家一定要掌握。
針對克隆體的控制一般的做法都是用當作為克隆體啟動時來做,里面套個無限循環,然后通過檢測私有標簽,來針對相應的克隆體做些動作,比如移動呀,碰撞檢測呀等等。
但是缺點就是如果克隆體的操作邏輯次序比較復雜時,那么這個方法就不合適了,你會需要用大量的判斷命令(控制命令),很容易出錯。
而消息命令就是個非常不錯的方法。
CC哥把針對小球的每一種控制都用消息來做,邏輯和編程就簡單多了。邏輯很簡單:
當你發布一條消息的時候,所有的克隆體都會同時收到,那么你只要在當接收到消息的代碼中加上一條對私有變量的判斷命令就ok了,符合這個判斷條件的克隆體就會發生動作,不符合的克隆體就不會有動作。是不是很方便,大家一定要掌握這個技巧。
如何進行相鄰球的同色檢測
同色檢測,以及檢測完畢后面的一系列動作,都是基于列表來操作的。
克隆體之間的互動是個難點,你不論是用消息,還是當克隆體啟動時來對克隆體進行控制,都是針對當前的克隆體,所以代碼就只能操縱當前這個克隆體,而不能在一個克隆體的代碼內去操縱其他的克隆體。如果真的需要,就只能在執行代碼里重新發布消息,這樣其他的克隆體才能接收到消息產生動作。編程就會變得復雜的多。
而通過列表就可以完美的解決問題,每一個克隆體對應列表里的一個數據,我們把希望做的邏輯和控制都在列表上做,對數據的操作,就相當于在克隆體之間進行邏輯和控制操作,當結果出來后,再針對結果通過消息來控制具體的克隆體做相應的動作就好了。
而且列表不是私有變量,完全可以在別的角色里面操作,更加靈活方便:
同色檢測的邏輯就是檢測具體的小球上下左右四個方向有沒有同色連排的球,并把結果反饋回來。(因為有了列表,而且列表跟克隆體的私有信息一一對應,所以我們只要檢測列表里面的數據就行了,不需要去檢測克隆體)
因為我們不確定到底有幾個小球相連,為了編程簡單,我們用了遞歸的技巧,遞歸之前有專題講座,如果不是太懂得朋友可以復習一下。
CC哥不像把編程邏輯做的太復雜,所以就用了四個自定義命令來檢測上下左右四個方向。雖然代碼多,但是邏輯簡單哦。
我們編程的時候沒必要為了代碼的簡單去可以去優化邏輯,大家一定記得,邏輯越復雜,bug越多的道理。
看只要知道一個小球的編號,減去9就是它上面小球的編號,加上9就是它下面小球的編號,多簡單。
因為互換操作是兩個球,每個球都可能發生同色球連排,所以兩個球都要做,通過返回的上下左右四個變量來表示同色球的起始位置,只要右減左,上減下,就可以得出同色的球是否有三個以上,來判斷是否要做下一步的消除同色球的操作了。
兩球交換動作注意
為了表現兩個球交換的動態效果,這兩個克隆體的移動是真實發生的。當克隆體真實移動的時候,就必須注意克隆體的私有標識信息要跟列表同步好,如果忘掉這一步,那么列表和克隆體的對應就亂掉了。
清除同色球的操作
要說明一點,這個游戲的關鍵是除了兩個球的交換CC哥用了克隆體的移動,其他的所有操作,都沒有發生克隆體的移動。那么如何做到消除呢?只是簡單的把小球的造型換了個空白的就實現了消除操作。
那消除后的空白,如果實現讓上面的球落下來呢?也沒有用克隆體位移,只是讓上面所有的克隆體一起改變顏色就好了。視覺上看著就像是上面的小球都落下來了。
因為這些小球都是克隆體,而不是一個個具體角色,所以當要操作這些需要消除的角色時,還是要通過消息來操作。因為同色球的數量是不固定的,最簡單的操作就是把所有要清除的同色球編號,都單獨放在一個列表里。那么只需要一個簡單的判斷就可以通知對應的球來進行消除動作了。
就這么一條語句,每一個克隆體就知道自己是不是清除的對象了。為了有消除的視覺感,我做了幾個對應的破裂的造型,做的有點糙,下次一定好好P一下。
消除并不是真的刪除克隆體,而只是換了個空白的造型,屏幕看上去沒有了。
如何讓上面的球落下來
一樣的情況,我們不是真的要讓克隆體移動下來,只是要讓克隆體的顏色變一下,造成下移的效果。(如果你真要做克隆體移動,估計會做崩潰掉的)那么哪些克隆體需要變顏色呢?
同樣,我們不用針對克隆體去做邏輯運算,只要去針對列表就行了。
每一個被清除的球,我們都要去計算這個球以及其上面每一個球,在下落發生后應該是什么顏色。每計算完一個球,就把它從要清除的列表里刪掉。(這種處理完就刪除的操作的列表操作,為了簡便,大家一定要從列表的尾部取,不要從頭部取)
這段程序就是檢測每一個要清除的小球上面一列所有的球,下落后應該對應的顏色。用的仍然是遞歸的算法。每一步只需要確認上方一個球的顏色,然后遞歸操作。
不確定循環次數的循環最好用遞歸
當列表更新完了,就出現了個問題,就是克隆體跟列表不能對應上了,所有改動過的列表項目跟克隆體的造型私有變量對不上了。那就剩下最后一步操作,把這兩項同步就好了。
只要克隆體的顏色與列表不一樣的,都以列表為準,同時切換到對應的造型,下移這么復雜的操作就很簡單的完成了。
最后一步,就是把上面空出來的位置補上新球。也就是把空白造型切換成1~5的隨機造型。
結束語
大家在學習編程的過程中,一定要實踐,實踐的過程也就是創造的過程,所謂實踐,不是指去復現程序的例子,而是要從頭到尾試著自己去編一些小程序。通過實踐去驗證自己的思路,不僅僅可以鍛煉你的創造性,更可以鍛煉你的邏輯的嚴謹性,還可以讓你活用學過的技巧。
聲明:本文章由網友投稿作為教育分享用途,如有侵權原作者可通過郵件及時和我們聯系刪除

- 上一篇
scratch少兒編程第二季——06、完善飛機大戰程序,修改bug之(一)
各位小伙伴大家好: 上期我們基本搭建好了游戲的運行程序,本期我們來修改一些bug完善一下程序。 首先是在運行程序的時候要隱藏敵機和子彈本體。 敵機好操作,只要在開始的時候插入隱藏就可以。
- 下一篇
Scratch基礎_移動和循環
? 移動和循環是Scratch里面非常重要的功能塊,通過一個小動畫讓孩子更好的理解這兩個功能積木的使用,只是聽不去練達不到學習的效果哦,如果同學們對這款工具感興趣,一定要帶著好奇去摸索練習,Scratch只是一款工具,只有多用才能熟悉,熟悉后我們才能發揮自己的想象力去創作更多的作品,可以