增改game.js与local.js代码,实现对游戏的设置计时、消行加分、游戏结束标志等环节的设计
- 计时
- 计分
- 游戏结束
- 完整代码
- local.js
- game.js
- 注意
文章图片
计时 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 = 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 (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 = 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.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;
}
注意 【前端学习|回归前端学习第25天-实现俄罗斯方块小游戏8(实现单机版4—设置计时、消行加分、游戏结束标志)】1.在geme.js中设计函数后,一定要在下面导出,才可以在别处调用该函数
2.添加元素到界面,要先定义一个变量,并在init函数中通过doms传入
推荐阅读
- 操作系统|[译]从内部了解现代浏览器(1)
- web网页模板|如此优秀的JS轮播图,写完老师都沉默了
- JavaScript|vue 基于axios封装request接口请求——request.js文件
- vue.js|vue中使用axios封装成request使用
- JavaScript|JavaScript: BOM对象 和 DOM 对象的增删改查
- JavaScript|JavaScript — 初识数组、数组字面量和方法、forEach、数组的遍历
- JavaScript|JavaScript — call()和apply()、Date对象、Math、包装类、字符串的方法
- JavaScript|JavaScript之DOM增删改查(重点)
- 网络|一文彻底搞懂前端监控
- javascript|vue使用js-xlsx导出excel,可修改格子样式,例如背景颜色、字体大小、列宽等