溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

使用canvas怎么弄迷宮游戲

發(fā)布時(shí)間:2020-10-23 15:24:54 來(lái)源:億速云 閱讀:145 作者:小新 欄目:web開(kāi)發(fā)

這篇文章主要介紹了使用canvas怎么弄迷宮游戲,具有一定借鑒價(jià)值,需要的朋友可以參考下。希望大家閱讀完這篇文章后大有收獲。下面讓小編帶著大家一起了解一下。

前言

(最近設(shè)計(jì)模式看的有點(diǎn)頭大,一直面對(duì)純js實(shí)在是有些枯燥-_-。所以寫(xiě)一點(diǎn)有趣的東西調(diào)劑一下)
現(xiàn)在canvas已經(jīng)不算新鮮了,不過(guò)由于日常業(yè)務(wù)中并不常用,所以實(shí)踐并不多,今天分享一下,如何實(shí)現(xiàn)簡(jiǎn)單canvas迷宮。這個(gè)例子來(lái)源于《html5秘籍》第二版,代碼有稍微做了點(diǎn)調(diào)整。

由于中間有一步使用canvas獲取圖片信息的時(shí)候,必須使用服務(wù)器環(huán)境。所以我先寫(xiě)了一個(gè)樣例扔在服務(wù)器上,大家可以先體驗(yàn)一下效果(用成就感作為驅(qū)動(dòng)力哈哈哈)

正文

實(shí)現(xiàn)這個(gè)小游戲也不難,讓我們想想,一個(gè)迷宮游戲有哪些基本要素。

首先當(dāng)然得有個(gè)地圖,然后得有個(gè)移動(dòng)的小人,這兩個(gè)我們利用cavans來(lái)繪制;

接下來(lái)是物體移動(dòng)的程序,這個(gè)程序主要包括2個(gè)方面:

1.讓物體跟我們指定的指令來(lái)移動(dòng);
2.檢測(cè)物體是否碰到墻體或者出口。

繪制迷宮的地圖和移動(dòng)的小人

繪制地圖的主要步驟是:

  1. 獲取一張地圖的圖片

  2. 利用cavans繪制圖像。

迷宮地圖的生成,可以借助谷歌的一個(gè)迷宮在線生成器來(lái)獲得。

繪制小人也是一樣直接找一個(gè)小人的圖片即可,不過(guò)這里要注意的是,要找正方形的圖片,因?yàn)橐粫?huì)我們需要做移動(dòng)的碰撞檢測(cè),方形比較好判斷。

接下來(lái)就要寫(xiě)繪制迷宮和小人的主要函數(shù)

function drawMaze(mazeFile, startingX, startingY) {
  var imgMaze = new Image()
  imgMaze.onload = function () {
    // 畫(huà)布大小調(diào)整
    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是迷宮的圖片地址,startingXstartingY,是起始點(diǎn)的坐標(biāo)。在這里圖片引入的方式用了2種,原因是小人的圖片我不經(jīng)常更換,就直接寫(xiě)在頁(yè)面里,迷宮的地圖打算做成可變的,所以在js里引入,你想把圖片都直接用js引入也沒(méi)有問(wèn)題。其他部分比較簡(jiǎn)單,不再贅述。

移動(dòng)函數(shù)

移動(dòng)的主要原理是:
接受指定的用戶輸入(在這里是響應(yīng)方向鍵),轉(zhuǎn)換成對(duì)應(yīng)的移動(dòng)指令。然后周期性的檢查移動(dòng)指令,繪制對(duì)應(yīng)的目標(biāo)位置。舉個(gè)簡(jiǎn)單的例子:

比如每按下一次方向鍵上,就記錄下應(yīng)該往上移動(dòng),然后每隔100毫秒檢查當(dāng)前的移動(dòng)指令,繪制應(yīng)該移動(dòng)的目標(biāo)地點(diǎn),重復(fù)這個(gè)過(guò)程。代碼也比較簡(jiǎn)單:

// 移動(dòng)函數(shù)
function processKey(e) {
  dx = 0
  dy = 0
  // 上下左右方向鍵檢測(cè)
  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)
    // 繪制移動(dòng)軌跡
    context.beginPath();
    context.fillStyle = "rgb(254,244,207)"
    context.rect(x, y, 15, 15)
    context.fill()
    x += dx
    y += dy
    // 碰撞檢測(cè)
    if (checkForCollision()) {
      x -= dx
      y -= dy
      dx = 0
      dy = 0
    }
    
    //繪制小人應(yīng)該移動(dòng)的地點(diǎn)
    var imgFace = document.getElementById('face')
    context.drawImage(imgFace, x, y)

    if (canvas.height - y < 17) {
      // isFirst = false
      alert('恭喜你通關(guān) 游戲結(jié)束')
      return false
    }
    // 這里如果重置的話變成非自動(dòng)移動(dòng),也就是每按下一次方向鍵只前進(jìn)一步,由于目前體驗(yàn)不好所以先不做重置
    // dx = 0
    // dy = 0
  }
  setTimeout(drawFrame, 20)
}

上述代碼中,移動(dòng)函數(shù)比較簡(jiǎn)單,繪制幀的函數(shù)里面比較重要的就是碰撞檢測(cè)函數(shù),在下面詳細(xì)解釋。

碰撞檢測(cè)

要檢測(cè)物體與墻體是否碰撞,通常情況是要先把地圖信息保存到內(nèi)存里,然后在移動(dòng)物體時(shí)檢測(cè)是否與當(dāng)前的某個(gè)墻體碰撞,但是由于我們的地圖背景是黑白迷宮,所以可以使用顏色來(lái)檢測(cè)碰撞。具體的做法是:

獲取當(dāng)前物體的坐標(biāo)位置,利用canvas檢測(cè)當(dāng)前地圖上這個(gè)位置的顏色是否為黑色,如果是,說(shuō)是是墻體,不應(yīng)該執(zhí)行移動(dòng),下面就是代碼:

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]

    // 檢測(cè)是否碰到黑色的墻
    if (red === 0 && green === 0 && blue === 0) {
      return true
    }
  }
  return false
}

在這里,15是小人的寬度,我們檢測(cè)小人兩側(cè)各1px范圍(對(duì)應(yīng)代碼中的getImageData(x - 1, y - 1, 15 + 2, 15 + 2)可以稍微思考下這里為什么是+2),如果是黑色,說(shuō)明檢測(cè)到碰撞。

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享使用canvas怎么弄迷宮游戲內(nèi)容對(duì)大家有幫助,同時(shí)也希望大家多多支持億速云,關(guān)注億速云行業(yè)資訊頻道,遇到問(wèn)題就找億速云,詳細(xì)的解決方法等著你來(lái)學(xué)習(xí)!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI