<!DOCTYPE html>
<body>
<script>//面向对象function Game () {//虚拟的节点对象var frag = document.createDocumentFragment();//大盒子this.div = document.createElement("div");//游戏结束的divthis.over = document.createElement("div");//游戏结束的小divthis.overdiv = document.createElement("div");//游戏结束后重新开始按钮this.overbtn = document.createElement("button");//使用键盘控制的可视化spansthis.spans = [];//方块变形的索引this.mi = 0;//游戏得分this.score = 0;//游戏是否正在进行this.inGame = false;for (var i = 0; i < 7; i++) {let span = document.createElement("span");this.spans.push(span);}this.spans[2].innerText = "SPACE";this.spans[1].style.fontSize = "30px";for (var i = 3; i <= 6; i++) {frag.appendChild(this.spans[i]);//设置元素的样式this.setstyle(this.spans[i], {width: "50px",height: "50px",color: "white",font: "30px/50px ''",textAlign: "center",backgroundColor: "gray",position: "absolute"});}for (var i = 2; i <= 5; i++) {this.spans[i].style.bottom = "85px";}this.spans[3].innerText = "<";this.spans[4].innerText = "∨";this.spans[5].innerText = ">";this.spans[6].innerText = "^";this.spans[3].style.left = "580px";this.spans[4].style.left = "640px";this.spans[5].style.left = "700px";this.setstyle(this.spans[6], {bottom: "145px",left: "640px"});this.setstyle(this.spans[2], {width: "250px",height: "40px",position: "absolute",bottom: "85px",color: "white",font: "20px/40px ''",textAlign: "center",backgroundColor: "gray",left: "5px"});for (var i = 0; i < 200; i++) {let div = document.createElement("div");this.setstyle(div, {width: "30px",height: "30px",backgroundColor: "rgba(0, 0, 0, .3)",float: "left",border: "5px solid rgba(0, 0, 0, .1)",boxSizing: "border-box"});this.div.appendChild(div);}this.setstyle(this.div, {width: "300px",height: "600px",backgroundColor: "rgba(0, 0, 0, .3)",border: "3px solid black",margin: "0 0 0 250px",position: "relative",overflow: "hidden"});this.setstyle(this.over, {width: "200px",height: "140px",backgroundColor: "whitesmoke",position: "absolute",zIndex: "1",top: "calc(50% - 100px)",left: "calc(50% - 100px)",display: "none"});this.setstyle(this.spans[0], {width: "120px",height: "40px",font: "20px/40px ''",color: "lightblue",marginLeft: "40px",textAlign: "center"});this.setstyle(this.overbtn, {width: "80px",height: "40px",font: "20px/34px ''",color: "white",margin: "10px 0 0 62px",textAlign: "center",backgroundColor: "blue"});this.setstyle(this.overdiv, {width: "130px",height: "40px",font: "20px/40px ''",color: "black",margin: "0 auto",textAlign: "center"});this.spans[0].innerText = "GAME OVER";this.spans[1].innerText = `已消除方块: ${this.score}个`;this.overbtn.innerText = "确定";[this.spans[0], this.overdiv, this.overbtn].forEach(ele => this.over.appendChild(ele));this.div.appendChild(this.over);[this.spans[1], this.spans[2], this.div].forEach(ele => frag.appendChild(ele));//将文档碎片放在body上document.body.appendChild(frag);//调用Game的原型的keyControl函数,使得可以通过键盘控制方块this.keyControl();}//方块移动之前调用的函数Game.prototype.oMove = function () {this.bodys = [[{ x: 120, y: 0 }, { x: 150, y: 0 }, { x: 120, y: 30 }, { x: 150, y: 30 }],[{ x: 120, y: 0 }, { x: 150, y: 0 }, { x: 120, y: 30 }, { x: 120, y: 60 }],[{ x: 120, y: 0 }, { x: 150, y: 0 }, { x: 150, y: 30 }, { x: 150, y: 60 }],[{ x: 120, y: 0 }, { x: 120, y: 30 }, { x: 150, y: 30 }, { x: 150, y: 60 }],[{ x: 150, y: 0 }, { x: 150, y: 30 }, { x: 120, y: 30 }, { x: 120, y: 60 }],[{ x: 120, y: 0 }, { x: 120, y: 30 }, { x: 120, y: 60 }, { x: 150, y: 30 }],[{ x: 90, y: 0 }, { x: 120, y: 0 }, { x: 150, y: 0 }, { x: 180, y: 0 }]];//为this.bodys而设置的索引this.bi = parseInt(Math.random() * 7);//准备移动的方块,数组,有length个小方块this.body = this.bodys[this.bi];//先放在大盒子上再移动this.createObj();this.move(400);}//将准备移动的方块放在盒子的函数Game.prototype.createObj = function () {for (var i = 0; i < this.body.length; i++) {let div = document.createElement("div");this.setstyle(div, {width: "30px",height: "30px",backgroundColor: "rgba(0,0,0,.6)",position: "absolute",border: "3px solid skyblue",boxSizing: "border-box",top: this.body[i].y + "px",left: this.body[i].x + "px"});div.className = "active";this.div.appendChild(div);}this.actives = document.querySelectorAll(".active");this.fixeds = document.getElementsByClassName("fixed");}//方块移动的函数Game.prototype.move = function (ms) {clearInterval(this.timer);this.timer = setInterval(() => {this.prevBody = this.clone(this.body);for (var i = 0; i < this.body.length; i++) {this.body[i].y += 30;}if (this.changeActives()) {for (var i = 0; i < this.body.length; i++) {this.div.removeChild(this.actives[i]);}this.createObj();} else this.body = this.prevBody;var bool = false;if (this.fixeds.length) {for (var j = 0; j < this.fixeds.length; j++) {for (var i = 0; i < this.body.length; i++) {if (this.body[i].y + 30 === this.div.clientHeight ||(this.body[i].y + 30 === this.fixeds[j].offsetTop &&this.body[i].x === this.fixeds[j].offsetLeft)) {bool = true;clearInterval(this.timer);setTimeout(() => this.addFixeds(), 300);break;}}if (bool) break;}} else {for (var i = 0; i < this.body.length; i++) {if (this.body[i].y + 30 === this.div.clientHeight) {clearInterval(this.timer);setTimeout(() => this.addFixeds(), 300);break;}}}}, ms);}//固定方块的函数Game.prototype.addFixeds = function () {var bool = true;var arr = [];if (this.fixeds.length) {for (var j = 0; j < this.fixeds.length; j++) {for (var i = 0; i < this.body.length; i++) {if (this.body[i].y + 30 === this.div.clientHeight ||(this.body[i].y + 30 === this.fixeds[j].offsetTop &&this.body[i].x === this.fixeds[j].offsetLeft)) {bool = false;break;}}}if (bool) {this.move(400);return;}}this.mi = 0;var toRed = [];for (var i = 0; i < this.actives.length; i++) {this.actives[i].className = "fixed";toRed.push(this.actives[i]);}this.fixeds = document.getElementsByClassName("fixed");if (this.space) {this.space = false;this.keyControl();}if (this.ifEliminate()) {arr = this.ifEliminate();this.colorEffect(arr, "rgba(255, 0, 0, .6)", 0);this.colorEffect(arr, "rgba(0, 0, 0, .6)", 80);this.colorEffect(arr, "rgba(255, 0, 0, .6)", 160);this.colorEffect(arr, "rgba(0, 0, 0, .6)", 240);this.colorEffect(arr, "rgba(255, 0, 0, .6)", 320);setTimeout(() => this.eliminate(), 320);} else {this.colorEffect(toRed, "rgba(255, 0, 0, .6)", 0);this.colorEffect(toRed, "rgba(0, 0, 0, .6)", 150);}//判断是否游戏结束if ((() => {for (var i = 0; i < this.fixeds.length; i++) {if (this.fixeds[i].offsetTop <= 60) return true;}})()) {clearInterval(this.timer);document.onkeydown = null;this.move = function () { };this.overdiv.innerText = `得分: ${this.score}分`;this.over.style.display = "block";this.overbtn.onclick = () => window.location.reload();} else if (arr.length) {setTimeout(() => this.oMove(), 320);} else this.oMove();}//固定方块的时候,设置一些颜色效果Game.prototype.colorEffect = function (arr, effect, ms) {setTimeout(() => arr.forEach(ele => ele.style.backgroundColor = effect), ms);}//判断方块是否可以移动的函数Game.prototype.changeActives = function () {if (this.fixeds.length) {for (var j = 0; j < this.fixeds.length; j++) {for (var i = 0; i < this.body.length; i++) {if (this.body[i].y >= this.div.clientHeight ||(this.body[i].y === this.fixeds[j].offsetTop &&this.body[i].x === this.fixeds[j].offsetLeft) ||this.body[i].x < 0 ||this.body[i].x > this.div.clientWidth - 30) return false;}}} else {for (var i = 0; i < this.body.length; i++) {if (this.body[i].y >= this.div.clientHeight ||this.body[i].x < 0 ||this.body[i].x > this.div.clientWidth - 30) return false;}}return true;}//使得可以键盘控制的函数Game.prototype.keyControl = function () {this.bool = true;this.repeat = true;document.onkeydown = (e) => {var e = window.event || e;//按下的键的ASCII码this.keycode = e.keycode || e.which;switch (this.keycode) {//上键case 38:this.spans[6].style.backgroundColor = "black";//嵌套switchswitch (this.bi) {case 1:this.arr = [[{ x: 120, y: 0 }, { x: 150, y: 0 }, { x: 120, y: 30 }, { x: 120, y: 60 }],[{ x: 120, y: 0 }, { x: 150, y: 0 }, { x: 180, y: 0 }, { x: 180, y: 30 }],[{ x: 150, y: 30 }, { x: 150, y: 0 }, { x: 150, y: 60 }, { x: 120, y: 60 }],[{ x: 120, y: 0 }, { x: 120, y: 30 }, { x: 150, y: 30 }, { x: 180, y: 30 }]];this.deform();break;case 2:this.arr = [[{ x: 120, y: 0 }, { x: 150, y: 0 }, { x: 150, y: 30 }, { x: 150, y: 60 }],[{ x: 120, y: 30 }, { x: 150, y: 30 }, { x: 180, y: 30 }, { x: 180, y: 0 }],[{ x: 120, y: 0 }, { x: 120, y: 30 }, { x: 120, y: 60 }, { x: 150, y: 60 }],[{ x: 120, y: 0 }, { x: 150, y: 0 }, { x: 180, y: 0 }, { x: 120, y: 30 }]];this.deform();break;case 3:this.arr = [[{ x: 120, y: 0 }, { x: 120, y: 30 }, { x: 150, y: 30 }, { x: 150, y: 60 }],[{ x: 180, y: 0 }, { x: 150, y: 0 }, { x: 150, y: 30 }, { x: 120, y: 30 }]];this.deform();break;case 4:this.arr = [[{ x: 150, y: 0 }, { x: 150, y: 30 }, { x: 120, y: 30 }, { x: 120, y: 60 }],[{ x: 120, y: 0 }, { x: 150, y: 0 }, { x: 150, y: 30 }, { x: 180, y: 30 }]];this.deform();break;case 5:this.arr = [[{ x: 150, y: -30 }, { x: 150, y: 0 }, { x: 150, y: 30 }, { x: 180, y: 0 }],[{ x: 120, y: 30 }, { x: 90, y: 30 }, { x: 150, y: 30 }, { x: 120, y: 0 }],[{ x: 150, y: 0 }, { x: 120, y: 30 }, { x: 150, y: 60 }, { x: 150, y: 30 }],[{ x: 150, y: 60 }, { x: 120, y: 30 }, { x: 180, y: 30 }, { x: 150, y: 30 }]];this.deform();break;case 6:this.arr = [[{ x: 90, y: 30 }, { x: 120, y: 30 }, { x: 150, y: 30 }, { x: 180, y: 30 }],[{ x: 150, y: -30 }, { x: 150, y: 0 }, { x: 150, y: 30 }, { x: 150, y: 60 }]];this.deform();break;default: break;}break;//左键case 37:this.spans[3].style.backgroundColor = "black";var bool = true;for (var j = 0; j < this.fixeds.length; j++) {for (var i = 0; i < this.body.length; i++) {if (this.fixeds[j].offsetLeft === this.body[i].x - 30 &&this.fixeds[j].offsetTop === this.body[i].y) bool = false;}}if (this.body.every(a => a.x > 0) && bool) {for (var i = 0; i < this.body.length; i++) {this.body[i].x -= 30;}for (var i = 0; i < this.actives.length; i++) {this.div.removeChild(this.actives[i]);}this.createObj();}break;//右键case 39:this.spans[5].style.backgroundColor = "black";var bool = true;for (var j = 0; j < this.fixeds.length; j++) {for (var i = 0; i < this.body.length; i++) {if (this.fixeds[j].offsetLeft === this.body[i].x + 30 &&this.fixeds[j].offsetTop === this.body[i].y) bool = false;}}if (this.body.every(a => a.x < this.div.clientWidth - 30) && bool) {for (var i = 0; i < this.body.length; i++) {this.body[i].x += 30;}for (var i = 0; i < this.actives.length; i++) {this.div.removeChild(this.actives[i]);}this.createObj();}break;//下键case 40:this.spans[4].style.backgroundColor = "black";if (this.bool) {this.bool = false;this.move(80);}break;case 32://空格键this.spans[2].style.backgroundColor = "black";if (!this.inGame) {this.inGame = true;this.oMove();} else if (this.bool) {this.bool = false;this.move(1);document.onkeydown = null;this.space = true;}break;default: break;}}document.onkeyup = () => {for (var i = 2; i <= 6; i++) {this.spans[i].style.backgroundColor = "gray";}clearInterval(this.key40);this.key40 = setTimeout(() => this.bool = true, 80);if (this.keycode === 40) this.move(400);}}//深拷贝的函数Game.prototype.clone = function (data) {if (Object.prototype.toString.call(data) === "[object Object]") var target = {};else if (Object.prototype.toString.call(data) === "[object Array]") var target = [];else return data;for (var key in data) {if (typeof data[key] === "object") target[key] = this.clone(data[key]);else target[key] = data[key];}return target;}//使方块变形的函数Game.prototype.deform = function () {this.mi++;if (this.mi === this.arr.length) this.mi = 0;var mint = this.actives[0].offsetTop;var minl = this.actives[0].offsetLeft;for (var i = 1; i < this.actives.length; i++) {if (this.actives[i].offsetTop < mint) mint = this.actives[i].offsetTop;if (this.actives[i].offsetLeft < minl) minl = this.actives[i].offsetLeft;}this.prevBody = this.clone(this.body);for (var i = 0; i < this.arr[this.mi].length; i++) {this.body[i].x = this.arr[this.mi][i].x + minl - 120;this.body[i].y = this.arr[this.mi][i].y + mint;}if (!this.changeActives()) {this.body = this.prevBody;this.mi--;}for (var i = 0; i < this.actives.length; i++) {this.div.removeChild(this.actives[i]);}this.createObj();}//设置样式的函数Game.prototype.setstyle = function (ele, styleobj) {for (var attr in styleobj) {ele.style[attr] = styleobj[attr];}}//判断是否可以消除方块的函数Game.prototype.ifEliminate = function () {var obj = {};var arr = [];for (var i = 0; i < this.fixeds.length; i++) {if (obj[this.fixeds[i].offsetTop]) obj[this.fixeds[i].offsetTop]++;else obj[this.fixeds[i].offsetTop] = 1;}for (var key in obj) {if (obj[key] === 10) {for (var j = 0; j < this.fixeds.length; j++) {if (this.fixeds[j].offsetTop == key) arr.push(this.fixeds[j]);}}}if (arr.length) return arr;}//消除方块的函数Game.prototype.eliminate = function () {var obj = {};var arr = [];for (var i = 0; i < this.fixeds.length; i++) {if (obj[this.fixeds[i].offsetTop]) obj[this.fixeds[i].offsetTop]++;else obj[this.fixeds[i].offsetTop] = 1;}for (var key in obj) {if (obj[key] === 10) {for (var j = 0; j < this.fixeds.length; j++) {if (this.fixeds[j].offsetTop == key) arr.push(this.fixeds[j]);if (this.fixeds[j].offsetTop < key)this.fixeds[j].style.top = this.fixeds[j].offsetTop + 30 + "px";}arr.forEach(a => {this.div.removeChild(a);this.score++;});this.eliminate();break;}}this.fixeds = document.getElementsByClassName("fixed");this.spans[1].innerText = `已消除方块: ${this.score}个`;}//创建实例var g = new Game();
</script>
</body>

原生JS实现俄罗斯方块相关推荐

  1. eclipse javascript_原生js实现贪吃蛇游戏_javascript技巧

    更新时间:2020年10月26日 11:46:36   作者:leisure-ZL 这篇文章主要为大家详细介绍了原生js实现贪吃蛇小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴 ...

  2. 原生js循环展示dom_【前端面试】用一道题讲 js 的事件循环队列

    昨天去面了滴滴,一口气面了三面,考了 promise 和事件循环.之前的猿辅导也考察了这些,几乎所有的大厂中厂都一定会考原生 js 的事件循环队列. 今天,我把昨天考察的原题拿出来分析一下. setT ...

  3. 进一步封装axios并调用其读取数据(吐槽~在安卓9.0以下或者IOS10.X以下手机端H5页面不支持,在这两种情况下的系统只能使用ajax或者原生js请求后台数据)

    注意!!!(修改于2020年7月18日) 在安卓9.0以下或者IOS10.X以下手机端H5页面不支持,在这两种情况下的系统只能使用ajax或者原生js请求后台数据 报错截图如下 报错内容: {&quo ...

  4. 黄聪:原生js的音频播放器,兼容pc端和移动端(原创)

    更新时间:2018/9/3 下午1:32:54 更新说明:添加音乐的loop设置和ended事件监听 loop为ture的时候不执行ended事件 1 2 3 4 5 6 7 8 9 10 11 12 ...

  5. 原生js实现点击按钮切换全屏!

    使用fullScreen API实现全屏 <head><meta charset="UTF-8"><meta name="viewport& ...

  6. 原生js清空上一个元素内容_原生JS实现动态添加新元素、删除元素方法

    1. 添加新元素 动态添加新元素 Coffee Tea Coffee Tea var child = document.getElementsByClassName("child" ...

  7. 蓝鸥原生JS:js的历史及JavaScript的优缺点

    蓝鸥原生JS:js的历史及JavaScript的优缺点 蓝鸥零基础学习HTML5-html+css基础 http://11824614.blog.51cto.com/11814614/1852769 ...

  8. 用原生 js jquery 实现知乎收起答案功能

    Update 2016.12.7 已封装为插件 原生 js 插件$ npm install foldcontent-zhihu@">=3.0.12" --save Usage ...

  9. 移动端实现文字轮播_使用原生JS实现移动端图片轮播效果(一)

    PC端上实现图片轮播效果非常简单,只要通过使用click事件就可以非常简单的实现效果,但是在移动端上,就要通过核心的touch事件来实现.话不多说,现在我们就开始移动端轮播效果的实现. 首先就是原生J ...

最新文章

  1. C#中new和override区别
  2. 电路常识性概念(8)-MOS管及简单CMOS逻辑门电路原理图
  3. 用html编写ASCII表,HTML ASCII
  4. 【Codeforces Round #452 (Div. 2) C】 Dividing the numbers
  5. 硬核|定时任务的10种实现方案,满足你的不同需求!
  6. java恐怖游戏_分享个经典恐怖游戏系列
  7. Docker学习总结(27)——Dockerfile详解
  8. Linux时间子系统之四:定时器的引擎:clock_event_device
  9. ajax后台重定向会返回什么_处理jquery ajax重定向
  10. 冗余链路中STP协议的工作过程以及二期STP收敛速度优化方案介绍
  11. fh 幅频特性曲线怎么画fl_数学老师用“函数曲线”绘出美图 学生舍不得擦黑板。唉,这样的老师我没有遇到!...
  12. Android 实时时间显示实现
  13. 家庭用计算机音响,7.1声道THX家庭影院音箱摆位计算器
  14. java怎么让图片自适应_Java使背景图片自适应窗体的办法
  15. 利用思维导图,快速整理小学语文复习重点,建议为孩子收藏!
  16. 互联网工作 常用名词及基础知识扫盲
  17. python之tkinter学生管理系统3-view(功能界面)
  18. loam中imu消除重力加速度的数学推导
  19. 基于EC57 标准 上的数据库 测试室颤VF节律准确性的一个问题
  20. 异步编程之美——CompletableFuture

热门文章

  1. 用番茄工作法提升工作效率 (四)ToDoList的持续优化
  2. 【VC++游戏开发#九】2D篇 —— 粒子系统(二):平安夜特别版——星光四射
  3. Java开发入门与实战!张孝祥java就业培训
  4. Avoid The Lakes(避开湖泊C++)
  5. 网站被k的原因症状有哪些,网站被k怎么恢复(笔记)
  6. 闪压压缩解压软件官方版
  7. SCSI/iSCSI及SAS、NAS、SAN的基本介绍
  8. 青龙面板之九章油条(更新)
  9. 世上无难事只怕有心人,GO!vmware15 安装win10详解
  10. Hot Restart Hot Reload