javascript ゲーム

JavaScriptでタイピング練習ゲームを作成しよう!

概要

この記事では、ブラウザで動作するタイピング練習ゲームを作成する方法について詳しく説明します。このゲームでは、日本語とそのローマ字表記を使ってタイピングの練習ができます。ゲームは10問出題し、正確にローマ字を入力することで得点が加算されます。ゲーム終了後、エンターキーを押すことで再スタートが可能です。下記の画像をクリックするとプレイできます。※PC,MACのブラウザのみ

https://chemtoollab.com/game/type/index.html

上記はサーバーを使用した、webでのみ動きましたが、ローカルで動くpython版は下記になります。

使用例

このタイピングゲームは、日本語とそのローマ字表記を使ってタイピングの練習ができます。JSONファイルから単語を読み込み、10問のタイピング問題を出題します。正しく入力するとスコアが加算され、間違えるとスコアが減点されます。ゲーム終了後、エンターキーを押すことで再スタートすることができます。

必要なソフトウェアとインストール方法

このプロジェクトを実行するために必要なソフトウェアとそのインストール方法は以下の通りです。

必要なソフトウェア

  • テキストエディタ(例:VSCode、Sublime Text)
  • Webブラウザ(例:Google Chrome、Firefox)

インストール方法

特別なインストールは不要です。HTML、CSS、JavaScriptのファイルを用意し、Webブラウザで開くだけで実行できます。

使用手順

  1. ファイルを準備する
    • 以下の4つのファイルを作成します。
      • index.html
      • style.css
      • script.js
      • word.json
  2. コードをコピーする
    • 下記のコードをメモ帳などに丸々コピーしてそれぞれファイル名を指定してください。

index.html

htmlコードをコピーする<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>タイピング練習ゲーム</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div class="container">
        <h1>タイピング練習ゲーム</h1>
        <div id="title-screen">
            <p>ゲームを始める前に、入力モードが半角英数字になっていることを確認してください。</p>
            <button id="start-button">ゲームを開始</button>
        </div>
        <div id="game-screen" style="display: none;">
            <div id="word-container">
                <div id="japanese-word"></div>
                <div id="romaji-word"></div>
            </div>
            <input type="text" id="input-field" autofocus>
            <div id="score">スコア: 0</div>
            <div id="progress">1/10</div>
            <div id="timer">タイマー: 0 秒</div>
            <button id="restart-button" style="display: none;">再スタート</button>
        </div>
    </div>
    <script src="script.js"></script>
</body>
</html>

style.css

cssコードをコピーするbody {
    font-family: Arial, sans-serif;
    text-align: center;
    background-color: #f0f0f0;
    margin: 0;
    padding: 0;
}

.container {
    width: 80%;
    max-width: 600px;
    margin: 50px auto;
    padding: 20px;
    background-color: #ffffff;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

h1 {
    margin-bottom: 20px;
}

#word-container {
    margin: 20px 0;
}

#japanese-word {
    font-size: 24px;
    margin-bottom: 10px;
}

#romaji-word {
    font-size: 20px;
    color: #555;
}

#input-field {
    width: 100%;
    padding: 10px;
    font-size: 18px;
}

#score, #progress, #timer {
    margin: 10px 0;
}

#restart-button {
    padding: 10px 20px;
    font-size: 16px;
    cursor: pointer;
}

#start-button {
    padding: 10px 20px;
    font-size: 18px;
    cursor: pointer;
}

script.js

javascriptコードをコピーするlet words = [];
let currentWordIndex = 0;
let score = 0;
let timer = 0;
let timerInterval;
const totalRounds = 10;

const japaneseWordElement = document.getElementById('japanese-word');
const romajiWordElement = document.getElementById('romaji-word');
const inputField = document.getElementById('input-field');
const scoreElement = document.getElementById('score');
const progressElement = document.getElementById('progress');
const timerElement = document.getElementById('timer');
const restartButton = document.getElementById('restart-button');
const startButton = document.getElementById('start-button');
const titleScreen = document.getElementById('title-screen');
const gameScreen = document.getElementById('game-screen');

async function loadWords() {
    const response = await fetch('word.json');
    const data = await response.json();
    if (data.words.length < totalRounds) {
        alert('ファイル内の単語が不足しています。');
        return;
    }
    words = data.words.sort(() => 0.5 - Math.random()).slice(0, totalRounds);
    startGame();
}

function startGame() {
    titleScreen.style.display = 'none';
    gameScreen.style.display = 'block';
    currentWordIndex = 0;
    score = 0;
    timer = 0;
    inputField.value = '';
    inputField.disabled = false;
    restartButton.style.display = 'none';
    updateScore();
    updateProgress();
    updateTimer();
    startTimer();
    nextWord();
}

function startTimer() {
    timerInterval = setInterval(() => {
        timer++;
        updateTimer();
    }, 1000);
}

function stopTimer() {
    clearInterval(timerInterval);
}

function updateScore() {
    scoreElement.textContent = `スコア: ${score}`;
}

function updateProgress() {
    progressElement.textContent = `${Math.min(currentWordIndex + 1, totalRounds)}/${totalRounds}`;
}

function updateTimer() {
    timerElement.textContent = `タイマー: ${timer} 秒`;
}

function nextWord() {
    if (currentWordIndex >= totalRounds) {
        endGame();
        return;
    }
    const wordPair = words[currentWordIndex];
    japaneseWordElement.textContent = wordPair.japanese;
    romajiWordElement.textContent = wordPair.romaji;
    inputField.value = '';
    inputField.focus();
}

function checkInput() {
    const userInput = inputField.value.trim();
    const currentWord = words[currentWordIndex].romaji;

    if (currentWord.startsWith(userInput)) {
        if (userInput === currentWord) {
            score += 10;
            currentWordIndex++;
            updateScore();
            if (currentWordIndex < totalRounds) {
                updateProgress();
                nextWord();
            } else {
                endGame();
            }
        } else {
            romajiWordElement.textContent = currentWord.slice(userInput.length);
        }
    } else {
        score -= 5;
        updateScore();
        inputField.value = userInput.slice(0, -1);
    }
}

function endGame() {
    stopTimer();
    updateProgress();  // Ensure progress is updated to 10/10
    japaneseWordElement.textContent = 'ゲーム終了';
    romajiWordElement.textContent = '';
    inputField.disabled = true;
    restartButton.style.display = 'block';
}

inputField.addEventListener('input', checkInput);
restartButton.addEventListener('click', loadWords);
startButton.addEventListener('click', loadWords);
window.addEventListener('keydown', (event) => {
    if (event.key === 'Enter' && restartButton.style.display === 'block') {
        loadWords();
    }
});

word.json

以下はサンプルのword.jsonです。10個以上のペアを用意してください。

{
"words": [
{"japanese": "りんご", "romaji": "ringo"},
{"japanese": "ばなな", "romaji": "banana"},
{"japanese": "さくらんぼ", "romaji": "sakuranbo"},
{"japanese": "なし", "romaji": "nashi"},
{"japanese": "ぶどう", "romaji": "budou"},
{"japanese": "みかん", "romaji": "mikan"},
{"japanese": "いちご", "romaji": "ichigo"},
{"japanese": "すいか", "romaji": "suika"},
{"japanese": "もも", "romaji": "momo"},
{"japanese": "めろん", "romaji": "meron"}
]
}

注意点

  • JSONファイルには10個以上の日本語とローマ字のペアが含まれている必要があります。
  • JSONファイルのフォーマットが正しくない場合、エラーメッセージが表示されます。
  • ゲーム中に表示されるローマ字を正確に入力することで、1文字ずつ表示が消えていきます。
  • ゲームを始める前に、入力モードが半角英数字になっていることを確認してください。
  • ローカルではうまくいかなかったので、レンタルサーバーなどにアップロードして使用してください。

まとめ

このHTML5とJavaScriptを使ったタイピング練習ゲームを使用することで、楽しくタイピングスキルを向上させることができます。JSONファイルから日本語とローマ字のペアを読み込み、10問のタイピング問題を出題します。ゲーム終了後、エンターキーを押すことで再スタートすることができるので、繰り返し練習が可能です。

-javascript, ゲーム