資訊內(nèi)容
Scratch第五十講:超級(jí)瑪麗(一)
超級(jí)瑪麗scratch編程圖片素材包下載地址:
https://www.jikexiaojiang.cn/165.html
首先感謝一下這么多人對(duì)CC哥的支持和鼓勵(lì),實(shí)話說CC哥并不是編程的專家,我也是一個(gè)跟著大家一起學(xué)習(xí)的編程愛好者。CC哥希望通過這個(gè)公眾號(hào),把自己學(xué)習(xí)Scratch過程中的一些體會(huì)和經(jīng)驗(yàn)免費(fèi)的分享給大家,讓所有愛好編程的朋友們能夠通過CC哥的分享共同來體會(huì)編程的樂趣。平常CC哥也很忙,但是不管再忙,為了支持CC哥的朋友們,CC哥也盡量做到每周一更,只要能幫到大家,CC哥就會(huì)覺得很開心。,而支持CC哥的朋友們只要把這些學(xué)習(xí)內(nèi)容,分享給更多的朋友,那就會(huì)享受跟CC哥一樣的開心。
今天跟大家一起交流一個(gè)超級(jí)瑪麗的例子,這個(gè)程序是CC哥在官網(wǎng)上看的,通過認(rèn)真分析了編程者的代碼,CC哥也學(xué)到了一些挺有意思的技巧,在這里分享給大家。
CC哥今天只是把程序中的一部分摘取出來跟大家分享,這樣讓大家更容易理解和學(xué)習(xí)。先看看運(yùn)行效果。
看到?jīng)],今天分享的很簡(jiǎn)單,就是馬里奧在奔跑和跳躍。其他的內(nèi)容以后CC哥再慢慢分享。
做程序首先要構(gòu)思,你想做成什么效果,然后這些效果你實(shí)現(xiàn)的方法是什么,有哪些難點(diǎn),你有什么解決方案?所以做程序,不是上來就做,認(rèn)真思考是第一步。
思考程序的關(guān)鍵點(diǎn)
那這個(gè)超級(jí)瑪麗奧的關(guān)鍵點(diǎn)在哪里?
1:首先是奔跑的效果。大家簡(jiǎn)單一想就知道,奔跑肯定不是馬里奧在往前跑,而是路在向后跑,實(shí)際上馬里奧在屏幕上的位置是不變的。很多跑酷游戲都是這樣的,通常是背景在動(dòng),而不是人物在動(dòng)。那這個(gè)路往后跑怎么實(shí)現(xiàn)?
2:這個(gè)路是高高低低不斷變化的,你用什么辦法能實(shí)現(xiàn)這種效果呢?
3:這個(gè)路是高高低低不斷變化的,那你怎么保證馬里奧是隨著路升高而升高,隨著路降低而降低呢?
4:另外游戲要做得精細(xì),那么馬里奧奔跑的動(dòng)作效果就特別重要,用什么方法來實(shí)現(xiàn)這個(gè)動(dòng)畫效果呢?
馬里奧奔跑動(dòng)作的效果
讓我們先從最簡(jiǎn)單的開始,馬里奧奔跑動(dòng)作的效果很簡(jiǎn)單,就是用無數(shù)個(gè)造型循環(huán)播放就行了,這個(gè)大家應(yīng)該都知道了。這個(gè)游戲里面馬里奧一個(gè)簡(jiǎn)單的奔跑用了24個(gè)造型,其中每?jī)蓚€(gè)連續(xù)的造型都是重復(fù)的。
通常我們做動(dòng)畫效果都會(huì)強(qiáng)調(diào)放等待命令,否則程序執(zhí)行的太快,那么角色的動(dòng)作可能就變成了快鏡頭。而這個(gè)編者就沒有放等待命令。
奔跑的效果的關(guān)鍵是角色的步子的頻率要跟路移動(dòng)的速度一致,這樣才能體現(xiàn)出來在路上跑,而不是在路上滑著跑。(好的編程就是對(duì)細(xì)節(jié)的處理)大家可以自己試一下,比如把等待命令放進(jìn)去,看看這兩者的差別。
另外如果大家覺得這個(gè)角色很好,特別是這幾十個(gè)造型,也是不容易找到的,想把這個(gè)角色拿到自己的程序里用,要怎么做呢?CC哥在這里教初學(xué)者一下,很簡(jiǎn)單,你只要把這個(gè)角色導(dǎo)出來,再導(dǎo)入到你自己的游戲里即可。
在角色上點(diǎn)右鍵,選擇導(dǎo)出。然后保存在某個(gè)目錄里,那么就會(huì)有一個(gè)后綴為sprite3的文件。然后打開你自己的程序。在角色的圖標(biāo)上選擇上傳角色就可以了。
所以以后大家看到好的素材,只要有源代碼,都可以很簡(jiǎn)單的導(dǎo)入到你自己的程序里面。(CC哥所有例子的源代碼,只要你懂得分享,都可以免費(fèi)得到哦)
路的實(shí)現(xiàn)方法
跑酷的關(guān)鍵就是背景的移動(dòng),這里路就相當(dāng)于背景。路的關(guān)鍵點(diǎn)是兩個(gè),一個(gè)是不斷往后退,一個(gè)是出現(xiàn)高高低低的效果。這里面其實(shí)有兩種方法實(shí)現(xiàn),一種是用屏幕滾動(dòng),之前的講座里面有講過,大家可以去復(fù)習(xí)一下第十八講:Scratch第十八講:如何正確實(shí)現(xiàn)背景的滾動(dòng)。這是一種方法。但是缺點(diǎn)是路徑會(huì)是循環(huán)的,而不是隨機(jī)的。而且背景和角色的互動(dòng)就只能通過顏色的碰撞來偵測(cè)了,編程難度增大。
今天介紹的是另一種方法,用角色來克隆實(shí)現(xiàn)。就是把路的一部分作為角色,然后不斷克隆來組成路,再通過移動(dòng)來形成背景移動(dòng)的效果。
這個(gè)路的角色有三個(gè)造型,一個(gè)是水平的路,一個(gè)是上升的路,一個(gè)是下降的路。這三種路的造型隨機(jī)組合起來,那么就形成了高高低低不斷變化的路。
這段程序大家可以自己讀。這里面有兩個(gè)關(guān)鍵點(diǎn):
1:第一個(gè)就是克隆的頻率要和路移動(dòng)的速度一致,如果不一致,那就亂套了。如何保持一致是關(guān)鍵點(diǎn)。
這就是不同步的效果。
那如何做到呢?我們分析代碼,會(huì)發(fā)現(xiàn)這里面有一個(gè)狀態(tài)變量:LaunchObstacle。這個(gè)變量就是一個(gè)開關(guān)變量,來決定什么時(shí)候開始一個(gè)克隆。在主程序的循環(huán)里面有一個(gè)等待命令。這有等待到這個(gè)變量的值是YES的時(shí)候才會(huì)克隆下一個(gè)變量。而在克隆啟動(dòng)的子程序里面,我們會(huì)看到有一段語句:
也就是克隆出來的變量要先向左邊移動(dòng)15步之后,這個(gè)變量才會(huì)變成YES。也就是說克隆出來的變量移動(dòng)開之后才會(huì)克隆一個(gè)新的克隆體。
通過這個(gè)變量和等待命令,就完美的讓一條路連貫起來。大家一定要記得這個(gè)編程方法哦。很實(shí)用的。
2:除了路的克隆頻率和運(yùn)動(dòng)速度的同步,還有一點(diǎn)很關(guān)鍵,如何讓三個(gè)造型能夠完美銜接,而不是會(huì)突然凸起一塊和凹陷一塊。也就是讓路平滑。所以每次克隆體的位置也是不一樣的,每次克隆的位置都要根據(jù)上一個(gè)克隆體的位置決定,如果前面一個(gè)克隆體是向上走的造型,那么下一個(gè)的起始位置就要向上一些。如果前面是向下走的造型,那么下一個(gè)克隆體的起始位置就要向下一些。
大家再看這三個(gè)造型的名字,看明白沒有?只要你讀取了每一個(gè)造型的名字,就知道下一個(gè)克隆體的起始位置了。是不是很有技巧。雖然不復(fù)雜,但是確實(shí)很有技巧。所以編程并不是非要做得很復(fù)雜,關(guān)鍵還是思路和實(shí)用。
好點(diǎn)子比技術(shù)更重要
3:另外路的高低要有限制,不能太高也不能太低,雖然用了隨機(jī)數(shù),但是需要做控制。這個(gè)大家自己看程序吧。
馬里奧如何在路上跑
如何在路上跑,說的意思是如何保持在路上,而不是跑到空中和路的下面。做這個(gè)我們最常見的思路是檢測(cè)馬里奧角色和路之間的碰撞關(guān)系。但是之前很多例子我們有講過,當(dāng)你做碰撞檢測(cè)時(shí),如果角色的造型比較復(fù)雜,那么碰撞檢測(cè)往往會(huì)出現(xiàn)很多問題。所以對(duì)于復(fù)雜造型角色的碰撞檢測(cè),往往引入形狀簡(jiǎn)單造型的角色專門用來做碰撞檢測(cè),然后只要保證讓復(fù)雜的角色來隨時(shí)跟隨這個(gè)簡(jiǎn)單造型的角色即可。
看,這位編程者不但引入了一個(gè),而是引入了三個(gè)。為什么要引入三個(gè)?且讓CC哥慢慢給你分解。
馬里奧的第一個(gè)影子角色
這個(gè)程序真的是體現(xiàn)了:簡(jiǎn)單的技巧,好的點(diǎn)子,達(dá)到完美效果的一個(gè)實(shí)例。所以說,以后大家不用太擔(dān)心自己的編程技巧,把更多的重心放在如何利用你掌握的技巧想出好的點(diǎn)子來實(shí)現(xiàn)完美的效果。大家一定要記住CC哥今天說的話。
馬里奧角色代碼
這是馬里奧角色的代碼,非常簡(jiǎn)單,就是跟緊controller這個(gè)角色。也就是說,controller這個(gè)角色是關(guān)鍵,用來跟路做互動(dòng)的角色。而不是馬里奧這個(gè)角色。然后就是不斷切換造型來形成跑步的動(dòng)畫效果。
controller角色代碼
這是controller的完整代碼,讓CC哥跟大家一起來分析一下。
大家知道,這種影子角色都是來做偵測(cè)的,不能讓大家看到。但是又不能隱藏,因?yàn)榻巧[藏之后就無法再做碰撞檢測(cè)了,那怎么辦?這里面有一個(gè)技巧就是把透明度設(shè)定成100!透明的角色,雖然你看不到,但是角色之間的碰撞檢測(cè)沒有任何問題。(這哥們?yōu)槭裁丛O(shè)成99?CC哥也沒搞明白,是不是有什么暗招CC哥沒看出來?不知道,大家如果知道了告訴我一聲。)
這一段代碼是指沒有跳躍動(dòng)作的代碼,其中的主循環(huán)是一個(gè)下降動(dòng)作的標(biāo)準(zhǔn)代碼。Obstacle是路的角色名字。這段代碼就是保證角色始終會(huì)落到路面上(下落過程是帶加速度的)。前面CC哥講下落講太多了,這里就不需要再講了。
這段代碼是處理收到起跳命令之后的跳躍處理過程。JumpStartPower這個(gè)變量是指起跳的初始動(dòng)能。代碼先包括一個(gè)起跳過程,然后是一個(gè)下降過程。這段代碼如果大家學(xué)過上一講:Scratch第四十九講:完美的下落和反彈,就非常容易理解。(他這個(gè)是簡(jiǎn)化的起跳和下落,不是完美的)
大家需要學(xué)習(xí)的是他的流程控制。大家注意到,編程者非常習(xí)慣用消息這個(gè)模式,也就是很多進(jìn)程的控制都是用消息來實(shí)現(xiàn)的。
程序開始就用了#NotJumping這個(gè)消息來啟動(dòng)這個(gè)影子角色的關(guān)鍵任務(wù),始終保持落在路面上。
然后用了#Jump這個(gè)消息來處理起跳和降落的過程。每個(gè)消息都有循環(huán)過程,那如何讓不同的消息導(dǎo)致角色控制不出現(xiàn)相互干擾呢?
編程者用了這條命令,停止該角色的其他腳本,來確保該角色在起跳后不受其他部分代碼的干擾,也就是保證起跳部分代碼的獨(dú)立性。
而在起跳這部分代碼完全結(jié)束后,再重新廣播#NotJumping,來保證原先進(jìn)程的繼續(xù)執(zhí)行。
所以大家可以學(xué)習(xí)這個(gè)技巧,當(dāng)你一個(gè)角色里有多個(gè)行動(dòng)進(jìn)程的時(shí)候,可以用這組命令來進(jìn)行控制,確保某部分動(dòng)作或進(jìn)程的獨(dú)立性。
大家注意到?jīng)]有,這個(gè)影子角色的代碼只做到了讓角色始終會(huì)落到路上,路水平和路下降都沒問題,但是如果當(dāng)路向上升的時(shí)候,怎么讓角色也跟著向上升呢?這個(gè)影子角色里沒有這部分的代碼!那如何實(shí)現(xiàn)呢?
馬里奧的第二個(gè)影子角色
CC哥把這三個(gè)影子角色的顯示特性打開,這樣我們就看到了三個(gè)影子角色,其中最上面小的那個(gè),就是Riser角色。
這個(gè)影子角色的目的是用來讓馬里奧能夠做到隨著上坡的路,一起上升的。
Riser的角色代碼
代碼很簡(jiǎn)單,就是檢測(cè)Riser這個(gè)變量如果碰到了路的角色Obstacle,然后就發(fā)布消息Raiseshadow3。
在第一個(gè)影子角色Controller里有對(duì)應(yīng)的接收消息的程序。如果接收到這個(gè)消息,就向上移動(dòng)3步。
問題來了,為什么要增加一個(gè)單獨(dú)的影子角色來判斷呢?為什么不用之前那個(gè)影子角色來做判斷呢?
編者的思路還是很巧妙的,第一個(gè)影子角色的目的是為了讓馬里奧始終能落在路上。所以這個(gè)角色應(yīng)該是盡量保持在跟路(Obstacle)接觸的狀態(tài)。路向下走,角色自然會(huì)落下來。但是如果往上走,那該怎么判斷路已經(jīng)在向上的走呢?第一個(gè)影子角色顯然就判斷不了了。編者另外設(shè)計(jì)了一個(gè)影子角色Riser,然后讓這個(gè)角色的位置比Controller這個(gè)角色高一點(diǎn),也就是正常來說,這個(gè)Riser的角色不會(huì)碰到路。會(huì)保持在比路高一點(diǎn)的位置。一旦路往上走,那么Riser繼續(xù)往前走就會(huì)碰到路,一旦Riser碰到路,那么馬上就知道路向上走了,就發(fā)布向上走的消息,通知Controller往上移動(dòng)三步,如果繼續(xù)碰到路,說明還在向上走,那么就再移動(dòng)三步。
是不是很有意思,雖然增加了一個(gè)角色,但是編碼簡(jiǎn)單了很多,否則如果只用一個(gè)影子角色來做,豈不是要增加無數(shù)條代碼,和處理更復(fù)雜的判斷。
CC哥把四個(gè)角色,一個(gè)馬里奧,三個(gè)影子角色全部都移動(dòng)到中心位置。移到中心位置以后,大家就會(huì)看到這四個(gè)角色的位置關(guān)系。所以說,編者在布局時(shí)就讓馬里奧的腳底跟Controller的角色的平齊,然后Riser的角色高于Controller角色。(一個(gè)簡(jiǎn)單技巧,當(dāng)你想調(diào)整角色之間的位置關(guān)系的時(shí)候,就讓每個(gè)角色移動(dòng)到正中心,然后再在造型里面把每個(gè)角色拖到你想要的位置。)
馬里奧的第三個(gè)影子角色
最難理解的就是第三個(gè)影子角色。CC哥也是想了半天,為什么要用這個(gè)角色呢?
Controller2的角色代碼
從代碼里看,這段代碼就是一個(gè)功能,控制馬里奧起跳的,非常簡(jiǎn)單,但是為什么單獨(dú)放一個(gè)角色呢?以我們做程序的經(jīng)驗(yàn),完全可以把這個(gè)角色省略掉,直接把這段程序做到controller里面。
就把這段程序放到controller的主循環(huán)里就好了。為什么單獨(dú)啟用這個(gè)角色呢?CC哥還特意測(cè)試了一下,放到controller完全沒有問題,代碼的邏輯也沒有毛病。這個(gè)角色完全可以刪掉。百思不得其解。然后CC哥就是反復(fù)比較這兩種模式游戲執(zhí)行的情況。試驗(yàn)了十幾分鐘后,突然領(lǐng)悟了!領(lǐng)悟完不得不點(diǎn)贊編程者思路的嚴(yán)謹(jǐn)。
大家仔細(xì)看這一段,CC哥把controller的角色顯示打開,這樣大家可以看得更清楚。大家發(fā)現(xiàn)一個(gè)問題沒有?
當(dāng)controller往上走和水平走的時(shí)候,controller會(huì)始終貼在路上。而在往下走的時(shí)候,controller就不是一直貼在路上了,而是跳著往下落,并不是一直貼在路上往下走。這就是關(guān)鍵點(diǎn)!
這種情況對(duì)程序有什么影響呢?
我們看代碼就知道了,起跳的關(guān)鍵判斷就是確保controller在路上才行。如果controller不在路上,那么起跳動(dòng)作就不會(huì)發(fā)生。而剛才大家看到了,controller在下降的時(shí)候并不是一直在路上。所以當(dāng)controller正好不在路上的時(shí)候,馬里奧就無法起跳了。而超級(jí)瑪麗這個(gè)游戲大家都知道,需要隨時(shí)起跳,吃金幣,躲避怪物等等,如果在沿著路向下走的時(shí)候由于controller不能始終貼在路上,所以會(huì)造成沒法及時(shí)起跳。一個(gè)起跳不靈活的超級(jí)瑪麗是不是就沒法玩了。
所以編程者特意做了一個(gè)新的角色,controller2,特意比controller低了一些,其目的就是為了確保在路下降的時(shí)候,controller2能盡量貼著路,避免掉controller隨著路向下走的時(shí)候不能及時(shí)貼到地的情況。
有意思吧,有時(shí)候分析一個(gè)游戲的代碼就像看一個(gè)藝術(shù)作品,慢慢體會(huì)編碼者在編程時(shí)候的思路和想法。好的程序都會(huì)有無數(shù)個(gè)思維巧妙的地方。不見得代碼有多復(fù)雜,邏輯判斷繞多少圈就顯得水平高。一個(gè)完全讓別人都看不懂的代碼也不是什么好代碼。
?
祝所有小朋友六一節(jié)快樂
今天是六一兒童節(jié),如果有小朋友今天還跟著CC哥一起學(xué)編程,那你一定會(huì)成為一個(gè)很厲害的編程小神童的。
如果覺得CC哥做的不錯(cuò),請(qǐng)點(diǎn)擊右下角的"好看",給CC哥一個(gè)鼓勵(lì)!
聲明:本文章由網(wǎng)友投稿作為教育分享用途,如有侵權(quán)原作者可通過郵件及時(shí)和我們聯(lián)系刪除

- 上一篇
Scratch3.0自建局域網(wǎng)環(huán)境(一)
操作系統(tǒng):Centos7 服務(wù)器:nginx 準(zhǔn)備工作: (1)源碼下載:https://github.com/llk; 下載scratch gui。 (2)準(zhǔn)備工具:
- 下一篇
五年級(jí)Scratch校本課堂紀(jì)實(shí)
? 在城鄉(xiāng)中小學(xué)校一體化發(fā)展項(xiàng)目的支持下,我校五年級(jí)本學(xué)期開設(shè)Scratch校本課。學(xué)生使用Scratch 編程軟件,通過拖動(dòng)積木的方法,實(shí)現(xiàn)屏幕畫布 上動(dòng)畫和游戲程序的制作,并通過智能硬件將現(xiàn)實(shí)物理世界與屏幕畫面相結(jié)合,創(chuàng)造出自己獨(dú)一無二的程序作品。課程將藝術(shù)和編程融合在技術(shù)、