
前回の記事では、ゲームクリア時にパッと表示される「モーダル(ポップアップ画面)」の演出についてお話しました。
前回の記事はこちら👇
今回の記事では、JavaからJavaScriptへの移植作業中に「難易度ボタンまわり」で起きたバグや、データの保存方法についての気づきをシェアしたいと思います。
🐛 難易度ボタンが反応しないバグ
ゲームを作る上で、ボタンを押したらちゃんと反応してくれるのは基本中の基本ですよね。
でも、最初はこんな問題が起きていました。
❌ 起きていた問題
1️⃣ 難易度ボタンを押してもゲームが始まらない
裏側で答えの数字(answer)が空っぽのままなので、「先に難易度を選んでください」というエラーが出続ける状態でした。2️⃣ 「押した感」がない
ボタンを押しても色が変わらない(.activeクラスが付かない)ので、ユーザーからすると「本当に押せた?」と不安になります。
例えるなら、「横断歩道のボタンを押したのに、カチッとも鳴らないし、信号も変わらない状態」です🚥
✅ 解決方法
これを直すには、難易度ボタンに「クリックされたときのルール(処理)」を追加してあげればOKです!
difficultyButtons.forEach((button) => { button.addEventListener("click", () => { // ① ボタンに設定された最大値(難易度)を取得 const selectedMax = Number(button.dataset.max); // ② ゲーム開始の合図! startGame(selectedMax); // ③ 他のボタンの「選択中」を消して、押したボタンだけを「選択中」にする difficultyButtons.forEach(btn => btn.classList.remove("active")); button.classList.add("active"); }); });
🎯 これでどうなるか?
ボタンを押すと startGame() が走り、答えがセットされてゲームが開始できるようになりました!
「先に選んでください」の警告も無事に消滅します。
🏆 ベストスコア更新!…でも、演出が出ない?
スコアを更新したら、盛大にお祝いしたいですよね🎉
でも、ここで2つ目のバグが発生しました。
❌ 起きていた問題
ベストスコアを更新する処理は書いたのに、「ベストスコアを更新しました!🏆」というモーダル(ポップアップ)が出ない…。
原因は、モーダルを出すための「スイッチの入れ忘れ」でした。
✅ 解決方法
if (...) { bestScores[currentDifficulty] = count; bestText = "ベストスコアを更新しました!🏆"; isBestUpdate = true; // 🔥ココを追加!スイッチON! }
この isBestUpdate = true; が、モーダルを呼び出すためのスイッチです。
これがないと、せっかくの演出が発動しません。
🎨 ボタンが真ん中に寄らない問題(CSS)
デザインを整えているとき、「GitHubのリンクボタン」がどうしても左に寄ってしまい、中央に配置できない問題がありました。
原因は inline-flex という設定です。
これは「中身の分だけ横幅を取る箱」なので、親要素(外側の枠)が「真ん中に寄せてね」と指示を出さないと動いてくれません。
✅ 中央配置のおすすめ3パターン
方法①:親要素で中央寄せ(一番簡単!)
.github-link { text-align: center; }
方法②:Flexboxの力で中央寄せ
.github-link { display: flex; justify-content: center; }
方法③:ボタン自身を中央に配置
.github-link__btn { display: block; margin: 0 auto; width: fit-content; }
💡 ちょい足しデザイン強化
.github-link__btn { backdrop-filter: blur(4px); }
これを足すと、背景がすりガラスのように「ほんのりぼやける」エフェクトがかかります。
北欧ナチュラルなデザインと相性抜群なのでおすすめです!
💾 データを保存しよう!(JavaScript編)
せっかくベストスコアを出しても、画面を閉じたら消えてしまうのは悲しいですよね。
そこで、ブラウザの「魔法のノート」こと localStorage を使います。
やることはたった2つです!
1️⃣ページを開いたときに「ノートを読む」
2️⃣ ベストスコアが出たら「ノートに書き込む」
✅ ① ページ読み込み時にデータを復元
ファイルの上の方にこれを追加します。
// ノートから文字を読み取って、JavaScriptが読める形(オブジェクト)に戻す const savedScores = JSON.parse(localStorage.getItem("numberGameScores")); // もしデータがあれば、今のbestScoresに上書きする if (savedScores) { Object.assign(bestScores, savedScores); }
JSON.parse は、ノートに書かれた「暗号(文字列)」を、JavaScriptの世界の「モノ(オブジェクト)」に翻訳する魔法の言葉です🧙♂️
✅ ② ベスト更新時にデータを保存
ベストスコアを更新する処理の直後に、保存のコードを追加します。
if (bestScores[currentDifficulty] === null || count < bestScores[currentDifficulty]) { bestScores[currentDifficulty] = count; // 🔥ここを追加!(オブジェクトを文字列に翻訳してノートに書き込む) localStorage.setItem("numberGameScores", JSON.stringify(bestScores)); bestText = "ベストスコアを更新しました!🏆"; isBestUpdate = true; }
これで、画面を開いた瞬間に過去のスコアが表示されるようになります!
一気に「ゲームアプリ」っぽくなりました。
☕ おまけ:JavaScriptの「保存」をJavaでやるとどうなる?
JavaScriptには localStorage という便利な魔法のノートがありましたが、実はJavaにはそれがありません。
じゃあJava版ではどうやって保存するの?というと、「本物のテキストファイル(.txt)を作って、そこに直接文字を書き込む」という泥臭い…もとい、本格的な処理を行います📝
Java版の保存イメージ読み込み:
Scannerを使ってテキストファイルを1行ずつ読む
// Javaでの書き込みイメージ(抜粋) static void saveData() { try (java.io.PrintWriter pw = new java.io.PrintWriter("game_data.txt")) { pw.println(playCount); // プレイ回数を書き込む pw.println(lastPlayed); // 最終プレイ日時を書き込む } catch (Exception e) { System.out.println("保存エラー"); } }
プレイ回数や、java.time.LocalDateTime.now() を使って「最終プレイ日時」を保存して画面に表示させると、一気に「作品感」がアップします!
書き込み:
PrintWriterを使ってテキストファイルに文字を書き込む
✍️ まとめ:JavaScriptとJavaの本質的な違い
JavaScript:画面の動きやユーザー体験(UI)を作るのが得意!
Java:データの管理や、裏側の堅牢な設計を作るのが得意!
同じゲームを作ってみることで、それぞれの言語の「得意なこと・苦手なこと」がハッキリ見えてきて面白いですね😊
🎮【Javaの数当てゲームをJavaScriptに移植】シリーズまとめ
Javaのコンソールで動いていた「数当てゲーム」を、ブラウザ上で動く
JavaScriptへと移植(お引っ越し)していく開発の記録です。まずは
Javaでの基本的なゲームの作り方からスタートし、いざJavaScriptへ書き換えた際に直面した思わぬバグやエラー、そしてその解決策までを綴っています。初学者がつまずきやすい「言語の違いによる壁」をどう乗り越えたのか、プログラムと対話しながら進めたリアルな試行錯誤のプロセスをまとめてみました。
【プロフィール・作品置き場】
Javaの学習記録や、ビジュアルノベル風のオリジナルAI楽曲などをポートフォリオで公開しています!