zoukankan      html  css  js  c++  java
  • 无聊的人用JS实现了一个简单的打地鼠游戏

    直入正题,用JS实现一个简单的打地鼠游戏

    因为功能比较简单就直接裸奔JS了,先看看效果图,或者 在线玩玩 吧 

    如果点击颜色比较深的那个(俗称坏老鼠),将扣分50;如果点击颜色比较浅的那个(俗称好老鼠),将得分100

    实现

    老鼠好像有点难画,又不想用图片,就直接用CSS画个简单的图代表老鼠和坑吧

    html结构

    挺简单,用9个 li 标签代表坑,用9个 div 标签代表老鼠

      <div class="container">
            <h4>无聊打打地鼠</h4>
    
            <div class="game-top">
                <p><input type="button" value="开始游戏" id="game-start"><p>
                <p>得分:<span id="game-score">0</span></p>
                <p>剩余时间:<span id="game-time">60</span> s</p>
            </div>
            <div class="game-content">
                <ul>
                    <li><div></div></li>
                    <li><div></div></li>
                    <li><div></div></li>
                    <li><div></div></li>
                    <li><div></div></li>
                    <li><div></div></li>
                    <li><div></div></li>
                    <li><div></div></li>
                    <li><div></div></li>
                </ul>
            </div>
        </div>

    CSS的实现

    有点小技巧

    对于坑,加个box-shadow: ... inset 美化一下样式

            .game-content li {
                float: left;
                margin-top: 50px;
                margin-left: 30px;
                width: 100px;
                height: 50px;
                border-radius: 50%;
                background-color: #67d0b4;
                box-shadow: 0 0 50px #706565 inset;
            }

    对于老鼠,用 border-radius:50%/40% 绘制,第二个参数还是有点使用价值的

            .game-content div {
                position: relative;
                margin-top: -15px;
                margin-left: 25px;
                width: 50px;
                height: 70px;
                border-radius: 50%/40%;
                background-color: #dfb25d;
                opacity: 0;
            }

    而要让老鼠动起来,这里的处理方式就是用动画了,老鼠运动的时候,先往上再往下即可,控制好相对位置看起来和谐一点就行

            @keyframes mouse-move {
                50% {
                    margin-top: -40px;
                    opacity: 1;
                }
                100% {
                    margin-top: -15px;
                    opacity: 0;
                }
            }
            .game-content div.active {
                animation: mouse-move 2s ease-in-out infinite;
            }

    注意 animation: ... infinite 的使用,让动画能一直进行下去,我们使用JS控制好时间差判断应该显示那个老鼠,应该显示多少只老鼠即可

    不然的画,会发现动画完成了再也无法让它继续进行了

    点击的是好老鼠还是坏老鼠,应该给出提示如:

      

    可以直接用CSS的伪元素::after置入对错,在点击的时候,根据不同的性质设置不同的值及颜色

    .game-content div.good {
        background-color: #dfb25d;
    }
    .game-content div.good[clicked="1"]::after {
        content: "✓";
        line-height: 70px;
        font-size: 40px;
        color: #0ad845;
    }
    
    .game-content div.bad {
        background-color: #a48f5c;
    }
    .game-content div.bad[clicked="1"]::after {
        content: "✕";
        line-height: 70px;
        font-size: 40px;
        color: #db1536;
    }
      1 .container {
      2     width: 500px;
      3     height: 300px;
      4     margin: 50px auto;
      5     border: 1px solid #ddd;
      6     text-align: center;
      7 }
      8 
      9 .game-top {
     10     padding-top: 10px;
     11     width: 100%;
     12     height: 90px;
     13 }
     14 .game-top p {
     15     margin: 5px;
     16 }
     17 
     18 .game-content {
     19     overflow: auto;
     20     width: 100%;
     21     border-top: 1px solid #ddd;
     22     background-color: #ddf;
     23 }
     24 
     25 .game-content ul {
     26     list-style: none;
     27 }
     28 .game-content li {
     29     float: left;
     30     margin-top: 50px;
     31     margin-left: 30px;
     32     width: 100px;
     33     height: 50px;
     34     border-radius: 50%;
     35     background-color: #67d0b4;
     36     box-shadow: 0 0 50px #706565 inset;
     37 }
     38 .game-content li:last-child {
     39     margin-bottom: 50px;
     40 }
     41 
     42 .game-content div {
     43     position: relative;
     44     margin-top: -15px;
     45     margin-left: 25px;
     46     width: 50px;
     47     height: 70px;
     48     border-radius: 50%/40%;
     49     background-color: #dfb25d;
     50     opacity: 0;
     51 }
     52 
     53 .game-content div.good {
     54     background-color: #dfb25d;
     55 }
     56 .game-content div.good[clicked="1"]::after {
     57     content: "✓";
     58     line-height: 70px;
     59     font-size: 40px;
     60     color: #0ad845;
     61 }
     62 
     63 .game-content div.bad {
     64     background-color: #a48f5c;
     65 }
     66 .game-content div.bad[clicked="1"]::after {
     67     content: "✕";
     68     line-height: 70px;
     69     font-size: 40px;
     70     color: #db1536;
     71 }
     72 
     73 @media screen and (max- 500px) {
     74     .container {
     75         width: 290px;
     76     }
     77     .game-content ul {
     78         padding: 0;
     79     }
     80     .game-content li {
     81         margin-left: 5px;
     82         width: 90px;
     83     }
     84     .game-content div {
     85         margin-left: 20px;
     86     }
     87 }
     88 
     89 @-webkit-keyframes mouse-move {
     90     50% {
     91         margin-top: -40px;
     92         opacity: 1;
     93     }
     94     100% {
     95         margin-top: -15px;
     96         opacity: 0;
     97     }
     98 }
     99 @keyframes mouse-move {
    100     50% {
    101         margin-top: -40px;
    102         opacity: 1;
    103     }
    104     100% {
    105         margin-top: -15px;
    106         opacity: 0;
    107     }
    108 }
    109 
    110 .game-content div.active {
    111     -webkit-animation: mouse-move 2s ease-in-out infinite;
    112         animation: mouse-move 2s ease-in-out infinite;
    113 }
    完整CSS

    JS的处理

    逻辑是点击开始游戏,倒计时开始,同时好坏老鼠不断运动,控制好坑中好坏老鼠及其数量的随机性,点击好老鼠加分,点击坏老鼠减分,时间到结束游戏。

    先看看老鼠的运动

              // 运动操作
                moveUpAndDown: function() {
                    var that = this;
    
                    // 定时器随机定义good|bad老鼠个数,以及需要显示的个数
                    that.moveTime = setInterval(function() {
    
                        for (var i = 0, j = that.mouses.length; i < j; ++i) {
                            that.mouses[i].setAttribute('clicked', '0');
                            that.mouses[i].className = 'good active';
                            that.mouses[i].style.display = 'none';
                        }
    
                        // bad 的个数
                        var badNum = that.getRandom(0, 8);
                        for (var i = 0; i < badNum; i++) {
                            that.mouses[that.getRandom(0, 8)].className = 'bad active';
                        }
    
                        // 要显示的个数
                        var showNum = that.getRandom(0, 8);
                        for (var i = 0; i < showNum; i++) {
                            that.mouses[that.getRandom(0, 8)].style.display = 'block';
                        }
                    }, 2000);
                },

    使用定时器,定时器的循环与CSS中的动画设置一致,保证循环连贯性

    设置class为good 即可定义出一只好老鼠,同理bad 为坏老鼠

    在开始游戏,进行调用时,设置class为active 即可让老鼠运动起来

    对于打老鼠的操作,要注意到只有运动的老鼠才能点击,每只老鼠只能点击一次

                  // 打地鼠操作
                    that.mousesWrap[0].addEventListener('click', function(e) {
                        e = e || window.event;
                        var elem = e.target || e.srcElement;
                        // 如果当前项被隐藏则不操作,多次点击只取第一次分数
                        if (elem.style.display !== 'block' || elem.getAttribute('clicked') === '1') {
                            return;
                        }
                        // 扣分
                        if (elem.className.indexOf('bad') !== -1) {
                            that.score -= that.badScore;
                        }
                        // 加分
                        else {
                            that.score += that.goodScore;
                        }
    
                        elem.setAttribute('clicked', '1');
                        that.text(that.gameScore[0], that.score);
                    }, false);

    倒计时结束之后,清除两个计时器,同时将所有老鼠项display都设为none 即可(否则动画会一直循环展示出来)

                // 倒计时,当前剩余游戏时间
                countDown: function() {
                    var that = this;
    
                    var t = setInterval(function() {
                        that.text(that.gameTime[0], --that.totalTime);
    
                        if (that.totalTime === 0) {
                            clearInterval(t);
                            clearInterval(that.moveTime);
    
                            for (var i = 0, j = that.mouses.length; i < j; ++i) {
                                that.mouses[i].style.display = 'none';
                            }
    
                            alert('游戏结束,得分为:' + that.score);
                        }
                    }, 1000);
                },
      1     function MouseGame() {
      2             this.mousesWrap = this.$('.game-content');
      3             this.mouses = this.$('.game-content div');
      4             this.gameStart = this.$('#game-start');
      5             this.gameTime = this.$('#game-time');
      6             this.gameScore = this.$('#game-score');
      7             this.goodScore = 100;
      8             this.badScore = 50;
      9 
     10             this.bindEvent();
     11         }
     12 
     13         MouseGame.prototype = {
     14             constructor: MouseGame,
     15 
     16             /**
     17              * 获取元素
     18              * @param  {String} elem 元素的字符串标识
     19              * @example
     20              * $('div') | $('p.active')
     21              * @return {NodeList}      获取的元素集
     22              */
     23             $: function(elem) {
     24                 return document.querySelectorAll(elem);
     25             },
     26 
     27             /**
     28              * 获取给定范围的随机数
     29              * @param  {Number} from 起始
     30              * @param  {Number} to   结束
     31              * @return {Number}      随机数
     32              */
     33             getRandom: function(from, to) {
     34                 return Math.floor(Math.random() * (to - from + 1)) + from;
     35             },
     36 
     37             /**
     38              * 设置元素内容
     39              * @param  {HTMLElement} elem 要设置的元素
     40              * @param  {String} val  设置的内容
     41              * @return {String}      设置好的内容|元素本身的内容
     42              */
     43             text: function(elem, val) {
     44                 if (elem.textContent) {
     45                     return val !== undefined ? elem.textContent = val : elem.textContent;
     46                 } else if (elem.innerText) {
     47                     return val !== undefined ? elem.innerText = val : elem.innerText;
     48                 }
     49             },
     50 
     51             // 运动操作
     52             moveUpAndDown: function() {
     53                 var that = this;
     54 
     55                 // 定时器随机定义good|bad老鼠个数,以及需要显示的个数
     56                 that.moveTime = setInterval(function() {
     57 
     58                     for (var i = 0, j = that.mouses.length; i < j; ++i) {
     59                         that.mouses[i].setAttribute('clicked', '0');
     60                         that.mouses[i].className = 'good active';
     61                         that.mouses[i].style.display = 'none';
     62                     }
     63 
     64                     // bad 的个数
     65                     var badNum = that.getRandom(0, 8);
     66                     for (var i = 0; i < badNum; i++) {
     67                         that.mouses[that.getRandom(0, 8)].className = 'bad active';
     68                     }
     69 
     70                     // 要显示的个数
     71                     var showNum = that.getRandom(0, 8);
     72                     for (var i = 0; i < showNum; i++) {
     73                         that.mouses[that.getRandom(0, 8)].style.display = 'block';
     74                     }
     75                 }, 2000);
     76             },
     77 
     78             // 打地鼠操作
     79             bindEvent: function() {
     80                 var that = this;
     81 
     82                 // 监听游戏开始/重新开始
     83                 that.gameStart[0].addEventListener('click', function() {
     84                     that.startGame();
     85                 }, false);
     86 
     87                 // 打地鼠操作
     88                 that.mousesWrap[0].addEventListener('click', function(e) {
     89                     e = e || window.event;
     90                     var elem = e.target || e.srcElement;
     91                     // 如果当前项被隐藏则不操作,多次点击只取第一次分数
     92                     if (elem.style.display !== 'block' || elem.getAttribute('clicked') === '1') {
     93                         return;
     94                     }
     95                     // 扣分
     96                     if (elem.className.indexOf('bad') !== -1) {
     97                         that.score -= that.badScore;
     98                     }
     99                     // 加分
    100                     else {
    101                         that.score += that.goodScore;
    102                     }
    103 
    104                     elem.setAttribute('clicked', '1');
    105                     that.text(that.gameScore[0], that.score);
    106                 }, false);
    107             },
    108 
    109             // 倒计时,当前剩余游戏时间
    110             countDown: function() {
    111                 var that = this;
    112 
    113                 var t = setInterval(function() {
    114                     that.text(that.gameTime[0], --that.totalTime);
    115 
    116                     if (that.totalTime === 0) {
    117                         clearInterval(t);
    118                         clearInterval(that.moveTime);
    119                         
    120                         for (var i = 0, j = that.mouses.length; i < j; ++i) {
    121                             that.mouses[i].style.display = 'none';
    122                         }
    123 
    124                         alert('游戏结束,得分为:' + that.score);
    125                     }
    126                 }, 1000);
    127             },
    128 
    129             // 开始游戏
    130             startGame: function() {
    131                 this.score = 0;
    132                 this.totalTime = 60;
    133                 this.text(this.gameTime[0], this.totalTime);
    134                 this.text(this.gameScore[0], this.score);
    135 
    136                 this.countDown();
    137                 this.moveUpAndDown();
    138             }
    139         };
    140 
    141         new MouseGame();
    完整JS

    代码有注释应该不难看懂了

    那么..快来fork吧..

  • 相关阅读:
    "use strict"详解
    HTML5 文件上传
    jquery $(document).ready() 与window.onload的区别
    前端面试题——错题集
    css-子div设置margin-top影响父div
    常见的dom操作----原生JavaScript与jQuery
    前端面试题——错题集
    JavaScript正则表达式知识点
    越权漏洞
    php反系列化原理和演示
  • 原文地址:https://www.cnblogs.com/imwtr/p/6011407.html
Copyright © 2011-2022 走看看