iT邦幫忙

2021 iThome 鐵人賽

DAY 20
0
Modern Web

從零開始打造網頁遊戲-造輪子你也辦的到!系列 第 20

Chapter4 - Canvas背景動畫(I)讓落葉隨風飄落、自然搖擺

  • 分享至 

  • xImage
  •  

本篇銜接上篇:https://ithelp.ithome.com.tw/articles/10272738

該如何讓動畫更自然?

今天來深入聊聊怎麼調節動畫模式的隨機性

今天由四個部分組成,來作循序漸進的思考:
讓我們用 今天的演示 來感受一下
https://ithelp.ithome.com.tw/upload/images/20210929/20135197jTaxhEEYic.png

為了沒看過前面19篇的朋友們簡述一下步驟

  1. 點選「上傳音樂」或「請選擇曲名」來換一首歌
  2. 點選「Play」進行播放,點選「Pause」暫停
  3. 選擇不同模式感受動畫的變化

規律

如果試著用昨天的代碼去跑動畫,就會發現它看起來相當規律

什麼意思呢?當時的角速度預設為定值,那每個物件的簡諧運動就很單純:

this.rotateOmega = 60 / 180 * Math.PI;
this.revolveOmega = 60 / 180 * Math.PI;

那如果我單純把60這個數字改成隨機的40~80之間行不行?這個問題留給大家思考答案,並想看看為什麼,歡迎留言表達觀點。

當角速度是定值時,就會發現動畫的路徑相當規律,可以很容易地透過觀察發現,每一個物件基本相同,更可以輕鬆預測動畫的走向,顯得呆版、無聊,卻可以減少使用者的負荷,更加輕鬆、具有一致性,很適合用在簡單的關卡,當你更重視注重情節而非挑戰性,規律顯然是最舒適的

多樣(period=1~2)

昨天我們寫了一個隨機數:this.period = 1 + Math.random() * 1;,但還沒真正拿來用,而之所以設定period的理由,其實是希望簡諧運動搖擺的幅度有大有小,假如週期不變,則幅度越大時移動速度越快,這樣就會變得相當奇怪(可以想像擺福是整個螢幕的寬度,然後在3秒間來回擺動),因此在擺福增加的時候也同時讓週期增加,這就是設定一個介於1~2之間的period之用意。

因此角速度除以period以後:

this.rotateOmega = 60 / this.period / 180 * Math.PI;
this.revolveOmega = 60 / this.period / 180 * Math.PI;

去把對應的擺福乘上period:

this.pointX = this.beginX + this.period * WIDTH * 0.04 * A + WIDTH * 0.02 * dT;
this.pointY = this.beginY + this.period * HEIGHT * 0.015 * C + HEIGHT * 0.08 * dT;

再順便提醒一下,最右側dT所負責的參數,就是動畫的線性前進方向,較容易被肉眼觀察!

當我們如上述代碼設置,就會使畫面更加生動,每一個彷彿都是獨立的個體,有著自己的運動軌跡,很難將兩三個物件聯想在一起,不過作為整體來看,還是能稍微看出整個動畫的走向,正往斜右下掉落,能夠良好的表達當前的意境,彷彿真的隨風飄落一般。

混亂

除了上述的作法,還可以考量到在角速度不變的情況下,增減整體的位移,設計兩個隨機數:

this.scaleX = 0.5 + Math.random() * 1;
this.scaleY = 0.5 + Math.random() * 1;

用來縮放XY的位移,使得有些走得更長,有些走的更短:

let x = this.scaleX * (this.period * WIDTH * 0.04 * A + WIDTH * 0.02 * dT);
let y = this.scaleY * (this.period * HEIGHT * 0.02 * C + HEIGHT * 0.06 * dT);
this.pointX = this.beginX + x;
this.pointY = this.beginY + y;

其實混亂概念上也就是遠近效果,可以搭配物件大小或Z軸作為參考標準,就不會顯得如此混亂

與上面的多樣相比,較難感受到隨風飄落的意境,更像是有更多不確定因素,是一個混亂的系統,即便還是能感受到物件來回擺動,然而物件的移動總是不如預期,似乎總會差一些、差一點,讓人覺得整體不和諧,各個都在搗亂的樣子,適合用於困難的關卡,增加挑戰性和挫折感。

自由

這是一個很主觀的定義,主要是對於掌控感下去作討論,我認為設計遊戲,無非就是思考:如何讓使用者感受到他能主宰整個遊戲世界,享受無邊無際的自由,強調回饋感這件事,是一個很值得摸索的設計,假如我們用在落葉掉落之時,那是否使用者就主宰了這個小世界,能隨著滑鼠的移動來改變動畫的行進,那是否,也掌控了風神呢?

採用的就是第二章用的滑鼠跟隨機制,參數設哪個沒有限制,看想研究哪個就設那個,該範例設置的是旋轉角速度:

function MouseAnime(){
    myMouse.NextFrame();
    animeList.forEach(obj => {
        obj.rotateOmega = myMouse.pointX * 40 / obj.period / 180 * Math.PI;
        if(mode == 'Free'){
            obj.scaleX = 1 + myMouse.pointX/2;
            obj.scaleY = 1 + myMouse.pointY/2;
        }
    })
}

不過要注意,每次滑鼠改變都會刷新,因此這種方法不能直接用於隨機數,比方說若想測試period,就得把一開始的隨機數存起來另外放,因此需要兩個變數。


上一篇
Chapter4 用音樂做動畫 結合前三章學習的內容,一口氣衝刺吧!
下一篇
Chapter4 - Canvas背景動畫(II)就如那輕薄的鴻毛,我心上小船載浮載沉
系列文
從零開始打造網頁遊戲-造輪子你也辦的到!31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言