最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

利用Vue.js制作一個(gè)拼圖華容道小游戲

 更新時(shí)間:2022年04月08日 10:35:13   作者:沐華  
這篇文章主要為大家詳細(xì)介紹了如何利用Vue.js編寫一個(gè)拼圖華容道游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

游戲介紹

先看看界面

這是一個(gè)拼圖游戲,可以自選難度和自選闖關(guān)圖片

游戲開(kāi)始后根據(jù)不同難度,生成與所選主圖 對(duì)應(yīng)的 不同張數(shù)的 隨機(jī)順序的小圖,然后只要把亂序的小圖片還原成完整的圖片就闖關(guān)成功

游戲區(qū)域有一個(gè)空白位置,可以用鼠標(biāo)點(diǎn)擊空白位相鄰的圖片完成替換,也就是移動(dòng),也可以用鍵盤上下左右操作

游戲好玩,可不要貪杯哦,學(xué)習(xí)也不能落下,不管什么游戲都一樣

這個(gè)雖然用到的技術(shù)很一般很簡(jiǎn)單,多數(shù)還是普通的 JS,但是也花了不少時(shí)間,特別是圖片。確定整體風(fēng)格,找背景圖、游戲框。也是前兩天假期,喊我女朋友幫忙找圖片,也找了很多圖片讓她幫忙參考,畢竟她的審美比我強(qiáng),我就粗漢子

核心思路

  • 游戲等級(jí)(level),比如初級(jí),等級(jí)數(shù)值定為3,游戲界面就是三行三列,中級(jí)等級(jí)數(shù)值為4,游戲界面就是四行四列,即當(dāng)前等級(jí)的平方,就是小格子總數(shù)量
  • 游戲開(kāi)始后以格子總數(shù)量為最大值,來(lái)生成隨機(jī)數(shù)的數(shù)組 randomData,初級(jí)如:[3,1,7,2,4,8,6,5,9],遍歷生成小圖片,最大數(shù)值為空白格子,就是9
  • 并根據(jù)當(dāng)前等級(jí)生成拼圖完成時(shí)的數(shù)據(jù) finishData,初級(jí)如:123456789
  • 點(diǎn)擊或鍵盤按鍵的時(shí)候?qū)⒎蠗l件的,randomData 里的目標(biāo)格子和空白格子對(duì)應(yīng)的值,交換,然后自動(dòng)更新視圖,完成移動(dòng)
  • 每走一步時(shí),統(tǒng)計(jì)步數(shù),并檢查 randomData().join('') == finishData,相等即拼圖完成

核心代碼

注意看注釋哦

html

以下就是拼圖區(qū)域全部html,根據(jù)狀態(tài) isStart 控制是否是處于游戲狀態(tài)

<div class="stage">
  <div class="game-name" v-show="!isStart">華容道</div>
  <div class="content clearfix" v-show="isStart">
    <div
      v-for="item in randomData"
      :key="item"
      :class="`img${level}`"
      @click="handleMove(item)"
    >
      <el-image
        v-if="item != randomData.length"
        :src="getSmallImg(`${gameImg}/${level}/${item}.jpg`)"
      ></el-image>
    </div>
  </div>
</div>

getSmallImg 這個(gè)方法是用于動(dòng)態(tài)引入圖片的,畢竟不是 webpack,沒(méi)有 require 那么方便

// 獲取當(dāng)前游戲小圖片
export const getSmallImg = (path: string) => {
  return new URL(`../assets/images/${path}`, import.meta.url).href
}

games 類

js 部分主要是封裝了一個(gè)類,方便統(tǒng)一管理操作

// 拼圖類
class Puzzle implements IPuzzle {
  isStart = false  // 游戲狀態(tài)
  randomData: Array<number> = [] // 亂序的,對(duì)應(yīng)當(dāng)前游戲小圖片張數(shù)的數(shù)組
  finishData = "" // 正序的,拼圖完成時(shí)的排序,用來(lái)對(duì)比
  gameImg = ""  // 游戲主圖
  level = 3 // 游戲等級(jí)
  step = 0 // 游戲步數(shù)
  constructor() {}
  // 初始化
  init({ gameImg, level }: IMode) {
    this.step = 0
    this.level = level
    this.gameImg = gameImg
    // 生成當(dāng)前游戲隨機(jī)數(shù)數(shù)組
    this.randomData = this.getRandomData()
    this.isStart = !this.isStart
    // 如果是開(kāi)始游戲,就計(jì)算出拼圖完成時(shí)的數(shù)據(jù)
    if (this.isStart) this.finishData = this.getFinishData()
  }
  // 移動(dòng)圖片
  move(idx: number) {}
  // 鍵盤事件
  onKeyDown(code: number){}
  // 檢查是否拼圖完成
  finish() {}
  // 生成小圖片數(shù)量數(shù)組
  getRandomData(){}
}

生成隨機(jī)圖片數(shù)量

就是在點(diǎn)擊開(kāi)始游戲的時(shí)候會(huì)執(zhí)行 getRandomData,生成隨機(jī)數(shù)數(shù)組,然后 DOM 部分就遍歷這個(gè)生成的隨機(jī)數(shù)數(shù)組,渲染切碎了的小圖片

// 生成小圖片數(shù)量數(shù)組
getRandomData() {
    // 隨機(jī)數(shù)集合
    let randomArr = []
    // 根據(jù)游戲等級(jí)生成最大值,減1是因?yàn)樽畲笾当A糇骺瞻孜环抛詈?
    let max = Math.pow(this.level, 2) - 1
    while (randomArr.length < max) {
      // 生成一個(gè)最大值范圍內(nèi)的隨機(jī)數(shù)
      let random = Math.floor(Math.random() * max) + 1
      if (randomArr.indexOf(random) == -1) {
        // 沒(méi)有重復(fù)的就添加
        randomArr.push(random)
      }
    }
    randomArr.push(max + 1) // 添加最大數(shù)字作為最后的空白位
    return randomArr // 如:[3, 1, 7, 2, 4, 8, 6, 5, 9]
}

移動(dòng)圖片

接收一個(gè)參數(shù),就是在遍歷隨機(jī)數(shù)數(shù)組 randomData 的時(shí)候,對(duì)應(yīng)每個(gè)圖片的值,鼠標(biāo)點(diǎn)擊的時(shí)候拿到這個(gè)值

// 移動(dòng)圖片
move(idx: number) {
    let level = this.level
    let target = this.randomData.indexOf(idx) // 當(dāng)前點(diǎn)擊位置下標(biāo)
    let space = this.randomData.indexOf(Math.pow(level, 2)) // 空白位置下標(biāo)

    // 過(guò)濾一下,不然空白位置在最左邊時(shí)點(diǎn)擊右邊上一個(gè)數(shù)字時(shí)也能實(shí)現(xiàn)交換
    // 以及空白位置在最右邊點(diǎn)擊左邊下一個(gè)數(shù)字時(shí)也能實(shí)現(xiàn)交換
    let condition =
      (space % level == 0 && target % level == level - 1) ||
      (space % level == level - 1 && target % level == 0)
      
    // 如果能交換
    if (!condition) {
      // 并且點(diǎn)擊目標(biāo)的,上或下或左或右是空白位,就交換位置
      if (
        target == space - level ||
        target == space + level ||
        target == space - 1 ||
        target == space + 1
      ) {
          this.change(space, target)
      }
    }
}
// 動(dòng)起來(lái)
change(space: number, target: number) {
    // 空白位置替換成目標(biāo)位置
    this.randomData[space] = this.randomData[target]
    // 目標(biāo)位置為最大值,實(shí)現(xiàn)交換
    this.randomData[target] = Math.pow(this.level, 2)
    // 步數(shù)
    this.step += 1
    // 檢查是否完成
    this.finish()
}

鍵盤事件

按下鍵盤上下左右的時(shí)候,判斷空格位置對(duì)應(yīng)你按的那個(gè)方向能不能移動(dòng),符合條件就替換

// 鍵盤事件
onKeydown(code: number) {
    let level = this.level
    // 目標(biāo)位置下標(biāo)
    let target
    // 空白位置下標(biāo)
    let space = this.randomData.indexOf(Math.pow(level, 2))
    // 上下左右
    switch (code) {
      case 37:
        target = space + 1
        if (space % level == level - 1) return
        this.change(space, target)
        break
      case 38:
        target = space + level
        if (target > this.randomData.length - 1) return
        this.change(space, target)
        break
      case 39:
        target = space - 1
        if (space % level == 0) return
        this.change(space, target)
        break
      case 40:
        target = space - level
        if (target < 0) return
        this.change(space, target)
        break
    }
}

拼圖完成

思路是把當(dāng)前亂序的 randomData 轉(zhuǎn)為字符串,和正序的 finishData 作對(duì)比,如果一樣了,就是拼圖完成了

// 檢查是否拼圖完成
finish() {
    // 如:'312' == '123'
    if (this.randomData.join("") == this.finishData) {
      ElMessageBox.alert(`恭喜你,闖關(guān)成功,僅用${this.step}步`, "提示", {
        confirmButtonText: "OK",
        callback: (action: Action) => {
          this.randomData = []
          this.step = 0
          this.isStart = false
        },
      })
    }
}
// 根據(jù)不同難度生成拼圖完成時(shí)的數(shù)據(jù)用來(lái)對(duì)比,判斷是否完成
// 比如初級(jí)難度就是:123456789
getFinishData(): string {
    let str = ""
    for (let i = 1, len = Math.pow(this.level, 2); i <= len; i++) {
      str += i
    }
    return str
}

結(jié)語(yǔ)

游戲體驗(yàn)地址(pc)

開(kāi)源地址

以上就是利用Vue.js制作一個(gè)拼圖華容道小游戲的詳細(xì)內(nèi)容,更多關(guān)于Vue.js拼圖華容道的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Element Notification通知的實(shí)現(xiàn)示例

    Element Notification通知的實(shí)現(xiàn)示例

    這篇文章主要介紹了Element Notification通知的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Vue-cli assets SubDirectory及PublicPath區(qū)別詳解

    Vue-cli assets SubDirectory及PublicPath區(qū)別詳解

    這篇文章主要介紹了Vue-cli assets SubDirectory及PublicPath區(qū)別詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • 如何用 Deepseek 寫的uniapp血型遺傳查詢工具

    如何用 Deepseek 寫的uniapp血型遺傳查詢工具

    在現(xiàn)代社會(huì)中,了解血型遺傳規(guī)律對(duì)于優(yōu)生優(yōu)育、醫(yī)療健康等方面都有重要意義,本文將介紹如何使用Uniapp開(kāi)發(fā)一個(gè)跨平臺(tái)的血型遺傳查詢工具,幫助用戶預(yù)測(cè)孩子可能的血型,感興趣的朋友一起看看吧
    2025-04-04
  • Ant?Design-vue?解決input前后空格問(wèn)題(推薦)

    Ant?Design-vue?解決input前后空格問(wèn)題(推薦)

    最近做項(xiàng)目遇到這樣一個(gè)問(wèn)題輸入框不允許有前后空格但字符中間可以有空格,怎么解決這個(gè)問(wèn)題呢,接下來(lái)小編把a(bǔ)nt?Design-vue?解決input前后空格問(wèn)題的實(shí)現(xiàn)代碼分享給大家,感興趣的朋友一起看看吧
    2022-10-10
  • 使用Electron打包vue文件變成exe應(yīng)用程序的全過(guò)程

    使用Electron打包vue文件變成exe應(yīng)用程序的全過(guò)程

    這篇文章主要給大家介紹了使用Electron打包vue文件變成exe應(yīng)用程序的全過(guò)程,文中通過(guò)代碼示例和圖文結(jié)合的方式給大家講解的非常詳細(xì),具有一定的參考價(jià)值,需要的朋友可以參考下
    2024-01-01
  • Vue給?elementUI?中的?this.$confirm、this.$alert、?this.$prompt添加按鈕加載效果

    Vue給?elementUI?中的?this.$confirm、this.$alert、?this.$promp

    這篇文章主要介紹了Vue給?elementUI?中的?this.$confirm、this.$alert、?this.$prompt添加按鈕的加載效果,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-07-07
  • vue實(shí)現(xiàn)百度搜索下拉提示功能實(shí)例

    vue實(shí)現(xiàn)百度搜索下拉提示功能實(shí)例

    這篇文章主要介紹了vue實(shí)現(xiàn)百度搜索下拉提示功能實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • vue如何自定義事件傳參

    vue如何自定義事件傳參

    這篇文章主要介紹了vue如何自定義事件傳參,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • vue中使用axios post上傳頭像/圖片并實(shí)時(shí)顯示到頁(yè)面的方法

    vue中使用axios post上傳頭像/圖片并實(shí)時(shí)顯示到頁(yè)面的方法

    今天小編就為大家分享一篇vue中使用axios post上傳頭像/圖片并實(shí)時(shí)顯示到頁(yè)面的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09
  • vuex中的state、getters、mutations、actions之間的關(guān)系解讀

    vuex中的state、getters、mutations、actions之間的關(guān)系解讀

    這篇文章主要介紹了vuex中的state、getters、mutations、actions之間的關(guān)系,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-10-10

最新評(píng)論

鄯善县| 竹北市| 大兴区| 新巴尔虎右旗| 河间市| 藁城市| 湛江市| 贺州市| 兴隆县| 洞头县| 雷山县| 特克斯县| 宜春市| 阿坝县| 阿尔山市| 竹溪县| 雷州市| 甘南县| 上饶县| 辉县市| 白朗县| 隆子县| 武乡县| 万州区| 渝北区| 高州市| 义乌市| 石景山区| 西林县| 南乐县| 天水市| 静乐县| 炉霍县| 福鼎市| 岫岩| 南川市| 柳林县| 浮梁县| 罗山县| 霍州市| 武川县|