【Phase 2】初めての機能追加:タイピングゲームに入力表示機能を実装

タイピングゲームに新しい機能を追加しました。「どこまで入力したか分かる」表示機能です。自分で設計し、自分で実装した初めての機能追加の記録です。

公開URL: https://dondokoboy.github.io/typing-game/


きっかけ:もっと分かりやすくしたい

現在の問題

既存のタイピングゲーム:

apple
[入力欄: app]

→ 入力した部分が分からない
→ どこまで打ったか視覚的に不明

やりたいこと

app|le
^^^ 青色(入力済み)
   ^^ 黒色(未入力)

[入力欄: app]

入力した部分を青色で表示


設計フェーズ

自分で考えた設計

HTML構造:

  • 新しい <div> 要素を追加
  • <span> 要素で文字を分ける
    • 入力済み文字用
    • 未入力文字用

CSS:

  • 入力済み文字を青色背景に
  • 未入力文字は通常表示

JavaScript:

  • 入力した文字数を計算
  • slice() で文字列を分割
  • DOM操作で表示を更新

AIからのアドバイス

設計の評価: ほぼ完璧
改善提案:

  • id より class の方が柔軟
  • split() より slice() の方がシンプル
  • updateWordDisplay 関数を追加して整理

自分の設計が正しかったことを確認できた。


実装前の準備

バックアップの作成

失敗に備えて、元のファイルをバックアップ:

cp index.html index.html.backup
cp style.css style.css.backup
cp script.js script.js.backup

Git + バックアップで二重の安全策。


実装フェーズ

Step 1: HTML修正

現在:

<p class="word-display" id="wordDisplay">apple</p>

変更後:

<div class="word-display" id="wordDisplay">
  <span class="entered"></span>
  <span class="remained">apple</span>
</div>

変更点:

  • <p><div> に変更
  • 2つの <span> を追加
    • class="entered": 入力済み文字
    • class="remained": 未入力文字

Step 2: CSS追加

ファイルの最後に追加:

/* 入力済み文字のスタイル */
.entered {
  background-color: #3498db;
  color: white;
  padding: 2px 4px;
  border-radius: 4px;
}

/* 未入力文字のスタイル */
.remained {
  color: #333;
}

ポイント:

  • 青色背景で入力済みが分かりやすい
  • 少し丸みをつけて見やすく

Step 3: JavaScript修正

修正1: updateWordDisplay関数を追加

新しい関数:

function updateWordDisplay(word, typedText) {
  const enteredPart = word.slice(0, typedText.length);
  const remainedPart = word.slice(typedText.length);
  
  document.querySelector('.entered').textContent = enteredPart;
  document.querySelector('.remained').textContent = remainedPart;
}

役割:

  • 入力文字数に応じて文字列を分割
  • 入力済み・未入力それぞれを表示

修正2: showRandomWord関数を修正

変更前:

function showRandomWord() {
  const randomIndex = Math.floor(Math.random() * words.length);
  currentWord = words[randomIndex];
  wordDisplay.textContent = currentWord;
}

変更後:

function showRandomWord() {
  const randomIndex = Math.floor(Math.random() * words.length);
  currentWord = words[randomIndex];
  
  // 新しい単語を表示
  document.querySelector('.entered').textContent = '';
  document.querySelector('.remained').textContent = currentWord;
}

変更点:

  • 入力済みは空に
  • 未入力に新しい単語を表示

修正3: checkInput関数を修正

追加した1行:

function checkInput() {
  const typedWord = inputField.value;
  
  // リアルタイムで表示を更新(この行を追加)
  updateWordDisplay(currentWord, typedWord);
  
  if (typedWord === currentWord) {
    // 正解処理
  }
}

効果:

  • 文字を入力するたびに表示が更新される
  • リアルタイムで青色部分が増える

動作確認

テスト結果

表示される単語: apple

入力テスト:

「a」入力 → a|pple(aが青色)
「ap」入力 → ap|ple(apが青色)
「app」入力 → app|le(appが青色)
「appl」入力 → appl|e(applが青色)
「apple」入力 → 正解!次の単語へ

完璧に動作!


新しく使った技術

1. slice()メソッド

文字列の一部を取り出す:

const word = "apple";
const entered = word.slice(0, 3);  // "app"
const remained = word.slice(3);    // "le"

構文:

  • slice(開始位置, 終了位置)
  • 終了位置を省略すると最後まで

2. querySelector()

クラスで要素を取得:

document.querySelector('.entered')

今まで:

  • getElementById(): ID指定

今回:

  • querySelector(): クラス指定(.をつける)

3. 動的なHTML更新

リアルタイムで表示を変更:

// 入力するたびに実行される
inputField.addEventListener('input', checkInput);

function checkInput() {
  // 表示を更新
  updateWordDisplay(currentWord, typedWord);
}

効果:

  • 文字を入力するたびに青色部分が更新される
  • スムーズなユーザー体験

GitHubにプッシュ

成功したのでアップロード

# バックアップファイルを削除
rm index.html.backup style.css.backup script.js.backup

# Gitでコミット
git add .
git commit -m "タイピング表示機能追加:入力済み文字を青色で表示"
git push origin main

GitHub Pagesに反映完了!


開発プロセスの成長

以前の開発フロー

クリックカウンター・タイピングゲーム作成時:

  1. AIが全コードを提示
  2. コピー&ペースト
  3. 動作確認

受動的な学習


今回の開発フロー

タイピングゲーム機能追加:

  1. 自分で設計を考える
  2. AIにアドバイスをもらう
  3. 自分で実装する
  4. 動作確認
  5. GitHubにプッシュ

能動的な開発


初めての「自分で実装」

できたこと

✅ 機能を自分で設計
✅ HTML/CSS/JavaScriptの修正を自分で実行
✅ バックアップの重要性を理解
✅ 段階的な実装(HTML → CSS → JavaScript)
✅ エラーなく成功

「教えてもらう」から「自分で作る」へ、また一歩前進。


難しかったこと

実は、ほとんど詰まらなかった。

理由:

  • 設計が明確だった
  • 段階的に進めた
  • バックアップがあるので安心

設計が良ければ、実装はスムーズ。


Phase 2の成果物(3つ + 機能追加)

作成した作品

作品公開日機能追加
自己紹介ページ3/14写真・進捗追加(3/15)
クリックカウンター3/15
タイピングゲーム3/18入力表示機能(3/22) ← New!

既存作品の改善もできるようになった。


学んだこと

技術面

slice()の便利さ:

  • 文字列を簡単に分割できる
  • 配列にも使える

querySelector()の柔軟性:

  • IDでもクラスでも使える
  • CSSセレクタと同じ書き方

動的更新の仕組み:

  • inputイベントで入力を検知
  • リアルタイムで表示を変更

開発プロセス

設計の重要性:

  • 先に考えることで、実装がスムーズ
  • 設計が明確なら詰まらない

段階的な実装:

  • HTML → CSS → JavaScript
  • 1つずつ確認しながら進める

バックアップの安心感:

  • 失敗を恐れずに実装できる

感想

「自分でできた」という実感

Phase 1: Progateの課題をこなす
Phase 2初期: AIの提示したコードをコピー
Phase 2中期: 自分で設計・実装 ← 今ここ

主体性がどんどん出てきている。


次はもっと複雑な機能に挑戦したい

追加したい機能のアイデア:

  • 制限時間の追加
  • タイプ速度の計算
  • 間違えた文字を赤色で表示
  • 難易度選択

今回成功したから、次も挑戦できる。


次のステップ

選択肢A: さらに機能追加

タイピングゲームをもっと強化:

  • 制限時間
  • スコアの記録
  • ランキング

選択肢B: 新しい作品

  • じゃんけんゲーム
  • 簡単な計算機
  • その他

選択肢C: Reactコース開始

Week 4の予定を前倒し:

  • Progateでの学習
  • フレームワークに挑戦

Phase 2、順調に進んでいます。

「教材に沿う」から「自分で作る」への転換、成功しています。

次は「自分で設計・実装する」段階へ。


コメント