用原生 JS 寫一個簡易版的臺球
前言
突發奇想想用JS寫一個臺球小游戲,磕磕碰碰之后,算是實現了一個簡易版的。用到的知識主要是通過遞歸來調用requestAnimationFrame,以及一些簡單的三角函數角度計算。requestAnimationFrame就是一個JS動畫幀,簡單來說和定時器有點相似,但是動畫呈現出來的效果比定時器更流暢,性能更好。
1、繪制游戲元素
CSS
html
JS
2、球桿跟隨鼠標旋轉
先獲取鼠標在頁面的坐標,然后減去球心的坐標,就得到了一個相對坐標。然后把球心當成原點,計算出鼠標相對球心的角度,最后把這個角度賦值給球桿的transform屬性,就可以實現球桿跟隨鼠標旋轉的效果了
3、球桿的擊球動畫
球桿其實是由 3 個盒子組成的,最外面的大盒子來控制球桿的旋轉,大盒子里面有兩個盒子 gan2 和 gan3, gan3 這個盒子用來放球桿的圖片。gan2 這個盒子是看不到的,它負責把球桿向外面撐開。所以球桿的動畫就很簡單了,只要增加和減少 gan2 盒子的寬,就能實現球桿的伸縮了。
實現動畫就是用尾遞歸來重復調用 requestAnimationFrame 函數。
4、球桿擊球后,母球的移動
母球的擊球動畫同樣是通過尾遞歸來重復調用 requestAnimationFrame 函數,但是涉及到墻壁反彈,以及撞擊子秋,母球的移動函數的參數會復雜一點。
母球移動的速度和距離,是通過i這個變量來控制的,這個函數每調用一次,i 會遞減。x 和 y 這兩個參數會接收一個 -1 到 1 之間的值,起到一個方向系數的效果,通過參數把球桿的撞擊方向傳遞進來。碰到邊界之后,就把對應的系數取負,然后用新系數執行移動函數,就能起到反彈的效果了。
5、母球撞擊子球移動
這是最麻煩的一步,撞擊后兩個球的運動軌跡都會發生變化。只考慮最普通的撞擊,子球的運動方向應該是撞擊點與子球球心這條直線的方向,這個比較好計算。母球的撞擊后的方向應該是以撞擊點的那條切線進行反彈,三角函數幾乎忘光了,這個我也不知道怎么計算了,所以用了個簡易的算法,就和撞墻壁一樣直接反彈,這樣會導致某些角度下,母球撞擊之后的方向不正常。
把這個撞擊判斷加到母球移動的函數里面,然后再補充一個子球的移動函數,整個代碼就寫完了
總結
這個小游戲實現的并不完美,因為用到了太多的遞歸,很多細節方面不好控制,球的運動軌跡也很難計算,在某些角度下會出現BUG。球雖然是圓的,但是它的盒子是正方形,所以撞擊有的時候會看著很奇怪。移動的函數寫的也有缺陷,它不能復用,如果想添加多個球,函數就得改。
這個破產版的臺球主要就是寫著玩一玩,嘗試了一下JS動畫的實現 , 不喜勿噴。