為處理更複雜的情境,我們在這個章節要學習以下兩種程式的流程控制方式:
除了基本的算術運算,我們還可以讓程式幫我們做「比較」與「邏輯」運算。當我們有特殊需要,想要在特定情況執行不同程式時,「比較」與「邏輯」這樣的運算就顯得格外重要;例如,「在 BMI 大於 25 而且身高小於 168 時,就提醒用戶需要減肥」這樣的動作,需要我們比較 BMI 與身高的大小,而且還要確認兩者同時發生。
比較運算相當直覺;我們提供兩組資料給電腦,請他將比較後的結果提供給我們。一般比較後的結果僅有兩種:
true
- 真 / 是 / 對false
- 假 / 否 / 錯其中 true
與 false
是一組特殊的資料,他們有別於「數字」與「字串」,我們稱之為「布林 ( boolean ) 」資料類別。
比方說下列運算,我們請電腦告訴我們 2 < 1
是否正確,並把計算結果存到 a_value
變數中:
以這個例子來說,a_value
得到的值永遠是 false
,因為 2 永遠都大於 1;比較常見的情況是我們比較變數裡的值,比方說:
因為變數 a
與 b
的值隨時都可能改變,因此這個比較結果就會隨情況而變。
常見的「比較」運算指令有以下幾種:
>
: 大於>=
: 大於或等於<
: 小於<=
: 小於或懂於==
: 等於!=
: 不等於要注意不同型別的資料比較會導致電腦進行資料轉型,進而可能得到意料之外的結果,這是一種即便資深工程師都很有可能忽視的問題。請隨時注意資料型態的問題避免程式發生意料之外的狀況。
如前述的例子,「在 BMI 大於 25 而且身高小於 168 時」除了做了兩個比較以外,我們還需要確認兩者同時發生。「而且」可以視做一個運算,把前者 ( bmi > 25 ) 與後者 ( height < 168 ) 做一個「而且」運算。這樣的運算我們叫他「邏輯運算」,寫法是「&&」:
與而且相對的是「或者」,可以用「||」表示:
邏輯運算主要是用來操作布林 ( boolean ) 型態的資料,因此在其前後的資料會被轉型為布林,例如:
會先將 1
轉型為布林 (得到 true
)、0
亦轉型為布林 (得到 false
),因此運算結果最後會是 true || false
,也就是 true
。
除了「小於」「大於」等概念,你也可以用「不大於」、「不小於」等方式運算。在運算結果前面加上驚嘆號!
可以使運算結果的真假交換 ( 真變假、假變真 ),例如:
各種運算混在一起揪~竟誰該先算是件很頭痛的事,因此程式語言本身規定了各種運算的先後順序 (operator precedence )。我們不深究優先序的細節,但請大家基本上簡單記住這個規則即可:
()
> 反向 -
> 算術 + - * /
> 邏輯 && ||
我們可以叫電腦在符合某些條件時才執行特定程式。我們只需要使用 if else
語法:
為了試試效果,我們來做做看下面的練習吧!
在基本語法的練習中,我們嘗試了 BMI 的計算。為了加強我們計算機的功能,我們試著用 if / else
來加入過重警告吧!
比方說,在 bmi 超過 25 時,使用 alert
函式提醒用戶:
您能基於以上程式碼,再加入一個體重 ( bmi < 18 ) 過輕的警告嗎?
在上面的練習中,我們有時候會在程式碼中看到像這樣、由斜線 /
與星號 *
組成的語法:
這其實是程式的註解,標記在 /*
與 */
之間的內容為「註解」,是寫給人看的文字描述,電腦會跳過這個段落不執行它。
為了讓東西動起來,我們需要不斷的執行指令來更新元素的位置等屬性,但是像這樣的程式是不行的:
雖然看起來好像更新了四次,但瀏覽器執行我們的指令會一次執行完以後,才開始重新繪製網網頁上的元素,也因此我們只會看到 node
瞬間跳到了 40px
的位置。
不過瀏覽器提供了一個方便的函式 requestAnimationFrame
,用來接收更新畫面的程式。他接收一個函式做為參數,並會在適當的時機幫你執行該函式:
我們可以在函式裡再次呼叫 requestAnimationFrame
,利用類似「自我呼叫」的方式達成無限重繪的循環:
注意到我們的自訂函式 myAnimation
有接受一個參數 t
,那是 requestAnimationFrame
會主動提供給我們的「時間」資訊 ( 單位 ms ),可以簡單想像成「目前播放多久了」的概念。
我們可以試著利用時間 t
來替標籤更新位置。簡單的使用餘數運算%
:
利用基本語法中的小童搭配 requestAnimationFrame
來嘗試做移動動畫吧!你能讓小童跑慢一點嗎?
上例直接使用時間來幫小童定位,但一般來說我們會想自行控制角色的位置。我們需要先定義一組變數儲存座標:
然後在繪製小童時,使用這組變數當做他的 left
與 top
樣式值:
接著,在鍵盤事件時觸發座標變換。由於方向有四種,我們需要用到條件判斷式搭配基本語法中提到的鍵盤事件來使用。
相對於前面使用的 onkeyup
,我們希望玩家按著鍵盤時角色就會移動,因此我們需要使用 onkeydown
事件:
還記得 evt.keyCode
對應到的方向鍵值嗎?
我們先試試看往右移動吧!當 evt.keyCode == 39
時, player.x
的值要增加 1
:
接下來的部份你可以把他完成嗎?
請把移動控制的部份完成、搭配前面實作的動畫循環來做出下列效果:
當你用方向鍵控制小童時,上下鍵會導致網頁捲動,很不方便。能不能不要讓他捲動呢?
在事件控制函式的 evt
參數中提供了一個函式,名字剛好就解釋了其用途:
預設行為即此事件發生時、瀏覽器原本預期要執行的動作 ( 比方說點擊連結跳轉、右鍵跳出選單、上下移動捲軸等 ),因此我們只要在按鍵事件中執行這個函式,原本預期的行為 ( 也就是捲動 ) 就不會發生了:
要注意這樣會擋住所有按鍵的預設行為,所以如果只想要避免捲動,我們可以使用條件判斷式,在按上、下時再執行 preventDefault
即可:
試著加上跳躍的動作吧!你有辦法讓玩家按空白鍵 ( keyCode 32 ) 時,讓小童原地跳一下嗎?
為了要實作跳躍,我們要簡單模擬重力。重力簡單的說就是向下的加速度,於是我們需要在 player
物件中額外加上一個速度變數 v
:
並在跳躍時給小童一個瞬間向上的速度,用變數 v
代表:
同時隨時不斷的以重力更新速度、再以速度更新座標、再設定一個地板條件讓他著陸:
以上僅為部份程式碼,細節留給你完成吧!下圖即為範例結果,試著按按看空白鍵即可以看到跳躍效果:
New Media Techniques and Design