俄罗斯方块

mac2025-01-29  22

最近看到有朋友在玩俄罗斯方块,瞬间引起了我的童年回忆。理论上来说,学了HTML+CSS+JS是可以写出游戏代码的,我就回去试了下,样式没那么好看,但基本功能已经实现了

这是HTML部分

<style type="text/css"> .c { margin: 1px; width: 19px; height: 19px; background: red; position: absolute; } .d { margin: 1px; width: 19px; height: 19px; background: gray; position: absolute; } .f { top: 0px; left: 0px; background: black; position: absolute; } .e { top: 0px; background: #151515; position: absolute; } .g { width: 100px; height: 20px; color: white; position: absolute; } </style>

这是JS部分

<script type="text/javascript"> var row = 18; var col = 10; var announcement = 6; var size = 20; var isOver = false; var shapes = ("0,1,1,1,2,1,3,1;1,0,1,1,1,2,2,2;2,0,2,1,2,2,1,2;0,1,1,1,1,2,2,2;1,2,2,2,2,1,3,1;1,1,2,1,1,2,2,2;0,2,1,2,1,1,2,2").split(";"); var tetris; var container; function createElm(tag, css) { var elm = document.createElement(tag); elm.className = css; document.body.appendChild(elm); return elm; } function Tetris(css, x, y, shape) { // 创建4个div用来组合出各种方块 var myCss = css ? css : "c"; this.divs = [createElm("div", myCss), createElm("div", myCss), createElm("div", myCss), createElm("div", myCss)]; if (!shape) { this.divs2 = [createElm("div", myCss), createElm("div", myCss), createElm("div", myCss), createElm("div", myCss)]; this.score = createElm("div", "g"); this.score.style.top = 10 * size + "px"; this.score.style.left = (col - -1) * size + "px"; this.score.innerHTML = "score:0"; } this.container = null; this.refresh = function() { this.x = (typeof(x) != 'undefined') ? x : 3; this.y = (typeof(y) != 'undefined') ? y : 0; // 如果有传参,优先使用参数的,如果有预告,优先使用预告,都没有就自己生成 if (shape) this.shape = shape; else if (this.shape2) this.shape = this.shape2; else this.shape = shape ? shape : shapes[Math.floor((Math.random() * shapes.length - 0.000000001))].split(","); this.shape2 = shapes[Math.floor((Math.random() * shapes.length - 0.000000001))].split(","); if (this.container && !this.container.check(this.x, this.y, this.shape)) { isOver = true; alert("游戏结束"); } else { this.show(); this.showScore(); this.showAnnouncement(); } } // 显示方块 this.show = function() { for (var i in this.divs) { this.divs[i].style.top = (this.shape[i * 2 + 1] - -this.y) * size + "px"; this.divs[i].style.left = (this.shape[i * 2] - -this.x) * size + "px"; } } // 显示预告 this.showAnnouncement = function() { for (var i in this.divs2) { this.divs2[i].style.top = (this.shape2[i * 2 + 1] - -1) * size + "px"; this.divs2[i].style.left = (this.shape2[i * 2] - -1 - -col) * size + "px"; } } // 显示分数 this.showScore = function() { if (this.container && this.score) { this.score.innerHTML = "score:" + this.container.score; } } // 水平移动方块的位置 this.hMove = function(step) { if (this.container.check(this.x - -step, this.y, this.shape)) { this.x += step; this.show(); } } // 垂直移动方块位置 this.vMove = function(step) { if (this.container.check(this.x, this.y - -step, this.shape)) { this.y += step; this.show(); } else { this.container.fixShape(this.x, this.y, this.shape); this.container.findFull(); this.refresh(); } } // 旋转方块 this.rotate = function() { var newShape = [this.shape[1], 3 - this.shape[0], this.shape[3], 3 - this.shape[2], this.shape[5], 3 - this.shape[4], this.shape[7], 3 - this.shape[6]]; if (this.container.check(this.x, this.y, newShape)) { this.shape = newShape; this.show(); } } this.refresh(); } function Container() { this.init = function() { // 绘制方块所在区域 var bgDiv = createElm("div", "f"); bgDiv.style.width = size * col + "px"; bgDiv.style.height = size * row + "px"; // 绘制预告所在区域 var bgDiv = createElm("div", "e"); bgDiv.style.left = size * col + "px"; bgDiv.style.width = size * announcement + "px"; bgDiv.style.height = size * row + "px"; // 清空积分 this.score = 0; } this.check = function(x, y, shape) { // 检查边界越界 var flag = false; var leftmost = col; var rightmost = 0; var undermost = 0; for (var i = 0; i < 8; i += 2) { // 记录最左边水平坐标 if (shape[i] < leftmost) leftmost = shape[i]; // 记录最右边水平坐标 if (shape[i] > rightmost) rightmost = shape[i]; // 记录最下边垂直坐标 if (shape[i + 1] > undermost) undermost = shape[i + 1]; // 判断是否碰撞 if (this[(shape[i + 1] - -y) * 100 - -(shape[i] - -x)]) flag = true; } // 判断是否到达极限高度 for (var m = 0; m < 3; m++) for (var n = 0; n < col; n++) if (this[m * 100 + n]) flag = true; if ((rightmost - -x + 1) > col || (leftmost - -x) < 0 || (undermost - -y + 1) > row || flag) return false; return true; } // 用灰色方块替换红色方块,并在容器中记录灰色方块的位置 this.fixShape = function(x, y, shape) { var t = new Tetris("d", x, y, shape); for (var i = 0; i < 8; i += 2) this[(shape[i + 1] - -y) * 100 - -(shape[i] - -x)] = t.divs[i / 2]; } // 遍历整个容器,判断是否可以消除 this.findFull = function() { var s = 0; for (var m = 0; m < row; m++) { var count = 0; for (var n = 0; n < col; n++) if (this[m * 100 + n]) count++; if (count == col) { s++; this.removeLine(m); } } this.score -= -this.calScore(s); } this.calScore = function(s) { if (s != 0) return s - -this.calScore(s - 1) else return 0; } // 消除指定一行方块 this.removeLine = function(row) { // 移除一行方块 for (var n = 0; n < col; n++) document.body.removeChild(this[row * 100 + n]); // 把所消除行上面所有的方块下移一行 for (var i = row; i > 0; i--) { for (var j = 0; j < col; j++) { this[i * 100 - -j] = this[(i - 1) * 100 - -j] if (this[i * 100 - -j]) this[i * 100 - -j].style.top = i * size + "px"; } } } } function init() { container = new Container(); container.init(); tetris = new Tetris(); tetris.container = container; document.onkeydown = function(e) { if (isOver) return; var e = window.event ? window.event : e; switch (e.keyCode) { case 38: //up tetris.rotate(); break; case 40: //down tetris.vMove(1); break; case 37: //left tetris.hMove(-1); break; case 39: //right tetris.hMove(1); break; } } setInterval("if(!isOver) tetris.vMove(1)", 500); } </script> </head> <body onload="init()"> </body>

有兴趣的可以看下,甚至可以改下样式,让其变得更好看一点,也可以增加些难度。

最新回复(0)