js版俄罗斯方块

上周闲来无事,忽然想起了经典的游戏俄罗斯方块。于是乎,我花点儿时间,自己用js代码写了一个。不敢独享,特为大家奉上源码。请各位看官吐槽!

斌斌 (给我写信) 原创博文(http://blog.csdn.net/binbinxyz),转载请注明出处

附源码(下载地址:http://download.csdn.net/detail/binbinxyz/5152877):

<!DOCTYPE html>
<html>
  <head>
    <title>俄罗斯方块_经典游戏</title>
	
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="斌斌的小游戏:俄罗斯方块">
	<!-- 
		作者:斌斌<br/>
		网站:http://blog.csdn.net/binbinxyz<br/>
	-->

	<style type="text/css">
	<!--  
	.thinBorderTable{border-collapse:collapse;}
	.thinBorderTable th{background:#ffffff;border:solid 1px #000000;}
	.thinBorderTable td{background:#ffffff;border:solid 1px #000000;}
	-->
	</style>

  </head>
  <body>
  <div id="game" align="center">
  	<h2>俄罗斯方块 <span style="font-size: 14">经典游戏</span></h2>
  	<table>
  		<tr>
  			<td>
  				<fieldset style="background-color: #aaaaaa">
				<legend>显示屏幕</legend>
				<div id="content" style="width:220;"> </div>
				</fieldset>
  			</td>
  			<td>
  				<div id="control" style="width:200;"> </div>
  			</td>
  		</tr>
  	</table>
  </div>
<script type="text/javascript">
	var column = 10; //显示屏幕的宽度(相对列数)
	var row = 20; //显示屏幕的高度(相对行数)
	var size = 20; //显示屏幕的分辨率(单元格的大小)
	var bottom = []; //底部方块堆
	var timer = function(){}; //计时器
	var currentTime = 0; //当前所用时间(秒)
	var score = 0; //当前分数
	var speed = 1; //当前速度
		
	function init()
	{
		var tableHtml = "<table id='screen' class='thinBorderTable'>";
		for(var i=0;i<row;i++)
		{
			tableHtml += "<tr height='" + size + "' align='center'>";
			for(var j=0;j<column;j++)
			{
				tableHtml += "<td id='td" + (i * column + j)
					+ "' width='" + size + "'> </td>";
			}
			tableHtml += "</tr>";
		}
		tableHtml += "</table>";
		
		document.getElementById("content").innerHTML = tableHtml;
		
		var nextHtml = "<table id='showNextBlock' class='thinBorderTable' style='font-size: 8'>";
		for(var i=0;i<4;i++)
		{
			nextHtml += "<tr height='15' align='center'>";
			for(var j=0;j<4;j++)
			{
				nextHtml += "<td width='15'> </td>";
			}
			nextHtml += "</tr>";
		}
		nextHtml += "</table>";
		
		var controlHtml = "<fieldset><legend>显示区域</legend><table>";
		controlHtml += "<tr><td>当前速度:</td><td><span id='speed'>1</span> </td></tr>";
		controlHtml += "<tr><td>当前分数:</td><td><span id='score'>0</span> </td></tr>";
		controlHtml += "<tr><td>当前时间:</td><td><span id='currentTime'>00:00</span> </td></tr>";
		controlHtml += "<tr><td colspan='2'>" + nextHtml + "</td></tr>";
		controlHtml += "</table></fieldset>";
		controlHtml += "<fieldset><legend>控制区域</legend><table>";
		controlHtml += "<tr><td><input id='btnstart' type='button' value='开始' οnclick='start()'/> </td></tr>";
		controlHtml += "<tr><td><input id='btnpause' type='button' value='暂停' οnclick='pause()'/> </td></tr>";
		controlHtml += "<tr><td><input id='btnend' type='button' value='结束' οnclick='end()'/> </td></tr>";
		controlHtml += "</table></fieldset>";
		
		document.getElementById("control").innerHTML = controlHtml;
		
		document.getElementById("btnpause").disabled = true;
		document.getElementById("btnend").disabled = true;
		
		currentTime = 0;
		score = 0;
		speed = 1;
		
		for(var i=0;i<row;i++)
		{
			bottom[i] = [];
			for(var j=0;j<column;j++)
			{
				bottom[i][j] = 0;
			}
		}
		
		showNextBlock(Factory.createBlock());
		next();
	}
	
	//生成方块的工厂
	var Factory = {
		maps:
		[
			[
				[1,1,1,1, 0,0,0,0, 0,0,0,0, 0,0,0,0],
				[1,0,0,0, 1,0,0,0, 1,0,0,0, 1,0,0,0]
			],
			[
				[1,1,1,0, 1,0,0,0, 0,0,0,0, 0,0,0,0],
				[1,1,0,0, 0,1,0,0, 0,1,0,0, 0,0,0,0],
				[0,0,1,0, 1,1,1,0, 0,0,0,0, 0,0,0,0],
				[1,0,0,0, 1,0,0,0, 1,1,0,0, 0,0,0,0]
			],
			[
				[1,1,1,0, 0,1,0,0, 0,0,0,0, 0,0,0,0],
				[0,1,0,0, 1,1,0,0, 0,1,0,0, 0,0,0,0],
				[0,1,0,0, 1,1,1,0, 0,0,0,0, 0,0,0,0],
				[1,0,0,0, 1,1,0,0, 1,0,0,0, 0,0,0,0]
			],
			[
				[1,1,1,0, 0,0,1,0, 0,0,0,0, 0,0,0,0],
				[0,1,0,0, 0,1,0,0, 1,1,0,0, 0,0,0,0],
				[1,0,0,0, 1,1,1,0, 0,0,0,0, 0,0,0,0],
				[1,1,0,0, 1,0,0,0, 1,0,0,0, 0,0,0,0]
			],
			[
				[1,1,0,0, 0,1,1,0, 0,0,0,0, 0,0,0,0],
				[0,1,0,0, 1,1,0,0, 1,0,0,0, 0,0,0,0]
			],
			[
				[1,0,0,0, 1,1,0,0, 0,1,0,0, 0,0,0,0],
				[0,1,1,0, 1,1,0,0, 0,0,0,0, 0,0,0,0]
			],
			[
				[1,1,0,0, 1,1,0,0, 0,0,0,0, 0,0,0,0]
			]
		],
		index:0, //方块的索引号
		status:0, //方块的状态号,即第几个状态
		oldIndex:0,
		oldStatus:0,
		createBlock: function(){ //生成一个新的方块
			this.oldIndex = this.index;
			this.oldStatus = this.status;
			this.index = Math.floor(Math.random() * this.maps.length);
			this.status = Math.floor(Math.random() * this.maps[this.index].length);
			//alert(this.index + ":" + this.getCurrentBlock());
			return this.getCurrentBlock();
		},
		getCurrentBlock: function(){
			return this.maps[this.index][this.status];
		},
		getNextStatus: function(){ //获取方块的下一个状态
			this.oldStatus ++;
			this.oldStatus %= this.maps[this.oldIndex].length;
			return this.maps[this.oldIndex][this.oldStatus];
		}
	};
	
	//在显示区域显示下一个方块block
	function showNextBlock(block){
		var table = document.getElementById("showNextBlock");
		var tds = table.getElementsByTagName("td");
		for(var i=0;i<tds.length;i++)
		{
			if(block[i] == 1)
			{
				tds[i].style.backgroundColor = "blue";
			}
			else
			{
				tds[i].style.backgroundColor = "white";
			}
		}
	}
	
	//旋转
	function up(){
		var oldBlock = Block.block;
		
		Block.block = Factory.getNextStatus();
		//alert(oldBlock + "\n" + Block.block);
		for(var i=0;i<Block.block.length;i++)
		{
			if(Block.block[i] == 1)
			{
				if(i % 4 + Block.x >= column) //右侧出界了
				{
					Block.x --;
					break;
				}
				
				var m = Math.floor(i / 4);
				var n = i % 4;
				
				 //下越界或者重叠了
				if(m + Block.y >= 20 || bottom[m + Block.y][n + Block.x] == 1)
				{
					Block.block = oldBlock;
					break;
				}
			}
		}
		reshow();
	}
	
	//下移
	function down(){
		Block.y ++; //向下移动一格
		if(!isDownable())
		{
			Block.y --;
			accept(Block);
		}
		reshow();
	}
	
	//左移
	function left(){
		Block.x --;
		if(Block.x < 0)
		{
			Block.x = 0;
		}
		reshow();
	}
	
	//右移
	function right(){
		Block.x ++;
		for(var i=0;i<Block.block.length;i++)
		{
			if(Block.block[i] == 1 && i % 4 + Block.x >= column) //
			{
				Block.x --;
				break;
			}
		}
		reshow();
	}
	
	//是否可以向下移动(即此次下移是否可行)
	function isDownable()
	{
		for(var i=0;i<Block.block.length;i++)
		{
			var x = i % 4;
			var y = Math.floor(i / 4);
			
			if(y + Block.y < 0) //该行位于屏幕上方,未显示
			{
				continue;
			}
			
			 //到达底部了
			if(Block.block[i] == 1 && y + Block.y >= row)
			{
				return false;
			}
			//alert(bottom[y+Block.y] + "===" + bottom[y + Block.y][x + Block.x]);
			if(Block.block[i] == 1 && bottom[y + Block.y][x + Block.x] == 1) //
			{
				return false;
			}
		}
		return true;
	}
	
	//接收一个Block
	function accept(Block){
		for(var i=0;i<Block.block.length;i++)
		{
			if(Block.block[i] == 1)
			{
				var m = Math.floor(i / 4);
				var n = i % 4;
				//alert((m + "," + n) + "\n" + (m + Block.y) + "," + (n + Block.x));
				if(m + Block.y < 0)
				{
					clearInterval(timer);
					alert("您的得分是:" + score + "!\n游戏结束!");
					
					if(confirm("您想重新挑战吗?"))
					{
						init();
						start();
					}
					return;
				}
				bottom[m + Block.y][n + Block.x] = 1;
			}
		}
		
		disappear();
		
		next();
	}
	
	//消去满行
	function disappear()
	{
		var line = 0; //此次消去行数
		var r = Block.y + 4 - 1;
		if(r>19)
		{
			r = 19;
		}
		for(var i=r;i>=Block.y;i--)
		{
			var flag = false; //是否继续判断下一行
			var disapperable = true; //当前行是否可以消去
			for(var j=0;j<bottom[i].length;j++)
			{
				/*if(!flase && bottom[i][j] == 1) //如果当前行不全空,则修改flag
				{
					flag = true;
				}*/
				if(bottom[i][j]==0)
				{
					disapperable = false;
					break;
				}
			}
			if(disapperable)
			{
				line ++; //更新消去行数
				for(var k=i;k>0;k--)
				{
					for(var j=0;j<bottom[i].length;j++)
					{
						bottom[k][j] = bottom[k-1][j];
					}
				}
				reshow();
				
				i ++; //消去一行时,继续判断当前行
			}
			/*if(!flag) //不需要判断下一行时,跳出循环
			{
				break;
			}*/
		}
		
		switch(line)
		{
		case 1:
			score += 10;
			break;
		case 2:
			score += 30;
			break;
		case 3:
			score += 60;
			break;
		case 4:
			score += 100;
			break;
		}
		document.getElementById("score").innerHTML = score;
	}
	
	//修改方块下落的速度
	function changeSpeed()
	{
		var args = Math.floor(score / 100)
		if(args >= 5)
		{
			speed = 5;
		}
		else
		{
			speed = args + 1;
		}
		
		document.getElementById("speed").innerHTML = speed;
	}
	
	//
	function next()
	{
		Block.init(Factory.getCurrentBlock());
		showNextBlock(Factory.createBlock());
	}
	
	//屏幕刷新
	function reshow(){
		var table = document.getElementById("screen");
		var tds = table.getElementsByTagName("td");
		
		for(var i=0;i<tds.length;i++)
		{
			var m = Math.floor(i / column);
			var n = i % column;
			if(bottom[m][n] == 1)
			{
				tds[i].style.backgroundColor = "blue";
			}
			else
			{
				tds[i].style.backgroundColor = "white";
			}
		}
		
		for(var i=0;i<Block.block.length;i++)
		{
			var m = Math.floor(i / 4);
			var n = i % 4;
			if(m + Block.y >= 0 && Block.block[i] == 1) //方块在显示屏幕上方时不显示
			{
				var k = (m + Block.y) * column + Block.x + n;
				document.getElementById('td' + k).style.backgroundColor = "blue";
			}
		}
	}
	
	//更新显示区域的时间
	function updateTime()
	{
		var currentTimeLabel = document.getElementById("currentTime");
		currentTime ++;
		currentTimeLabel.innerHTML = formatTime(currentTime);
	}
	
	//格式化时间
	function formatTime(time)
	{
		var m = Math.floor(time / 60); //分钟
		var s = time % 60; //秒数
		
		var str = "";
		if(m < 10)
		{
			str = "0";
		}
		str += m + ":";
		if(s < 10)
		{
			str += "0";
		}
		str += s;
		return str;
	}
	
	
	//定义Block用于表示当前屏幕中的方块
	var Block = {
		x:0, //方块所在4×4矩形的左上角x坐标
		y:0, //方块所在4×4矩形的左上角y坐标
		block:new Array(),
		init:function(block){
			this.x = 4;
			this.y = -3;
			this.block = block;
		}
	};
	
	//开始游戏
	function start()
	{
		document.getElementById("btnstart").disabled = true;
		document.getElementById("btnpause").disabled = false;
		document.getElementById("btnend").disabled = false;
		
		timer = setInterval("down();updateTime();", 1100 - 50 * speed);
	}
	
	//暂停游戏
	function pause()
	{
		var btnpause = document.getElementById("btnpause");
		if(btnpause.value=="暂停")
		{
			btnpause.value = "恢复";
			clearInterval(timer);
		}
		else{
			btnpause.value = "暂停";
			timer = setInterval("down();updateTime();",1100 - 50 * speed);
		}
	}
	
	//结束游戏
	function end()
	{
		if(confirm("你确定要结束游戏吗?"))
		{
			document.getElementById("btnstart").disabled = false;
			document.getElementById("btnpause").disabled = true;
			document.getElementById("btnend").disabled = true;
			clearInterval(timer);
			init();
		}
	}
	
	function keyUp(e) {
		if(navigator.appName == "Microsoft Internet Explorer")
		{
			//var keycode = event.keyCode;
			//var realkey = String.fromCharCode(event.keyCode);
			//alert("按键码: " + keycode + " 字符: " + realkey);
			keyAction(event.keyCode);
		}else
		{
			//alert(e.which);
			keyAction(e.which);
		}
	}
	
	function keyAction(key)
	{
		switch(key)
		{
		case 37: //向左移动
			left();
			break;
		case 38: //向上移动
			up();
			break;
		case 39: //向右移动
			right();
			break;
		case 40: //向下移动
			down();
			break;
		}
	}
	
	init();
	document.onkeyup = keyUp;
</script>
  </body>
</html>


下载源码:http://download.csdn.net/detail/binbinxyz/5152877

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值