一步一步HTML5粒子編輯器


寫在前面

大家閱讀此文之前,可以先看一篇MiloYip的文章:用JavaScript玩轉游戲物理(一)運動學模擬與粒子系統,看完之后再看此文,更加容易理解。

MiloYip使用的粒子是canvas中繪制的圓,還有一些粒子效果是基於 像素級別的,如:火焰字 ,但是使用像素的計算成本太大,因為需要的粒子數量太多,甚至要配合一些nosie算法,如(perlin nosie),計算量太大。

所以一般會先設計好粒子的紋理(每個紋理假設是32*32,一個粒子就包含了九百多個像素了),這樣需要的粒子個數不多,計算量也不大,管理粒子的成本也不高(對粒子增刪改查)。

canvas globalCompositeOperation

粒子系統在什么時候最漂亮?晚上!所以在繪制紋理的時候,需要設置globalCompositeOperation 的值為lighter。其作用是:在圖形重疊的地方,顏色由兩種顏色值的加值來決定。

globalCompositeOperation 還有非常多的屬性可以設置,詳情見:w3school。

粒子系統

粒子系統的本質其實就是粒子從發射到消失的過程。所以,可以立刻想到一些配置項目:

1.發射速度(每個粒子的速度、方向、角度范圍)

2.發射區域(定點發射,還是在某個區域發射)

3.重力場(你是在月球上發射,還是在地球上發射,還是太空的失重狀態下)

4.粒子紋理(你發射的是激光、還是五角星、還是煙霧)

5.紋理濾鏡(激光是紅色還是藍色)

6.發射頻率(你是一秒發射一次、還是一秒發射100次)

每個參數的變化都會導致呈現效果截然不同。

數學與物理

比如運動方向的獨立性,2維空間可以使用new Vector2(1,2)來描繪速度,把速度拆分成x和y方向,1代表x軸方向的速度,2代表y軸方向的速度

同樣,重力場也可以拆封成兩個方向。如new Vector2(0,0.98),0代表x軸方向的速度,0.98代表y軸方向的速度

簡單的積分思想:(如:速度是加速度在時間上的累加,路程是速度在時間上的累加等等)。

當然,聽上去好像要會微積分才能寫粒子系統似的,但其實微積分根本體現不再程序里面,因為程序/游戲里面有core loop,loop里面干的事情就是積分… 比如:

tick: function () {
    this.velocity.add(this.acceleration);
    this.position.add(this.velocity.multiply(0.1));
    this.rotatingSpeed+=this.rotatingAcceleration;
    this.rotation += this.rotatingSpeed;
    this.alpha -= this.hideSpeed;
}

所以有這個思想就行,根本不需要會微積分 =  =!

Canvas UI小控件

整個編輯器的所有控件都是canvas寫的,感覺就三個詞:簡單、粗暴、直接。使用起來也非常方便。如,下面這個控制發射范圍、粒子、方向的控件:

使用控件的代碼:

var dirCtrl=new PE.CircleAdjust({
    min: 0,
    max: 50,
    rotation: -30,
    value: 10,
    angleRange:50,
    change: function (value,angle) {
        ps.setAngle(angle);
        ps.setSpeed(value);
    },
    renderTo: document.getElementById("emitAngleCtrl")
 
});

當然這里不是否定dom寫控件,而是,有的時候canvas寫UI更具備優勢。還有一些場景是dom寫控件無法實現的。(比如全局的濾鏡效果、波浪效果等,也就是跟像素有關,dom相對較弱)

其他

粒子編輯器,還使用了一些HTML5特性,比如拖拽、FileReader、和blob下載功能。如,基於blob封裝了一個工具函數用於下載文件:

Util.downloadFile=function(code, fileName) {
    if (window.URL.createObjectURL) {
        var fileParts = [code];
        var bb = new Blob(fileParts, {
            type: "text/plain"
        });
        var dnlnk = window.URL.createObjectURL(bb);
        var dlLink = document.createElement("a");
        dlLink.setAttribute("href", dnlnk);
        dlLink.setAttribute("download", fileName);
        dlLink.click();
    }
}

傳送門

demo: http://alloyteam.github.io/ParticleEditor/

github: https://github.com/AlloyTeam/ParticleEditor

ps:編輯器使用小測驗:你能使用demo的粒子編輯器實現下面那只企鵝效果嗎?:)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM