写了个简单的俄罗斯方块儿游戏,算个笔记吧
关于在边界的图形转换还存在一些问题,待优化。
HTML代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>俄罗斯方块</title>
<script type="text/javascript" src="js/game.js"></script>
</head>
<body>
<div id="maindiv" style="width: 800px;margin: 0 auto;">
<span id="score" style="color: red;font-size: 18px;font-weight: bold;">您的分数为:0</span>
</div>
</body>
</html>
JavaScript代码
/*游戏的宽度和高度*/
var TRTRIS_COLS = 16;
var TRTRIS_ROWS = 16;
var score = 0;
var timer1;
//定义全局方块儿颜色
var colors = ['#F0F',"#F00","#0F0","#609","#CF0","#0FF"];
//定义一个存储已经下落方块位置的数组
var tetris_status = [];
for (var i = 0; i < TRTRIS_ROWS; i++) {
tetris_status[i] = [];
for (var j = 0; j < TRTRIS_COLS; j++) {
tetris_status[i][j] = -1;
}
}
//全局的table对象,以方便后期的函数处理
var Tries_table;
/*创建表格*/
var createTable = function(rows,cols,cellWidth,cellHeight){
//DOM API
var table = document.createElement('table');
for (var i = 0; i < rows; i++) {
var row = table.insertRow(i);
for (var j = 0; j < cols; j++) {
var cell = row.insertCell();
cell.style.width = cellWidth+'px';
cell.style.height = cellHeight+'px';
}
}
return table; //把创建的table对象返回
}
//定义一个下落方块的坐标值,当前下落的坐标值
var blocks = [
//Z方块
[
{x:TRTRIS_COLS/2-1,y:0,color:0},
{x:TRTRIS_COLS/2,y:0,color:0},
{x:TRTRIS_COLS/2,y:1,color:0},
{x:TRTRIS_COLS/2+1,y:1,color:0}
],
//田方块
[
{x:TRTRIS_COLS/2,y:0,color:1},
{x:TRTRIS_COLS/2+1,y:0,color:1},
{x:TRTRIS_COLS/2,y:1,color:1},
{x:TRTRIS_COLS/2+1,y:1,color:1},
],
//一方块
[
{x:TRTRIS_COLS/2-1,y:0,color:2},
{x:TRTRIS_COLS/2,y:0,color:2},
{x:TRTRIS_COLS/2+1,y:0,color:2},
{x:TRTRIS_COLS/2+2,y:0,color:2},
],
//右L方块
[
{x:TRTRIS_COLS/2,y:0,color:3},
{x:TRTRIS_COLS/2,y:1,color:3},
{x:TRTRIS_COLS/2,y:2,color:3},
{x:TRTRIS_COLS/2+1,y:2,color:3},
],
//左L方块
[
{x:TRTRIS_COLS/2,y:0,color:4},
{x:TRTRIS_COLS/2,y:1,color:4},
{x:TRTRIS_COLS/2,y:2,color:4},
{x:TRTRIS_COLS/2-1,y:2,color:4},
],
//T方块
[
{x:TRTRIS_COLS/2-1,y:0,color:5},
{x:TRTRIS_COLS/2,y:0,color:5},
{x:TRTRIS_COLS/2+1,y:0,color:5},
{x:TRTRIS_COLS/2,y:1,color:5},
]
];
var currutBlock;
//初始化方块儿
var initBlock = function(){
var i = Math.floor(Math.random()*blocks.length);
//var i = 2;
currutBlock = [
{x:blocks[i][0].x,y:blocks[i][0].y,color:blocks[i][0].color},
{x:blocks[i][1].x,y:blocks[i][1].y,color:blocks[i][1].color},
{x:blocks[i][2].x,y:blocks[i][2].y,color:blocks[i][2].color},
{x:blocks[i][3].x,y:blocks[i][3].y,color:blocks[i][3].color},
];
}
//页面加载完成时再加载逻辑代码
window.onload = function(){
//创建table
Tries_table = createTable(TRTRIS_ROWS,TRTRIS_COLS,16,16);
//设置table属性
Tries_table.border = 1;
Tries_table.style.borderCollapse = "collapse";
Tries_table.style.margin = "0 auto";
//把table放置到文档中
document.getElementById("maindiv").appendChild(Tries_table);
//初始化新块
initBlock();
//创建周期定时器
timer1 = setInterval(fall,800);
}
//下落处理函数
var fall = function(){
//遍历下落中的每个方块,是否能下落
var canDown1 = true;
var canDown2 = true;
for (var i = 0; i < currutBlock.length; i++) {
//判断当前的y值是否触底或者下方是否有方块
if(currutBlock[i].y >= (TRTRIS_ROWS-1)){
canDown1 = false;
break;
}
//判断下落的方块是否和已经存放的方块有冲突
if(tetris_status[currutBlock[i].y+1][currutBlock[i].x] != -1){
canDown2 = false;
break;
}
}
if(canDown1 && canDown2){
//把原来的位置变为白色
for (var i = 0; i < currutBlock.length; i++) {
var blo = currutBlock[i];
Tries_table.rows[blo.y].cells[blo.x].style.backgroundColor = "white";
}
//绘制下落方块
for (var i = 0; i < currutBlock.length; i++) {
var blo = currutBlock[i];
blo.y++;
Tries_table.rows[blo.y].cells[blo.x].style.backgroundColor = colors[blo.color];
}
}else{
//存储方块
for (var i = 0; i < currutBlock.length; i++) {
var cur = currutBlock[i];
tetris_status[cur.y][cur.x] = cur.color;
}
initBlock();
removeBlock();
document.getElementById("score").innerText='您的分数为:'+score;
}
//判断游戏是否结束
var flag1 = false;
for (var i = 0; i < TRTRIS_COLS; i++) {
if(tetris_status[0][i] != -1) flag1 = true;
}
if(flag1){
clearInterval(timer1);
alert("Game Over");
location.reload(true);
}
}
//注册事件,给整个窗体文档注册事件
window.onkeydown = function(e){
switch(e.keyCode){
//左移
case 37:{
moveLeft();
break;
}
//右移
case 39:{
moveRight();
break;
}
//下移
case 40:{
moveDown();
break;
}
//旋转
case 38:{
rotate();
break;
}
}
}
//左移动处理
var moveLeft = function(){
var canLeft = true;
for (var i = 0; i < currutBlock.length; i++) {
if(currutBlock[i].x < 1){
canLeft = false;
break;
}
//判断左面是否有方块
if(tetris_status[currutBlock[i].y][currutBlock[i].x-1] != -1){
canLeft = false;
break;
}
}
if(canLeft){
//把原来的位置变为白色
for (var i = 0; i < currutBlock.length; i++) {
var blo = currutBlock[i];
Tries_table.rows[blo.y].cells[blo.x].style.backgroundColor = "white";
}
//左移方块
for (var i = 0; i < currutBlock.length; i++) {
var blo = currutBlock[i];
blo.x--;
Tries_table.rows[blo.y].cells[blo.x].style.backgroundColor = colors[blo.color];
}
}
}
//右移动处理
var moveRight = function(){
var canRight = true;
for (var i = 0; i < currutBlock.length; i++) {
if(currutBlock[i].x >= TRTRIS_COLS-1){
canRight = false;
break;
}
//判断右面是否有方块
if(tetris_status[currutBlock[i].y][currutBlock[i].x+1] != -1){
canRight = false;
break;
}
}
if(canRight){
//把原来的位置变为白色
for (var i = 0; i < currutBlock.length; i++) {
var blo = currutBlock[i];
Tries_table.rows[blo.y].cells[blo.x].style.backgroundColor = "white";
}
//左移方块
for (var i = 0; i < currutBlock.length; i++) {
var blo = currutBlock[i];
blo.x++;
Tries_table.rows[blo.y].cells[blo.x].style.backgroundColor = colors[blo.color];
}
}
}
//下移动处理
var moveDown = function(){
var canDown1 = true;
var canDown2 = true;
for (var i = 0; i < currutBlock.length; i++) {
//判断当前的y值是否触底或者下方是否有方块
if(currutBlock[i].y >= (TRTRIS_ROWS-1)){
canDown1 = false;
break;
}
//判断下落的方块是否和已经存放的方块有冲突
if(tetris_status[currutBlock[i].y+1][currutBlock[i].x] != -1){
canDown2 = false;
break;
}
}
if(canDown1 && canDown2){
//把原来的位置变为白色
for (var i = 0; i < currutBlock.length; i++) {
var blo = currutBlock[i];
Tries_table.rows[blo.y].cells[blo.x].style.backgroundColor = "white";
}
//左移方块
for (var i = 0; i < currutBlock.length; i++) {
var blo = currutBlock[i];
blo.y++;
Tries_table.rows[blo.y].cells[blo.x].style.backgroundColor = colors[blo.color];
}
}
}
//旋转方块
var rotate = function(){
var canRotate = true;
//判断能否旋转
for (var i = 0; i < currutBlock.length; i++) {
var preX = currutBlock[i].x;
var preY = currutBlock[i].y;
if(i != 2){
afterX = currutBlock[2].x + preY - currutBlock[2].y;
afterY = currutBlock[2].y + currutBlock[2].x - preX;
//是否超过左边界
if(afterX < 0 || tetris_status[afterY][afterX-1] != -1){
canRotate = false;
break;
}
//是否超过右边界
if(afterX >= TRTRIS_COLS-1 || tetris_status[afterY][afterX+1] != -1){
canRotate = false;
break;
}
//是否超过上边界
if(tetris_status[afterY+1][afterX] != -1 || afterY < 0){
canRotate = false;
break;
}
//是否超过下边界
if(afterY >= TRTRIS_ROWS-1 || tetris_status[afterY+1][afterX] != -1){
canRotate = false;
break;
}
}
}
if(canRotate){
//将原来的方块变白
for (var i = 0; i < currutBlock.length; i++) {
Tries_table.rows[currutBlock[i].y].cells[currutBlock[i].x].style.backgroundColor = 'white';
}
//给旋转完的方块儿上色
for (var i = 0; i < currutBlock.length; i++) {
var preX = currutBlock[i].x;
var preY = currutBlock[i].y;
//定义一个中心点,这个点为下落方块儿的旋转中心
if(i != 2){
currutBlock[i].x = currutBlock[2].x + preY - currutBlock[2].y;
currutBlock[i].y = currutBlock[2].y + currutBlock[2].x - preX;
}
}
for (var i = 0; i < currutBlock.length; i++) {
var blo = currutBlock[i];
Tries_table.rows[blo.y].cells[blo.x].style.backgroundColor = colors[blo.color];
}
}
}
//绘图
var draw = function(){
for (var m = 0; m < TRTRIS_ROWS; m++) {
for (var n = 0; n < TRTRIS_COLS; n++) {
if(tetris_status[m][n] != -1){
Tries_table.rows[m].cells[n].style.backgroundColor = colors[tetris_status[m][n]];
}else{
Tries_table.rows[m].cells[n].style.backgroundColor = "white";
}
}
}
}
//满行消除
var removeBlock = function(){
var flag = true;
var theFull = [];
for (var i = TRTRIS_ROWS-1; i >= 0; i--) {
for (var j = 0; j < TRTRIS_COLS; j++) {
if(tetris_status[i][j] == -1) {
flag = false;
break;
}
}
if(flag) theFull[theFull.length] = i;
/*if(flag){
for (var k = 0; k < TRTRIS_COLS; k++) {
tetris_status[i][k] = tetris_status[i-1][k];
}
}
//draw();*/
flag = true;
}
//解决多行同时消除问题
//从上至下修改变量
for (var i = theFull.length-1; i >=0 ; i--) {
for (var l = theFull[i]; l > 0 ; l--) {
for (var j = 0; j < TRTRIS_COLS; j++) {
tetris_status[l][j] = tetris_status[l-1][j];
}
}
}
score += TRTRIS_COLS * theFull.length;
draw();
}