SOURCE

console 命令行工具 X clear

                    
>
console
var w = 0;
var ctx;
var s = [];
var spos = 0;
var epos = 0;
var step = 0;
var score = 0;
var state = 0;
var size = 9;
var c;
var b = 0;
var colors = ['#CCC','#000','#F00','#FC0','#0C0','#00F','#0FF','#F0F'];
var prev = [];
var link = [];
var mpath = [];
var ani_hdl;
var ani_prev;
var growstep = 0;
var growid = [];
function init(){
	c = document.getElementById("grid");
	ctx = c.getContext("2d");
}
function reset(){
	w = Math.floor(($('.box').width() - 10) / size);
	c.width = w * size + 10;
	c.height = w * size + 10;
	$('#grid').css('margin-left',($('.box').width() - w * size - 10) / 2 + 'px');

	ctx.fillStyle = colors[0];
	ctx.fillRect(0,0,(w + 1) * size,(w + 1) * size);
	
	s = [];
	link = [];
	prev = [];
	spos = 0;
	epos = 0;
	step = 0;
	score = 0;
	state = 0;
	b = size * size;
	$('#step').html('0');
	$('#score').html('0');
	
	ctx.lineWidth = 1;
	ctx.strokeStyle = '#000';
	for (var i = 0;i < size + 1;i++){
			ctx.beginPath();
			ctx.moveTo(0,i * (w + 1) + 0.5);
			ctx.lineTo(size * (w + 1) + 1,i * (w + 1) + 0.5);
			ctx.stroke();
			ctx.beginPath();
			ctx.moveTo(i * (w + 1) + 0.5,0);
			ctx.lineTo(i * (w + 1) + 0.5,size * (w + 1) + 1);
			ctx.stroke();
	}
	for (var i = 0;i < size * size;i++){
		s[i] = 0;
	}
	setprev();
	addball();
}
function addball(){
	var p;
	growid = [];
	for (var i = 0;i < 3;i++){
		if (b > 0){
			b--;
			p = -1;
			while (p < 0){
				p = Math.floor(Math.random() * size * size);
				if (s[p] == 0){
					s[p] = prev[i];//Math.floor(Math.random() * 7) + 1;
					growid[i] = p;
					//draw(p);
				}else{
					p = -1;
				}
			}
		}
	}
	growstep = 1;
	window.requestAnimationFrame(grow);
	if (b == 0){
		state = 1;
		alert('结束');
	}else{
		setprev();
	}
}
function grow(){
	for (var i in growid){
		if (growstep < 10){
			var x,y;
			y = Math.floor(growid[i] / size);
			x = growid[i] - y * size;
			ctx.fillStyle = colors[s[growid[i]]];
			ctx.beginPath();
			ctx.arc(x * (w + 1) + 1 + w / 2,y * (w + 1) + 1 + w / 2,w * 0.4 * growstep / 10,0,2*Math.PI);
			ctx.fill();
		}else{
			draw(growid[i]);
		}
	}
	growstep++;
	if (growstep < 11){
		window.requestAnimationFrame(grow);
	}
}
function setprev(){
	prev = [];
	$('#prev').html('');
	for (var i = 0;i < 3;i++){
		var r = Math.floor(Math.random() * 7) + 1;
		prev.push(r);
		$('#prev').append('<i style="background:' + colors[r] + '"></i>');
	}
}
function draw(num){
	var x,y;
	y = Math.floor(num / size);
	x = num - y * size;
	ctx.fillStyle = colors[s[num]];
	//ctx.fillRect(x * (w + 1) + 1,y * (w + 1) + 1,w,w);
	ctx.beginPath();
	ctx.arc(x * (w + 1) + 1 + w / 2,y * (w + 1) + 1 + w / 2,w * 0.4,0,2*Math.PI);
	ctx.fill();
	ctx.beginPath();
	ctx.strokeStyle = '#FFF';
	ctx.arc(x * (w + 1) + 1 + w / 2,y * (w + 1) + 1 + w / 2,w * 0.3,1.125*Math.PI,1.375*Math.PI);
	ctx.stroke();
	ctx.beginPath();
	ctx.strokeStyle = '#666';
	ctx.arc(x * (w + 1) + 1 + w / 2,y * (w + 1) + 1 + w / 2,w * 0.3,0.125*Math.PI,0.375*Math.PI);
	ctx.stroke();
}
function select(num){
	var x,y;
	y = Math.floor((num - 1) / size);
	x = num - y * size - 1;
	
	if (!spos){
		if (s[num - 1]){
			spos = num;
			frame(num,1);
		}
	}else{
		if (!s[num - 1]){
			epos = num;
			move();
		}else{
			frame(spos,0);
			spos = num;
			frame(num,1);
		}
	}
}
function move(){
	if (!canlink()){return;}
	mpath.pop();
	ani_prev = 0;
	clear(spos);
	//cancelAnimationFrame(ani_hdl);
	ani_hdl = window.requestAnimationFrame(animove);
}
function animove(){
	if (ani_prev){
		s[ani_prev - 1] = 0;
		clear(ani_prev);
	}
	if (mpath.length > 0){
		var l = mpath.pop();
		s[l - 1] = s[spos - 1];
		draw(l - 1);
		ani_prev = l;
		ani_hdl = window.requestAnimationFrame(animove);
	}else{
		cancelAnimationFrame(ani_hdl);
		s[epos - 1] = s[spos - 1];
		s[spos - 1] = 0;
		draw(epos - 1);
		spos = 0;
		epos = 0;
		step++;
		$('#step').html(step);
		check();
	}
}
function canlink(){
	if (!spos || !epos || s[epos-1]){return false;}
	for (var i = 0;i < size * size;i++){
		link[i] = 0;
	}
	link[spos - 1] = 1;
	golink(spos,1);
	mpath = [];
	if (link[epos - 1] > 0){
		getpath(epos);
		return true;
	}else{
		return false;
	}
}
function getpath(l){
	var x,y;
	y = Math.floor((l - 1) / size);
	x = l - y * size - 1;
	var next = 0;
	if (x > 0){
		if (link[l - 2] == link[l - 1] - 1){
			next = l - 1;
		}
	}
	if (x < size - 1 && !next){
		if (link[l] == link[l - 1] - 1){
			next = l + 1;
		}
	}
	if (y > 0 && !next){
		if (link[l - size - 1] == link[l - 1] - 1){
			next = l - size;
		}
	}
	if (y < size - 1 && !next){
		if (link[l + size - 1] == link[l - 1] - 1){
			next = l + size;
		}
	}
	mpath.push(next);
	if (next != spos){
		getpath(next);
	}
}
function golink(l,step){
	var x,y;
	y = Math.floor((l - 1) / size);
	x = l - y * size - 1;
	if (x > 0){
		if ((link[l - 2] == 0 || link[l - 2] > step + 1) && s[l - 2] == 0){
			link[l - 2] = step + 1;
			golink(l - 1,step + 1);
		}
	}
	if (x < size - 1){
		if ((link[l] == 0 || link[l] > step + 1) && s[l] == 0){
			link[l] = step + 1;
			golink(l + 1,step + 1);
		}
	}
	if (y > 0){
		if ((link[l - size - 1] == 0 || link[l - size - 1] > step + 1) && s[l - size - 1] == 0){
			link[l - size - 1] = step + 1;
			golink(l - size,step + 1);
		}
	}
	if (y < size - 1){
		if ((link[l + size - 1] == 0 || link[l + size - 1] > step + 1) && s[l + size - 1] == 0){
			link[l + size - 1] = step + 1;
			golink(l + size,step + 1);
		}
	}
}
function clear(num){
	var x,y;
	y = Math.floor((num - 1) / size);
	x = num - y * size - 1;
	ctx.beginPath();
	ctx.fillStyle = colors[0];
	ctx.fillRect(x * (w + 1) + 1.5,y * (w + 1) + 1.5,w - 1,w - 1);
}
function check(){
	var inline = 0;
	var movet = [];
	var movea = [];
	for (var i = 0;i < size * size;i++){
		if (s[i]){
			var x,y;
			y = Math.floor(i / size);
			x = i - y * size;
			
			inline = 1;
			movet = [i];
			if (x < size - 4){
				for (var n = 1;n < size - x;n++){
					if (s[i + n] == s[i]){
						inline++;
						movet.push(i + n);
					}else{
						break;
					}
				}
			}
			if (inline > 4){
				movea = movea.concat(movet);
			}
			
			inline = 1;
			movet = [i];
			if (y < size - 4){
				for (var n = 1;n < size - y;n++){
					if (s[i + n * size] == s[i]){
						inline++;
						movet.push(i + n * size);
					}else{
						break;
					}
				}
			}
			if (inline > 4){
				movea = movea.concat(movet);
			}
			
			inline = 1;
			movet = [i];
			if (x < size - 4 && y < size - 4){
				for (var n = 1;n < size - Math.max(x,y);n++){
					if (s[i + n * (size + 1)] == s[i]){
						inline++;
						movet.push(i + n * (size + 1));
					}else{
						break;
					}
				}
			}
			if (inline > 4){
				movea = movea.concat(movet);
			}
			
			inline = 1;
			movet = [i];
			if (x > 3 && y < size - 4){
				for (var n = 1;n < Math.min(size - y,x + 1);n++){
					if (s[i + n * (size - 1)] == s[i]){
						inline++;
						movet.push(i + n * (size - 1));
					}else{
						break;
					}
				}
			}
			if (inline > 4){
				movea = movea.concat(movet);
			}
		}
	}
	$.unique(movea);
	if (movea.length > 0){
		for (i in movea){
			s[movea[i]] = 0;
			clear(movea[i] + 1);
		}
		b += movea.length;
		score += Math.pow(2,movea.length - 5);
		//layer.msg('消除了'+movea.length+'个球,得'+Math.pow(2,movea.length - 5)+'分');
		$('#score').html(score);
	}else{
		addball();
	}
}
function frame(num,on){
	var x,y;
	y = Math.floor((num - 1) / size);
	x = num - y * size - 1;
	ctx.beginPath();
	ctx.strokeStyle = (on?'#FFF':colors[0]);
	ctx.rect(x * (w + 1) + 1.5,y * (w + 1) + 1.5,w - 1,w - 1);
	ctx.stroke();
	ctx.beginPath();
	ctx.strokeStyle = (on?'#F00':colors[0]);
	ctx.rect(x * (w + 1) + 2.5,y * (w + 1) + 2.5,w - 3,w - 3);
	ctx.stroke();
}
$(function(){
	init();
	reset();
	$('#grid').click(function(){
		var x = Math.floor((event.pageX - c.getBoundingClientRect().left - 1) / (w + 1));
		var y = Math.floor((event.pageY - c.getBoundingClientRect().top - 1) / (w + 1));
		if (x >= 0 && y >= 0){
			//console.log(x + y * size);
			select(x + y * size + 1);
		}
	});
});
<div class="box">
	<canvas id="grid"></canvas>
	<div class="ctrl">
		<span id="prev"></span>
		<span id="score"></span>
		<span id="step"></span>
		<a href="javascript:;" onclick="reset();">重置</a>
	</div>
</div>
* {margin:0 auto; padding:0;list-style:none;text-decoration:none;}
body {background:#0e7142;-moz-user-select:none;-webkit-user-select:none;user-select:none;}
body:after {content:'v1.0_0213';position:fixed;left:0;bottom:0;color:#0C6138;line-height:16px;font-size:12px;}
.box {width: 677px;}

.ctrl {width:100%;height:30px;padding:10px 0;background:#084428;border-radius:10px;color:#FFF;text-align:center;line-height:30px;margin-top:10px;}
.ctrl:after {content: '';display: block;height: 0;clear: both;}
.ctrl span {background:#030a09;color:#FFF;width:50px;height:30px;text-align:center;display:inline-block;vertical-align: top;border-radius:5px;position:relative;padding-left:15px;font-family:'Courier New';}
.ctrl span:before {font-family: FontAwesome;position:absolute;left:5px;}
#step:before {content:'\f245';}
#score:before {content:'\f005';}
.ctrl a {display:inline-block;width:60px;height:30px;text-align:center;background:#C32641;color:#FFF;border-radius:3px;vertical-align: top;}
#prev {width:80px;}
#prev:before {content:'\f0a4';}
#prev i {display: inline-block;width: 16px;height: 16px;border-radius: 100%;border:#FFF 1px solid;line-height: 30px;margin: 6px 1px;}


@media (max-width: 677px){
	.box {width: 100%;height: auto;border: none;}
	
}

本项目引用的自定义外部资源