疾速完成一個簡樸的canvas迷宮遊戲

媒介

(近來設想形式看的有點頭大,一向面臨純js實在是有些死板-_-。所以寫一點風趣的東西調解一下)
如今canvas已不算新穎了,不過由於一樣平常營業中並不常常運用,所以實踐並不多,本日分享一下,怎樣完成簡樸canvas迷宮。這個例子來源於《html5秘笈》第二版,代碼有輕微做了點調解。

由於中心有一步運用canvas獵取圖片信息的時刻,必需運用服務器環境。所以我先寫了一個樣例扔在服務器上,人人能夠先體驗一下結果(用成就感作為驅動力哈哈哈)

點我體驗

git所在

正文

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

起首固然得有個輿圖,然後得有個挪動的小人,這兩個我們應用cavans來繪製;

接下來是物體挪動的順序,這個順序主要包含2個方面:

1.讓物體跟我們指定的指令來挪動;
2.檢測物體是不是遇到牆體或許出口。

繪製迷宮的輿圖和挪動的小人

繪製輿圖的主要步驟是:

  1. 獵取一張輿圖的圖片
  2. 應用cavans繪製圖象。

迷宮輿圖的天生,能夠藉助谷歌的一個迷宮在線天生器來取得。

繪製小人也是一樣直接找一個小人的圖片即可,不過這裏要注意的是,要找正方形的圖片,由於一會我們需要做挪動的碰撞檢測,方形比較好推斷。

接下來就要寫繪製迷宮和小人的主要函數

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是迷宮的圖片所在,startingXstartingY,是起始點的坐標。在這裏圖片引入的體式格局用了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的請求不高,拿來玩一下照樣挺不錯的。

然後依然是每次都一樣的末端,假如內容有毛病的處所迎接指出;假如對你有協助,迎接點贊和珍藏,轉載請徵得贊同后著明出處,假如有題目也迎接私信交換,主頁有郵箱所在~溜了

    原文作者:安歌
    原文地址: https://segmentfault.com/a/1190000015431930
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞