原生javascript实现连连看游戏

本文实例为大家分享了js实现连连看游戏的具体代码,供大家参考,具体内容如下

<!DOCTYPE html>
<html>
<head>
<title>连连看</title>
<meta charset="gbk">
<style type="text/css">
 body {
  text-align: center;
 }
 .text {text-align: center; margin-top: 60px; color: #fff;}
 .agin {text-align: center; margin-top: 60px; color: #fff;}

 #game-box {
   margin: 60px auto;
   position: relative;
 }

 #game-box img {
  float: left;
  width: 59px;
  height: 59px;
  border: 1px solid #000000;
 }

 #game-box img.hover {
   border: 1px solid #ffffff;
 }

 #game-box img.active {
   border: 1px solid #7fff00;
 }
 #game-box div {
  background-color: #7fff00;
  position: absolute;
 }
</style>
<script type="text/javascript">
  var byId = function (id) {
   return document.getElementById(id);
  }
  var boxWidth = 61; //格子宽度
  var gameBox;
  var mapid = 'game-box';//地图 id
  //22张图片
  var arr = '1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22'.split(',');
  var h = 8; //图片共8行
  var w = 11; //图片共11列
  var boxsLength = h*w;
  var boxArr = {};  //map对象
  var startBox = ''; //开始的格子
  var endBox = '';  //结束的格子
  window.onload = init;

  //初始化
  function init() {
   byId('agin').style.display = 'none';//隐藏再来一把按钮
   boxsLength = h*w;//图片方框的个数
   boxArr = {};
   startBox = '';
   endBox = '';
   var str = '';
   gameBox = byId(mapid);
   for (var i = 0; i < h; i++) {
    for (var j = 0; j < w; j++) {
     str += '<img class="" onclick="choose(this);" id="t' + i + '_l'
       + j + '" src="img/blank.gif">'
     // alert(str);
    }//id="t0_l0,t0_l1,t0_l2,t0_l3..."
   }
   gameBox.innerHTML = str;
   gameBox.style.width = w * boxWidth + 'px';
   pushBoxArr();
   toHTML();
  }

  // 随机获取坐标
  function getPosition() {
   var t, f;
   (function () {
    t = parseInt(Math.random() * h);
    l = parseInt(Math.random() * w);
    if (('t' + t + '_l' + l) in boxArr) {
      arguments.callee();
    }
   })();
   return {t:t, l:l}
  }

  // 创建随机坐标的格子
  function CearteBox(name) {
  var p = getPosition();
  this.name = name;//图片名
  this.t = p.t;//行
  this.l = p.l;//列
  this.position = 't' + p.t + '_l' + p.l;//位置
  this.love = 0;//这个用于特殊,某些图片不同也可以连接
  switch (name) {
   case '100':
   case '200':
    this.love = 1;
    break;
   case '300':
   case '400':
   case '500':
    this.love = 2;
    break;
   case '600':
   case '700':
    this.love = 3;
    break;
   case '800':
   case '900':
    this.love = 4;
    break;
   }
  }

  // 产生88个格子(图片框)
  function pushBoxArr() {
   var index = 0;
   var last = arr.length - 1;
   for (var i=0; i< h;i++) {
    for (var j=0;j< w;j++) {
     var a = new CearteBox(arr[index]);//用图片名创建,每张图片四次
     boxArr['t' + a.t + '_l' + a.l] = a;//格子的位置(也是每张图片的id)
     if (index === last) {
      index = 0;
     } else {
      index += 1;
     }
    }
   }
  }

  // 初始化html
  function toHTML() {
   for (var i in boxArr) {//遍历所有图片的id
    byId(i).src = 'img/' + boxArr[i].name + '.png';
   }
  }

  // choose
  function choose(el) {
   if (el.src.indexOf('blank') >= 0) {//鼠标点击了空白图片
     return false;
   }else{
    el.className = 'active';//更改点击图片的样式
     //第一次点击或点击了同一张图片
    if (startBox == '' || startBox == el.id) {
     startBox = el.id;
    } else {//点击了第二张图片
     endBox = el.id;
     test(boxArr[startBox], boxArr[endBox]);
    }
   }
  }

 // 判断是不是可连接格子
 function test(a, b) {
  var can = function (a, b) {
    if (a.name == b.name) {//图片名相同就可以连接
     return true;
    } else {
     if (a.love != 0 && b.love != 0) {
      if (a.love == b.love) {
       return true;
      } else {
       return false;
      }
     } else {
      return false;
     }
   }
  }(a, b);//立即执行
  if (can) {//可以连接
   go(a, b);
  } else {//不能连接
   byId(startBox).className = '';
   startBox = endBox;//指向第二张图片
   endBox = '';
  }
 }

 // 判断是否连通
 function go(a, b) {
  var _ap = a.position, _bp = b.position;
  var a = a, b = b, temp, isKill = false;

  // 建立四个点,判断是否两两相通
  var pt1, pt2, pt3, pt4;
  // 上到下扫描
  if (isKill == false) {
   //交换位置
   if (a.t > b.t) {
    temp = a;
    a = b;
    b = temp;
   }
   for (var i = -1, len = h; i <= len; i++) {
    pt1 = a;
    pt2 = {t:i, l:a.l};
    pt3 = {t:i, l:b.l};
    pt4 = b;
    if( (!isNull(pt2) && (pt2.t != a.t) ) || ( !isNull(pt3) && (pt3.t != b.t) ) ){
       continue;
    }
    else if (link4pt(pt1, pt2, pt3, pt4)){
      isKill = true;
      kill(a, b);
      showLine(pt1, pt2, pt3, pt4);
      break;
      return;
    }
  }
  }

   // 左到右扫描
   if (isKill == false) {
    //交换位置
      if (a.l > b.l) {
        temp = a;
        a = b;
        b = temp;
      }
      for (var i = -1, len = w; i <= len; i++) {
        pt1 = a;
        pt2 = {t:a.t, l:i};
        pt3 = {t:b.t, l:i};
        pt4 = b;
        if( (!isNull(pt2) && (pt2.l != a.l) ) || ( !isNull(pt3) && (pt3.l != b.l) ) ){
          continue;
        }
        else if (link4pt(pt1, pt2, pt3, pt4)){
          isKill = true;
          kill(a, b);
          showLine(pt1, pt2, pt3, pt4);
          break;
          return;
        }
      }
    }

    //扫描完毕
    if(isKill == false){
      endBox = '';
      byId(_ap).className = '';
      startBox = _bp;
    }
  }

  //干掉格子,删除boxArr中相应格子
  function kill(a, b) {
    boxArr[a.position] = null;
    boxArr[b.position] = null;
    boxsLength -= 2;
    startBox = '';
    endBox = '';
  }

  // 显示链接路径
  function showLine(a, b, c, d) {
    var line1 =show2pt(a,b);
    var line2 = show2pt(b,c);
    var line3 = show2pt(c,d);
    var hideLine = function () {
      gameBox.removeChild(line1);
      gameBox.removeChild(line2);
      gameBox.removeChild(line3);
      byId(a.position).src = byId(d.position).src ='img/blank.gif';
      byId(a.position).className = byId(d.position).className = '';
      if (boxsLength<=0) {
        alert('亲,你赢了!好腻害啊。');
        byId('agin').style.display = 'block';
      }
    }
    setTimeout(hideLine, 300);

    function show2pt (a, b){
      var top, left, width, height, line = document.createElement('div');
      var a = a, b = b, temp;
      // 交换位置
      if (a.t > b.t || a.l > b.l) {
        temp = a;
        a = b;
        b = temp;
      }
      top = boxWidth * a.t + 30 + 'px';
      left = boxWidth * a.l + 30 + 'px';
      // 同行(t相等)
      if (a.t == b.t) {
        width = boxWidth * (b.l - a.l) + 1 + 'px';
        height = '1px';
      }
      // 同列(l相等)
      if (a.l == b.l) {
        width = '1px';
        height = boxWidth * (b.t - a.t) + 1 + 'px';
      }
      line.style.top = top;
      line.style.left = left;
      line.style.width = width;
      line.style.height = height;
      return gameBox.appendChild(line);
    }
  }

  // 单个格子是否空值
  function isNull (a) {
    return boxArr['t' + a.t + '_l' + a.l] ? false : true;
  }

  // 2点是否连通
  function link2pt (a, b) {
    var a = a, b = b, temp, canLink = true;
    // 交换位置
    if (a.t > b.t || a.l > b.l) {
      temp = a;
      a = b;
      b = temp;
    }
    if (a.t == b.t) {  //同行(t相等),a在b的左边
      for (var i = a.l + 1, len = b.l - 1; i <= len; i++) {
        if (boxArr['t' + a.t + '_l' + i]) {
          canLink = false;
          break;
        }
      }
    }else if (a.l == b.l) {  //同列(l相等),a在b的上边
      for (var i = a.t + 1, len = b.t - 1; i <= len; i++ ) {
        if(boxArr['t' + i + '_l' + a.l]) {
          canLink = false;
          break;
        }
      }
    } else {
      throw ('位置错误:a.t=' + a.t + ' b.t=' + b.t + ' a.l=' + a.l + ' b.l=' + b.l);
    }
    return canLink;
  }

  // 4个点是否两两连通
  function link4pt (pt1, pt2, pt3, pt4) {
    return link2pt(pt1, pt2) && link2pt(pt2, pt3) && link2pt(pt3, pt4);
  }
</script>
</head>
<body>
<p class="agin" id="agin" style="display: none;"><input type="button" onclick="init()" value="再来一把"></p>
<div id="game-box">
</div>
<p class="text" style="">相同图片可以连哦!啊哈哈哈~~ </p>
</body>
</html>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Java计算器核心算法代码实现

    在进行一个表达式的计算时,先将表达式分割成数字和字符串然后利用出入栈将分割后的表达式进行中缀转后缀,再将后缀表达式进行计算得到结果(思想在上一篇写过)现在贴下Java语言的代码实现.(学习Java时间不长所以可能会有很多不足的地方,我会改进也欢迎大神可以给我一些意见和建议~谢谢啦) 我将这部分分成三个方法完成功能,并在getResult方法调用(getResult方法被主方法调用) private String getResult(String str) { //分割 String[] Str

  • Java经典快排思想以及快排的改进讲解

    一.经典快排思想 前提条件:给定一个无序数组arr 取这个数组最后一个数 num 作为标准,将前面部分的数分为两部分,使得<=num的部分在左边,>num的数在右边: 然后将最后一个数和>num部分的第一个数进行交换,就使得原本在数组最后位置的num找到了正确的位置,它的左边都是比它小的以及和它一样的数,右边都是比它大的数 回到1,进行递归或迭代,使得所有的数都找到正确的位 二.通过荷兰国旗问题改进快排 什么是荷兰国旗问题? 已知一个整形数组arr,和一个整数num,请把小于num的数放

  • Java语言实现非递归实现树的前中后序遍历总结

    前言 三种遍历的递归写法都很好写,所以总结一下非递归写法. 先贴一张图复习一下三种遍历方式就进入正文啦~ [注:本文所有代码实现中树的结点定义如下: public class Node { int val; Node left; Node right; Node parent; Node() {} Node(int val) { this.val = val; } } 1.前序遍历 实现思路: 前序遍历的顺序是:根结点 -> 左孩子 -> 右孩子 借助一个栈结构先将根结点压入栈,然后循环每次取

  • java连连看游戏菜单设计

    本文实例为大家分享了java连连看游戏菜单的具体实现代码,供大家参考,具体内容如下 先写GUI. 首先初始化框架,菜单,按钮,需要把菜单和按钮都添加在框架中.注意添加的顺序,首先要设置菜单,再设置框架,再设置按钮,如果交换了设置菜单和框架的顺序,会导致菜单显示不出,被框架挡住.对菜单设置了三个选项,第一个选项有五个下拉按键,用循环添加,第二个和第三个选项的下拉按键直接添加. GUI代码如下: package gui; import java.awt.Font; import javax.swin

  • Java排序算法之堆排思想及代码实现

    在介绍堆排序前,我们需要了解一下一种数据结构 -- 顶堆. 什么是顶堆? 它是一颗完全二叉树,顶堆有大顶堆和小顶堆两种.所谓大顶堆就是在这颗完全二叉树中,任何一颗子树都满足:父结点的值 > 孩子结点的值:小顶堆则相反. 如图: 什么是堆排序(Heapsort)? 利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种.可以利用数组的特点快速定位指定索引的元素. 现在给我们一个无序数组,我们将其从小到大排序,使用堆排序的实现步骤和思想如下: 1.让这个数组变成一个大根堆 2.将最后一

  • 浅谈Java 8 新增函数式接口到底是什么

    从 Java 8 开始便出现了函数式接口(Functional Interface,以下简称FI) 定义为: 如果一个接口只有唯一的一个抽象接口,则称之为函数式接口.为了保证接口符合 FI ,通常会在接口类上添加 @FunctionalInterface 注解.理解了函数式接口可以为 Java 函数式编程打下基础,最终可通过运用函数式编程极大地提高编程效率. 函数式接口 (Functional Interface) 就是一个有且仅有一个抽象方法,但是可以有多个非抽象方法的接口. 函数式接口可以对

  • Java多边形重心计算

    多边形重心计算 三角形重心 顶点为a,b,c的三角形重心为x = (xa + xb + xc) / 3,y = (ya + yb + yc) / 3 多边形重心 x = (x1w1 + x2w2 + - + xnwn)/W y = (y1w1 + y2w2 + - + ynwn)/W import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.Polygon; import org.locationt

  • Java二叉树的遍历思想及核心代码实现

    二叉树在计算机中的存储方式往往线性结构,线性存储分为顺序存储和链式存储,将二叉树按层序编号. 顺序结构:按编号的顺序进行存储,对于完全二叉树而言,顺序存储可以反映二叉树的逻辑,但是对于大多数的二叉树则无法反映其逻辑关系,不过可以用 ^ 来代替不存在的结点,但是如果这个树是一个右斜树,就非常浪费存储空间.所以二叉树的存储形式一般为链式存储结构. 链式存储:每一个结点都分有一个数据域(data)和两个指针域(lchild和rchild),指针域分别指向左孩子和右孩子,若为空则为null.遍历方式有四

  • JavaScript键盘事件常见用法实例分析

    本文实例讲述了JavaScript键盘事件常见用法.分享给大家供大家参考,具体如下: JavaScript 键盘事件有以下3种 keydown 键盘按键按下(如果按着不放,会持续触发该事件),可以捕获组合键. keypress 键盘非功能按键按下(在keydown之后触发,如果按着不放会持续触发该事件),只能捕获单个键. keyup 键盘按键弹起,可以捕获组合键. 全局事件对象event event.ctrlKey 功能键"ctrl"键是否按下. event.altKey 功能键&qu

  • JavaScript实现动态添加、移除元素或属性的方法分析

    本文实例讲述了JavaScript实现动态添加.移除元素或属性的方法.分享给大家供大家参考,具体如下: JavaScript 动态添加.移除元素 appendChild(newnode) 向节点的子节点列表的末尾添加新的子节点. insertBefore(newnode, existingnode) 在已有子节点之前插入新的子节点. removeChild(node) 删除元素的某个指定的子节点,并以 Node 对象返回被删除的节点,如果节点不存在则返回 null. innerHTML 属性设置

随机推荐