這篇文章主要介紹了關於使用canvas實現迷宮遊戲,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下
#(最近設計模式看的有點頭大,一直面對純js實在是有些枯燥-_-。所以寫一點有趣的東西調劑一下)
現在canvas
已經不算新鮮了,不過由於日常業務中並不常用,所以實踐不多,今天分享一下,如何實現簡單canvas
迷宮。這個範例來自《html5秘籍》第二版,程式碼有稍微做了點調整。
由於中間有一步使用canvas取得圖片資訊的時候,必須使用伺服器環境。所以我先寫了一個範例丟在伺服器上,大家可以先體驗一下效果(用成就感作為驅動力哈哈哈)
實現這個小遊戲也不難,讓我們想想,一個迷宮遊戲有哪些基本要素。
首先當然得有個地圖,然後得有個移動的小人,這兩個我們利用cavans來繪製;
接下來是物體移動的程序,這個程式主要包括2個面向:
1.讓物體跟我們指定的指令來移動;
2.偵測物體是否碰到牆體或者出口。
繪製地圖的主要步驟是:
取得一張地圖的圖片
利用cavans繪製影像。
迷宮地圖的生成,可以藉助Google的一個迷宮線上生成器來獲得。
繪製小人也是一樣直接找一個小人的圖片即可,不過這裡要注意的是,要找正方形的圖片,因為一會兒我們需要做移動的碰撞檢測,方形比較好判斷。
接下來就要寫繪製迷宮和小人的主要函數
function drawMaze(mazeFile, startingX, startingY) { var imgMaze = new Image() imgMaze.onload = function () { // 画布大小调整 canvas.width = imgMaze.width canvas.height = imgMaze.height // 绘制笑脸 var imgFace = document.getElementById("face") context.drawImage(imgMaze, 0, 0) x = startingX y = startingY context.drawImage(imgFace, x, y) context.stroke() } imgMaze.src = mazeFile }
mazeFile
是迷宮的圖片位址,startingX
和 startingY
,是起始點的座標。這裡圖片引入的方式用了2種,原因是小人的圖片我不常更換,就直接寫在頁面裡,迷宮的地圖打算做成可變的,所以在js裡引入,你想把圖片都直接用js引入也沒問題。其他部分比較簡單,不再贅述。
移動的主要原理是:
接受指定的使用者輸入(這裡是回應方向鍵),轉換成對應的移動指令。然後週期性的檢查移動指令,繪製對應的目標位置。舉個簡單的例子:
例如每按下一次方向鍵上,就記錄下應該往上移動,然後每隔100毫秒檢查當前的移動指令,繪製應該移動的目標地點,重複這個過程。程式碼也比較簡單:
// 移动函数 function processKey(e) { dx = 0 dy = 0 // 上下左右方向键检测 if (e.keyCode === 38) { dy = -1 } if (e.keyCode === 40) { dy = 1 } if (e.keyCode === 37) { dx = -1 } if (e.keyCode === 39) { dx = 1 } } // 绘制帧 function drawFrame() { if (dx != 0 || dy != 0) { // context.clearRect(x,y,canvas.width,canvas.height) // 绘制移动轨迹 context.beginPath(); context.fillStyle = "rgb(254,244,207)" context.rect(x, y, 15, 15) context.fill() x += dx y += dy // 碰撞检测 if (checkForCollision()) { x -= dx y -= dy dx = 0 dy = 0 } //绘制小人应该移动的地点 var imgFace = document.getElementById('face') context.drawImage(imgFace, x, y) if (canvas.height - y < 17) { // isFirst = false alert('恭喜你通关 游戏结束') return false } // 这里如果重置的话变成非自动移动,也就是每按下一次方向键只前进一步,由于目前体验不好所以先不做重置 // dx = 0 // dy = 0 } setTimeout(drawFrame, 20) }
上述程式碼中,移動函數比較簡單,繪製幀的函數裡面比較重要的就是碰撞偵測函數,在下面詳細解釋。
要偵測物體與牆體是否碰撞,通常情況是要先把地圖資訊儲存到記憶體裡,然後在移動物體時偵測是否與目前的某個牆體碰撞,但是由於我們的地圖背景是黑白迷宮,所以可以使用顏色來偵測碰撞。具體的做法是:
取得目前物件的座標位置,利用canvas
偵測目前地圖上這個位置的顏色是否為黑色,如果是,說是牆體,不應該執行移動,下面就是程式碼:
function checkForCollision() { var imageData = context.getImageData(x - 1, y - 1, 15 + 2, 15 + 2) var pixels = imageData.data for (var i = 0, len = pixels.length; i < len; i++) { var red = pixels[i], green = pixels[i + 1] blue = pixels[i + 2] alpha = pixels[i + 3] // 检测是否碰到黑色的墙 if (red === 0 && green === 0 && blue === 0) { return true } } return false }
在這裡,15
是小人的寬度,我們偵測小人兩側各1px範圍(對應程式碼中的getImageData(x - 1, y - 1, 15 2, 15 2)
可以稍微思考這裡為什麼是2),如果是黑色,表示偵測到碰撞。
在程式碼裡,我加了一些其他的功能,像是提示答案等。至於更換地圖也比較簡單:把地圖對應的檔案位址,起點座標,答案圖片路徑等存在一個物件裡,然後設定一個地圖數組,點擊的時候切換地圖並重新渲染就可以了。還有一些值得優化的地方,例如:
碰撞偵測在拐彎的地方體驗不佳;
以上是使用canvas實現迷宮遊戲的詳細內容。更多資訊請關注PHP中文網其他相關文章!