回归前端学习第25天-实现俄罗斯方块小游戏8(实现单机版4—设置计时、消行加分、游戏结束标志)

增改game.js与local.js代码,实现对游戏的设置计时、消行加分、游戏结束标志等环节的设计

  • 计时
  • 计分
  • 游戏结束
  • 完整代码
    • local.js
    • game.js
  • 注意

回归前端学习第25天-实现俄罗斯方块小游戏8(实现单机版4—设置计时、消行加分、游戏结束标志)_第1张图片

计时

1.定义显示时间的div,并通过init赋值到dom中(在game.js中

2.通过local.js传入doms
3.game.js中写函数setTime,显示到界面
4.在local.js设置计时函数

1.定义显示时间的div,并通过init赋值到dom中(在game.js中
)
var timeDiv;

2.通过local.js传入doms
timeDiv = doms.timeDiv;
timeDiv: document.getElementById('time')

3.game.js中写函数setTime,实现计时
 var setTime = function (time) {
        timeDiv.innerHTML = time;
    }
    
4.在local.js设置计时函数
 // 时间计数器
    var timeConut = 0;
    var time = 0;
// 计时函数
    var timeFunc = function () {
        timeConut = timeConut + 1;
        if (timeConut == 5) {
            timeConut = 0;
            time = time + 1;
            // 将更新的时间传入界面
            game.setTime(time);
        }
    }

计分

1.反馈消行数目,从而switch来判断分数
2.addScore函数判断消行,实现加分,添加div模块,添加变量并显示到界面,通过doms传入

1.反馈消行数目,从而switch来判断分数,checkClear函数里添加line变量记录消行数目
var line = 0;
  if (clear) {
               line = line + 1;
               ……
} 

2.addScore函数判断消行,实现加分
move函数中添加判断,若游戏不结束且消行了,则函数判断并显示加分
if (line) {
               // 行数不为0,则传入addScore函数
               game.addScore(line);
           }
           计分函数
           var addScore = function (line) {
       var s = 0;
       switch (line) {
           // 消除一行十分
           case 1:
               s = 10;
               break;
           case 2:
               s = 40;
               break;
           case 3:
               s = 60;
               break;
           case 4:
               s = 80;
               break;
           default:
               break;
       }
       score = score + s;
       scoreDiv.innerHTML = score;
   }
   

游戏结束

gameover函数通过传入参数,判断是否获胜,并显示到界面

//添加游戏结束的div
 var resultDiv;
 
 // 游戏结束函数
    var gameOver = function (win) {
        // 赢了
        if (win) {
            resultDiv.innerHTML = '你赢了啦!';
        } else {
            resultDiv.innerHTML = '你输了啦!';
        }
    }

local.js中调用gameOver函数
 var gameOver = game.checkGameOver();
            if (gameOver) {
                game.gameOver(false);
                stop();
            } else {
                game.performNext(generateType(), generateDir());
            }
        }

完整代码

local.js

var Local = function () {
    // 游戏对象
    var game;
    // 时间间隔 200毫秒
    var INTERVAL = 200;
    // 定时器
    var timer = null;
    // 绑定键盘事件
    // 时间计数器
    var timeConut = 0;
    var time = 0;
    var bindKeyEvent = function () {
        document.onkeydown = function (e) {
            if (e.keyCode == 38) {
                // 向上
                game.rotate();
            } else if (e.keyCode == 39) {
                // 向右
                game.right();
            } else if (e.keyCode == 40) {
                // 向下
                game.down();
            } else if (e.keyCode == 37) {
                // 向左
                game.left();
            } else if (e.keyCode == 32) {
                // 空格键
                game.fall();
            }
        }
    }
    // 移动
    var move = function () {
        timeFunc();
        // 不能下降再调用
        if (!game.down()) {
            // 落下的方块固定
            game.fixed();
            var line = game.checkClear();
            if (line) {
                // 行数不为0,则传入addScore函数
                game.addScore(line);
            }
            var gameOver = game.checkGameOver();
            if (gameOver) {
                game.gameOver(false);
                stop();
            } else {
                game.performNext(generateType(), generateDir());
            }
        }
    }
    // 计时函数
    var timeFunc = function () {
        timeConut = timeConut + 1;
        if (timeConut == 5) {
            timeConut = 0;
            time = time + 1;
            // 将更新的时间传入界面
            game.setTime(time);
        }
    }
    // 随机生成下一个方块
    var generateType = 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'),
            timeDiv: document.getElementById('time'),
            scoreDiv: document.getElementById('scpre'),
            resultDiv: document.getElementById('gameover')
        }
        game = new Game();
        game.init(doms, generateType(), generateDir());
        bindKeyEvent();
        game.performNext(generateType(), generateDir());
        timer = setInterval(move, INTERVAL);
    }
    // 结束,关闭计时
    var stop = function () {
        if (timer) {
            clearInterval(timer);
            timer = null;
        }
        document.onkeydown = null;
    }
    // 导出API
    this.start = start;
}

game.js

var Game = function () {
    //dom元素
    var gameDiv;
    var nextDiv;
    var timeDiv;
    var scoreDiv;
    var resultDiv;
    // 分数
    var score = 0;
    // 游戏矩阵
    var gameData = [
        [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 (pos.y + y >= gameData[0].length) {
            // 到最右边
            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 (var j = 0; j < data[0].length; j++) {
                if (data[i][j] != 0) {
                    if (!check(pos, i, j)) {
                        // 不等于0且非法
                        return false;
                    }
                }
            }
        }
        return true;
    }
    // 清除数据
    var clearData = 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.origin.x = cur.origin.x + 1;
            // var downJudge = new Square();
            // cur = downJudge.down();
            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 () {
        // 计分用,反映消行行数
        var line = 0;
        for (var i = gameData.length - 1; i >= 0; i--) {
            var clear = true;
            for (var j = 0; j < gameData[0].length; j++) {
                if (gameData[i][j] != 1) {
                    clear = false;
                    break;
                }
            }
            if (clear) {
                line = line + 1;
                // 下移一行
                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++;
            }
        }
        return line;
    }
    // 游戏结束
    var checkGameOver = function () {
        var gameOver = false;
        for (var i = 0; i < 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);
    }
    // 设置时间
    var setTime = function (time) {
        timeDiv.innerHTML = time;
    }
    // 加分
    var addScore = function () {
        var s = 0;
        switch (line) {
            // 消除一行十分
            case 1:
                s = 10;
                break;
            case 2:
                s = 40;
                break;
            case 3:
                s = 60;
                break;
            case 4:
                s = 80;
                break;
            default:
                break;
        }
        score = score + s;
        scoreDiv.innerHTML = score;
    }
    // 游戏结束
    var gameOver = function (win) {
        // 赢了
        if (win) {
            resultDiv.innerHTML = '你赢了啦!';
        } else {
            resultDiv.innerHTML = '你输了啦!';
        }
    }
    // 初始化 doms对象包含两个内容gameDiv、nextDiv
    var init = function (doms, type, dir) {
        gameDiv = doms.gameDiv;
        nextDiv = doms.nextDiv;
        timeDiv = doms.timeDiv;
        scoreDiv = doms.scoreDiv;
        resultDiv = doms.resultDiv;
        let square = new SquareFactory();
        next = square.make(type, dir);
        initDiv(gameDiv, gameData, gameDivs);
        initDiv(nextDiv, next.data, nextDivs);
        refreshDiv(next.data, nextDivs);
    }
    // 导出API,在外部local里就可以调用这个init函数了
    this.init = init;
    this.down = down;
    this.left = left;
    this.right = right;
    this.rotate = rotate;
    this.fall = function () {
        // 返回false就不能再下降
        while (down());
    }
    this.fixed = fixed;
    this.performNext = performNext;
    this.check = check;
    this.checkClear = checkClear;
    this.checkGameOver = checkGameOver;
    this.setTime = setTime;
    this.addScore = addScore;
    this.gameOver = gameOver;
}

注意

1.在geme.js中设计函数后,一定要在下面导出,才可以在别处调用该函数
2.添加元素到界面,要先定义一个变量,并在init函数中通过doms传入

你可能感兴趣的:(前端学习,javascript,html,css)