Vue 2048

Xiaoyu, health in the home, boring to write a little game to play, thought of 2048

Demo address

The project address

Usage:

git clone
npm i
npm run dev
Copy the code

Implementation approach

  1. Using vue-CLI to build a project may be a bit cumbersome for this project, but it’s lazy to build another one
  2. The 4X4 square is stored in a two-dimensional array. After binding, only the two-dimensional array is concerned, and the rest is left to VUE
  3. Listening for keyboard events
  4. 2048 is the core part of the mobile merge algorithm, because it is a 4X4 matrix, so as long as the left shift algorithm, the other direction of the movement only need to rotate the matrix, move merge, and then rotate back, rendering DOM
  5. Bind styles for different values
  6. Score calculation, and use localStorage to store the highest score

The key to realize

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>
Copy the code

The main game part of the DOM, quite simply, is rendered with a two-dimensional array and dynamically bound styles

Shift to the left

Mainly by the following situations:

  • 2 2 2 2 => 4 4 0 0

  • 2 2 2 => 4 4 2 0

  • 0 4 2 2=> 4 4 0 0

  • 2 2 4 2 => 4 4 2 0

Taking a single line of data as an example,

  1. Traverse the single-row array. If there is any data, call it cell. Find the furthest empty position that the cell can move to the left
  2. Judge if the left side of the tear is present, if not, move directly to the tear
  3. If so, determine whether the value of apne-1 is the same as that of the cell
  4. If yes => Merge
  5. If not, move to the apsis position
  6. After the move, clear the cell
  7. The next round of

Merged figure merged figure merged figure merged figure merged figure merged figure merged figure merged figure merged figure merged figure merged figure

Main code:

    _list.forEach(item => {
        let farthest = this.farthestPosition(list, item)
        let next = list[farthest - 1]
        if(next && next === item.value && ! _list [farthest - 1]. Merged) {/ / merge 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 } } })Copy the code

Matrix rotation

Because up, down, left, right are actually the same thing, and you could write it four times, but it’s easy to make mistakes, so I’m just going to rotate the matrix, rotate it, and move it.

For example, as long as you rotate the matrix counterclockwise once, the shift up becomes the shift left. After the shift is combined, as long as you rotate the matrix counterclockwise 4-1 times, the matrix is the same as the single shift up.

Counterclockwise rotation algorithm:

    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
    },
Copy the code

At this point, it’s 80% done, so just refine it, add points, restart, etc.

Write relatively rough, have good comments welcome to issue.