vue實現2048

vue實現2048

小雨,在家養生,無聊想寫點小遊戲玩玩,就想到了2048vue

試玩地址git

項目地址github

使用方法:算法

git clone
npm i
npm run dev
複製代碼

實現思路

  1. 用vue-cli搭建項目,對這個項目可能有點笨重,可是也懶的再搭一個
  2. 4X4的方格用一個二維數組存放,綁定好後只關心這個二維數組,其餘事交給vue
  3. 監聽鍵盤事件
  4. 2048的核心部分就是移動合併的算法,由於是一個4X4的矩陣,因此只要實現左移的算法,其餘方向的移動只須要將矩陣旋轉,移動合併,再旋轉回來,渲染dom便可
  5. 綁定不一樣數值的樣式
  6. 分值計算,以及用localstorage存放最高分

關鍵實現

DOM

<div class="box">
    <div class="row" v-for="row in list">
        <div class="col" :class="'n-'+col" v-for="col in row">{col}}</div>
    </div>
</div>
複製代碼

主要的遊戲部分的DOM,很簡單,用一個二維數組渲染,並動態綁定樣式vue-cli

左移

主要由如下幾種狀況:npm

  • 2 2 2 2 => 4 4 0 0數組

  • 4 2 2 2 => 4 4 2 0bash

  • 0 4 2 2=> 4 4 0 0dom

  • 2 2 4 2 => 4 4 2 0ui

按單行數據舉例,

  1. 遍歷單行數組,若存在數據,記爲cell,尋找cell往左可移到的最遠空位置farthest
  2. 判斷farthest的左邊是否存在,不存在則直接移到到farthest
  3. 若存在,則判斷farthest - 1的值和cell是否相同
  4. 相同=> 合併
  5. 不相同=>移到farthest位置
  6. 移動完後,清空cell
  7. 下一輪

由於一輪移動中,一個數只能合併一次,因此每一個格子要有merged參數來記錄是否已經合併過。

主要代碼:

_list.forEach(item => {
        let farthest = this.farthestPosition(list, item)
        let next = list[farthest - 1]
        if (next && next === item.value && !_list[farthest - 1].merged) {
            //合併
            list[farthest - 1] = next * 2
            list[item.x] = undefined
            item = {
                x: farthest - 1,
                merged: true,
                value: next * 2
            }
            this.score += next * 2
        } else {
            if (farthest != item.x) {
                list[farthest] = item.value
                list[item.x] = undefined
                item.x = farthest
            }
        }
    })
複製代碼

矩陣旋轉

由於上移,下移,左移,右移其實是相同的,寫4遍也能夠,可是容易出錯,因此我直接旋轉將矩陣旋轉,再進行移動。

以上移爲例,只要將矩陣逆時針旋轉一次,上移就變成了左移,移動合併成以後,只要再將矩陣逆時針旋轉4-1次,矩陣就和單純上移同樣了。

逆時針旋轉算法:

rotate(arr, n) {
        n = n % 4
        if (n === 0) return arr
        let tmp = Array.from(Array(this.size)).map(() => Array(this.size).fill(undefined))
        for (let i = 0; i < this.size; i++) {
            for (let j = 0; j < this.size; j++) {
                tmp[this.size - 1 - i][j] = arr[j][i]
            }
        }
        if (n > 1) tmp = this.rotate(tmp, n - 1)
        return tmp
    },
複製代碼

到這時候已經完成了80%了,只要再完善一下,加入分值,從新開始等功能就能夠了。

寫得比較粗糙,有好的意見歡迎提issue。

相關文章
相關標籤/搜索