[ 邏輯鍛鍊] 用 JavaScript 作一個小遊戲 ——2048 (初級版)

前言

前段時間發現網上有不少收費或公開課都有教用 js 作 2048 小遊戲的,而後本身就也想動手作一個,作這個小遊戲主要是爲了鍛鍊本身的邏輯能力,也算是對以前一些學習的總結吧html

注:vue

  1. 實現方法徹底是本身邊玩 2048 邊想的,全部些亂還請見諒
  2. 另外配色方案是在某個 2048 遊戲截屏,而後用 ps 吸收的,非本人原創
  3. 代碼中有不少均可以使用數組相關的方法來代替,這裏是爲了本身理解數組方法是什麼原理
  4. 因爲時間關係本次不作詳解

遊戲邏輯

  1. 隨機位置生成數字 2 或 4
  2. 按方向鍵,有挨着的相同的數字就合併成新的數字
  3. 按方向鍵,數字會移動到對應方向的最邊上(按左,數字所有移動到左邊)
  4. 每次按方向鍵,合併完成後,會在沒有數字的隨機位置都會生成新的數字 2 或 4
  5. 當前分數等於當前全部數字相加
  6. 當有數字達到 2048 遊戲結束

項目相關

這個版本是用原生 ES6 寫的,只實現了遊戲邏輯中的 1,2,3,4;
初版地址:github.com/yhtx1997/Sm…git

以後是打算用 vue 從新寫一遍,而且完善下,由於長時間用原生,致使 vue 有些生疏,藉此機會從新溫習下github

項目代碼

採用二維數組進行數據的管理,默認所有爲零

let arr = [
    [0, 0, 0, 0],
    [0, 0, 0, 0],
    [0, 0, 0, 0],
    [0, 0, 0, 0]
];
複製代碼

隨機建立數字

let s = 0;
let create = () => {
    let x = Math.floor(Math.random() * 4);
    let y = Math.floor(Math.random() * 4);

    // console.log(s)
    if (s > 100) {
        s = 0;
        return;
    }
    if (arr[x][y] == 0) {
        if (Math.floor(Math.random() * 10) % 2 == 0) {
            arr[x][y] = 2;
        } else {
            arr[x][y] = 4;
        }
        s = 0;
        return;
    } else {
        s++;
        return create();
    }
}
複製代碼

渲染頁面

let updateHtml = () => {
    //獲取元素
    let warp = document.getElementById('warp');
    let html = '';
    //將數據轉換爲 HTML 
    for (let i = 0; i < arr.length; i++) {
        for (let j = 0; j < arr[i].length; j++) {
            html += `<div class='c c-${arr[i][j]}'>${arr[i][j]==0?'':arr[i][j]}</div>`;
        }
    }
    //將 數據轉換的 HTML 渲染到頁面
    warp.innerHTML = html;
}
複製代碼

事件監聽

window.onkeydown = (e) => {
    switch (e.keyCode) {
        case 37:
            // ←
            console.log('←');
            arr = new move(arr).moveLeft();
            create(); //隨機位置新建
            updateHtml(); //更新數據到頁面
            break;
        case 38:
            // ↑
            console.log('↑');
            arr = new move(arr).moveUp();
            create(); //隨機位置新建
            updateHtml(); //更新數據到頁面
            break;
        case 39:
            // →
            console.log('→');
            arr = new move(arr).moveRight();
            create(); //隨機位置新建
            updateHtml(); //更新數據到頁面
            break;
        case 40:
            // ↓
            console.log('↓');
            arr = new move(arr).moveDown();
            create(); //隨機位置新建
            updateHtml(); //更新數據到頁面
            break;
    }
}
複製代碼

具體處理函數

先提取非零數字

export default function ClearZero (arr){//去零
    let clearZero = [[],[],[],[]];
    for (let i = 0; i < 4; i++) {
        for (let j = 0; j < 4; j++) {
            if (arr[i][j] != 0) {
                clearZero[i].push(arr[i][j])
            }
        }
    }
    return clearZero;
}
複製代碼

將挨着的相等數字分組並相加

分組數組

import Deduplication from './deduplication';//將相鄰且相同的數字相加

export default class Grouping{//將相鄰的相同數字分組
    constructor(clearZero){
        this.clearZero = clearZero;
    }
    left(){
        let newarr = [[],[],[],[]];
        for (let j = 0; j < this.clearZero.length; j++) {
            let grouping = [];
            let i = 0;
            //將重複的 分到一組
            while (i < this.clearZero[j].length) {
                if (this.clearZero[j][i] == this.clearZero[j][i + 1]) {
                    grouping.push([this.clearZero[j][i], this.clearZero[j][i + 1]]);
                    i += 2;
                } else {
                    grouping.push(this.clearZero[j][i]);
                    i++;
                }
            }
            //去重複
            newarr[j] = Deduplication(grouping);
        }
        return newarr;
    }
    right(){
        let newarr = [[],[],[],[]];
        for (let i = 0; i < this.clearZero.length; i++) {
            let grouping = [];
            let j = this.clearZero[i].length - 1;
            //將重複的 分到一組
            while (j >= 0) {
                if (this.clearZero[i][j] == this.clearZero[i][j - 1]) {
                    grouping.unshift([this.clearZero[i][j], this.clearZero[i][j - 1]]);
                    j -= 2;
                } else {
                    grouping.unshift(this.clearZero[i][j]);
                    j--;
                }
            }
            //將重複的進行計算
            newarr[i] = Deduplication(grouping);

        }
        return newarr;
    }


}
複製代碼

相加bash

export default function Deduplication (grouping){//將相鄰且相同的數字相加
    for (let i = 0; i < grouping.length; i++) {
        if (typeof grouping[i] == 'object') {
    
            grouping[i] = grouping[i][0] + grouping[i][1];
        }
    }
    return grouping;
}
複製代碼

添加佔位用的零

export default function AddZero (newarr,w){//加零
    for (let i = 0; i < newarr.length; i++) {
        while (newarr[i].length != 4) {
            if(w == 'l'){
                newarr[i].push(0);
            }else if(w == 'r'){

                newarr[i].unshift(0);
            }
        }
    }
    return newarr;
}
複製代碼

上下的處理

將 Y 軸的處理轉換成 X 軸的處理dom

export default function turn(arr) {//將數組轉一下
    let clearZero = [[],[],[],[]];
    for (let i = 0; i < 4; i++) {
        for (let j = 0; j < 4; j++) {
            clearZero[i][j] = arr[j][i]
        }
    }
    return clearZero;
}
複製代碼

等處理完成後再調用上邊的函數,將 X 軸的處理結果轉換回 Y 軸的表現方式函數

相關文章
相關標籤/搜索