其實在2016年,我就準備寫這個小遊戲了。可是奈何當時沒文化😌,也尚未轉行成前端。既沒有面向對象的思想,也不懂什麼尋徑算法,更不瞭解模塊化,只是掌握了canvas的基本知識。因此以當時的水平,就搞了一段時間後,把羊,狼,磚塊畫了出來,具體怎麼運動?搞不下去,就擱置下來了。時間飛逝,這個小遊戲就這麼靜靜地爛尾了兩年多,直到前幾天,在codepen上看到了一個尋徑的demo,才又從新撿起來。css
如今再撿起來,感受駕輕就熟應手了許多,儘管中間也碰到了一些坑,但不至於無從下手。儘管還有許多能夠改進的地方,代碼寫的也不怎麼規範,斷斷續續搞了一週多,好歹搞出來一個能用的版本。下面說說開發過程當中遇到的一些問題,和學到的知識。html
這裏是試玩地址:https://www.imgss.top/demo/wAs/
github: https://github.com/imgss/wAs前端
在手機上打開這個小遊戲時,遊戲畫面會變得比較模糊,這是因爲手機屏幕的css尺寸和真實的物理像素數量是不同的。這也是window.devicePixelRatio
這個屬性存在的意義。同時canvas的css寬度和canvas自己的寬度也是這個區別。舉個例子:git
一個手機的 devicePixelRatio 是3,canvas的css寬度是500px,要想使canvas繪製出的圖片不模糊,須要給canvas的寬度設置成多少?答案是500 * 3 = 1500。寫成代碼是:github
var ratio = window.devicePixelRatio; var oldWidth = canvas.width; var oldHeight = canvas.height; canvas.width = oldWidth * ratio; //根據radio設置新的width,解決圖片模糊問題 canvas.height = oldHeight * ratio; canvas.style.width = oldWidth + "px"; canvas.style.height = oldHeight + "px";//使canvas在屏幕上的顯示和以前保持一致
這也是整個遊戲最難的地方,遊戲中羊是在不斷運動的,狼須要根據羊當前的位置計算出行動路徑。在實現中,我參考了codepen上的這個demo,具體的思路是,用一個二維數組來表示整張地圖,從目標節點(羊的位置)開始,向上下左右遍歷,若是碰到牆或者邊界就中止,並標記爲訪問過。再根據這些節點的兄弟節點進行遍歷,直到找到狼所在的位置,或者整個地圖所有搜索了一遍。算法
當在遍歷中找到狼的位置後,進行一次回溯,就拿到了狼的運動路徑。canvas
整個算法在search.js中,是根據上面的那個demo修改的,實現了一個pathFinder類;數組
export default class Pathfinder{ constructor(gridData, targetPosition, foundCallback) { this.gridData = gridData; this.targetPosition = targetPosition; this.foundCallback = foundCallback; this.width = this.gridData[0].length; this.height = this.gridData.length; } // 將二維地圖轉換成節點數據 parseGridData() { ... }
瞭解更多的尋徑算法知識能夠看這篇文章: https://www.redblobgames.com/pathfinding/a-star/introduction.html模塊化
在開發過程當中發現手機端的操做不是很流暢,找到了一個叫nipplejs的虛擬搖桿的庫。使用方法也很簡單,虛擬搖桿能夠是固定在屏幕的某個地方,也能夠是顯示在屏幕的任何一個地方。可是在實際中使用發現,用搖桿操做,很容易致使羊多跑或者少跑一兩格,對於這個遊戲來講,不如箭頭控制精度好,最終仍是放棄了。優化
遊戲裏還用到一個sweetalert庫,用來作彈出框的,沒有依賴,用起來很方便(實際上是作不出酷炫的彈窗特效)。
整個過程當中,加深了本身對算法重要性的認識,雖然前端不多涉及高深的算法,可是多懂一點算法知識絕對大有裨益。小遊戲中還有許多值得優化的地方,也還有幾個bug,這些之後再慢慢優化吧。(完)