JavaScript 实现连连看

        最近在看 JavaScript, 想着上网找一个连连看游戏写一写, 看别人的代码很乱, 于是结合了思路好的, 自己模仿着写, 记录一下
        页面如下:
实现的其实是 6*6 的连连看, 为什么会多一个框框一会会解释, 但是确实是做的没有那么好看的完善, 可能还有很多 bug , 欢迎大家找 bug .
JavaScript 实现连连看_第1张图片
JavaScript 实现连连看_第2张图片
html 文件, 也就是页面, 很简单, 写成 8*8的表格就可以了
代码参考:


<html>
<head>
    <title>连连看title>
    <meta charset="UTF-8">
    <style type="text/css">
        #container{
      
            width:620px;
            height:620px;
            position:relative;
        }
        .row{
      
            display:flex;
        }
        .row div{
      
            width:100px;
            height:100px;
            border:solid 1px gray;
            flex:1;
            text-align: center;
            line-height: 100px;
        }
        #handles{
      
            width: 300px;
            height: 800px;
            position: absolute;
            left:700px;
            top: 0px;

        }
        .handleBtn{
      
            width:150px;
            height: 30px;
            margin-left: 25% ;
            margin-top: 20px;
            text-align: center;
        }
    style>

head>
<body>
<div id="container">
    <div id="row1" class="row">
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
    div>
    <div id="row2" class="row">
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
    div>
    <div id="row3" class="row">
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
    div>
    <div id="row4" class="row">
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
    div>
    <div id="row5" class="row">
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
    div>
    <div id="row6" class="row">
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
    div>
    <div id="row7" class="row">
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
    div>
    <div id="row8" class="row">
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
        <div class="col">div>
    div>
div>
<div id="handles">
    <button id="btn" class="handleBtn">重新开始button>

    <div id="showInfo">div>
div>
<script type="text/javascript" src="game_test.js">script>
<script type="text/javascript">
script>
body>
html>

JS 文件: (分为几个部分来写, 但是都是同一个 JS 文件)

// 获取表格元素
var container=document.getElementById('container');
// 获取行元素
var rows=document.getElementsByClassName('row');
// 获取列元素
var cols=document.getElementsByClassName('col');
// 获取按钮
var btn=document.getElementById('btn');
// 创建空数组
var targetArr=[];
// container 的子元素的长度, 也就是一共有几个同等级的子元素
var len=container.children.length;
// container 的第一个子元素包含几个同等级子元素
var childLen=container.firstElementChild.children.length;
// 此处定义了连连看的元素
var fruit=[['葡萄','橘子','香蕉','苹果','桃子','石榴','柚子','甘蔗'],
    ['芒果','榴莲','草莓','菠萝','西瓜','柠檬','荔枝','樱桃'],

    ['葡萄','橘子','香蕉','苹果','桃子','石榴','柚子','甘蔗'],
    ['芒果','榴莲','草莓','菠萝','西瓜','柠檬','荔枝','樱桃']];

定义点击重新开始按钮时的事件

// 对按钮元素添加事件句柄, 第一个参数代表事件名, 第二个参数代表事件触发时执行的函数
btn.addEventListener('click',reStart);

// 重新开始的函数
var reStart= function (){
     
	// 生成数据函数
    setData(fruit);

	// 生成数据后, 给表格添加数据
    for(var i=0;i<len;i++){
     
        for(var j=0;j<childLen;j++){
     
            container.children[i].children[j].innerText=container.children[i].children[j].getAttribute('info');
        }
    }
}

生成数据数组, 当然也可以不这么写, 但是前面综合找到的就用了这个, 如果后续真的有需要找更简单的, 会尝试更新

//生成数据数组
var setData=function( arr ){
     
    var arrLen=arr.length;
    var data=new Array();
    var index,value;
    var at=[];
    //二维数组转一维数组, 当前一共有32个数据,生成36个数据还需要4个,当然也可以一开始就指定36个数据,当时找到的是后面在随机抽取两个数据, 大家喜欢咋地就咋地
    arr=[].concat.apply([],arr);

	// 随机取出两个数据凑数
    for(var i=0;i<(36-arr.length)/2;i++){
     
        at[i]=arr[Math.floor(Math.random()*(arr.length))];
    }

	// 将36个数据放在arr中
    var a=arr.concat(at,at);

	// 这里创建的是 8*8 的表格, 而我的需求只有36个数据,并且将边缘都空出来
    for(var i=0;i<8;i++){
     
        for(var j=0;j<8;j++){
     
        	//如果是边缘,则空出来,不填充数据
            if (i==0 || i==7||j==0||j==7){
     
                value = "";
            }else {
     
            	// 生成一个随机下标
                r=Math.floor(Math.random()*(a.length));
                // 拿出值
                value=a[r];
                // 该方法其实是将value值删除,确保了每一个a里面的数据只出现一次
                a.splice(r,1)
            }

			// 添加属性,增加x,y值,以及是否被选择,和数据具体值
			// 这个表格敲重点!!!!!!!!!后面要考!!!!!!!
            cols[i*8+j].setAttribute('x',i);
            cols[i*8+j].setAttribute('y',j);
            //console.log("生成 data x "+i,",y "+j);
            cols[i*8+j].setAttribute('isSelected',false);
            cols[i*8+j].setAttribute('info',value);     
        }
    }
}

关于表格, 重点看坐标分布!!!和传统的不一样, 后续的函数会用到的
JavaScript 实现连连看_第3张图片

点击事件: 这部分还没有修改过, 只注释是啥意思, 复杂是复杂了, 未来看看会不会修改一下

container.onclick=function(e){
     
	// 获取选中的部分
    var tag=e.target;
    var aTag;
    var arr;
    var x0,y0,x1,y1;
    // 遍历
    for(var i=0;i<len;i++){
     
        for(var j=0;j<childLen;j++){
     
        	// 获取值
            aTag=container.children[i].children[j]
            // 如果值相等
            if(aTag==tag){
     
            	// 将该值放入targetArr中
                targetArr.push(aTag);
                // 设置选中框的背景.
                targetArr[0].style.backgroundColor='lightblue';
               // 如果 targetArr 数组中有两个数据, 则可以开始比较了
                if(targetArr.length==2){
     
                	// 该方法会获取到整个表格的内容
                    arr=getCellCondition();
                    // 将选中的格子的背景变为空白
                    targetArr[0].style.backgroundColor=null;
                    targetArr[1].style.backgroundColor=null;
					// 获取两个选中数据的坐标
                    x0=targetArr[0].getAttribute('x');
                    y0=targetArr[0].getAttribute('y');
                    x1=targetArr[1].getAttribute('x');
                    y1=targetArr[1].getAttribute('y');
                    // 确保选中的数据是值相等的并且不是选中了同一个元素
                    if(targetArr[0].innerText===targetArr[1].innerText && targetArr[0]!==targetArr[1]){
     
                    	// getRoad 寻找可以连通的路径
                        var arrTest=getRoad(x0,y0,x1,y1,arr);
                        // 判断是否有路径可以连通, 可以则将选中的格子清空
                        if(arrTest){
     
                            targetArr[0].innerText='';
                            targetArr[1].innerText='';
                        }
                    }else{
     
                        console.log('不相同')
                    }
                    // 清空数组
                    targetArr=[];
                    arr=null;
                }
                return ;
            }
        }
    }
}

获取到整个表格的内容 getCellCondition();

var  getCellCondition = function (){
     
    //用来保存所有单元格对象
    var arrs=new Array();
    for(var i=0;i<len;i++){
     
        arrs[i]=new Array();
        for(var j=0;j<childLen;j++){
     
            arrs[i][j]=rows[i].children[j].innerText;
        }
    }
    return arrs;
}

接下来重点讲路径:
分为: 水平连接, 垂直连接, 一个拐点, 两个拐点, 如图
JavaScript 实现连连看_第4张图片
于是乎寻找路径的函数如下:

function getRoad(x0,y0,x1,y1,arr) {
     
    if ( Horizontal(x0,y0,x1,y1,arr) ){
     
    	// 水平
        return true;
    }else if (Vertical(x0,y0,x1,y1,arr)){
     
    	// 垂直
        return true;
    }else if ( OnePoint(x0,y0,x1,y1,arr) ){
     
    	// 一个拐点
        return true;
    }else if (TwoPointPath(x0,y0,x1,y1,arr)){
     
    	// 两个拐点
        return true;
    }else return false;
}

水平连接;

// 对于上述生成的坐标来看, 水平遍历 x 不变
function Horizontal(x0,y0,x1,y1,arr){
     
    // 判断 x 是否不变
    if (x0!=x1) return false;
    // 定义一个标记
    var flag = true;

	// 获取两个 y 坐标, -1, +1 的目的都是忽略本身
	// 这个设定里面, 如果元素相邻, 则 yMax < yMin
    var yMax = parseInt((y0 > y1 ? y0 : y1)) -1 ;
    var yMin = parseInt((y0 < y1 ? y0 : y1)) +1 ;

	// 判断从一个元素到另个元素进行水平遍历时, 中间的元素是否为空, 不是则路径不可用
    for(i = yMin; i <= yMax; i++){
     
        if (arr[x0][i] != ''){
     
            flag = false;
            break;
        }
    }
    return flag;
}

垂直连接, 同理上面

function Vertical(x0,y0,x1,y1,arr){
     
    if (y0!=y1) return false;
    var flag = true;
    var xMax = parseInt((x0 > x1 ? x0 : x1)) -1;
    var xMin = parseInt((x0 < x1 ? x0 : x1)) +1;

    for(i = xMin; i <= xMax; i++){
     
        if (arr[i][y0] != ''){
     
            flag = false;
            break;
        }
    }
    return flag;
}

一个拐点
可通过图来理解代码, A,B分别是选中的元素, C, D分别是拐点.
如果拐点C可行, 则C应该垂直于A且水平于B.
如果拐点D可行, 则D应该垂直于B且水平于A.
JavaScript 实现连连看_第5张图片

function OnePoint(x0,y0,x1,y1,arr){
     
    var flag = false;
    var x3 = x0, y3 = y1;
    var x4 = x1, y4 = y0;
    // 如果拐点不为空, 则路径是不合理的,返回false
    if (arr[x3][y3]!=''&&arr[x4][y4]!=''){
     return false};
    flag = ((Horizontal(x0,y0,x3,y3,arr) && Vertical(x1,y1,x3,y3,arr) )|| (Vertical(x0,y0,x4,y4,arr) && Horizontal(x1,y1,x4,y4,arr)));
    return flag;
}

两个拐点: 也就是说,两个拐点, 必定是其中一个元素的"一个拐点", 并且会垂直或水平于另一个元素
JavaScript 实现连连看_第6张图片

function TwoPointPath(x0,y0,x1,y1,arr){
     
    var flag = false;
    // 网上参考的方式, 全部遍历一次来找拐点
    for (var i = 0; i < childLen; i++){
     
        for (var j = 0; j < len; j++){
     
        	// 四个顶脚我给排除了,如果找到这四个顶脚也符合的可以滴滴我,因为我真的没有找到
            if ((i==0&&j==0)||(i==0&&j==7)||(i==7&&j==0)||(i==7&&j==7)){
     
                continue;
            }else {
     
                var x3 = i, y3 = j;
				// 现在找的就是拐点,必须为空路径才是成立的
                if (arr[x3][y3]!=''){
     continue;}             
                var flag1 = (OnePoint(x0,y0,x3,y3,arr) && (Vertical(x1,y1,x3,y3,arr) || Horizontal(x1,y1,x3,y3,arr)));
                var flag2 = (OnePoint(x1,y1,x3,y3,arr) && (Vertical(x0,y0,x3,y3,arr) || Horizontal(x0,y0,x3,y3,arr)));
                flag = flag1 || flag2;
    return flag;
}

结束!

你可能感兴趣的:(JavaScript)