前端学习|回归前端学习第24天-实现俄罗斯方块小游戏7(实现单机版3—实现消行、更新方块、结束)


更改game.js、local.js、

  • game.js中加入代码
    • 使用下一个方块
    • 设置到底部后,方块定住并换色
    • 实现消行、
    • 游戏结束
    • 最后导出
    • 整体代码
  • local.js代码
    • move函数更改
    • 随机生成下一个方块
    • 修改开始函数,增加结束函数
【前端学习|回归前端学习第24天-实现俄罗斯方块小游戏7(实现单机版3—实现消行、更新方块、结束)】
game.js中加入代码 使用下一个方块 // 使用下一个方块
var performNext = function (type, dir) {
cur = next;
setData();
let squareDiv = new SquareFactory();
next = squareDiv.make(type, dir);
refreshDiv(gameData, gameDivs);
refreshDiv(next.data, nextDivs);
}
设置到底部后,方块定住并换色
// 方块移动到底部后固定住 var fixed = function () { for (var i = 0; i < cur.data.length; i++) { for (var j = 0; j < cur.data[0].length; j++) { // 判断合法性 if (check(cur.origin, i, j)) { if (gameData[cur.origin.x + i][cur.origin.y + j] == 2) { gameData[cur.origin.x + i][cur.origin.y + j] == 1; } } } } // 反馈到界面上 refreshDiv(gameData, gameDivs); }

实现消行、
// 消行 var checkClear = function () { for (var i = gameData.length - 1; i >= 0; i--) { var clear = true; for (j = 0; j < gameData[0].length; j++) { if (gameData[i][j] != 1) { clear = false; break; } } if (clear) { // 下移一行 for (var m = i; m >= 0; m--) { for (var n = 0; n < gameData[0].length; n++) { gameData[m][n] = gameData[m - 1][n]; } } for (var n = 0; n < gameData[0].length; n++) { gameData[0][n] = 0; } i++; } } }

游戏结束
// 游戏结束 var checkGameOver = function () { var gameOver = false; for (var i = 0; gameData[0].length; i++) { if (gameData[1][i] == 1) { gameOver = true; } } return gameOver; }

最后导出
this.fixed = fixed; this.performNext = performNext; this.checkClear = checkClear; this.checkGameOver = checkGameOver;

整体代码
var Game = function () { //dom元素 var gameDiv; var nextDiv; // 游戏矩阵 var gameData = https://www.it610.com/article/[ [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], ]; // 当前方块 var cur; // 下一个方块 var next; // divs var nextDivs = []; var gameDivs = []; // 初始化div var initDiv = function (container, data, divs) { for (var i = 0; i < data.length; i++) { var div = []; for (var j = 0; j < data[0].length; j++) { var newNode = document.createElement('div'); newNode.className = 'none'; newNode.style.top = (i * 20) + 'px'; newNode.style.left = (j * 20) + 'px'; // 建立一维数组 container.appendChild(newNode); div.push(newNode); } // 把一维数组放到多维数组中 divs.push(div); } }// 刷新div var refreshDiv = function (data, divs) { for (var i = 0; i < data.length; i++) { for (var j = 0; j < data[0].length; j++) { if (data[i][j] == 0) { divs[i][j].className = 'none'; } else if (data[i][j] == 1) { divs[i][j].className = 'done '; } else if (data[i][j] == 2) { divs[i][j].className = 'current'; } } } } // 检测点是否合法,即是否降落到最底部——pos为方块原点位置,x=cur.origin.x,y=cur.origin.y, var check = function (pos, x, y) { if (pos.x + x < 0) { // 超出上面 return false; } else if (pos.x + x >= gameData.length) { // 超出下面 return false; } else if (pos.y + y < 0) { // 到最左边 return false; } else if (gameData[pos.x + x][pos.y + y] == 1) { // 已经有落下来的方块了 return false; } else { return true; }} // 检测数据是否合法,pos为原点,data为每次下降的方块的数据,为有方块存在的数据下降操作时做准备 var isValid = function (pos, data) { for (var i = 0; i < data.length; i++) { for (j = 0; j < data[0].length; j++) { if (data[i][j] != 0) { if (!check(pos, i, j)) { // 不等于0且非法 return false; } } } } return true; } // 清除数据 var clearData = https://www.it610.com/article/function () { for (var i = 0; i < cur.data.length; i++) { if (check(cur.origin, i, j)) { for (var j = 0; j < cur.data[0].length; j++) { gameData[cur.origin.x + i][cur.origin.y + j] = 0; } } } } // 设置数据 var setData = function () { for (var i = 0; i < cur.data.length; i++) { for (var j = 0; j < cur.data[0].length; j++) { // 先判断是否合法 if (check(cur.origin, i, j)) { // 将cur.data[i][j]中的数据拷贝到gameData数组中 gameData[cur.origin.x + i][cur.origin.y + j] = cur.data[i][j]; } } } } // 下移设置 var down = function () { // 判断是否可以下降,方法写在square中 if (cur.canDown(isValid)) { clearData(); cur.down(); setData(); refreshDiv(gameData, gameDivs); return true; } else { // 不能再向下 return false; } } // 旋转设置 var rotate = function () { // 判断是否可以下降,方法写在square中 if (cur.canRotate(isValid)) { clearData(); cur.rotate(); setData(); refreshDiv(gameData, gameDivs); } }// 左移设置 var left = function () { // 判断是否可以,方法写在square中 if (cur.canLeft(isValid)) { clearData(); cur.left(); setData(); refreshDiv(gameData, gameDivs); } } // 右移设置 var right = function () { // 判断是否可以,方法写在square中 if (cur.canRight(isValid)) { clearData(); cur.right(); setData(); refreshDiv(gameData, gameDivs); } } // 方块移动到底部后固定住 var fixed = function () { for (var i = 0; i < cur.data.length; i++) { for (var j = 0; j < cur.data[0].length; j++) { // 判断合法性 if (check(cur.origin, i, j)) { if (gameData[cur.origin.x + i][cur.origin.y + j] == 2) { gameData[cur.origin.x + i][cur.origin.y + j] == 1; } } } } // 反馈到界面上 refreshDiv(gameData, gameDivs); } // 消行 var checkClear = function () { for (var i = gameData.length - 1; i>= 0; i--) { var clear = ture; for (j = 0; j < gameData[0].length; j++) { if (gameData[i][j] != 1) { clear = false; break; } } if (clear) { // 下移一行 for (var m = i; m >= 0; m--) { for (var n = 0; n < gameData[0].length; n++) { gameData[m][n] = gameData[m - 1][n]; } } for (var n = 0; n < gameData[0].length; n++) { gameData[0][n] = 0; } i++; } } } // 游戏结束 var checkGameOver = function () { var gameOver = false; for (var i = 0; gameData[0].length; i++) { if (gameData[1][i] == 1) { gameOver = true; } } return gameOver; } // 使用下一个方块 var performNext = function (type, dir) { cur = next; setData(); let squareDiv = new SquareFactory(); next = squareDiv.make(type, dir); refreshDiv(gameData, gameDivs); refreshDiv(next.data, nextDivs); }// 初始化 doms对象包含两个内容gameDiv、nextDiv var init = function (doms) { gameDiv = doms.gameDiv; nextDiv = doms.nextDiv; let square = new SquareFactory(); cur = square.make(2, 2); next = square.make(3, 3); setData(); initDiv(gameDiv, gameData, gameDivs); initDiv(nextDiv, next.data, nextDivs); // 调用封装函数,将cur.data[i][j]中的数据拷贝到gameData数组中 setData(); refreshDiv(gameData, gameDivs); refreshDiv(next.data, nextDivs); } // 导出API,在外部local里就可以调用这个init函数了 this.init = init; this.down = down; this.left = left; this.right = right; this.rotate = rotate; this.fixed = fixed; this.performNext = performNext; this.checkClear = checkClear; this.checkGameOver = checkGameOver; this.fall = function () { // 返回false就不能再下降 while (down()); } }

local.js代码 move函数更改
var move = function () { // 不能下降再调用 if (!game.down()) { // 落下的方块固定 game.fixed(); game.checkClear(); var gameOver = game.checkGameOver(); if (gameOver) { stop(); } else { game.performNext(generrateType(), generateDir()); } } }

随机生成下一个方块
var generrateType = function () { // 随机生成0-6的整数 return Math.ceil(Math.random() * 7) - 1; } // 随机生成旋转次数 var generateDir = function () { // 随机生成0-3的整数 return Math.ceil(Math.random() * 4) - 1; }

修改开始函数,增加结束函数
// 开始 var start = function () { var doms = { gameDiv: document.getElementById('game'), nextDiv: document.getElementById('next') } game = new Game(); game.init(doms); bindKeyEvent(); timer = setInterval(move, INTERVAL); } // 结束,关闭计时 var stop = function () { if (timer) { clearInterval(timer); timer = null; } document.onkeydown = null; }

    推荐阅读