WebAssembly Demo之Canvas中隨機運動圓球

雲荒杯傾發表於2019-05-14

作者:雲荒杯傾

1、Demo功能介紹

實現了一個圓球在800px * 600px畫布內隨機運動,固定時間間隔隨機運動一次,運動方向由x和y軸組成的向量決定,這個向量是隨機值(後面會稱它為隨機向量),從C語言程式碼中的隨機函式獲取,JS程式碼實現小球的畫布渲染、越界糾正等工作。

Demo同時實現了純JS(即不使用WebAssembly)和WebAssembly兩個版本,都在Demo地址中。

2、Demo地址

github倉庫
檢視演示1 :一個不顯示軌跡的小球demo
檢視演示2 :一個顯示運動軌跡的小球demo
檢視演示3:一個小球平移demo

3、Demo目錄結構

因為demo比較簡單,也沒有什麼js庫依賴,所以本庫的所有demo都是按照目錄區分的(一個目錄是一個demo,億一共四個),而沒有使用諸如src、doc、dist之類的結構。

canvasDemo-wasm1:C程式碼中未加隨機時間種子的一種實現,因此每次重新整理HTML頁面實際上產生的是同一個隨機序列,也就是說每次重新整理頁面後,若觀察小球的運動軌跡,都是一樣的。不過因為沒有隨機時間種子,所以,不管JS setInerval設定的時間間隔多短暫,這一個隨機序列的每個值都是新鮮隨機出來的,即:與上一個隨機值重複的概率僅等於隨機範圍分之一。因此,這種實現下,小球的運動軌跡在canvas內的分佈更加的均勻。
canvasDemo-wasm2 :C程式碼中加了隨機時間種子的一種實現,小球移動不均勻,因為隨機種子的時間粒度比較粗,而隨機運動的時間間隔遠小於這個時間粒度,所以同一對隨機值(向量)會連續重複好幾次,這就造成了小球某次執行實際上並不隨機的效果。

注:上面兩種實現只有下面兩句C程式碼的差別:
#include<time.h>
srand(time(NULL))
再注:wasm1和wams2兩個demo本質是一個。僅僅是因為C語言中的隨機時間種子問題,單獨多寫了一個。

canvasDemo-JS版本: 是canvasDemo-wasm1 demo的純JS實現的版本。跟wasm沒有關係。
translate-wasm:實現小球從左到右平移運動的demo,wasm實現,使用的wasm的API,沒有用膠水程式碼。

4、canvasDemo-wasm1 Demo中主要函式介紹

C語言部分

有三個函式

函式名 引數 返回值 描述
Radom int m,int n int x 使用c語言的rand()函式生成m和n之間的整數,以x返回。
randomInTwoSection int m,int n int x 給定一個隨機區間,如果生成的隨機值在左半邊,則生成一個負的移動值,以x返回;反之,x返回正的移動值
randomGenerator int xpos,int ypos,int radius char* a 給定當前小球在畫布內的位置:[xpos,ypos]和小球半徑,生成下一次移動的向量,之所以有半徑引數傳入,是設定了一個規則,如果小球pos加減radius已經到達canvas邊界,則下次移動,某個方向的隨機值必須為負。比如已經到達左邊界,則下次運動,X方向的隨機數必須是正數,小球才會向右滾動,否則會出左邊界。

JS部分

功能1:初始化canvas
功能2:run函式,內部是接受C程式碼傳過來的隨機向量,賦給canvas的ctx.arc()以畫圓。
功能3:設定移動變換的時間間隔。

5、編譯C程式碼過程解釋

本demo使用的emscripten編譯命令為:

emcc -o a.html a.c -Os -s WASM=1 --shell-file shell_minimal.html

執行完,會生成,一個a.HTML,一個a.wasm,一個a.js。
加上a.c和shell_minimal.html,共五個檔案。所以第3節中的random和random2目錄下都有這5個檔案,為方便大家重複編譯,還附加了1個使用的編譯命令的文字檔案。

說明:
(1)a.c,a.html中的a是舉例,自己開發編譯時 請按實際的c檔名稱和想要輸出的html檔名;
(2)-Os是優化引數,生成的a.js是已經壓縮過的,這是膠水程式碼,它裡面有引用生成的a.wasm,有使用WebAssembly API,如WebAssembly.memory和WebAssembly.Table()等;不加就不壓縮,js體積變大;
(3)shell_minimal.html是模板檔案,7KB大小,有一些膠水程式碼,按官方說法,不建議自己寫模板。關於到底使用什麼開發模式,用asm?用wasm?用wasm的話用不用膠水程式碼?這幾個問號分別對應什麼編譯命令?若想理清以上幾個問題,請關注以下網址:https://kripken.github.io/ems…

注:為啥要寫一下我demo中使用的編譯命令呢?因為emcc的命令選項實在是太多了,稍微有點不一樣,編譯出來的wasm就不同,導致報錯之類。

6、Demo使用或檢視

直接執行canvasDemo-wasm1和canvasDemo-wasm1目錄下的HTML檔案應該不行,因為是ftp協議,fetch之類的函式會報錯,建議git clone後到webstorm開發環境,這樣直接執行html檔案就可以了。

可以寫個node server跑一下。
或者直接用http-server庫。

相關文章