教你用JavaScript實現調皮的字母

来源:https://www.cnblogs.com/xFeater/archive/2022/12/25/17003923.html
-Advertisement-
Play Games

案例介紹 歡迎來到我的小院,我是霍大俠,恭喜你今天又要進步一點點了!我們來用JavaScript編程實戰案例,製作提高打字速度的小游戲-調皮的字母。點擊與屏幕上字母相對應的按鍵,若按鍵與出現的字母一致,則可以獲得相應的分數。 案例演示 根據屏幕上隨機出現的字母來點擊鍵盤上對應的按鍵,可自行調節字母下 ...


調皮的字母-豎-封面.jpg

案例介紹

歡迎來到我的小院,我是霍大俠,恭喜你今天又要進步一點點了!
我們來用JavaScript編程實戰案例,製作提高打字速度的小游戲-調皮的字母。點擊與屏幕上字母相對應的按鍵,若按鍵與出現的字母一致,則可以獲得相應的分數。

案例演示

根據屏幕上隨機出現的字母來點擊鍵盤上對應的按鍵,可自行調節字母下落的速度以及時間間隔,還會有分數統計。


源碼學習

進入核心代碼學習,我們先來看HTML中的核心代碼。

<!-- 有個小院-興趣編程 -->
<body>
    <!-- onkeydown 事件會在用戶按下一個鍵盤按鍵時發生keydown()事件 -->
    <input type="text" id="input" onkeydown="keydown()">
    <div id="ground">
        <label for="interval">生成間隔:</label>
        <input type="number" id="interval" value="100">
        <br>
        <label for="speed">下落速度:</label>
        <input type="number" id="speed" value="5">
        <input type="button" value="重新開始" onclick="gameStart()">
        <input type="button" value="重置時間" onclick="location.reload()">
        <p id="hint">3</p>
        <p id="score">分數: <span id="scorenum">0</span></p>
    </div>
    <!-- 主體部分 -->
    <div id="container"></div>
    <script src="../js/調皮的字母.js"></script>
</body>

然後再讓我們來看CSS核心代碼,CSS主要是對要頁面部件的樣式進行設置。

*{
    margin: 0;
    padding: 0;
    overflow: hidden;
}
#input{
    display:block;
    width: 100%;
    height: 100%;
    position:absolute;
    cursor: default;
    background: rgb(156, 83, 83);
}
/* 底部的顯示 */
#ground{
    width: 100%;
    height:200px;
    position:absolute;
    padding-top: 80px;
    bottom:0;
    background-color: #4d292c;
}
/* 下落的字母 */
.stone{
    background-size: 100% 100%;
    position:absolute;
    bottom:1200px;
    width: 80px;
    height:80px;
    text-align: center;
    line-height:80px;
    font-size: 40px;
    color:white;
    overflow:hidden;
    transform-origin: center;
}
label{
    color: white;
    margin-left: 20px;
}
input[type="number"] {
    width:100px;
    height: 40px;
    font-size: 30px;
    margin-top: 30px;
}
input[type="button"] {
    padding-left:10px;
    width: 200px;
    padding-right: 10px;
    height: 50px;
    font-size: 18px;
    margin-left: 300px;
}
/* 提示 */
#hint{
    position: absolute;
    top:10px;
    right: 10px;
    font-size: 35px;
    color:red;
}
/* 分數的顯示 */
#score{
    position: absolute;
    top:60px;
    left:50%;
    text-align: center;
    font-size: 30px;
    color:white;
}

讓我們來編寫核心的JavaScript代碼,首先聲明相關的變數。通過countdown()方法設置時間倒計時,分數初始化為0。getElementById()方法獲取id對應的組件。設置定時器,併在每次游戲重新開始前對定時器進行清除。random()方法獲取隨機字母以及隨機位置,並將字母添加到容器里。for()迴圈遍歷每一個字母修改屬性,設置游戲結束的位置。removeChild()方法移除最前面的字母,更新分數。

//有個小院-興趣編程
// 生成字母的間隔
var interval = 50;
// 計數,如果和間隔一樣就下落
var time = interval;
// 下落的速度
var speed = 5;
// 判斷游戲是否結束
var gameOver = false;
// 生成的字元從這裡隨機取
var str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
// 作為setInterval的返回值
var down;
// 分數
var score = 0;
// 開始倒計時
function countdown() {
    score = 0;
    document.getElementById('scorenum').innerHTML = score;
    // 倒計時3,2,1
    let hint = document.getElementById('hint');
    // 倒計時
    var countTime = 3;
    // 設置定時器
    let count = setInterval(() => {
        hint.innerHTML = countTime;
        if (!countTime) {
            clearInterval(count);
            hint.innerHTML = '游戲開始!';
            document.getElementById('input').focus();
            down = setInterval(fall, 20);
        }
        countTime -= 1;
    }, 500);
}
countdown();
// 字母下降
function fall() {
    let stones = document.getElementsByClassName('stone');
    // 如果次數達到設定的值,生成一個新的字母
    if (time == interval) {
        let newStone = document.createElement('div');
        newStone.setAttribute('class', 'stone');
        // 隨機字元
        newStone.innerHTML = str[Math.round(Math.random() * 25)];
        // 隨機位置
        newStone.style.left = `${Math.round(Math.random() * 80) + 10}%`
        // 獲取容器
        let container = document.getElementById('container');
        // 把生成的字母添加到容器里
        container.appendChild(newStone);
        time = 0;
    }
    // 遍歷每一個字母,修改屬性,實現下落
    for (let i = 0; i < stones.length; i++) {
             // 計算下落的距離,賦值給style.bottom
        let distance = parseInt(getComputedStyle(stones[i]).bottom) - speed;
        stones[i].style.bottom = `${distance}px`;
        // 距離小於 150px 表示接觸到地板,游戲結束
        if (distance < 260) {
            document.getElementById('hint').innerHTML = '游戲結束!'
            gameOver = true;
            clearInterval(down);
        }
    }
    time ++;
}
// 按下按鍵觸發的事件
function keydown() {
    // 晚1ms清空input里的字元,不然有可能清空失敗
    setTimeout(() => {
        document.getElementById('input').value = '';
    }, 1);
    // 如果游戲結束,停止觸發
    if (gameOver)
        return;
    // 遍歷所有的字母,如果和鍵盤輸入的值相同則移除最前面的字母
    let stones = document.getElementsByClassName('stone');
    for (let i = 0; i < stones.length; i++) {
        // 判斷字母的值是否和鍵盤輸入的值相同
        if (arguments.callee.caller.arguments[0].key.toUpperCase() == stones[i].textContent) {
            let die = stones[i];
            die.innerHTML = '';
            setTimeout(() => {
                die.parentElement.removeChild(die);
                die = null;
            }, 300);
            // 更新分數
            score ++;
            document.getElementById('scorenum').innerHTML = score;
            break;
        }
    }
}
// 按下 重新開始鍵 觸發的事件
function gameStart() {
    // 如果游戲沒結束則不能重新開始,防止下落抖動
    if (!gameOver)
        return;
    // 從輸入框獲取各項參數
    interval = document.getElementById('interval').value;
    time = interval;
    speed = document.getElementById('speed').value;
    // 清空容器里的字母
    let container = document.getElementById('container');
    while (container.children.length) {
        container.children[0].remove();
    }
    gameOver = false;
    countdown();
}

記得關註我,每天學習一點點

你覺得這個游戲,最吸引你的地方在哪裡?

全網可搜:小院里的霍大俠, 免費獲取簡單易懂的實戰編程案例。編程/就業/副業/創業/資源。
私微信:huodaxia_xfeater
二維碼: http://www.yougexiaoyuan.com/images/weixin_huodaxia.jpg
公眾號:有個小院(微信公眾號:yougexiaoyuan)
github:yougexiaoyuan (視頻源碼免費獲取)
(部分素材來源於互聯網,如有保護請聯繫作者)


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

-Advertisement-
Play Games
更多相關文章
  • 在VsCode中搭建C/C++運行環境需要先安裝以下插件 1、安裝c/c++插件 2、安裝code runner插件 當然也可以安裝一些其他的美化插件根據個人習慣,但是以上這兩個是必裝的。 安裝好插件後來到插件主頁點擊卸載旁邊的小齒輪選擇擴展設置 找到擴展設置中的下圖選項並打上勾即可,設置完後重啟V ...
  • 返回值類型後置語法,是為瞭解決函數返回值類型依賴於參數而導致難以確定返回值類型的問題。有了這種語法以後,對返回值類型的推導就可以用清晰的方式(直接通過參數做運算)描述出來,而不需要像 C++98/03 那樣使用晦澀難懂的寫法。 在泛型編程中,可能需要通過參數的運算來得到返回值的類型。比如如下的代碼: ...
  • 大家好,我是王有志,歡迎來到《Java面試都問啥?》的第一篇技術文章。 這個系列會從Java部分開始,接著是MySQL和Redis的內容,同時會繼續更新數據結構與演算法的部分,這樣在第一階段,我們就完成了面試“三幻神”的挑戰。 Java的部分從併發編程開始,接著是Java虛擬機,最後是集合框架。至於J ...
  • 一個簡單的C#實例。包括:GRPC文件的創建生成、服務端和客戶端函數類庫的封裝、創建服務端和客戶端調用測試。若有錯誤或更好的方法還請指正。 1、創建並生成GRPC服務文件 (1)打開vs2022,創建新項目控制台應用(其他應用好像不行)。 (2)需要安裝三個nuget包,如圖: (3)項目添加新建項 ...
  • 在前面隨筆介紹的基於SqlSugar的WInform端管理系統中,數據提供者是直接訪問資料庫的方式,不過窗體界面調用數據介面獲取數據的時候,我們傳遞的是標準的介面,因此可擴展性比較好。我曾經在隨筆《基於SqlSugar的開發框架循序漸進介紹(5)-- 在服務層使用介面註入方式實現IOC控制反轉》中介... ...
  • 在實際應用開發中,隨著項目業務逐漸複雜,耦合度會越來越高,維護成本也會直線上升,所以解耦也變得越來越重要。Prism框架為WPF開發中解耦提供了非常便捷的應用。今天主要以一個簡單的小例子,簡述WPF開發中Prism框架的簡單應用,如有不足之處,還請指正。 ...
  • AIR32F103CBT6 和 AIR32F103CCT6 分別帶 32K Byte和 64K Byte 記憶體. 對於48pin封裝的 AIR32F103, 32K和64K的記憶體已經是市面上M3晶元中相當不錯的容量, 至於64pin封裝的AIR32F103RPT6, 96K的記憶體只在市場上的高端型號... ...
  • 近年來,有關數據泄露相關的新聞事件屢見不鮮,不斷地引發大眾的討論和擔憂。各家企業都或多或少在承受相關的數據安全風險,這種可能性會給企業運行帶來額外的風險,包括大眾的質疑以及政府的處罰等。 Facebook超5億用戶個人數據遭到泄露; Elector Software投票應用泄露超650萬以色... ...
一周排行
    -Advertisement-
    Play Games
  • C#TMS系統代碼-基礎頁面BaseCity學習 本人純新手,剛進公司跟領導報道,我說我是java全棧,他問我會不會C#,我說大學學過,他說這個TMS系統就給你來管了。外包已經把代碼給我了,這幾天先把增刪改查的代碼背一下,說不定後面就要趕鴨子上架了 Service頁面 //using => impo ...
  • 委托與事件 委托 委托的定義 委托是C#中的一種類型,用於存儲對方法的引用。它允許將方法作為參數傳遞給其他方法,實現回調、事件處理和動態調用等功能。通俗來講,就是委托包含方法的記憶體地址,方法匹配與委托相同的簽名,因此通過使用正確的參數類型來調用方法。 委托的特性 引用方法:委托允許存儲對方法的引用, ...
  • 前言 這幾天閑來沒事看看ABP vNext的文檔和源碼,關於關於依賴註入(屬性註入)這塊兒產生了興趣。 我們都知道。Volo.ABP 依賴註入容器使用了第三方組件Autofac實現的。有三種註入方式,構造函數註入和方法註入和屬性註入。 ABP的屬性註入原則參考如下: 這時候我就開始疑惑了,因為我知道 ...
  • C#TMS系統代碼-業務頁面ShippingNotice學習 學一個業務頁面,ok,領導開完會就被裁掉了,很突然啊,他收拾東西的時候我還以為他要旅游提前請假了,還在尋思為什麼回家連自己買的幾箱飲料都要叫跑腿帶走,怕被偷嗎?還好我在他開會之前拿了兩瓶芬達 感覺感覺前面的BaseCity差不太多,這邊的 ...
  • 概述:在C#中,通過`Expression`類、`AndAlso`和`OrElse`方法可組合兩個`Expression<Func<T, bool>>`,實現多條件動態查詢。通過創建表達式樹,可輕鬆構建複雜的查詢條件。 在C#中,可以使用AndAlso和OrElse方法組合兩個Expression< ...
  • 閑來無聊在我的Biwen.QuickApi中實現一下極簡的事件匯流排,其實代碼還是蠻簡單的,對於初學者可能有些幫助 就貼出來,有什麼不足的地方也歡迎板磚交流~ 首先定義一個事件約定的空介面 public interface IEvent{} 然後定義事件訂閱者介面 public interface I ...
  • 1. 案例 成某三甲醫預約系統, 該項目在2024年初進行上線測試,在正常運行了兩天後,業務系統報錯:The connection pool has been exhausted, either raise MaxPoolSize (currently 800) or Timeout (curren ...
  • 背景 我們有些工具在 Web 版中已經有了很好的實踐,而在 WPF 中重新開發也是一種費時費力的操作,那麼直接集成則是最省事省力的方法了。 思路解釋 為什麼要使用 WPF?莫問為什麼,老 C# 開發的堅持,另外因為 Windows 上已經裝了 Webview2/edge 整體打包比 electron ...
  • EDP是一套集組織架構,許可權框架【功能許可權,操作許可權,數據訪問許可權,WebApi許可權】,自動化日誌,動態Interface,WebApi管理等基礎功能於一體的,基於.net的企業應用開發框架。通過友好的編碼方式實現數據行、列許可權的管控。 ...
  • .Net8.0 Blazor Hybird 桌面端 (WPF/Winform) 實測可以完整運行在 win7sp1/win10/win11. 如果用其他工具打包,還可以運行在mac/linux下, 傳送門BlazorHybrid 發佈為無依賴包方式 安裝 WebView2Runtime 1.57 M ...