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;}
}