(难度:40%)纯js的俄罗斯方块游戏(含源码)

第一次写这么大的js程序, 代码量首破300的页面, 而且是纯js, 没用到任何库或框架...

断断续续写了四天终于弄好了, 除了觉得自己通过这个游戏, js进步了不少之外, 还培养了自己对代码的控制. 虽然没用到面向对象, 但我严格要求自己, 90%以上的函数不带注释不能超过10行, 一来易写而来容易更新维护.

html文件:

<body>
<div id='game'>
	<div id='main'></div>
	<div id='count'>
		<h3>Sorce:</h3>
		<div id='sorce'>0</div>
		<h3>Next:</h3>
		<div id='next'></div>
		<div id='panel'>
			<div class='button'><a href="#">START</a></div>
			<div class='button'><a href="#">STOP</a></div>
		</div>
	</div>
</div>

css文件

#game{
	margin:50px auto;
	width: 960px;
}
#main{
	border:3px solid black;
	float: left;
}
#count{
	width: 120px;
	height: 190px;
	padding: 5px 20px 10px 20px;
	float: right;
	border:3px solid black;
}
#next{
	width: 60px;
	height: 60px;
	text-align: center;
}
#panel{
	width: 120px;
	height:205px;
	margin-top: 20px;
	padding: 5px 20px 10px 20px;
	border:3px solid black;
	float: right;
	margin-right: -23px;
}
.cell{
	background: white;
	float: left;
	width: 20px;
	height: 20px;
		}
._cell{
	background: white;
	float: left;
	width: 15px;
	height: 15px;
}
.button{
	position: relative;
	margin-top: 20px;
	width: 120px;
	height:40px;
	border-radius: 10px;
	background: black;
	text-align: center;
	line-height: 40px;
	text-decoration: none;
	cursor:pointer;
}
.button:hover{
	background: orange;
}
.button a{
	text-decoration: none;
	color: white;
}

js文件

var row   = 24,
	col   = 12,
	len   = 20,
	game  = document.getElementById('game'),
	main  = document.getElementById('main'),
	count = document.getElementById('count'),
	next = document.getElementById('next'),
	sorce = document.getElementById('sorce'),
	_sorce= 0,
	nextb = 0,
	nextn = 0,
    width = col*len,
	height= row*len,
	map   = [],
	_map  = [],
	bak   = [],
	cur   = [],
	timer = null,
	cells = null,
	_cells= null,
	mark  = 0,
	color = '#0cf',
	_color= 'orange',
    block = [[0x3300,0x3300,0x3300,0x3300],[0x3110,0x1700,0x2230,0x7400],
			 [0xf000,0x1111,0xf000,0x1111],[0x3220,0x7100,0x1130,0x4700],
			 [0x1320,0x6300,0x1320,0x6300],[0x2310,0x3600,0x2310,0x3600],
			 [0x2700,0x2320,0x7200,0x2620]];

	init();
	newBlock();
function start(e){
	// event.preventDefault();
	timer=setInterval(down,400);
}
function stop(e){
	// event.preventDefault();
	clearInterval(timer);
}
function init(){
	var tmp;

	main.style.width=width+"px";
	main.style.height=height+"px";
	game.style.width=width+200+"px";
	game.style.height=height+"px";


	cur={x:~~Math.random()*(col-8)+4,	//到右边的距离
		 y:-1,
		 b:~~(Math.random()*7),	//block编号
		 n:~~(Math.random()*4),}	//block状态
	//新的方块
	nextb=~~(Math.random()*7);
	//新的状态
	nextn=~~(Math.random()*4);
	//不能连写
	//document.createElement('div').cloneNode
	var _cell=document.createElement('div');
	_cell.className="_cell";
	for (var i=0;i<4;i++)
		for (var j=0;j<4;j++){
			tmp=_cell.cloneNode(true)
			next.appendChild(tmp);
			// _cells.push(tmp)
		}
	_cells=document.querySelectorAll('._cell');
	showNext();


	var cell=document.createElement('div');
	cell.className="cell";
	for (var i=0;i<row;i++){
		for (var j=0;j<col;j++){
			tmp=cell.cloneNode(true);
			tmp.id=i*row+j;
			main.appendChild(tmp);
			//Cannot call method 'push' of null 
			// cells.push(tmp);
		}
	}
	cells=document.querySelectorAll(".cell");
	//每行都初始化为100..001
	//首尾为1是为了判断边界
	//最后一行初始化为全1
	var tmp="1"
	for (var i=0;i<col;i++) tmp+='0';
	tmp+='1'
	mark=tmp=parseInt(tmp,2);
	for (var i=0;i<row;i++){
		map[i]=tmp;
	}
	tmp="1";
	for (var i=1;i<col+2;i++) tmp+='1';
	map[row]=parseInt(tmp,2);

	document.οnkeydοwn=function(e){
		e=e?e:event;
		// console.log(e.keyCode)
		switch (e.keyCode){
			case 37:move(1);break;	//左
			case 38:rotate();break;	//上
			case 39:move(-1);break;	//右
			case 40:down();break;	//下
			case 32:down();break;	//空格
		}
	}

	tmp=document.querySelectorAll('.button');
	tmp[0].οnclick=start;
	tmp[1].οnclick=stop;

}
function newBlock(){
	cur={
		x:~~(Math.random()*(col-8)+4),
		y:0,
		b:nextb,	//block编号
		n:nextn		//block状态
	}
	nextb=~~(Math.random()*7);
	nextn=~~(Math.random()*4);
	showNext();
	bak={
		x:cur.x,
		y:0,
		b:cur.b,
		n:cur.n
	}
	update();
}
function down(){
	if (isOver()){
		return
	}
	cur.y++;
	if (!canDown()){
		//更新视图
		for (var i=0;i<row;i++) map[i]=_map[i];
		show();
		if (matchLine()) show();
		newBlock();
	}
	else{
		update();
	}
}
function move(dir){
	bak={
		x:cur.x
	}
	cur.x+=dir;
	//bak.x=cur.x
	// console.log(cur.x)
	// console.log(bak.x)
	//bak.x==cur.x
	if (canDown()){
		update();
	}else{
		// console.log(cur.x)
		cur.x=bak.x;
		// console.log(cur.x)
	}
}
function rotate(){
	bak={
		n:cur.n
	}
	cur.n++;
	cur.n%=4;
	if (!canDown()) cur.n=bak.n;
	else update();
}
function update(){
	var tmp=block[cur.b][cur.n];
	for (var i=0;i<row;i++) _map[i]=map[i];
	for (var i=0;i<4;i++) _map[cur.y+i]|=((tmp>>(12-4*i)&0x000f)<<cur.x);
	show();
}
function canDown(){
	var tmp=block[cur.b][cur.n];
	//cur.x<0, 移位结果出错
	if (cur.x<0) return false;
	//一个方块四行
	for (var i=0;i<4;i++){
		//每行与map的下一行进行或运算
		// console.log(map[cur.y+1+i].toString(2))
		if ( ( (tmp>>(12-4*i)&0x000f)<<cur.x ) & map[cur.y+i]) return false;
	}
	return true;
}
function matchLine(){
	var upgreade=0;
	var _mark=map[row];	//_mark全是1
	for (var i=cur.y,j=0;j<4&&i<row;i++,j++){
		// if (map[i]&0xffffffffff==0xffffffffff){
		if ((map[i]&_mark)==_mark){
			map.splice(i,1);
			map.unshift(mark);
			upgreade=1;
			_sorce++;
		}
	}
	sorce.innerHTML=_sorce;
	return upgreade;
}
function show(){
	// console.log(block[cur.b][cur.n].toString(2))
	// console.log(cur.x)
	for (var i=0;i<row;i++){
		for (var j=0;j<col;j++)
			if (_map[i]>>(col-j)&0x000000001){
				cells[i*col+j].style.background=color;
			}else{
				cells[i*col+j].style.background='white';
			}
		// alert(i+" "+j+" "+cells[i*row+j].id)
		// console.log(_map[i].toString(2))
	}
}
function showNext(){
	var tmp=block[nextb][nextn];
	for (var i=0;i<4;i++)
		for (var j=0;j<4;j++)
			if (tmp>>(15-i*4-j)&0x0001)
				_cells[i*4+j].style.background=_color;
			else
				_cells[i*4+j].style.background='white';
}
function isOver(){
	if ((map[0]|0x000000000)!=mark){
		clearInterval(timer);
		alert("game over");
		return true;
	}
	return false;
}
运行效果如下:

演示地址(点解START运行游戏):点击打开链接

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值