一边练习一下javascript,一边搞的稍微有趣一点。
这次的界面就是个table表格。其实所有的操作只要操作tabel的class就可以了。我这里把颜色直接用 cell.style.backgroundColor
来设置内联样式的属性了。
完整代码如下,预先显示下一个方块的功能没做。Game Over也没有写。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>俄罗斯方块</title>
<style>
p.tips {margin-top: 20px; text-align: center;}
table#gameUI {margin: 30px auto;}
td {width: 20px; height: 20px; border: 1px solid red;}
td.wall {background-color: red;}
</style>
</head>
<body>
<p class="tips">按回车开始游戏</p>
<table id="gameUI"></table>
</body>
<script>
// 参数设置
var rows = 22, cells = 14; // 界面的高度和宽度
// 获取元素
var tab = document.getElementById('gameUI');
var tips = document.getElementsByClassName('tips')[0];
// 设置变量
var control; // 当前控制的方块
var score = 0; // 分数
var scoreConf = [100, 200, 300, 350]; // 一次小几行,分数不同
init();
function init() {
// 为了页面时的初始化
createTab();
bindKeyEnter();
// gameStart()
}
function bindKeyEnter() {
// 按下回车处理的事件
document.onkeydown = function (ev) {
if (ev.keyCode===13){
tips.innerHTML ='游戏开始';
document.onkeydown = null;
gameStart();
}
}
}
function gameStart() {
// 开始游戏
bindKeysForGame();
tips.innerHTML = '按 Z 或 X 旋转方块';
control = createSqu();
control.position = [1, 4]; // 添加blocks[0]的位置属性
map(control);
setInterval("move('down')", 500)
}
function createSqu() {
// 创建一个方块
var types = [
{'name': "方块", 'color': 'saddlebrown', 'blocks': [[0, 0], [0, 1], [1, 0], [1, 1]],
'styleIndex': 0, 'styles': [
[[0, 0], [0, 1], [1, 0], [1, 1]]
]},
{'name': "7形", 'color': 'green', 'blocks': [[0, 0], [0, 1], [1, 1], [2, 1]],
'styleIndex': 0, 'styles': [
[[0, 0], [0, 1], [1, 1], [2, 1]],
[[1, 0], [1, 1], [1, 2], [0, 2]],
[[0, 0], [1, 0], [2, 0], [2, 1]],
[[0, 0], [1, 0], [0, 1], [0, 2]]
]},
{'name': "反7", 'color': 'green', 'blocks': [[0, 0], [0, 1], [1, 0], [2, 0]],
'styleIndex': 0, 'styles': [
[[0, 0], [0, 1], [1, 0], [2, 0]],
[[0, 0], [0, 1], [0, 2], [1, 2]],
[[0, 1], [1, 1], [2, 0], [2, 1]],
[[0, 0], [1, 0], [1, 1], [1, 2]]
]},
{'name': "长条", 'color': 'darkorange', 'blocks': [[0, 0], [0, 1], [0, 2], [0, 3]],
'styleIndex': 0, 'styles': [
[[0, 0], [0, 1], [0, 2], [0, 3]],
[[0, 0], [1, 0], [2, 0], [3, 0]]
]},
{'name': "丁字", 'color': 'blue', 'blocks': [[0, 0], [0, 1], [1, 1], [0, 2]],
'styleIndex': 0, 'styles': [
[[0, 0], [0, 1], [1, 1], [0, 2]],
[[1, 0], [0, 1], [1, 1], [2, 1]],
[[1, 0], [1, 1], [0, 1], [1, 2]],
[[0, 0], [1, 0], [1, 1], [2, 0]]
]},
{'name': "Z字", 'color': 'gold', 'blocks': [[0, 0], [0, 1], [1, 1], [1, 2]],
'styleIndex': 0, 'styles': [
[[0, 0], [0, 1], [1, 1], [1, 2]],
[[0, 1], [1, 0], [1, 1], [2, 0]]
]},
{'name': "反Z", 'color': 'gold', 'blocks': [[1, 0], [1, 1], [0, 1], [0, 2]],
'styleIndex': 0, 'styles': [
[[1, 0], [1, 1], [0, 1], [0, 2]],
[[0, 0], [1, 0], [1, 1], [2, 1]]
]}
];
var index = Math.floor(Math.random()*types.length+1);
return types[index-1]
}
function map(square) {
// 把方块画在表格里
var rubber = arguments[1] ? arguments[1] : false;
for (var i=0; i<square.blocks.length; i++) {
var cell = tab.rows[square.blocks[i][0]+square.position[0]].cells[square.blocks[i][1]+square.position[1]];
if (rubber){
cell.style.backgroundColor = '';
cell.classList.remove('control')
} else {
cell.style.backgroundColor = square.color;
cell.classList.add('control')
}
}
}
function fixed(square){
// 固定方块
for (var i=0; i<square.blocks.length; i++) {
var cell = tab.rows[square.blocks[i][0]+square.position[0]].cells[square.blocks[i][1]+square.position[1]];
cell.classList.remove('control');
cell.classList.add('fixed')
}
}
function bindKeysForGame() {
// 游戏时候需要绑定的按键
document.onkeydown = function (ev) {
switch (ev.keyCode) {
case 37: // 向左
move('left');
break;
case 38: // 向上
// move('up');
change();
break;
case 39: // 向右
move('right');
break;
case 40: // 向下
move('down');
break;
case 90: // 字母Z
change(true);
break;
case 88: // 字母X
change();
break;
// default:
// tips.innerHTML = ev.keyCode;
}
}
}
function change() {
// 改变形状
var contrarotate = arguments[0] ? arguments[0] : false;
if (contrarotate) {
control.styleIndex -= 1;
if (control.styleIndex < 0) {
control.styleIndex = control.styles.length-1;
}
} else {
control.styleIndex += 1;
if (control.styleIndex > control.styles.length-1){
control.styleIndex = 0;
}
}
var target = [[0,0],[0,0],[0,0],[0,0]];
for (var i=0; i<control.styles[control.styleIndex].length; i++){
target[i][0] = control.styles[control.styleIndex][i][0]+control.position[0];
target[i][1] = control.styles[control.styleIndex][i][1]+control.position[1];
}
if (canMove(target)){
map(control, true);
for (var j=0; j<control.blocks.length; j++){
control.blocks[j][0] = control.styles[control.styleIndex][j][0];
control.blocks[j][1] = control.styles[control.styleIndex][j][1];
}
map(control)
}
}
function move(mode) {
var row, cell;
switch (mode){
case 'left':
row = 0;
cell = -1;
break;
case 'right':
row = 0;
cell = 1;
break;
case 'up':
row = -1;
cell = 0;
break;
case 'down':
row = 1;
cell = 0;
break;
}
var target = [[0,0],[0,0],[0,0],[0,0]];
for (var i=0; i<control.blocks.length; i++){
target[i][0] = control.blocks[i][0]+control.position[0]+row;
target[i][1] = control.blocks[i][1]+control.position[1]+cell;
}
if (canMove(target)){
map(control, true);
control.position[0] += row;
control.position[1] += cell;
map(control)
} else {
if (mode==='down') {
// 向下移动,并且判定为不可移动,则固定
fixed(control); // 固定住方块
checkAndClean(control); // 检查消行
control = createSqu();
control.position = [1, 4]; // 添加blocks[0]的位置属性
map(control);
}
}
}
function checkAndClean(square) {
// 检查并消除
var checked = [];
var cleaned = [];
var row;
for (var i=0; i<square.blocks.length; i++){
row = square.blocks[i][0] + square.position[0];
if (checked.indexOf(row) === -1){
checked.push(row);
var needClean = true;
for (var j=1; j<cells-1; j++ ) {
var cell = tab.rows[row].cells[j];
if(cell.className.search(/\b(fixed)\b/) === -1){
needClean = false;
break;
}
}
if (needClean) {
// 消除一行
cleaned.push(row);
for (var k=1; k<cells-1; k++) {
cell = tab.rows[row].cells[k];
cell.classList.remove('fixed');
cell.style.backgroundColor = '';
}
}
}
}
cleaned.length && addScore(cleaned.length) && goDown(cleaned); // 结算分数,然后下沉
}
function addScore(n) {
n = n<=scoreConf.length ? n : scoreConf[scoreConf.length-1];
score += scoreConf[n-1];
tips.innerHTML = "分数:" + score;
return true
}
function goDown(list) {
// 消行后的沉降
var count = 0;
for (var i=list.length; i--;){
for (var r=list[i]-1; r--;){
tab.rows[r+2+count].innerHTML = tab.rows[r+1+count].innerHTML
}
count += 1;
}
}
function canMove(target) {
// 是否可以移动
for (var j=0; j<target.length; j++){
var cell = tab.rows[target[j][0]].cells[target[j][1]];
if(cell.className.search(/\b(wall|fixed)\b/) > -1){
return false
}
}
return true
}
function createTab() {
// 绘制游戏界面
for (var r=rows; r--;){
var row = tab.insertRow();
for (var c=cells; c--;){
var cell = row.insertCell();
if (r===0 || r===rows-1 || c===0 || c===cells-1){
cell.classList.add('wall');
}
}
}
}
</script>
</html>
转载于:https://blog.51cto.com/steed/2129105