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

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