5秒ちょうどでストップ！HTMLとJavaScriptで作る簡単なゲーム

# 5秒ちょうどでストップ！HTMLとJavaScriptで作る簡単なゲーム

今回は、HTMLとJavaScriptを使って、 **「5秒ちょうどでストップするゲーム」** を作成する方法を紹介します。ゲームのルールはとても簡単です。スタートボタンを押して、5秒ちょうどにストップボタンを押すというシンプルなものです。さらに、プレイ中に経過時間をリアルタイムで表示するモードや、非表示にして目測で5秒を測るモードも用意しました！

## ゲームの概要

1. **スタートボタン**を押すとタイマーが開始。
2. **ストップボタン**を押したタイミングで経過時間を測定。
3. 結果として、5秒との差分が表示されます。
4. 経過時間の表示をリアルタイムでオン/オフできる切り替え機能も実装。

![スクリーンショット 2024-09-17 17.28.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75802/8b3c45b2-c5d4-a841-0c90-bf1c66b3dd95.png)


それでは、実際のプログラムと説明を見ていきましょう。

## 1. HTMLの構成

まず、HTMLでゲームの基本的なレイアウトを作成します。スタートボタンとストップボタン、そして結果や経過時間の表示領域を準備します。

```html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>5秒ストップゲーム</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="container">
        <h1>5秒ストップゲーム</h1>
        <p id="message">5秒ちょうどでストップボタンを押してください！</p>
        
        <!-- 経過時間表示の切り替え -->
        <label>
            <input type="checkbox" id="timeDisplayToggle"> 経過時間表示
        </label>
        
        <div class="buttons">
            <button id="startButton" class="btn">スタート</button>
            <button id="stopButton" class="btn" disabled>ストップ</button>
        </div>
        
        <!-- 経過時間表示領域 -->
        <p id="timerDisplay" class="hidden">経過時間: 0.00秒</p>
        
        <p id="result"></p>
    </div>

    <script src="game.js"></script>
</body>
</html>
```

### 説明：
- **スタートボタン**と**ストップボタン**がプレイヤーの操作を受け付けます。
- **経過時間表示の切り替えスイッチ**で、リアルタイムの経過時間を表示するかどうかを切り替えられます。
- プレイ中の経過時間と結果が画面に表示される領域を用意しています。

## 2. JavaScriptの実装

次に、ゲームのロジックをJavaScriptで実装します。スタート時の時間計測、リアルタイムの経過時間表示、結果の表示などを制御します。

```javascript
let startTime;
let timerId;
let timerDisplayId;
let displayTime = false; // 経過時間表示の状態

// 経過時間表示切り替えのチェックボックスの状態を取得
document.getElementById("timeDisplayToggle").addEventListener("change", function() {
    displayTime = this.checked;
    if (displayTime) {
        document.getElementById("timerDisplay").classList.remove("hidden");
    } else {
        document.getElementById("timerDisplay").classList.add("hidden");
    }
});

document.getElementById("startButton").addEventListener("pointerdown", function() {
    startTime = new Date().getTime();
    document.getElementById("message").textContent = "タイマーが動いています...";
    document.getElementById("startButton").disabled = true;
    document.getElementById("stopButton").disabled = false;
    document.getElementById("result").textContent = ""; // 前回の結果をクリア

    // 経過時間をリアルタイムで更新する
    if (displayTime) {
        timerDisplayId = setInterval(function() {
            let currentTime = new Date().getTime();
            let elapsedTime = ((currentTime - startTime) / 1000).toFixed(2);
            document.getElementById("timerDisplay").textContent = `経過時間: ${elapsedTime}秒`;
        }, 100); // 0.1秒ごとに更新
    }

    // 強制停止用のタイマー（10秒）
    timerId = setTimeout(function() {
        document.getElementById("message").textContent = "時間が経過しました。";
    }, 10000);
});

document.getElementById("stopButton").addEventListener("pointerdown", function() {
    let currentTime = new Date().getTime();
    let elapsedTime = ((currentTime - startTime) / 1000).toFixed(2);
    let difference = (elapsedTime - 5).toFixed(2);
    let resultMessage;
    
    if (difference == 0) {
        resultMessage = `おめでとう！ちょうど5秒です！`;
    } else {
        resultMessage = `差: ${Math.abs(difference)}秒`;
    }

    document.getElementById("result").textContent = resultMessage;
    document.getElementById("message").textContent = "再度挑戦してください！";
    document.getElementById("startButton").disabled = false;
    document.getElementById("stopButton").disabled = true;

    // 経過時間表示の更新を停止
    clearInterval(timerDisplayId);
    clearTimeout(timerId);
});

```

### 説明：
- **スタートボタンを押すと**、スタート時間を記録し、リアルタイムで経過時間を更新します。チェックボックスで経過時間の表示をオンにしている場合のみ表示します。
- **ストップボタンを押すと**、現在の時間とスタート時の時間を比較して、5秒との差を計算し、その結果を表示します。
- **経過時間の表示は0.1秒ごとに更新**され、タイマーが10秒を超えると自動的に停止するようになっています。
- **pointerdownイベントにより、ボタンを押した瞬間にイベントが発火するため、タイミングをより正確に計測できます。

## 3. CSSでデザインをおしゃれに

ゲームの見た目も少しおしゃれにするために、CSSでスタイルを追加します。シンプルながらも柔らかい色合いとボタンのアニメーションを加えることで、プレイヤーに楽しさを感じてもらえるデザインにします。

```css
* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
    font-family: 'Arial', sans-serif;
}

body {
    background-color: #f0f8ff;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
}

.container {
    text-align: center;
    background-color: #ffffff;
    padding: 20px;
    border-radius: 10px;
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
}

h1 {
    font-size: 2em;
    color: #333;
    margin-bottom: 10px;
}

p {
    font-size: 1.2em;
    color: #666;
    margin-bottom: 20px;
}

.buttons {
    margin-bottom: 20px;
}

.btn {
    background-color: #4CAF50;
    color: white;
    padding: 10px 20px;
    font-size: 1.2em;
    border: none;
    border-radius: 5px;
    cursor: pointer;
    margin: 5px;
    transition: background-color 0.3s;
}

.btn:disabled {
    background-color: #ccc;
    cursor: not-allowed;
}

.btn:hover:not(:disabled) {
    background-color: #45a049;
}

#result {
    font-size: 1.5em;
    color: #333;
}

label {
    display: block;
    margin-bottom: 20px;
    font-size: 1.2em;
    color: #333;
}

.hidden {
    display: none;
}

#timerDisplay {
    font-size: 1.2em;
    color: #ff4500;
    margin-bottom: 20px;
}
```

### 説明：
- **全体のレイアウト**を中央に揃え、背景色には柔らかいブルーを採用。
- **ボタン**はホバー時に色が変わるようにし、視覚的なフィードバックを与えます。
- **経過時間の表示部分**は、重要な要素として目立つように色をオレンジで強調しています。

## まとめ
このゲームは、非常にシンプルな構造ですが、プログラミングの基本的なタイミング処理やDOM操作の理解に役立ちます。また、リアルタイムに経過時間を表示する機能や、その切り替えを実装することで、よりインタラクティブなゲーム体験を提供できます。