在昨天的移動點光源實作上,我們透過更改光源的位置來達到動畫的效果,今天讓我們深入動畫的操作並實際上透過讓苦力怕擺頭、走動、膨脹的動作來練習基本動畫。
Photo by Mikhail Vasilyev on Unsplash
這是本系列第 11 篇,如果還沒看過第 10 篇可以點以下連結前往:
用 Three.js 來當個創世神 (10):專案實作#5 - 光影效果
在前面的文章中有提過,為了實現動畫的效果,就需要處理「每隔一段時間重新渲染畫面」的工作,而我們利用 requestAnimationFrame
完美的處理這個任務,讓畫面能在每 16.67ms(60 fps)
就執行一次 render()
裡的內容。
因此我們能透過在 render()
中更改物體的位置、旋轉、縮放、材質、形狀等等來達到動畫的效果,以下就讓我們實際操作來練習如何讓場景中的物體動起來!
在開始做動畫前,最重要的還是要了解目標物預期要如何動作,因此先參考一下在 Minecraft 中苦力怕實際上是怎麼運動的(參考影片)。
建議像筆者一樣動態視力不佳的朋友,可以將播放速度調成 0.25 倍觀察。
了解了苦力怕怎麼動之後,今天的目標要先來做到可以讓苦力怕有基本的擺頭、走動、膨脹三個動作,可以透過 dat.GUI 面板開關動畫:
let rotateHeadOffset = 0
// 苦力怕擺頭
function creeperHeadRotate() {
rotateHeadOffset += 0.04
creeperObj.head.rotation.y = Math.sin(rotateHeadOffset)
}
這邊 rotateHeadOffset
是遞增的弧度值,我們利用 sinθ
值會介於 (-1, 1)
的特性,讓苦力怕的頭可以沿著 y 軸有左右來回擺動的效果。
let walkOffset = 0
// 苦力怕走動
function creeperFeetWalk() {
walkOffset += 0.04
creeperObj.foot1.rotation.x = Math.sin(walkOffset) / 4 // 前腳左
creeperObj.foot2.rotation.x = -Math.sin(walkOffset) / 4 // 後腳左
creeperObj.foot3.rotation.x = -Math.sin(walkOffset) / 4 // 前腳右
creeperObj.foot4.rotation.x = Math.sin(walkOffset) / 4 // 後腳右
}
這邊跟上面擺頭的原理差不多,而分別都除以四代表旋轉的值介於 (-0.25, 0.25)
這個區間。由於四隻腳在走動的過程中會有前後交叉的效果,所以這邊需要分邊操縱四隻腳,但若是要同時調整四隻腳時,則可以更方便地使用 creeperObj.feet
整個腳的群組物件。
let scaleHeadOffset = 0
// 苦力怕膨脹
function creeperScaleBody() {
scaleHeadOffset += 0.04
let scaleRate = Math.abs(Math.sin(scaleHeadOffset)) / 16 + 1
creeperObj.creeper.scale.set(scaleRate, scaleRate, scaleRate)
}
膨脹的效果是苦力怕在爆炸前會有的前置動作,這邊的 scaleRate
利用 Math.abs(Math.sin(scaleHeadOffset))
取值在 (0, 1)
之間,再除以 16 後加 1,則會得到一個 (1, 1.0625)
的區間作為膨脹比例,讓苦力怕有輕微膨脹的效果。
而這裡因為要做到整隻苦力怕膨脹,所以是針對 creeperObj.creeper
整個群組做在每個方向縮放比例的操縱。
最後最重要的是記得要在 render()
中加入以上三個操作動畫的 function 才會有效果:
function render() {
...
creeperHeadRotate()
creeperFeetWalk()
creeperScaleBody()
...
requestAnimationFrame(render)
renderer.render(scene, camera)
}
可以發現動畫的操作並不難,以下是基本動畫的技術總結:
- 宣告遞增(減)值
- 將物體根據遞增(減)值做位置、旋轉、縮放等效果
- 在
render()
中加入動畫函式- 回家找高中的三角函數課本開始複習
今天實作基本動畫讓苦力怕能有擺頭、走動、膨脹的效果,明天將會繼續進行更複雜的動畫操作,並練習使用 Tween.js
來實作如何讓苦力怕能「追蹤鏡頭做有位移的走動」及「轉身」的動畫,我們明天見!