
案例介紹
歡迎來到我的小院,我是霍大俠,恭喜你今天又要進步一點點了!
我們來用JavaScript編程實戰(zhàn)案例,制作提高打字速度的小游戲-調(diào)皮的字母。點擊與屏幕上字母相對應的按鍵,若按鍵與出現(xiàn)的字母一致,則可以獲得相應的分數(shù)。
案例演示
根據(jù)屏幕上隨機出現(xiàn)的字母來點擊鍵盤上對應的按鍵,可自行調(diào)節(jié)字母下落的速度以及時間間隔,還會有分數(shù)統(tǒng)計。


源碼學習
進入核心代碼學習,我們先來看HTML中的核心代碼。
<!-- 有個小院-興趣編程 -->
<body>
? ? <!-- onkeydown 事件會在用戶按下一個鍵盤按鍵時發(fā)生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">分數(shù): <span id="scorenum">0</span></p>
? ? </div>
? ? <!-- 主體部分 -->
? ? <div id="container"></div>
? ? <script src="../js/調(diào)皮的字母.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;
}
/* 分數(shù)的顯示 */
#score{
? ? position: absolute;
? ? top:60px;
? ? left:50%;
? ? text-align: center;
? ? font-size: 30px;
? ? color:white;
}
讓我們來編寫核心的JavaScript代碼,首先聲明相關的變量。通過countdown()方法設置時間倒計時,分數(shù)初始化為0。getElementById()方法獲取id對應的組件。設置定時器,并在每次游戲重新開始前對定時器進行清除。random()方法獲取隨機字母以及隨機位置,并將字母添加到容器里。for()循環(huán)遍歷每一個字母修改屬性,設置游戲結束的位置。removeChild()方法移除最前面的字母,更新分數(shù)。
//有個小院-興趣編程
// 生成字母的間隔
var interval = 50;
// 計數(shù),如果和間隔一樣就下落
var time = interval;
// 下落的速度
var speed = 5;
// 判斷游戲是否結束
var gameOver = false;
// 生成的字符從這里隨機取
var str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
// 作為setInterval的返回值
var down;
// 分數(shù)
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');
? ? // 如果次數(shù)達到設定的值,生成一個新的字母
? ? 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;
? ? }
? ? // 遍歷每一個字母,修改屬性,實現(xiàn)下落
? ? 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 ++;
}
// 按下按鍵觸發(fā)的事件
function keydown() {
? ? // 晚1ms清空input里的字符,不然有可能清空失敗
? ? setTimeout(() => {
? ? ? ? document.getElementById('input').value = '';
? ? }, 1);
? ? // 如果游戲結束,停止觸發(fā)
? ? 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);
? ? ? ? ? ? // 更新分數(shù)
? ? ? ? ? ? score ++;
? ? ? ? ? ? document.getElementById('scorenum').innerHTML = score;
? ? ? ? ? ? break;
? ? ? ? }
? ? }
}
// 按下 重新開始鍵 觸發(fā)的事件
function gameStart() {
? ? // 如果游戲沒結束則不能重新開始,防止下落抖動
? ? if (!gameOver)
? ? ? ? return;
? ? // 從輸入框獲取各項參數(shù)
? ? 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();
}
記得關注我,每天學習一點點
你覺得這個游戲,最吸引你的地方在哪里?
全網(wǎng)可搜:小院里的霍大俠, 免費獲取簡單易懂的實戰(zhàn)編程案例。編程/就業(yè)/副業(yè)/創(chuàng)業(yè)/資源。
私微信:huodaxia_xfeater
二維碼: http://www.yougexiaoyuan.com/images/weixin_huodaxia.jpg
公眾號:有個小院(微信公眾號:yougexiaoyuan)
github:yougexiaoyuan (視頻源碼免費獲取)
(部分素材來源于互聯(lián)網(wǎng),如有保護請聯(lián)系作者)