JavaScript连连看小游戏

来源:互联网 发布:大数据与政府统计 编辑:程序博客网 时间:2024/04/29 16:36
 
<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>JS连连看源码完美注释版</title></head><style>table{border-collapse: collapse;}td{border: solid #ccc 1px;height: 36px;width: 36px;cursor: pointer;}td img{  height: 30px;  width: 30px;  border: solid #fff 3px;  /*  filter: alpha(opacity=80);  -moz-opacity: 0.8;  opacity: 0.8;  */ }</style><script>/*** js连连看完美注释版* 原创作者: sunxing007(http://blog.csdn.net/sunxing007)* 转载请注明出处**///以下部分为路径搜索算法部分,与表现层无关//全局变量var X = 16;//总行数var Y = 14;//总列数var types = 15;//图形种类//布局矩阵//为了算法方便,矩阵的第一行,第一列,最后一行,最后一列都标注为0,天然通路。var arr = new Array(Y);var tbl;//显示布局的table元素var p1 = null;//搜索路径用的第1个点的坐标var p2 = null;//搜索路径用的第2个点的坐标var e1 = null;//第1个点对应的元素var e2 = null;//第2个点对应的元素//路径搜索,给出两个点,搜索出通路//通路用可连通的点表示function getPath(p1, p2){//开始搜索前对p1,p2排序,使p2尽可能的在p1的右下方。//这样做可以简化算法if(p1.x>p2.x){var t = p1; p1 = p2;p2 = t;}else if(p1.x==p2.x){if(p1.y>p2.y){var t = p1; p1 = p2;p2 = t;}}//通过分析连连看中两点之间的位置关系,逐步由简到难分析每一种类型//第一种类型, 两点是否在一条直线上,而且两点之间可直线连通if((onlineY(p1, p2)||onlineX(p1, p2)) && hasLine(p1, p2)){status = 'type 1';return [p1,p2];}//第二种类型, 如果两点中任何一个点被全包围,则不通。if( !isEmpty({x:p1.x, y:p1.y+1}) && !isEmpty({x:p1.x, y:p1.y-1}) && !isEmpty({x:p1.x-1, y:p1.y}) && !isEmpty({x:p1.x+1, y:p1.y}) ){status = 'type 2';return null;}if( !isEmpty({x:p2.x, y:p2.y+1}) && !isEmpty({x:p2.x, y:p2.y-1}) && !isEmpty({x:p2.x-1, y:p2.y}) && !isEmpty({x:p2.x+1, y:p2.y}) ){status = 'type 2';return null;}//第三种类型, 两点在一条直线上,但是不能直线连接var pt0, pt1, pt2, pt3;//如果都在x轴,则自左至右扫描可能的路径,//每次构造4个顶点pt0, pt1, pt2, pt3,然后看他们两两之间是否连通if(onlineX(p1, p2)){for(var i=0; i<Y; i++){if(i==p1.y){continue;}pt0 = p1;pt1 = {x: p1.x, y: i};pt2 = {x: p2.x, y: i};pt3 = p2;//如果顶点不为空,则该路不通。if(!isEmpty(pt1) || !isEmpty(pt2)){continue;}if( hasLine(pt0, pt1) && hasLine(pt1, pt2) && hasLine(pt2, pt3) ){status = '(x:' + pt0.x + ',y:' + pt0.y + ')' + ', (x:' + pt1.x + ',y:' + pt1.y + ')' + ', (x:' + pt2.x + ',y:' + pt2.y + ')' + ', (x:' + pt3.x + ',y:' + pt3.y + ')';return [pt0, pt1, pt2, pt3];}}}//如果都在y轴,则自上至下扫描可能的路径,//每次构造4个顶点pt0, pt1, pt2, pt3,然后看他们两两之间是否连通if(onlineY(p1, p2)){for(var j=0; j<X; j++){if(j==p1.x){continue;}pt0 = p1;pt1 = {x:j, y:p1.y};pt2 = {x:j, y:p2.y};pt3 = p2;//如果顶点不为空,则该路不通。if(!isEmpty(pt1) || !isEmpty(pt2)){continue;}if( hasLine(pt0, pt1) && hasLine(pt1, pt2) && hasLine(pt2, pt3) ){status = '(x:' + pt0.x + ',y:' + pt0.y + ')' + ', (x:' + pt1.x + ',y:' + pt1.y + ')' + ', (x:' + pt2.x + ',y:' + pt2.y + ')' + ', (x:' + pt3.x + ',y:' + pt3.y + ')';return [pt0, pt1, pt2, pt3];}}}//第四种类型, 两点不在一条直线上。//先纵向扫描可能的路径//同样,每次构造4个顶点,看是否可通for(var k=0; k<Y; k++){pt0 = p1;pt1 = {x:p1.x, y:k};pt2 = {x:p2.x, y:k};pt3 = p2;status = '(x:' + pt0.x + ',y:' + pt0.y + ')' + ', (x:' + pt1.x + ',y:' + pt1.y + ')' + ', (x:' + pt2.x + ',y:' + pt2.y + ')' + ', (x:' + pt3.x + ',y:' + pt3.y + ')';//特殊情况,如果pt0和pt1重合if(equal(pt0,pt1)){//如果pt2不为空,则此路不通if(!isEmpty(pt2)){continue;}if( hasLine(pt1, pt2) && hasLine(pt2, pt3) ){return [pt1, pt2, pt3];}else{continue;}}//特殊情况,如果pt2和pt3重合else if(equal(pt2,pt3)){//如果pt1不为空,则此路不通if(!isEmpty(pt1)){continue;}if( hasLine(pt0, pt1) && hasLine(pt1, pt2) ){return [pt0, pt1, pt2];}else{continue;}}//如果pt1, pt2都不为空,则不通if(!isEmpty(pt1) || !isEmpty(pt2)){continue;}if( hasLine(pt0, pt1) && hasLine(pt1, pt2) && hasLine(pt2, pt3) ){return [pt0, pt1, pt2, pt3];}}//横向扫描可能的路径for(var k=0; k<X; k++){pt0 = p1;pt1 = {x:k, y:p1.y};pt2 = {x:k, y:p2.y};pt3 = p2;status = '(x:' + pt0.x + ',y:' + pt0.y + ')' + ', (x:' + pt1.x + ',y:' + pt1.y + ')' + ', (x:' + pt2.x + ',y:' + pt2.y + ')' + ', (x:' + pt3.x + ',y:' + pt3.y + ')';if(equal(pt0,pt1)){if(!isEmpty(pt2)){continue;}if( hasLine(pt1, pt2) && hasLine(pt2, pt3) ){return [pt1, pt2, pt3];}}if(equal(pt2,pt3)){if(!isEmpty(pt1)){continue;}if( hasLine(pt0, pt1) && hasLine(pt1, pt2) ){return [pt0, pt1, pt2];}}if(!isEmpty(pt1) || !isEmpty(pt2)){continue;}if( hasLine(pt0, pt1) && hasLine(pt1, pt2) && hasLine(pt2, pt3) ){return [pt0, pt1, pt2, pt3];}}//status='type4';return null;/********** end type 4 **************/}function equal(p1, p2){return ((p1.x==p2.x)&&(p1.y==p2.y));}function onlineX(p1, p2){return p1.y==p2.y;}function onlineY(p1, p2){return p1.x==p2.x;}function isEmpty(p){return (arr[p.y][p.x]==0);}function hasLine(p1, p2){if(p1.x==p2.x&&p1.y==p2.y){return true;}if(onlineY(p1, p2)){var i = p1.y>p2.y?p2.y:p1.y;i = i+1;var max = p1.y>p2.y?p1.y:p2.y;for(; i<max; i++){var p = {x: p1.x, y: i};if(!isEmpty(p)){break}}if(i==max){return true;}return false;}else if(onlineX(p1, p2)){var j = p1.x>p2.x?p2.x:p1.x;j = j+1;var max = p1.x>p2.x?p1.x:p2.x;for(; j<max; j++){var p = {x: j, y: p1.y};if(!isEmpty(p)){break}}if(j==max){return true;}return false;}}/*** js连连看完美注释版* 原创作者: sunxing007(http://blog.csdn.net/sunxing007)* 转载请注明出处**///以下部分为表现层部分,包括绘图, 初始化矩阵, 绑定鼠标事件...function $(id){return document.getElementById(id)}var t1, t2;//测试用//图片基路径var IMG_PATH = 'http://images.cnblogs.com/cnblogs_com/sunxing007/231491/';//初始化function init(){//构造图片库var imgs = new Array(30);for(var i=1; i<=30; i++){imgs[i] = 'r_' + i + '.gif';}tbl = $('tbl');//构造tablefor(var row=0;row<Y-2;row++){var tr=tbl.insertRow(-1);for(var col=0;col<X-2;col++) {var td=tr.insertCell(-1);}}//构造矩阵for(var i=0; i<Y; i++){arr[i] = new Array(X);for(var j=0; j<X; j++){arr[i][j] = 0;}}var total = (X-2)*(Y-2);var tmp = new Array(total);//产生随机位置用for(var i=0; i<total; i++){tmp[i] = 0;}for(var i=0; i<total; i++){if(tmp[i]==0){var t = Math.floor(Math.random()*types) + 1;tmp[i] = t;while(true){var c = Math.floor(Math.random()*(total-i)) + i;if(tmp[c]==0){tmp[c] = t;break;}}}}var c = 0;for(var i=1; i<Y-1; i++){for(var j=1; j<X-1; j++){arr[i][j] = tmp[c++];tbl.rows[i-1].cells[j-1].innerHTML = '<img src="' + IMG_PATH + imgs[arr[i][j]] + '" />';}}//绑定鼠标事件  var img1, img2;document.body.onclick = function(e){var el = document.all?event.srcElement:e.target;if(el.parentNode.tagName!='TD'){return;}if(!img1){img1 = el;}else{img2 = el;}el.style.border = 'solid #3399FF 3px';el = el.parentNode;if(el.innerHTML==''){p1 = p2 = e1 = e2 = null;}var r = el.parentNode.rowIndex +1;var c = el.cellIndex +1;if(p1==null){//el.childNodes[0].style.border = 'solid #ccc 3px';p1 = {x:c, y:r};e1 = el;}else{p2 = {x:c, y:r};e2 = el;if(!equal(p1, p2)&&e1.innerHTML==el.innerHTML){var path = getPath(p1, p2);if(path!=null){e1.innerHTML = e2.innerHTML = '';arr[p1.y][p1.x] = arr[p2.y][p2.x] = 0;}}if(t1){t1.style.backgroundColor = '';}t1 = e1;if(t2){t2.style.backgroundColor = '';}t2 = e2;img1.style.border = 'solid #fff 3px';img2.style.border = 'solid #fff 3px';p1 = p2 = e1 = e2 = img1 = img2 = null;t1.style.backgroundColor = t2.style.backgroundColor = 'lightpink';}}/*** js连连看完美注释版* 原创作者: sunxing007(http://blog.csdn.net/sunxing007)* 转载请注明出处**/}</script><body onload="init();">js连连看完美注释版<br />原创作者: <a href="http://blog.csdn.net/sunxing007">sunxing007</a><br />Date: 2010-02-03<br />转载请注明出处:<a href="http://blog.csdn.net/sunxing007">http://blog.csdn.net/sunxing007</a><br /><br /><table id="tbl" cellspacing="0" cellpadding="0" border="1"></table></body></html>