首頁 >web前端 >H5教程 >使用canvas實現迷宮遊戲

使用canvas實現迷宮遊戲

不言
不言原創
2018-07-10 17:32:452733瀏覽

這篇文章主要介紹了關於使用canvas實現迷宮遊戲,有著一定的參考價值,現在分享給大家,有需要的朋友可以參考一下

前言

#(最近設計模式看的有點頭大,一直面對純js實在是有些枯燥-_-。所以寫一點有趣的東西調劑一下)
現在canvas已經不算新鮮了,不過由於日常業務中並不常用,所以實踐不多,今天分享一下,如何實現簡單canvas迷宮。這個範例來自《html5秘籍》第二版,程式碼有稍微做了點調整。

由於中間有一步使用canvas取得圖片資訊的時候,必須使用伺服器環境。所以我先寫了一個範例丟在伺服器上,大家可以先體驗一下效果(用成就感作為驅動力哈哈哈)

正文

實現這個小遊戲也不難,讓我們想想,一個迷宮遊戲有哪些基本要素。

首先當然得有個地圖,然後得有個移動的小人,這兩個我們利用cavans來繪製;

接下來是物體移動的程序,這個程式主要包括2個面向:

1.讓物體跟我們指定的指令來移動;
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),如果是黑色,表示偵測到碰撞。

其餘

在程式碼裡,我加了一些其他的功能,像是提示答案等。至於更換地圖也比較簡單:把地圖對應的檔案位址,起點座標,答案圖片路徑等存在一個物件裡,然後設定一個地圖數組,點擊的時候切換地圖並重新渲染就可以了。還有一些值得優化的地方,例如:

  1. 碰撞偵測在拐彎的地方體驗不佳;

  2. ##目前狀況運行時有軌跡,在答案模式下該如何去除軌跡?

有興趣的同學可以試著自己實現下。

小結

這個範例相對比較簡單,對js的要求不高,拿來玩一下還是挺不錯的。

以上就是本文的全部內容,希望對大家的學習有所幫助,更多相關內容請關注PHP中文網!

相關推薦:

HTML5 Canvas API製作簡單的猜字遊戲

HTML5 Canvas實作煙火綻放的特效

以上是使用canvas實現迷宮遊戲的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn