實作2-2

楓資 廖姸惁

目錄

程式碼

<!DOCTYPE html>
<html lang="zh-Hant">
<head>
<meta charset="UTF-8">
<title>鍵盤反應遊戲 Ultimate</title>
<link rel="stylesheet" href="style.css">
</head>

<body>

<div id="score">分數:0</div>
<div id="highscore">最高分:0</div>
<div id="timer">時間:30</div>

<div id="game"></div>

<div id="gameover">遊戲結束</div>
<button onclick="restartGame()">再玩一次</button>

<script src="main.js"></script>
<link rel="stylesheet" href= "main.css">
</body>
</html>
body {
  margin: 0;
  overflow: hidden;
  background: #020617;
  color: white;
  font-family: Arial;
}

#game {
  position: relative;
  width: 100vw;
  height: 100vh;
}

.letter {
  position: absolute;
  font-size: 40px;
  color: #22c55e;
  text-shadow: 0 0 10px #22c55e;
  animation: fall linear forwards;
}

@keyframes fall {
  from { top: -50px; }
  to { top: 100vh; }
}

#score, #timer, #highscore {
  position: fixed;
  top: 20px;
  font-size: 30px;
}

#score { left: 20px; }
#highscore { left: 180px; }
#timer { right: 20px; }

#gameover {
  position: fixed;
  display: none;
  color: #3589ce;
  text-shadow: 0 0 10px #7e9cd4;
  top: 35%;
  width: 100%;
  text-align: center;
  font-size: 50px;
  font-weight: bolder;
}

button {
  position: fixed;
  top: 55%;
  left: 50%;
  transform: translateX(-50%);
  padding: 12px 25px;
  font-size: 18px;
  border: none;
  border-radius: 10px;
  background: #4b8fe7;
  cursor: pointer;
  display: none;
}

button:hover {
  background: #3381e7;
}
<div class="sl-block" data-block-type="code" data-name="Code 2" style="width: 438.889px; height: 300px; left: 366.389px; top: 210px;" data-origin-id="9ddf29d6f0f8"><div class="sl-block-content notranslate" data-highlight-theme="monokai" data-code-frame="none" style="z-index: 13;"><pre style="font-size: 16px; line-height: 19px; tab-size: 4;"><code data-line-numbers="">body {
  margin: 0;
  overflow: hidden;
  background: #020617;
  color: white;
  font-family: Arial;
}

#game {
  position: relative;
  width: 100vw;
  height: 100vh;
}

.letter {
  position: absolute;
  font-size: 40px;
  color: #22c55e;
  text-shadow: 0 0 10px #22c55e;
  animation: fall linear forwards;
}

@keyframes fall {
  from { top: -50px; }
  to { top: 100vh; }
}

#score, #timer, #highscore {
  position: fixed;
  top: 20px;
  font-size: 30px;
}

#score { left: 20px; }
#highscore { left: 180px; }
#timer { right: 20px; }

#gameover {
  position: fixed;
  display: none;
  color: #3589ce;
  text-shadow: 0 0 10px #7e9cd4;
  top: 35%;
  width: 100%;
  text-align: center;
  font-size: 50px;
  font-weight: bolder;
}

button {
  position: fixed;
  top: 55%;
  left: 50%;
  transform: translateX(-50%);
  padding: 12px 25px;
  font-size: 18px;
  border: none;
  border-radius: 10px;
  background: #4b8fe7;
  cursor: pointer;
  display: none;
}

button:hover {
  background: #3381e7;
}</code></pre><div class="editing-ui sl-block-content-preview visible-in-preview"><pre style="font-size: 16px; line-height: 19px; tab-size: 4;"><code data-line-numbers="" class="hljs css"><table class="hljs-ln"><tbody><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-selector-tag">body</span> {</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="3"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-attribute">overflow</span>: hidden;</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="4"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-attribute">background</span>: <span class="hljs-number">#020617</span>;</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="5"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-attribute">color</span>: white;</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="6"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-attribute">font-family</span>: Arial;</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="7"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">}</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="8"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line"> </div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="9"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-selector-id">#game</span> {</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="10"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-attribute">position</span>: relative;</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="11"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-attribute">width</span>: <span class="hljs-number">100vw</span>;</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="12"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-attribute">height</span>: <span class="hljs-number">100vh</span>;</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="13"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">}</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="14"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line"> </div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="15"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-selector-class">.letter</span> {</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="16"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-attribute">position</span>: absolute;</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="17"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">40px</span>;</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="18"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-attribute">color</span>: <span class="hljs-number">#22c55e</span>;</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="19"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-attribute">text-shadow</span>: <span class="hljs-number">0</span> <span class="hljs-number">0</span> <span class="hljs-number">10px</span> <span class="hljs-number">#22c55e</span>;</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="20"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-attribute">animation</span>: fall linear forwards;</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="21"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">}</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="22"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line"> </div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="23"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">@keyframes</span> fall {</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="24"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-selector-tag">from</span> { <span class="hljs-attribute">top</span>: -<span class="hljs-number">50px</span>; }</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="25"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-selector-tag">to</span> { <span class="hljs-attribute">top</span>: <span class="hljs-number">100vh</span>; }</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="26"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">}</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="27"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line"> </div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="28"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-selector-id">#score</span>, <span class="hljs-selector-id">#timer</span>, <span class="hljs-selector-id">#highscore</span> {</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="29"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-attribute">position</span>: fixed;</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="30"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-attribute">top</span>: <span class="hljs-number">20px</span>;</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="31"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">30px</span>;</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="32"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">}</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="33"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line"> </div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="34"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-selector-id">#score</span> { <span class="hljs-attribute">left</span>: <span class="hljs-number">20px</span>; }</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="35"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-selector-id">#highscore</span> { <span class="hljs-attribute">left</span>: <span class="hljs-number">180px</span>; }</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="36"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-selector-id">#timer</span> { <span class="hljs-attribute">right</span>: <span class="hljs-number">20px</span>; }</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="37"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line"> </div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="38"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-selector-id">#gameover</span> {</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="39"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-attribute">position</span>: fixed;</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="40"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-attribute">display</span>: none;</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="41"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-attribute">color</span>: <span class="hljs-number">#3589ce</span>;</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="42"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-attribute">text-shadow</span>: <span class="hljs-number">0</span> <span class="hljs-number">0</span> <span class="hljs-number">10px</span> <span class="hljs-number">#7e9cd4</span>;</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="43"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-attribute">top</span>: <span class="hljs-number">35%</span>;</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="44"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-attribute">width</span>: <span class="hljs-number">100%</span>;</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="45"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-attribute">text-align</span>: center;</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="46"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">50px</span>;</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="47"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-attribute">font-weight</span>: bolder;</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="48"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">}</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="49"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line"> </div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="50"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-selector-tag">button</span> {</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="51"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-attribute">position</span>: fixed;</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="52"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-attribute">top</span>: <span class="hljs-number">55%</span>;</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="53"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-attribute">left</span>: <span class="hljs-number">50%</span>;</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="54"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-attribute">transform</span>: <span class="hljs-built_in">translateX</span>(-<span class="hljs-number">50%</span>);</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="55"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-attribute">padding</span>: <span class="hljs-number">12px</span> <span class="hljs-number">25px</span>;</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="56"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-attribute">font-size</span>: <span class="hljs-number">18px</span>;</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="57"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-attribute">border</span>: none;</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="58"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">10px</span>;</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="59"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-attribute">background</span>: <span class="hljs-number">#4b8fe7</span>;</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="60"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-attribute">cursor</span>: pointer;</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="61"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-attribute">display</span>: none;</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="62"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">}</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="63"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line"> </div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="64"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-selector-tag">button</span><span class="hljs-selector-pseudo">:hover</span> {</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="65"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">  <span class="hljs-attribute">background</span>: <span class="hljs-number">#3381e7</span>;</div></td></tr><tr><td class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="66"></div></td><td class="hljs-ln-code"><div class="hljs-ln-line">}</div></td></tr></tbody></table></code></pre></div></div></div>

html

css

js

字母會掉下來

js

let div = document.createElement("div");

JS建立字母

div.className = "letter";
div.innerText = letter;
div.style.left = Math.random() * 90 + "vw";
game.appendChild(div);

JS

加上 class

放入字母

隨機位置

放進畫面

js

@keyframes fall {
  from { top: -50px; }
  to { top: 100vh; }
}

css

from是起點

to是終點

animation: fall linear forwards;

套用動畫

動畫名稱

等速

結束停在最後

按對才消失

JS

document.addEventListener("keydown", function(e) {

取得按鍵

let key = e.key.toUpperCase();
if (activeLetters[i].letter === key)

如果按的鍵跟字母一樣

從畫面刪除

加分

偵測鍵盤按下

game.removeChild(activeLetters[i].el);
score++;

沒按到會扣分

JS

幾秒後執行

setTimeout(() => {

如果字母還存在就代表玩家沒按到

if (game.contains(div))
score--;

所以

30秒結束

JS

每秒執行一次

timerLoop = setInterval(() => {

倒數

更新畫面

time--;
document.getElementById("timer").innerText =

時間到

停止計時器

if (time <= 0)
clearInterval(gameLoop);
clearInterval(timerLoop);

最高分

JS

從瀏覽器記憶資料儲存資料

localStorage.getItem("highscore")

存最高分

localStorage.setItem("highscore", highscore);

即使重整網頁都還在

再玩一次

JS

重設變數

score = 0;
time = 30;

清空畫面

game.innerHTML = "";

再開始

startGame();

預告之後課程

實作2-2

By ys

實作2-2

  • 38