小雨,在家養生,無聊想寫點小遊戲玩玩,就想到了2048vue
試玩地址git
項目地址github
使用方法:算法
git clone
npm i
npm run dev
複製代碼
<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
按單行數據舉例,
由於一輪移動中,一個數只能合併一次,因此每一個格子要有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。