做了很多小游戲,都會遇到碰撞和反彈的情況,CC哥大多時候也都是簡單處理一下,包括之前的講座也有提過,但是沒有認真的講解過。今天就專門為這個主題做一講,把這部分內容徹底講透,大家可以一起探討一下。
是不是覺得很簡單,就是一個小球落到地上再彈起來,但是讓我們一起來過過這個下落反彈里面有多少坑。
1:勻速下墜
先來看下落,一個最簡單的下落程序是這樣的:
小球勻速下落,碰到黑線停下來。這肯定不完美,因為下墜應該是加速度的,而不是勻速的。v=at,這是加速度公式。所以下墜的每一步都隨着時間的增加,下墜的距離在增大。
2:下墜配上加速度。
這個也不復雜,讓每一次循環的時候都將下落速度增加一點,這樣就有加速度的效果了。
加速度的效果有了,但是大家發現問題沒?小球碰到黑線並沒有停下來,而是會一部分穿過黑線才能停下來。也就是說小球碰到黑線時並沒有完全停下來。這是怎么發生的呢?
因為小球下降的每一步走的距離就會變大,我們仔細讀程序,也就是小球碰到黑線的前一步和碰到黑線的后一步之間,行進的步數已經比較大了,已經超過了小球最后和黑線的距離。所以在碰到黑線時,實際上已經一部分越過了黑線。那如何解決這個問題呢?
3:碰到黑線剛好停住。
如果解決這個問題,解決的方法就是讓小球再退回到黑線的上方。我們這時候並不知道小球應該退后多少步,所以只能一步步試,直到小球和黑線分離。
我們加了一段程序,如果小球碰到了黑色那么就執行一個循環,讓小球回到黑線上方。
奇怪不?小球在向上后退離開黑線后為什么又掉了下來,然后在黑線上反復震動?其實在做碰撞處理的時候這是經常會出的一個bug。
我們仔細讀程序,就會發現,在這個循環里的判斷邏輯是這樣,如果沒有碰到黑線,就往下落。每一步下落的距離就是“下落速度”這個變量的值。如果碰到黑線,就往上后退,直到離開黑線。那大家有沒有發現,這個邏輯其實就是個死循環。小球永遠不可能停下來。
我們修改一下程序,重新把邏輯判斷的位置調整一下,同時再加上一條關鍵語句。
邏輯判斷調整成,在每一步下落時都判斷是否碰到黑線,如果碰到黑線后就后退,后退完畢后又增加了一條語句,讓小球再下降一步,保證小球和黑線接觸上。小球再下降一步就是一個關鍵語句。然后大循環就終止了。大家再好好理解一下。
但是大家發現沒有,這樣效果還是不好,小球在返回黑線上方有個過程,我們已經沒有加等待命令了,這已經是最快的方式了。但是這個過程還是讓人不舒服。(有人在返回黑線上方的操作做的更復雜些,比如一次退回更多步數,比如一次退10步,如果退過了,再返回5步,這種反復趨近的操作也是一種辦法。但是程序復雜不說,效果也不好)那如何解決這個問題呢?
這里教大家一種方法,用自定義命令的方式。把后退的操作用一個單獨的自定義命令來做。
猛一看,這段程序跟剛才沒什么區別呀?其實區別是有的,之所以大家看到小球向上回退的過程,是因為程序有刷新的過程,每一步都需要刷新屏幕。而把這段程序放到自定義的語句,就可以解決這個問題。因為新的積木屬性里面有一個 選項:運行時不刷新屏幕。只要勾選了這個選項,那么這段程序每一步執行的時候就不會刷新屏幕。大家看看效果。
看,通過這種方法就完美解決了吧。
4:下墜加反彈
這段代碼不復雜,反彈操作發生在當球碰到了黑線停止不動后,然后以之前的速度進行向上走的過程,走的過程,速度不斷減小到零。為了讓代碼看着簡單清晰,我們又用了自定義語句的做法。單獨做了個反彈的語句命令。
5:下墜反彈,反彈幅度不斷減小直到靜止在黑線上。
這個效果不復雜,只需要每次反彈的時候減少反彈的初始速度就行。讓我們把這條語句加上。
奇怪了,球最后靜止之后,竟然沒有停下來,反而飛到天上去了。這是什么bug呢?這是因為在最后當反彈速度為零的時候,已經應該靜止下來的時候,由於沒有做判斷控制,反彈速度的數值繼續增加已經由負值轉為正值,不再是向下降落,而是向上飛了。所以球就直接向上加速飛去了。所以我們要加個判斷,當反彈的初始速度為零時,反彈要停止下來。
這個下落和反彈目前看起來挺完美了。
6:用空格鍵做個起跳的過程。
最后一步就是把這個程序做成剛開始視頻的樣子,需要增加一個用空格鍵來控制小球起跳的過程。
看起來很簡單,通常我們也會這么做,但是實際執行效果呢?我們看一下:
關於按空格鍵,我們之前就有過一講,主要是按鍵這個過程這么簡單處理有兩個問題:
1:按鍵的過程有時延,有的人按的快,有的人按的慢,所以可能你按了一下,由於按的慢,程序當成你按了幾下。
2:球在跳躍的過程中,你按了空格鍵,球就在半空中進入了起跳的過程。
要解決這個問題就要加狀態變量了,只有在球已經靜止在黑線上時,才准許用空格鍵起跳。
下面我把這個程序全部貼出來。大家可以試着做一下。
我們做程序有時候就像畫一幅畫一樣,如果有畫的不好的地方,你總會時不時想起來,總想把它畫好。做程序也一樣,只有你對自己的程序很滿意了,你才會覺得非常開心。