回归前端学习第23天-实现俄罗斯方块小游戏6(实现单机版2——键盘控制方块移动)

news/2024/11/24 4:11:00/

界面出现对应方块后,可自行控制其左右或快速下降的移动,上键可以实现方块形状的改变

  • 调整代码结构
  • 实现键盘控制方块移动
    • game.js中代码
      • 注意这里在SquareFactory中又写了个make函数,所以在game.js调用的时候,需要先new一个实例,否则会出现未定义的情况
    • square.js中代码
    • squareFactory.js中代码
    • local.js代码
    • script.js代码
  • 实现效果

调整代码结构

首先调整代码结构,建立JS文件,如图
在这里插入图片描述
在这里插入图片描述

实现键盘控制方块移动

game.js中代码

var Game = function () {//dom元素var gameDiv;var nextDiv;// 游戏矩阵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;// divsvar nextDivs = [];var gameDivs = [];// 初始化divvar 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);}}// 刷新divvar 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 = 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);}}// 初始化 doms对象包含两个内容gameDiv、nextDivvar 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.fall = function () {// 返回false就不能再下降while (down());}
}

注意这里在SquareFactory中又写了个make函数,所以在game.js调用的时候,需要先new一个实例,否则会出现未定义的情况

在这里插入图片描述

square.js中代码

var Square = function () {// 方块数据this.data = [[0, 0, 0, 0],[0, 0, 0, 0],[0, 0, 0, 0],[0, 0, 0, 0]];// 原点对象this.origin = {x: 0,y: 0}// 方向,即旋转中的索引this.dir = 0;
}
// 判断是否可以旋转
Square.prototype.canRotate = function (isValid) {var d = (this.dir + 1) % 4;var test = [[0, 0, 0, 0],[0, 0, 0, 0],[0, 0, 0, 0],[0, 0, 0, 0]];for (var i = 0; i < this.data.length; i++) {for (var j = 0; j < this.data[0].length; j++) {test[i][j] = this.rotates[d][i][j];}}return isValid(this.origin, test);
}
Square.prototype.rotate = function (num) {if (!num) num = 1;this.dir = (this.dir + num) % 4;for (var i = 0; i < this.data.length; i++) {for (var j = 0; j < this.data[0].length; j++) {this.data[i][j] = this.rotates[this.dir][i][j];}}
}
// 判断是否可以下降
Square.prototype.canDown = function (isValid) {var test = {};test.x = this.origin.x + 1;test.y = this.origin.y;return isValid(test, this.data);
}
Square.prototype.down = function () {this.origin.x = this.origin.x + 1;
}
// 判断是否可以左移
Square.prototype.canLeft = function (isValid) {var test = {};test.x = this.origin.x;test.y = this.origin.y - 1;return isValid(test, this.data);
}
Square.prototype.left = function () {this.origin.y = this.origin.y - 1;
}
// 判断是否可以右移
Square.prototype.canRight = function (isValid) {var test = {};test.x = this.origin.x;test.y = this.origin.y + 1;return isValid(test, this.data);
}
Square.prototype.right = function () {this.origin.y = this.origin.y + 1;
}

squareFactory.js中代码

var Square1 = function () {// 调用Square方法Square.call(this);// 旋转数组,枚举可能的情况 其中每个元素都是二维数组this.rotates = [[[0, 2, 0, 0],[2, 2, 2, 0],[0, 0, 0, 0],[0, 0, 0, 0]],[[2, 0, 0, 0],[2, 2, 0, 0],[2, 0, 0, 0],[0, 0, 0, 0]],[[2, 2, 2, 0],[0, 2, 0, 0],[0, 0, 0, 0],[0, 0, 0, 0]],[[0, 2, 0, 0],[2, 2, 0, 0],[0, 2, 0, 0],[0, 0, 0, 0]],]
}
// 省去代码
Square1.prototype = Square.prototype;var Square2 = function () {// 调用Square方法Square.call(this);// 旋转数组,枚举可能的情况 其中每个元素都是二维数组this.rotates = [[[0, 2, 0, 0],[0, 2, 0, 0],[0, 2, 0, 0],[0, 2, 0, 0]],[[0, 0, 0, 0],[2, 2, 2, 2],[0, 0, 0, 0],[0, 0, 0, 0]],[[0, 2, 0, 0],[0, 2, 0, 0],[0, 2, 0, 0],[0, 2, 0, 0]],[[0, 0, 0, 0],[2, 2, 2, 2],[0, 0, 0, 0],[0, 0, 0, 0]],]
}
// 判断是否可以旋转
Square2.prototype = Square.prototype;var Square3 = function () {// 调用Square方法Square.call(this);// 旋转数组,枚举可能的情况 其中每个元素都是二维数组this.rotates = [[[2, 2, 2, 0],[0, 0, 2, 0],[0, 0, 0, 0],[0, 0, 0, 0]],[[0, 2, 0, 0],[0, 2, 0, 0],[2, 2, 0, 0],[0, 0, 0, 0]],[[2, 0, 0, 0],[2, 2, 2, 0],[0, 0, 0, 0],[0, 0, 0, 0]],[[2, 2, 0, 0],[2, 0, 0, 0],[2, 0, 0, 0],[0, 0, 0, 0]],]
}
// 判断是否可以旋转
Square3.prototype = Square.prototype;var Square4 = function () {// 调用Square方法Square.call(this);// 旋转数组,枚举可能的情况 其中每个元素都是二维数组this.rotates = [[[2, 2, 2, 0],[2, 0, 0, 0],[0, 0, 0, 0],[0, 0, 0, 0]],[[2, 2, 0, 0],[0, 2, 0, 0],[0, 2, 0, 0],[0, 0, 0, 0]],[[0, 0, 2, 0],[2, 2, 2, 0],[0, 0, 0, 0],[0, 0, 0, 0]],[[2, 0, 0, 0],[2, 0, 0, 0],[2, 2, 0, 0],[0, 0, 0, 0]],]
}
// 判断是否可以旋转
Square4.prototype = Square.prototype;var Square5 = function () {// 调用Square方法Square.call(this);// 旋转数组,枚举可能的情况 其中每个元素都是二维数组this.rotates = [[[2, 2, 0, 0],[2, 2, 0, 0],[0, 0, 0, 0],[0, 0, 0, 0]],[[2, 2, 0, 0],[2, 2, 0, 0],[0, 0, 0, 0],[0, 0, 0, 0]],[[2, 2, 0, 0],[2, 2, 0, 0],[0, 0, 0, 0],[0, 0, 0, 0]],[[2, 2, 0, 0],[2, 2, 0, 0],[0, 0, 0, 0],[0, 0, 0, 0]],]
}
// 判断是否可以旋转
Square5.prototype = Square.prototype;var Square6 = function () {// 调用Square方法Square.call(this);// 旋转数组,枚举可能的情况 其中每个元素都是二维数组this.rotates = [[[0, 2, 2, 0],[2, 2, 0, 0],[0, 0, 0, 0],[0, 0, 0, 0]],[[2, 0, 0, 0],[2, 2, 0, 0],[0, 2, 0, 0],[0, 0, 0, 0]],[[0, 2, 2, 0],[2, 2, 0, 0],[0, 0, 0, 0],[0, 0, 0, 0]],[[2, 0, 0, 0],[2, 2, 0, 0],[0, 2, 0, 0],[0, 0, 0, 0]],]
}
// 判断是否可以旋转
Square6.prototype = Square.prototype;var Square7 = function () {// 调用Square方法Square.call(this);// 旋转数组,枚举可能的情况 其中每个元素都是二维数组this.rotates = [[[2, 2, 2, 0],[2, 2, 2, 0],[0, 0, 0, 0],[0, 0, 0, 0]],[[2, 2, 0, 0],[2, 2, 0, 0],[2, 2, 0, 0],[0, 0, 0, 0]],[[2, 2, 2, 0],[2, 2, 2, 0],[0, 0, 0, 0],[0, 0, 0, 0]],[[2, 2, 0, 0],[2, 2, 0, 0],[2, 2, 0, 0],[0, 0, 0, 0]],]
}
// 判断是否可以旋转
Square7.prototype = Square.prototype;var SquareFactory = function () {SquareFactory.prototype.make = function (index, dir) {var s;index = index + 1;switch (index) {case 1:s = new Square1();break;case 2:s = new Square2();break;case 3:s = new Square3();break;case 4:s = new Square4();break;case 5:s = new Square5();break;case 6:s = new Square6();break;case 7:s = new Square7();break;default:break;}// 定义原点s.origin.x = 0;s.origin.y = 3;s.rotate(dir);return s;}
}

local.js代码

var Local = function () {// 游戏对象var game;// 绑定键盘事件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 start = function () {var doms = {gameDiv: document.getElementById('game'),nextDiv: document.getElementById('next')}game = new Game();game.init(doms);bindKeyEvent();}// 导出APIthis.start = start;
}

script.js代码

 // 创建local对象并调用var local = new Local();local.start();

实现效果

在这里插入图片描述


http://www.ppmy.cn/news/475456.html

相关文章

回归前端学习第22天-实现俄罗斯方块小游戏5(实现单机版1——结合HTML、CSS、JS来搭建界面)

实现单机版俄罗斯方块小游戏&#xff0c;搭建页面 实现静态基础页面 实现静态基础页面 HTML&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"width…

十二、俄罗斯方块代码拆分

将主要代码进行拆分如下&#xff1a; bf_button.py 上一章中提到的不用图片自己制作的按钮控件 globals.py 一些全局变量 matrix.py 自己定义的矩阵类 controls.py 游戏界面上的一些控件元素 block_manage.py 各类方块的定义和游戏方块的管理 players.py 各类玩家的定义 single…

单机版火拼俄罗斯方块源程序

发表日期&#xff1a;2005年11月12日 已经有3587位读者读过此文 /*这是我在参考别人的的俄罗斯方块的基础上&#xff0c;写的一个单机版火拼俄罗斯方块源程序&#xff0c;*//*如果有须要下载可到www.jxnczyp.ys168.com中的个人小程序中下载己编译好的程序*//*如果想自己…

基于java的俄罗斯方块小游戏设计(含源文件)

欢迎添加微信互相交流学习哦&#xff01; 项目源码&#xff1a;https://gitee.com/oklongmm/biye 题 目 小游戏开发 摘 要 俄罗斯方块是我们最常见的游戏之一&#xff0c;该游戏出现过在掌上游戏机、家用游戏机、手机游戏和电脑游戏中&#xff0c;因此俄罗斯方…

Qt做的俄罗斯方块游戏

最近一直在用Qt折腾一个简单的俄罗斯方块游戏&#xff0c;期间断断续续经过将近一个月的折腾&#xff0c;终于完成啦&#xff0c;挂在这里&#xff0c;供大家评阅&#xff0c;第一次做游戏&#xff0c;肯定会有很多的不足之处&#xff0c;希望大家指正。 其实做这个游戏主要是…

回归前端学习第26天-实现俄罗斯方块小游戏9(实现单机版,一个计时带干扰的单机版俄罗斯方块小游戏完成)

最终完善单机版俄罗斯方块小游戏&#xff0c;增加干扰功能——每10秒增加一行 增加干扰功能game.js中加入addBotLine函数local.js中加入 增加干扰功能 game.js中加入addBotLine函数 // 底部增加行var addBotLine function (lines) {for (var i0; i<gameData.length - lin…

JSP版俄罗斯发方块+用户积分排行榜

一、游戏截图 二、查看所有成绩 三、技术原理&#xff1a; 学习过程是循序渐进的&#xff1a; 1.俄罗斯方块第1版&#xff1a;能移动&#xff0c;能接收按键&#xff0c;刷新画面。 https://blog.csdn.net/weixin_42644456/article/details/103080277 2.俄罗斯方块第2版&am…

阿里云1分钟部署经典小游戏(2048,Flappy Bird,俄罗斯方块,超级马里奥)

简介 场景指导您通过Serverless应用引擎SAE实现开箱即用、快速部署经典小游戏&#xff0c;包括2048、俄罗斯方块、超级马里奥和Flappy Bird。 必读实验说明&#xff08;总结&#xff0c;云产品需收费&#xff09; SLB起充100 可提现 按照操作文档&#xff0c;完成所有任务&…