zoukankan      html  css  js  c++  java
  • JavaScript实现数字配对游戏

    游戏效果如下图所示:
    配对游戏


    规则:

      在4X5的格子中,有随机的互不相等的10个数,每个数据有两份(也就是20个数,有两两相等的十对),随机分布在20个格子中。游戏开始,弹出二十个数的序列。每次点击格子会显示当前格子中的数据并暂时保留显示,直到下一次点击,如果下一次点击显示的数据与保留的数据不同,则之前点击保留的数据会消失(仍然存在于该格子但不显示)。如果连续点击显示的两个数据一样,则两个数据都会显示并且不会再消失。
      直到所有数据都通过连续点击相同数据的方式显示出来,就算游戏结束,报出游戏用时。此时可以点击开始游戏或刷新来继续。

    分析:

      1:二十个格子对应二十个数据,产生两组相等的十个随机数并放入数组,数组下标决定显示位置。
      2:每个格子的状态的三种:数据隐藏,暂时保留数据和永久显示。数据隐藏的格子通过点击的下一次状态是暂时保留。暂时保留数据的格子通过点击下一次状态是永久显示或数据隐藏,这里要根据连续两次获取的数据是否相等来判断。永久显示之后状态已经不可变,只能永久显示出来,此时对点击是无效的。
      3 :计时从点击开始按钮之后,点击第一个格子时开始。直到游戏完成或点击刷新重开,期间计时器不能停止。
      4 :得出,这里需要一个布尔值,记录游戏是否已经开始,已经开始的游戏对开始按钮应该拒绝,计时器运行直到游戏完成。游戏完成时,改变布尔值,计时器停止工作,显示游戏用时,开始按钮可用。

    实现:

    表格通过script创建,其中的元素先默认显示为“”空字符串。通过对应的点击来显示。CSS样式可自行设定。

     1  <table border:1>
     2         <script>
     3             var rowlength = 4;
     4             var collength = 5;
     5             var str = '';
     6             for (var i = 0; i < rowlength; i++) {
     7                 str += '<tr>'
     8                 for (var j = 0; j < collength; j++) {
     9                     //这里将每个td的id拼接为imgxx  xx为元素索引
    10                     var index = i * collength + j;
    11                     var id = "img" + index;
    12                     //注意这里字符串  每个''是一个字符串进行输出
    13                       str += '<td id="' + id + '" onclick="showImg(' + index + ')">';
    14                     str += '</td>';
    15                 }
    16                 str += '</tr>'
    17             }
    18             document.write(str);
    19         </script>
    20     </table>

     NEW_START记录是否可以开始游戏的变量
     times记录已用时间
     trans记录每个格子的翻转状态 ,数组每个格子有三种状态 0:隐藏-1:显示(仍可翻转)-2:显示(不可翻转)。也就是数组的每个元素只有三个可能的值0,1,2)
    numArr三十个数的随机序列数组

     var NEW_START = true;
    
         var times = 0;
    
         var trans = [];
    
         var numArr = [];
     

    通过ID获取到元素的方法:

     function $(id) {
            return document.getElementById(id);
              }

    下面通过函数获取到二十个随机数,两两相等的十组(可参见:生成指定范围随机数

     function getNum() {
                    var index = 0;
                    var arrLength = rowlength * collength / 2;
                    var arr = new Array();
                    while (index < arrLength) {
                        var flag = true;
                        var num = parseInt(Math.random() * 100);
                        for (var i in arr) {
                            if (arr[i] == num || arr[i] < 1) {
                                flag = false;
                            }
                        }
                        if (flag == true) {
                            arr[index] = num;
                            index++;
                        }
                    }
                    //alert(arr.length);
                    //arr是十个互不相等的随机数 
                    // newArr数组就是每个随机数都有两个的数组
                    var newArr = new Array();
                    for (var i = 0; i < arrLength; i++) {
                        newArr[i] = arr[i];
                        newArr[arrLength + i] = arr[i];
                    }
                    return newArr;
                }

    创建表格,生成随机数数组这些都是准备工作。

    下面是具体的逻辑:



    开始游戏的点击函数

    <input type="button"
       id="startButton" 
    value="开始游戏" 
    onclick="init()">

    点击开始游戏,需要初始化游戏相关的参数,注意如果已经开始,就需要拒绝处理。将数组元素用排序函数打乱做到随机性。

     function init() {
                    //如果已经开始  拒绝点击
                    if (NEW_START == false) {
                        return;
                    }
                    //结束时用于显示时间的h4标签
                    $('end').innerHTML = '';
    
                    var count = rowlength * collength;
                    //将每个格子的数据隐藏  初始化每个格子的翻转状态
                    for (var i = 0; i < count; i++) {
                        $('img' + i).innerHTML = '';
                        trans[i] = 0;
                    }
                    //将游戏用时置为0
                    times = 0;
                    $('gametime').innerHTML = times + '秒';
                    //获取随机的三十个数的随机序列数组 注意排序函数的使用
                    numArr = getNum().sort(function () {
                        return Math.random() - 0.5;
                    });
    
                    alert("已生成随机数,按表格顺序排列:" + numArr);
                }


    计时函数

    在点击第一个格子时,就需要开始计时。NEW_START=false表示已经开始,需要确保只在游戏进行中时才计时。每秒调用自身一次,并通过innerHTML把所用时间实时显示出来。

    用时:<span id="gametime">0秒</span>
    1
     function countTime() {
                    if (NEW_START == false) {
                        setTimeout('countTime()', 1000);
                        $('gametime').innerHTML = times + "秒";
                        times++;
                    }
                }


    每个格子的点击函数(超重点)

    在未开始时拒绝点击格子的(没有效果)。进入游戏点击第一个格子,游戏开始,状态改变,NEW_START=false表示已经开始不可创建新游戏。计时开始。
    后面的点击事件就需要判断点击的格子来处理不同的逻辑:

    • 点击已永久显示的元素,不处理return。
    • 点击刚显示但不是永久显示的元素,也不处理return。
        (注意这里判断是不是同一元素是直接通过状态值在trans中将索引index查找出来后对比)
    • 点击未显示元素,获取值,与前一个显示的元素对比:
      • 相等,都将trans中对应索引的状态值改为2,表示永久显示
      • 不等,新点击元素在trans中对应索引状态值改为1(暂时保留),前一个点击的元素索引值为0(需要隐藏)。

    设置完状态值,就立马需要更新显示(refreshUI函数)。更新显示时根据记录状态值的数组trans来操作的。

     function showImg(index) {
                    //未点击开始,还未初始化,退出
                    if (numArr[0] == undefined) {
                        return;
                    }
    
                    //初次点击进入,开启计时
                    if (NEW_START) {
                        NEW_START = false;
                        countTime();
                    }
                    //1-点击已经彻底显示的元素  退出
                    if (trans[index] == 2) {
                        return;
                    }
                    //将点击的格子的元素显示出来,并改变翻转状态
                    //alert(index);
                    //alert(numArr)
    
                    var clickEle = $('img' + index);
                    clickEle.innerHTML = numArr[index];
    
                    //已点击元素的index
                    var transIndex;
                    for (var i in trans) {
                        if (trans[i] == 1) {
                            transIndex = i;
                        }
                    }
                    //2-如果点击的是刚刚已显示元素
                    if (transIndex == index) {
                        trans[index] = 1;
                        return;
                    }
                    //3-点击新元素 与先前显示元素对比 两种情况-相等  不等
                    else {
                        if (numArr[transIndex] == numArr[index]) {
                            trans[transIndex] = 2;
                            trans[index] = 2;
                        } else {
                            trans[transIndex] = 0;
                            trans[index] = 1;
                        }
                    }
                    refreshUI();
                }
     


    根据状态值设置显示的函数refreshUI

    根据trans中每个元素的值,改变对应索引的格子的值。注意,如果格子的数据永久显示,需要记录已经永久显示的格子的数量,当等于所有格子数量时,表示已经全部显示。需要判定游戏结束,显示出游戏用时。

     function refreshUI() {
                    //此处用fore循环会最后存在一个undefined
                    //count记录已经被彻底显示的个数
                    var count = 0;
                    for (var i = 0; i < trans.length; i++) {
                        if (trans[i] == 0) {
                            $('img' + i).innerHTML = '';
                        }
                        if (trans[i] == 1) {
                            $('img' + i).innerHTML = numArr[i];
                        }
                        if (trans[i] == 2) {
                            $('img' + i).innerHTML = numArr[i]
                            count++;
                        }
                    }
                    if (count == collength * rowlength) {
                        NEW_START = true;
                        var endTime = times;
                        $('end').innerHTML = '用时' + endTime + '秒!!游戏结束,点击开始游戏继续';
                        $('gametime').innerHTML = endTime + "秒";
                    }
                }


    通过数组和表格的配合,实现配对游戏,加深对表格创建和数组的运用。处理逻辑和数据显示分离,根据状态值做到不同显示的状态。

    web前端/H5/javascript学习群:250777811

    欢迎大家关注我的微信号公众号,公众号名称:web前端EDU。扫下面的二维码或者收藏下面的二维码关注吧(长按下面的二维码图片、并选择识别图中的二维码)

  • 相关阅读:
    第三百节,python操作redis缓存-其他常用操作,用于操作redis里的数据name,不论什么数据类型
    第二百九十九节,python操作redis缓存-SortSet有序集合类型,可以理解为有序列表
    第二百九十八节,python操作redis缓存-Set集合类型,可以理解为不能有重复元素的列表
    第二百九十七节,python操作redis缓存-List类型,可以理解为列表
    第二百九十六节,python操作redis缓存-Hash哈希类型,可以理解为字典类型
    第二百九十五节,python操作redis缓存-字符串类型
    第二百九十四节,Redis缓存-Redis安装
    第二百九十三,Memcached缓存
    第二百九十二节,RabbitMQ多设备消息队列-Python开发
    数据库大小写与编程语言大小写的区别
  • 原文地址:https://www.cnblogs.com/gongyue/p/8006001.html
Copyright © 2011-2022 走看看