Laya2.x遊戲引擎入門系列(三):經常使用的動畫開發

Laya引擎提供了哪些實現動畫的方式?

在開始講小遊戲開發中會使用到的實現動畫的方式,咱們先來回顧一下在H5開發中若是你想作一個動畫能夠會用到實現動畫的方式。css

  • Gif:最簡單的動畫實現方式,不須要開發插手只須要設計師提供資源便可,僅僅適合重複播放不須要控制動畫播放速度的動畫;html

  • CSS3 Keyframes:它是H5中最常使用的實現動畫方式,經過控制每一幀的圖片便可實現動做複雜的動畫,在不考慮性能的前提下,這種動畫實現方式適合大部分動畫場景css3

  • CSS3 Transition:能夠控制一個Dom元素的某些CSS屬性實現過渡效果,這種動畫實現方式通常是爲了不CSS屬性改變時樣式切換過於生硬而使用的;git

  • 視頻:目前已經有不少H5活動開始嘗試直接經過視頻做爲動畫的主要實現手段,經過JS響應用戶的行爲來播放不一樣的視頻來實現和用戶交互的效果,這種動畫實現方式適合代碼沒法實現的超複雜動畫github

  • JS實現的動畫:在上述實現動畫的方式都沒法實現時,只能經過JS大法來實現了,這裏即包括2種狀況:一、經過JS控制動畫流程或控制Dom緩動;二、經過JS控制Canvas或WebGL來畫動畫,這種動畫實現方式適合大部分複雜動畫場景typescript

回顧完H5中的一些動畫實現方式,咱們再來看看Laya遊戲引擎給咱們提供了哪些實現動畫的方式。json

  • 圖集動畫:這裏的圖集動畫是遊戲開發中的一個新概念,效果相似咱們前面提到的CSS Keyframes動畫,你能夠簡單的理解爲圖集 ≈ 雪碧圖,兩者的區別就是圖集還多了一份每一個圖片對應位置關係的配置表;c#

  • 緩動動畫:相似於前面提到的CSS Transition,這裏說相似其實只是最終實現的效果相似,Laya提供的緩動動畫是經過代碼控制的,更像JQuery中的$(selector).animate() 或者 Tween.js的Tween.to()Tween.from(),提供Laya.Tween.from()Laya.Tween.to()函數控制元素從狀態A逐步切換到狀態B;微信

  • 時間軸動畫:它能夠說是Laya遊戲開發中最經常使用的功能之一,初學者能夠把它理解成多個緩動動畫和圖集動畫的集合。在LayaIDE中還提供了時間軸動畫編輯器,能夠經過編輯時間軸上的每個關鍵幀快速實現圖片替換、位移、漸變、縮放等動畫效果;dom

  • 動效模板:它是將基於時間軸動畫的動畫效果提煉出來抽象成一個效果模板,後續將效果附加給其餘ui組件上,使得組件能夠無需編碼就實現已有的動畫效果;

  • 骨骼動畫:遊戲中特有的一種模型動畫效果,在模型中具備互相鏈接的骨骼組成的骨架結構,經過改變骨骼的朝向和位置從而造成動畫,目前Laya支持2種骨骼動畫,Spine骨骼動畫DragonBone龍骨動畫

目前,僅僅H5中的Gif動畫沒法在Laya遊戲引擎中支持,其餘動畫方式均可以在Laya遊戲中使用。下圖爲來自靈魂畫師的動畫對比圖

咱們應該怎麼去使用這些動畫?

介紹了遊戲提供的實現動畫的方式以後,咱們來看一下該如何使用這些動畫

1. 圖集動畫

圖集動畫自己就是直接播放圖集資源,咱們前面也提到了圖集資源其實就是雪碧圖搭配一個圖片位置信息表,如今咱們來看一下真實的圖集資源是什麼樣子的。

下圖爲咱們具體用到的圖集資源,blink.atlas(每一個圖片資源的位置信息),blink.png(每一幀圖片合成的雪碧圖)

blink.atlas:記錄每一張圖片在雪碧圖中的位置,內容以下:

{"frames":{"lz_01.png":{"frame":{"h":604,"idx":0,"w":650,"x":0,"y":0},"sourceSize":{"h":667,"w":720},"spriteSourceSize":{"x":15,"y":23}},"lz_03.png":{"frame":{"h":625,"idx":0,"w":667,"x":651,"y":0},"sourceSize":{"h":667,"w":720},"spriteSourceSize":{"x":42,"y":25}},"lz_05.png":{"frame":{"h":619,"idx":0,"w":623,"x":0,"y":605},"sourceSize":{"h":667,"w":720},"spriteSourceSize":{"x":63,"y":13}},"lz_07.png":{"frame":{"h":617,"idx":0,"w":670,"x":624,"y":626},"sourceSize":{"h":667,"w":720},"spriteSourceSize":{"x":20,"y":24}},"lz_09.png":{"frame":{"h":618,"idx":0,"w":688,"x":1295,"y":626},"sourceSize":{"h":667,"w":720},"spriteSourceSize":{"x":13,"y":30}},"lz_11.png":{"frame":{"h":617,"idx":0,"w":671,"x":0,"y":1244},"sourceSize":{"h":667,"w":720},"spriteSourceSize":{"x":35,"y":7}},"lz_13.png":{"frame":{"h":615,"idx":0,"w":676,"x":1319,"y":0},"sourceSize":{"h":667,"w":720},"spriteSourceSize":{"x":35,"y":13}},"lz_15.png":{"frame":{"h":642,"idx":0,"w":613,"x":672,"y":1244},"sourceSize":{"h":667,"w":720},"spriteSourceSize":{"x":71,"y":0}},"lz_17.png":{"frame":{"h":614,"idx":0,"w":702,"x":1286,"y":1245},"sourceSize":{"h":667,"w":720},"spriteSourceSize":{"x":10,"y":18}},"lz_19.png":{"frame":{"h":598,"idx":0,"w":614,"x":1984,"y":616},"sourceSize":{"h":667,"w":720},"spriteSourceSize":{"x":98,"y":24}},"lz_21.png":{"frame":{"h":613,"idx":0,"w":621,"x":1996,"y":0},"sourceSize":{"h":667,"w":720},"spriteSourceSize":{"x":79,"y":25}},"lz_23.png":{"frame":{"h":551,"idx":0,"w":602,"x":1989,"y":1215},"sourceSize":{"h":667,"w":720},"spriteSourceSize":{"x":53,"y":46}}},"meta":{"image":"blink.png","prefix":"lamp/blink/"}}
複製代碼

blink.png:全部幀對應的圖片的合集(此處爲原圖,可自行下載做爲demo使用),內容以下:

總體的使用過程也很簡單,加載圖集資源以後,直接播放便可

/** * 使用圖集動畫流程: * 一、建立動畫實例 * 二、加載圖集資源 *.atlas * 三、添加到舞臺 * 四、播放動畫 */
 
// 建立動畫實例
let animation = new Laya.Animation();
// 加載圖集資源 blink.atlas,引擎會根據atlas文件自行查找到圖片資源 blink.png
animation.loadAtlas('animation/blink.atlas', new Laya.Handler(this, () => {
    // 加載完成後,將動畫添加到舞臺上,並開始播放
    this.addChild(animation);
    // 無限循環播放
    animation.play()
}));
複製代碼

具體效果以下:

2. 緩動動畫

緩動動畫是提升遊戲體驗的重要手段,Laya引擎將緩動動畫封裝的很不錯,對外只暴露出2個類,緩動類Laya.Tween、速度類Laya.Ease,經過這2個類便可快速實現緩動動畫。咱們來看一下如何實現一個方塊移動且變色:

/** * 使用緩動動畫流程: * 一、給須要移動的元素設置緩動後的樣式屬性便可 */
 
// 舞臺中添加元素,並設置大小和位置
let $box = new Laya.Box();
$box.size(100, 100).pos(0, 0);
$box.bgColor = 'red';
this.addChild($box)

// 經過緩動動畫控制 $box位置移動、大小變化;整個動畫耗時2秒
Laya.Tween.to($box, {
    width: 200,
    height: 200,
    x: 300,
    y: 700
}, 2000, Laya.Ease.linearInOut, Laya.Handler.create(this, () => {
    // 緩動動畫結束後的操做
    Laya.Tween.to($box, {
        width: 100,
        height: 100,
        x: 0,
        y: 0
    }, 2000);
}));
複製代碼

具體效果以下:

3. 時間軸動畫

Laya提供了2種方式實現時間軸動畫,一是利用IDE的編輯模式建立時間軸動畫,二是利用代碼直接建立時間軸動畫。咱們來看一下如何實現一個方塊移動且改變大小:

一、 經過編輯模式建立時間軸動畫的步驟以下:

(a) 右擊左側場景目錄,新建時間軸動畫文件

(b) 將圖片拖入場景,點擊「動畫編輯模式」,設置關鍵幀屬性,修圖片大小和xy屬性

(c) 點擊時間軸上對應的幀增長想要的屬性,重複屢次,添加多個關鍵幀

(d) 將生成的時間軸動畫*.ani拖拽到場景中,從新編譯便可看到效果

二、 經過代碼建立時間軸動畫的方式:

/** * 使用時間軸動畫流程: * 一、給須要移動的元素設置每一幀的樣式便可 */

// 舞臺中添加元素,並設置大小和位置
let $box = new Laya.Box();
$box.size(100, 100).pos(0, 0);
$box.bgColor = 'blue';
this.addChild($box)

// 建立時間軸動畫
let timeline = new Laya.TimeLine();
timeline
    // 時間軸動畫第一個序列
    .to($box, {
        width: 200,
        height: 200,
        x: 300,
        y: 700
    }, 2000)
    // 時間軸動畫第二個序列
    .to($box, {
        width: 100,
        height: 100,
        x: 0,
        y: 0
    }, 2000);
timeline.play();
複製代碼

具體效果以下:

4. 動效模板

動效模板能夠理解成是一個時間動畫效果的抽象,相似於一個css3中定義一個@keyframes,只要給對應的dom添加上該keyframes便可執行相同的動畫。目前動效模板只支持在IDE的編輯模式中建立。步驟以下:

(a) 右擊左側場景目錄,建立動效模板

(b) 拖拽添加圖片

(c) 經過鼠標控制組件的軸心點

(d) 編輯關鍵幀,添加搖動的動畫效果,相似前面的編輯時間軸動畫時的操做

(e) 在新的場景中新建圖片組件,並將剛剛實現的動效模板 Shake.efc添加到圖片組件中

具體效果以下:

5. 骨骼動畫

骨骼動畫的使用相對其餘動畫較爲複雜,由於他須要先利用Laya自帶的ui資源轉換工具把現有的設計資源轉換成Laya引擎認識的資源(紋理集*.png、龍骨資源信息*.sk)。由於目前市面上主流的作龍骨動畫的工具備2種:DragonBone、Spine。其中Spine是收費軟件,DragonBone是免費的,爲了方便你們本身操做,咱們就用DragonBones作演示工具。使用步驟:

(a) 下載DragonBones工具,官網地址

(b) 打開DragonBone工具後隨便選擇一個骨骼動畫的示例,若是你有本身的龍骨動畫資源也能夠用本身的,這裏爲了方便就選了第一個資源。

(c) 導出laya引擎能夠解析的資源,選擇文件 -> 導出,選擇正確的格式

(d) 利用IDE建立一個新的Laya2D項目,並把上述導出的文件放到項目的根目錄下面

(e) 經過IDE提供的工具將龍骨動畫資源轉換引擎可用的資源

(f) 轉換完成後,會在目錄中生成*.png*.sk文件,將文件放到項目的資源文件中 laya/assets/dragonBone(dragonBone文件爲本身建立,取別的名字也能夠)。

(g) 在編輯模式下,按F9,增長勾選類庫laya.ani.js

(h) 直接修改初始化項目中的src/script/GameUI.ts,修改成以下代碼,從新編譯便可看到效果

import { ui } from "./../ui/layaMaxUI";

export default class GameUI extends ui.test.TestSceneUI {
    onEnable(): void {
        /** * 使用龍骨動畫的流程: * 一、建立動畫模版 * 二、加載龍骨資源 * 三、經過模版建立龍骨動畫實例 * 四、播放龍骨動畫 */

        // 建立動畫模版,方便後續存在複用動畫的場景
        let templet = new Laya.Templet();
        // 加載龍骨資源
        templet.loadAni('dragonBone/Dragon_1.sk');
        // 處理加載完成事件
        templet.on(Laya.Event.COMPLETE, this, () => {
            // 經過模版建立動畫實例
            // 0,使用模板緩衝的數據,模板緩衝的數據,不容許修改
            // 1,使用動畫本身的緩衝區,每一個動畫都會有本身的緩衝區,至關耗費內存 (內存開銷大,計算開銷小,支持換裝)
            // 2,使用動態方式,去實時去畫 (內存開銷小,計算開銷大,支持換裝,不建議使用)
            let skeleton = templet.buildArmature(1);
            skeleton.pos(200, 500);
            this.addChild(skeleton);
            // 播放動畫
            skeleton.play(0, true);
        });
    }
}
複製代碼

具體效果以下:

經常使用的動畫優化策略

基本上任何動畫均可以經過時間軸動畫或者圖集動畫來實現,只不過是實現的須要的圖集大小的區別和是否適合的區別,咱們快遊戲自己對包體大小都有嚴格的控制,快遊戲主包限制爲10MB,若是按照設計師提供的動畫資源直接使用,大機率會致使遊戲包體很快就超過限制,針對這一問題這裏列舉幾個經常使用的動畫優化策略:

  • 壓縮圖集中每個圖片資源,裁剪圖片的空白區域

  • 剔除圖集動畫中的重複圖片

  • 調整動畫的播放速率,跳幀刪除動畫圖片

  • 嘗試將複雜圖集動畫拆減爲多個簡單圖集動畫或者緩動動畫,儘可能減小純粹的圖集動畫

  • 實現遊戲角色的動做動畫時,能夠考慮使用骨骼動畫

上述優化策略主要仍是從如何減小動畫資源大小方向上考慮。Laya引擎自身對動畫作了不少本身的優化,保證了你們開箱即用便可,有興趣瞭解Laya引擎,能夠自行查看源碼。

Laya2.x遊戲引擎入門系列介紹

筆者19年5月開始深度參與了一個OPPO快遊戲項目(相似微信小遊戲),從零開始折騰到如今,終於算是入了H5遊戲開發的門。目前關於Laya引擎開發快遊戲的教程還很少,因而筆者決定把這幾個月踩過的坑、解決的問題、總結的經驗都記錄下來,方便其餘準備入坑的同窗提早規避。

Laya2.x遊戲引擎入門系列預計會寫如下文章,記錄如何從零開始完成一個快遊戲的開發和上架:

同時,Laya2目前將引擎代碼經過TypeScript進行了重構,你們若是在寫代碼中遇到什麼疑問均可以直接在GitHub源碼中找到答案,後續筆者也會寫一些關於Laya2源碼解析的文章,有興趣的朋友能夠關注。

第一次嘗試寫完整的教學文章,若有錯誤或不嚴謹的地方,請務必給予指正,十分感謝!

相關文章
相關標籤/搜索