JS實現一個基本的打地鼠游戲

来源:http://www.cnblogs.com/imwtr/archive/2016/10/29/6011407.html
-Advertisement-
Play Games

直入正題,用JS實現一個簡單的打地鼠游戲 因為功能比較簡單就直接裸奔JS了,先看看效果圖,或者 線上玩玩 吧 如果點擊顏色比較深的那個(俗稱壞老鼠),將扣分50;如果點擊顏色比較淺的那個(俗稱好老鼠),將得分100 實現 老鼠好像有點難畫,又不想用圖片,就直接用CSS畫個簡單的圖代表老鼠和坑吧 ht ...


直入正題,用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-width: 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吧..


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • // 首碼形式:增加然後取回值UPInt& UPInt::operator++(){ *this += 1; // 增加 return *this; // 取回值}// postfix form: fetch and incrementconst UPInt UPInt::operator++(in ...
  • 如下記錄一次作業: 很顯然,我這個應該屬於二逼青年版,會在以後更新文藝青年版的答案。 1、模仿sed,一個文件中,用新字元串替換老字元串。 2、查找、添加、刪除特定的內容 ...
  • 我的博客園博文地址:http://www.cnblogs.com/tenglongwentian/ Lucene,最新版是Lucene6.2.1,匹配的jdk版本是1.8正式版。這裡用jdk7最後一版,所以用Lucene5.3.3。 新建一個maven項目,如果不會可以參考前面的博文,前面的博文有專 ...
  • 以太坊是區塊鏈開發領域最好的編程平臺,而truffle是以太坊(Ethereum)最受歡迎的一個開發框架,這是我們第一篇區塊鏈技術文章介紹truffle的原因,實戰是最重要的事情,這篇文章不講原理,只搭建環境,運行第一個區塊鏈程式(Dapp)。 安裝truffle $ npm install -g ...
  • 1.計算程式運行時常 2.文件讀寫 3.立flag 設置布爾變數,用來在程式運行時對一些邏輯進行標記。其中false和true需要自己定義其含義。因此在設置flag的時,需要註意false以及true對應的含義。否則這些邏輯上的錯誤很難被檢查出來。 4.使用HashMap 聲明myMap為HashM ...
  • 這個案例類似於在地圖上滾動滾輪,能縮小或者放大地圖,分別用zoomIn和zoomOut來命名。 代碼如下: 另外,detail在滾輪事件中,向上滾——放大(detail == -3),觸發zoomOut;向下滾——縮小(detail == 3),觸發zoomIn。 自定義事件需要trigger來主動 ...
  • 通過資料庫和ajax方法寫出地圖 客戶端部分:html、js、css代碼部分: 服務端部分:app.js(一個JavaScript): 資料庫mysql信息: 最終結果: ...
  • 類似的文章園子里已有,請看這裡,個人感覺稍顯複雜,日前也打算寫一個簡單的給項目用,一些關鍵點記錄於此。最終效果如下: 後端使用Asp.net mvc5,前端框架有:jquery.validate、jquery.validate.unobtrusive、requirejs、Bootstrap,都是當前 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...