兼容性
兼容IE10,现代浏览器
效果图
项目结构
tetris
css
tetris.css
js
tetris.js
tetris.html
tetris.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>俄罗斯方块</title><link rel="stylesheet" type="text/css" href="css/tetris.css">
</head>
<body>
<div class="container"><div class="left"><div id="score-panel" class="score-panel"><span class="score-label">得分:</span><span class="score">0</span></div><div id="main-panel" class="panel"><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div><div class="panel-cell"></div></div><div id="fail" class="fail hidden"><div class="fail-down">失败了</div><div class="fail-up">失败了</div></div></div><div class="right"><div id="preview" class="preview"></div><div class="key-summary"><div class="key-summary-row"><!----><div id="left-turn" class="key-summary-show key-summary-left-turn"><span>Q</span> <span>左转</span></div><!----><div id="right-turn" class="key-summary-show key-summary-right-turn"><span>E</span> <span>右转</span></div><!----></div><div class="key-summary-row"><!----><div id="left-move" class="key-summary-show key-summary-left-move"><span>A</span> <span>左移</span></div><!----><div id="bottom-move" class="key-summary-show key-summary-bottom-move"><span>S</span> <span>下移</span></div><!----><div id="right-move" class="key-summary-show key-summary-right-move"><span>D</span> <span>右移</span></div><!----></div><div class="key-summary-row"><!----><div id="pause-restore" class="key-summary-show key-summary-pause-restore"><!----><span>SPACE</span> <span class="show-pause-restore">暂停</span><!----></div><!----></div></div><div class="start-container"><!----><div id="start-normal" class="start start-normal">重新开始</div><!----></div><div class="start-container"><!----><div id="start-random" class="start start-random">随机玩法</div><!----></div></div>
</div>
</body>
<script type="text/javascript" src="js/tetris.js"></script>
</html>
tetris.css
html,body {height: 100%;}
.container {position: fixed;left: 0;right: 0;top: 0;bottom: 0;margin: auto;width: 460px;height: 514px;background-color: #00AA00;font-family: "Microsoft YaHei", "微软雅黑", serif;
}
.left {position: absolute;left: 0;top: 0;width: 244px;height: 514px;
}
.left .score-panel {height: 30px;-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;border: 2px solid #202020;border-bottom: none;line-height: 28px;font-size: 16px;background-color: #00FFFF;
}
.left .score-panel .score-label {margin-left: 10px;
}
.left .score-panel .score {font-weight: bold;
}
.left .panel {position: relative;left: 0;top: 0;overflow: hidden;-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;border: 2px solid #202020;height: 484px;
}
.left .panel-cell {float: left;width: 24px;height: 24px;-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;border: 1px solid #f0f0f0;background-color: #D0D0D0;
}
.left .fail {position: absolute;z-index: 3;width: 160px;height: 40px;left: 0;right: 0;top: 30px;bottom: 0;margin: auto;text-align: center;line-height: 40px;font-size: 30px;letter-spacing: 8px;text-indent: 8px;color: #ffffff;-webkit-user-select: none;-ms-user-select: none;user-select: none;
}
.left .fail-down {position: absolute;width: 100%;color: #202020;left: 2px;top: 2px;opacity: 0.35;
}
.left .fail-up {position: absolute;width: 100%;left: 0;top: 0;text-shadow: 0 0 5px #202020;
}
.left .hidden {display: none;
}.right {position: absolute;right: 0;top: 0;width: 216px;height: 514px;-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;border: 2px solid #202020;border-left: none;background-color: #d5c9f0;-webkit-user-select: none;-ms-user-select: none;user-select: none;
}
.right .preview {position: relative;left: 0;top: 0;overflow: hidden;height: 214px;-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;border-bottom: 2px solid #202020;
}
.right .preview .preview-shape {position: absolute;top: 0;bottom: 0;left: 0;right: 0;margin: auto;
}
.right .preview .preview-cell {float: left;width: 24px;height: 24px;-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;border: 1px solid #d5c9f0;
}
.right .key-summary {-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;border-bottom: 2px solid #202020;cursor: default;
}
.right .key-summary .key-summary-row {text-align: center;margin: 10px 0;
}
.right .key-summary .key-summary-show {display: inline-block;height: 36px;border: 2px solid #5cffa8;background-color: #122b40;-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;padding: 4px 10px;overflow: hidden;color: #f0f0f0;font-size: 14px;line-height: 24px;border-radius: 16px;margin: 0 2px;cursor: pointer;
}
.right .key-summary .key-summary-left-turn,
.right .key-summary .key-summary-right-turn {padding: 4px 27px;
}
.right .key-summary .key-summary-pause-restore {padding: 4px 62px;background-color: #d58a05;
}
.right .key-summary .down {line-height: 26px;
}
.right .start-container {text-align: center;margin: 18px 0;
}
.right .start {display: inline-block;height: 40px;-webkit-box-sizing: border-box;-moz-box-sizing: border-box;box-sizing: border-box;padding: 4px 12px;color: #f0f0f0;font-size: 18px;font-weight: bold;letter-spacing: 4px;text-indent: 4px;line-height: 28px;border: 2px solid #0000FF;border-radius: 20px;margin: 0 2px;cursor: pointer;
}
.right .start.down {line-height: 30px;
}
.right .start-normal {background-color: #00e000;
}
.right .start-random {background-color: #FF00FF;
}
tetris.js
(function (window, document) {var scoreDom = document.querySelector('#score-panel .score');var panelCellDoms = document.querySelectorAll('#main-panel .panel-cell');var previewDom = document.querySelector('#preview');var failDom = document.querySelector('#fail');var leftTurn = document.querySelector('#left-turn');var rightTurn = document.querySelector('#right-turn');var leftMove = document.querySelector('#left-move');var bottomMove = document.querySelector('#bottom-move');var rightMove = document.querySelector('#right-move');var pauseRestoreDom = document.querySelector('#pause-restore');var showPauseRestore = pauseRestoreDom.querySelector('.show-pause-restore');var startNormalDom = document.querySelector('#start-normal');var startRandomDom = document.querySelector('#start-random');var mainCells = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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 shapes = {//O0: {0: {point: [[1, 1], [1, 1]], x: 0, y: 0},length: 1, type: 'O', color: '#ff0096'},//I1: {0: {point: [[1, 1, 1, 1]], x: 1, y: 0},1: {point: [[1], [1], [1], [1]], x: 0, y: 2},length: 2, type: 'I', color: '#00ee0c'},//T2: {0: {point: [[1, 1, 1], [0, 1, 0]], x: 1, y: 0},1: {point: [[0, 1], [1, 1], [0, 1]], x: 1, y: 1},2: {point: [[0, 1, 0], [1, 1, 1]], x: 1, y: 1},3: {point: [[1, 0], [1, 1], [1, 0]], x: 0, y: 1},length: 4, type: 'T', color: '#ffa905'},//L13: {0: {point: [[1, 0], [1, 0], [1, 1]], x: 0, y: 1},1: {point: [[1, 1, 1], [1, 0, 0]], x: 1, y: 0},2: {point: [[1, 1], [0, 1], [0, 1]], x: 1, y: 1},3: {point: [[0, 0, 1], [1, 1, 1]], x: 1, y: 1},length: 4, type: 'L', color: '#ff000a'},//L24: {0: {point: [[0, 1], [0, 1], [1, 1]], x: 1, y: 1},1: {point: [[1, 0, 0], [1, 1, 1]], x: 1, y: 1},2: {point: [[1, 1], [1, 0], [1, 0]], x: 0, y: 1},3: {point: [[1, 1, 1], [0, 0, 1]], x: 1, y: 0},length: 4, type: 'L', color: '#00d1b4'},//S5: {0: {point: [[1, 0], [1, 1], [0, 1]], x: 0, y: 1},1: {point: [[0, 1, 1], [1, 1, 0]], x: 1, y: 0},length: 2, type: 'S', color: '#0660ff'},//Z6: {0: {point: [[0, 1], [1, 1], [1, 0]], x: 0, y: 1},1: {point: [[1, 1, 0], [0, 1, 1]], x: 1, y: 0},length: 2, type: 'Z', color: '#a745ff'},length: 7};var Cell = (function () {function Cell(shape, index, x, y) {this.shape = shape;this.index = index;this.x = x || 0;this.y = y || 0;}Cell.prototype.getX = function () {return this.x;};Cell.prototype.getY = function () {return this.y;};Cell.prototype.setX = function (x) {this.x = x;};Cell.prototype.setY = function (y) {this.y = y;};Cell.prototype.incrX = function (x) {this.x += x;};Cell.prototype.incrY = function (y) {this.y += y;};Cell.prototype.decrX = function (x) {this.x -= x;};Cell.prototype.decrY = function (y) {this.y += y;};return Cell;})();var CellUtil = (function () {var score = 0;var cellQueue = [];var currentCell = null;var isPause = false, isStart = false;var nextTimeout = null, moveTimeout = null;var magic = 0, loopEventTime = null;function Util() {}Util.prototype.setMagic = function (num) {magic = num;};Util.prototype.getMagic = function () {return magic;};Util.prototype.clearLoopEventTime = function () {this.setMagic(0);window.clearTimeout(loopEventTime);};Util.prototype.initNormal = function () {this._clear();for (var i = 0; i < mainCells.length; i++) {mainCells[i] = 0;}this._init();};Util.prototype.initRandom = function () {this._clear();var count = 0;for (var i = 0; i < mainCells.length; i++) {var act = i < 50 || count >= 9 ? 0 : (Math.random() + 0.15) | 0;act > 0 ? count++ : count = 0;mainCells[i] = act;}this._init();};Util.prototype.pauseOrRestore = function () {if (!isStart) {return;}if (isPause) {isPause = false;showPauseRestore.innerText = '暂停';this._loopMoveBottom();} else {isPause = true;showPauseRestore.innerText = '恢复';window.clearTimeout(moveTimeout);}};Util.prototype._clear = function () {isPause = false;isStart = true;this.setMagic(0);window.clearTimeout(nextTimeout);window.clearTimeout(moveTimeout);cellQueue = [];currentCell = null;failDom.classList.add('hidden');scoreDom.innerText = score = 0;previewDom.innerHTML = '';showPauseRestore.innerText = '暂停';};Util.prototype._alertFail = function () {isStart = false;this.setMagic(0);window.clearTimeout(nextTimeout);window.clearTimeout(moveTimeout);cellQueue = [];currentCell = null;failDom.classList.remove('hidden');};Util.prototype._init = function () {scoreDom.innerText = 0;previewDom.innerHTML = '';for (var i = 0; i < mainCells.length; i++) {if (mainCells[i] === 1) {panelCellDoms[i].style.backgroundColor = '#204060';} else {panelCellDoms[i].style.backgroundColor = '#D0D0D0';}}this._start();};Util.prototype._start = function () {this.previewCell();this._next();};Util.prototype._next = function () {var that = this;window.clearTimeout(nextTimeout);nextTimeout = window.setTimeout(function () {currentCell = cellQueue.shift();that.previewCell();that._refresh(currentCell, function (cell) {var shape = cell.shape[cell.index];var point = shape.point;var wCnt = point[0].length, hCnt = point.length;cell.setX(((10 - wCnt) / 2) | 0);cell.setY(0 - hCnt);});if (isPause) {return;}that._loopMoveBottom();}, 1800);};Util.prototype._loopMoveBottom = function () {var that = this;window.clearTimeout(moveTimeout);if (currentCell == null) {return;}var delay = Math.max(1200 - ((score / 10) | 0), 200);moveTimeout = window.setTimeout(function () {if (currentCell !== null) {that.moveToBottom();that._loopMoveBottom();}}, delay);};Util.prototype.previewCell = function () {var cell = this._createCell();cellQueue.push(cell);previewDom.innerHTML = '';var shapeColor = cell.shape.color;var shape = cell.shape[cell.index];var point = shape.point;var previewShape = document.createElement('div');previewShape.classList.add('preview-shape');var hCnt = point.length, wCnt = point[0].length;for (var i = 0; i < hCnt; i++) {var pointSub = point[i];for (var j = 0; j < wCnt; j++) {var previewCell = document.createElement('div');previewCell.classList.add('preview-cell');if (pointSub[j] === 1) {previewCell.style.backgroundColor = shapeColor;}previewShape.appendChild(previewCell);}}previewShape.style.width = wCnt * 24 + 'px';previewShape.style.height = hCnt * 24 + 'px';previewDom.appendChild(previewShape);};Util.prototype._createCell = function () {var shapesIndex = (Math.random() * shapes.length) | 0;var shape = shapes[shapesIndex];var cell = new Cell(shape, (Math.random() * shape.length) | 0);var subShape = shape[cell.index];var point = subShape.point;cell.x = Math.round((10 - point[0].length) / 2);cell.y = 0 - point.length;return cell;};Util.prototype._refresh = function (cell, func) {var originalCell = new Cell(cell.shape, cell.index, cell.x, cell.y);var preIndexes = this.getPanelCellDomIndexes(cell);var check = func(cell);var postIndexes = this.getPanelCellDomIndexes(cell);if (check) {if (this._isOutBottom(cell) || this._isCover(postIndexes)) {cell.shape = originalCell.shape;cell.index = originalCell.index;cell.setX(originalCell.getX());cell.setY(originalCell.getY());this._fixCell(cell);currentCell = null;if (this._isFail(originalCell, this._eliminate())) {this._alertFail();} else {this._next();}return;}} else {if (originalCell.index === cell.index) {if (!this._checkMove(cell, postIndexes)) {cell.shape = originalCell.shape;cell.index = originalCell.index;cell.setX(originalCell.getX());cell.setY(originalCell.getY());return;}} else {//旋转边缘检查if (!this._checkRotate(cell)) {cell.shape = originalCell.shape;cell.index = originalCell.index;cell.setX(originalCell.getX());cell.setY(originalCell.getY());return;}}}postIndexes = this.getPanelCellDomIndexes(cell);var pasIndexes = this.arrayExcept(preIndexes, postIndexes);this._refreshDom(cell, pasIndexes, postIndexes);};Util.prototype._fixCell = function (cell) {var postIndexes = this.getPanelCellDomIndexes(cell);for (var i = 0; i < postIndexes.length; i++) {mainCells[postIndexes[i]] = 1;}};Util.prototype._eliminate = function () {var indexs = [];for (var i = 0; i < mainCells.length; i++) {if (i % 10 === 0) {if (mainCells[i] === 1) {indexs.push(i);} else {i = ((i / 10 + 1) | 0) * 10 - 1;}} else {if (mainCells[i] === 1) {indexs.push(i);} else {indexs.splice(indexs.length - i % 10);i = ((i / 10 + 1) | 0) * 10 - 1;}}}if (!indexs.length) {return 0;}scoreDom.innerText = this._incrScore(indexs.length / 10);for (var i = 0; i < indexs.length; i++) {var index = indexs[i];for (var j = index; j >= 0; j -= 10) {if (j < 10) {mainCells[j] = 0;panelCellDoms[j].style.backgroundColor = '#D0D0D0';} else {mainCells[j] = mainCells[j - 10];panelCellDoms[j].style.backgroundColor = panelCellDoms[j - 10].style.backgroundColor;}}}return indexs.length / 10;};Util.prototype._isFail = function (cell, rows) {return cell.y + rows < 0;};Util.prototype._incrScore = function (rows) {if (rows === 1) {score += 10;} else if (rows === 2) {score += 20;} else if (rows === 3) {score += 40;} else if (rows === 4) {score += 80;}return score;};Util.prototype._checkMove = function (cell, postIndexes) {if (!this._isInnerMain(cell)) {return false;}//平移边缘检查, 如果无覆盖,则返回true,否则返回falsereturn !this._isCover(postIndexes);};Util.prototype._isOutBottom = function (cell) {var subShape = cell.shape[cell.index], point = subShape.point;var hCnt = point.length;return cell.y + hCnt > 20;};Util.prototype._isCover = function (postIndexes) {//平移边缘检查, 如果无覆盖,则返回true,否则返回falsefor (var i = 0; i < postIndexes.length; i++) {if (mainCells[postIndexes[i]] === 1) {return true;}}return false;};Util.prototype._checkRotate = function (cell) {//旋转边缘检查, 如果无覆盖,则返回true,否则返回falsevar innerMain = this._isInnerMain(cell);var subShape = cell.shape[cell.index], point = subShape.point;var hCnt = point.length, wCnt = point[0].length;if (!innerMain) {cell.x < 0 ? cell.setX(0) : cell.setX(10 - wCnt);}var outBottom = cell.y + hCnt > 20, isBottom = cell.y + hCnt >= 20;if (outBottom) {cell.setY(20 - hCnt);}var indexes = this.getPanelCellDomIndexes(cell);var x = cell.x, y = cell.y;if (innerMain) {if (x > 0 && this._isCover(indexes) && (cell.shape.type !== 'T' || (cell.shape.type === 'S' || cell.shape.type === 'Z') && cell.index === 0)) {cell.setY(y);cell.setX(x - 1);indexes = this.getPanelCellDomIndexes(cell);}if (x + wCnt < 20 && this._isCover(indexes) && (cell.shape.type !== 'T' && cell.shape.type !== 'I' || (cell.shape.type === 'S' || cell.shape.type === 'Z') && cell.index === 1)) {cell.setY(y);cell.setX(x + 1);indexes = this.getPanelCellDomIndexes(cell);}}return !this._isCover(indexes);};Util.prototype._isInnerMain = function (cell) {var shape = cell.shape[cell.index], point = shape.point;var wCnt = point[0].length;return cell.x >= 0 && cell.x + wCnt <= 10;};Util.prototype._refreshDom = function (cell, pasIndexes, postIndexes) {for (var i = 0; i < pasIndexes.length; i++) {panelCellDoms[pasIndexes[i]].style.backgroundColor = '';}for (var i = 0; i < postIndexes.length; i++) {panelCellDoms[postIndexes[i]].style.backgroundColor = cell.shape.color;}};Util.prototype.getPanelCellDomIndexes = function (cell) {var shape = cell.shape[cell.index], x = cell.x, y = cell.y, point = shape.point;var panelCellDomIndexes = [];var hCnt = point.length, wCnt = point[0].length;for (var i = 0; i < hCnt; i++) {var pY = i + y;if (pY < 0 || pY >= 20) {continue;}var pointSub = point[i];for (var j = 0; j < wCnt; j++) {var pX = j + x;if (pX < 0 || pX >= 10) {continue;}if (pointSub[j] === 1) {panelCellDomIndexes.push(pX + pY * 10);}}}return panelCellDomIndexes;};Util.prototype.arrayExcept = function (arr1, arr2) {var except = [];loop:for (var i = 0; i < arr1.length; i++) {for (var j = 0; j < arr2.length; j++) {if (arr1[i] === arr2[j]) {continue loop;}}except.push(arr1[i]);}return except;};Util.prototype.moveToLeft = function () {if (currentCell == null || isPause) {return;}var shape = currentCell.shape[currentCell.index], hCnt = shape.point.length;if (currentCell.y + hCnt < 1) {return;}this._refresh(currentCell, function (cell) {cell.decrX(1);return false;});};Util.prototype.moveToRight = function () {if (currentCell == null || isPause) {return;}var shape = currentCell.shape[currentCell.index], hCnt = shape.point.length;if (currentCell.y + hCnt < 1) {return;}this._refresh(currentCell, function (cell) {cell.incrX(1);return false;});};Util.prototype.moveToBottom = function () {if (currentCell == null || isPause) {return;}this._refresh(currentCell, function (cell) {cell.incrY(1);return true;});};Util.prototype.turnToLeft = function () {if (currentCell == null || isPause) {return;}var shape = currentCell.shape[currentCell.index], hCnt = shape.point.length;if (currentCell.y + hCnt < 1) {return;}this._refresh(currentCell, function (cell) {var shape = cell.shape;var preCell = shape[cell.index];cell.index = (cell.index + shape.length - 1) % shape.length;var postCell = shape[cell.index];cell.incrX(preCell.x - postCell.x);cell.incrY(preCell.y - postCell.y);return false;});};Util.prototype.turnToRight = function () {if (currentCell == null || isPause) {return;}var shape = currentCell.shape[currentCell.index], hCnt = shape.point.length;if (currentCell.y + hCnt < 1) {return;}this._refresh(currentCell, function (cell) {var shape = cell.shape;var preCell = shape[cell.index];cell.index = (cell.index + 1) % shape.length;var postCell = shape[cell.index];cell.incrX(preCell.x - postCell.x);cell.incrY(preCell.y - postCell.y);return false;});};Util.prototype.loopEvent = function (delay) {var that = this;loopEventTime = window.setTimeout(function () {if (magic === 3) {delay = Math.max(delay - 30, 30);}that.loopEvent(delay);switch (magic) {case 1:that.moveToLeft();break;case 2:that.moveToRight();break;case 3:that.moveToBottom();break;case 4:that.turnToLeft();break;case 5:that.turnToRight();break;}}, delay);};Util.prototype.keyDown = function (magic) {if (this.getMagic() !== magic) {CellUtil.clearLoopEventTime();CellUtil.setMagic(magic);switch (magic) {case 1:this.moveToLeft();CellUtil.loopEvent(150);break;case 2:this.moveToRight();CellUtil.loopEvent(150);break;case 3:this.moveToBottom();CellUtil.loopEvent(150);break;case 4:this.turnToLeft();CellUtil.loopEvent(250);break;case 5:this.turnToRight();CellUtil.loopEvent(250);break;}}};return new Util();})();document.onkeydown = (function () {return function (e) {var code = (e.code || e.key).toLowerCase();switch (code) {case 'keyq':case 'q':case 'keyw':case 'w':case 'arrowup':case 'up':CellUtil.keyDown(4);break;case 'keye':case 'e':CellUtil.keyDown(5);break;case 'keya':case 'a':case 'arrowleft':case 'left':CellUtil.keyDown(1);break;case 'keys':case 's':case 'arrowdown':case 'down':CellUtil.keyDown(3);break;case 'keyd':case 'd':case 'arrowright':case 'right':CellUtil.keyDown(2);break;}document.onkeyup = function (e) {var code = (e.code || e.key).toLowerCase();switch (code) {case 'keyq':case 'q':case 'keyw':case 'w':case 'arrowup':case 'up':case 'keye':case 'e':case 'keya':case 'a':case 'arrowleft':case 'left':case 'keys':case 's':case 'arrowdown':case 'down':case 'keyd':case 'd':case 'arrowright':case 'right':CellUtil.clearLoopEventTime();break;case 'space':case 'spacebar':CellUtil.clearLoopEventTime();CellUtil.pauseOrRestore();break;}};return false;}})();(function () {function click(dom, downFunc, upFunc) {var el = dom.setCapture ? dom : document;dom.onmousedown = function (ev) {dom.focus();var oEvent = ev || window.event;downFunc(oEvent);el.onmouseup = function (ev) {var oEvent = ev || window.event;if(oEvent.stopPropagation) {oEvent.stopPropagation();} else {oEvent.cancelBubble = true;}upFunc(oEvent);el.onmousemove = null; el.onmouseup = null; if(dom.releaseCapture) {dom.releaseCapture();}};if(dom.setCapture) {dom.setCapture();}return false;};}click(leftTurn, function (e) {leftTurn.classList.add('down');CellUtil.keyDown(4);}, function (e) {leftTurn.classList.remove('down');CellUtil.clearLoopEventTime();});click(rightTurn, function (e) {rightTurn.classList.add('down');CellUtil.keyDown(5);}, function (e) {rightTurn.classList.remove('down');CellUtil.clearLoopEventTime();});click(leftMove, function (e) {leftMove.classList.add('down');CellUtil.keyDown(1);}, function (e) {leftMove.classList.remove('down');CellUtil.clearLoopEventTime();});click(bottomMove, function (e) {bottomMove.classList.add('down');CellUtil.keyDown(3);}, function (e) {bottomMove.classList.remove('down');CellUtil.clearLoopEventTime();});click(rightMove, function (e) {rightMove.classList.add('down');CellUtil.keyDown(2);}, function (e) {rightMove.classList.remove('down');CellUtil.clearLoopEventTime();});click(startNormalDom, function (e) {startNormalDom.classList.add('down');}, function (e) {startNormalDom.classList.remove('down');CellUtil.initNormal();});click(startRandomDom, function (e) {startRandomDom.classList.add('down');}, function (e) {startRandomDom.classList.remove('down');CellUtil.initRandom();});click(pauseRestoreDom, function (e) {pauseRestoreDom.classList.add('down');}, function (e) {pauseRestoreDom.classList.remove('down');CellUtil.clearLoopEventTime();CellUtil.pauseOrRestore();});})();
})(window, document);