個人開発日記 (Day1〜3)
初めに
初めまして!未経験からエンジニアを目指して奮闘している者です。
今回は、学習のアウトプットとして個人開発日記を毎日書いていたので、その中から独自のタイピングゲームを作り始めた頃の話をまったり書いていこうと思います(日記は既に60日分を超えているので、追いつくのが大変です!笑)。
🌙 完成品🌙
今回の開発で、タイピングゲームのLP(ランディングページ)とゲーム本体が完成しました!
ドメインも購入して気合を入れて公開しています。
🔻 LPサイト
https://criticaltyping.com/
(ドメイン買っちゃいました!なんかめっちゃ嬉しいです笑)
🔻 タイピングゲーム本体
https://typing-game-eta-lime.vercel.app/
演出や機能にかなりこだわって作ったので、もしよろしければプレイしてフィードバックをいただけると嬉しいです!👀
個人開発日記:スタートアップ編
開発のきっかけ・前提
基本情報の取得やJavaScriptの入門書学習が一段落したので、アウトプットもしなきゃなと思い、前から作りたかった独自のタイピングゲームの製作に移ろうと思いました。
📖 参考にした書籍
-
1冊ですべて身につくJavaScript入門講座
Webサイトを作成するにあたって必要な知識が体系的に学べて、かつ分かりやすく書かれているためとてもおすすめです!
※非同期処理や複雑な設計パターン等は、個人開発で実際にいじる作品を作るか、実務経験を積むか、別の実践書を買うといいかもしれません。基礎を固めるのには十分すぎる良書です!
どういうタイピングゲームを作成しようと思ったかについては、こちらの記事をご確認ください!
【一日目】 開発スタート!
基本情報も取得し、入門書も読み終えたので「早速タイピングゲームを作ろう!」と思い、ルンルン気分でファイルを作成しました。
しかし、まっさらなエディタを見た瞬間、絶望しました。
「……さて、こっから何をやればいいのだ????」
頭の中は真っ白。入門書を読んだはずなのに、いざ自分で作ろうとすると全く手が動きません。
そこで「まずは画像を出力させよう!」と思い書き始めましたが、いざ自力で書くとパスの指定すら分からず画像も読み込めない始末…。泣く泣くAIに聞いたり入門書に戻ったりして解決しました💦
正直、初日は「テキストボックスを表示する」ところまでやりたかったのですが、ここで脳みそがパンクしてしまいました。無念なり...
【二日目】 テキストボックスから入力判定まで
2日目は気を取り直して、以下の機能を実装しました。
- テキストボックスの表示
- 仮の単語データの表示
- 入力判定(正解なら緑、ミスなら赤にする処理)
ここでも「少しずつ理解してきた」と思った矢先に、分からないことが10倍に膨れ上がるという現象が発生しました。
テキストを表示するだけでもDOM操作などの知識が必要で、実装が終わる頃には夜遅い時間になっていました。
反省点:
開発初期段階は「分からないこと」や「解決策」を深くメモしていなかったため、めちゃくちゃ後悔してます泣。
分からないことはどんどんAIに聞いて深堀りしつつ、ハルシネーション(簡単に言うとAIが嘘をつく)も起こるので、時々公式ドキュメント等で自分で調べるのも忘れずに!
【三日目】 BackSpace処理
この日は今回のゲームのメインとも言えるBackSpace(文字消去)処理を実装しました。
自分で修正させるというコンセプトもあるためここは死んでも実装させたい処理です😭
ここから「入力分岐」と「BackSpace」を噛み合わせる処理で、しばらく苦戦する日々が続きます💦
自分のBackSpace時の構想はこんな感じでした。(左側)
しかし、実際に処理を落とし込むのがAIを頼ってもすごく難しく、この日も自分の納得いく処理ができるまで粘り、夜遅くに寝ました。
💥 ぶつかった壁と解決策
1. ミスしても緑で表示される(色の管理)
最初は innerHTML を使って直接書き換えていました。
- innerHTML: JavaScriptのプロパティでHTMLの中身を取得・変更できる(力技)。書き方はHTMLと似ていますが、状態管理が難しいので要研究ですね...。あとXSS等のセキュリティのリスクもあるためあまり使わないほうがいいかも
最終的には、以下のように状態を管理する形に修正しました(イメージ)。
// 正解時
this.typedLog.push({ char: expectedChar, color: "#4aff50" }); // 緑
// ミス時
this.typedLog.push({ char: k, color: "#ff4444" }); // 赤
2. BackSpaceで先頭以外を消すと文字がおかしくなる
- 配列方式に変換(スタック)
3. 全文入力後も内部でindex処理されてるため、消すときに見えない文字を消している感じの挙動になる
- ガード処理を追加し入力が終わったら以降入力を受け付けないように
- // 完了チェック(ミスがある場合は拒否する仕様)
※ 当時のコードがないためゲーム部分完成時ののコードになります🙇♂️
function checkCompleted() {
if (!segments.every(s => s.isDone())) return;
const allGreen = segments.every(s =>
s.typedLog.every(t => t.color === "#4aff50")
);
if (allGreen) {
playCorrectSound();
completedWordsCount++;
if (UI.statWords) UI.statWords.textContent = completedWordsCount;
loadRandom();
} else {
// ミスが含まれている:大きく揺らして拒否
resetCombo();
if (UI.wordBox) {
UI.wordBox.classList.remove("error-shake");
void UI.wordBox.offsetWidth;
UI.wordBox.classList.add("error-shake");
setTimeout(() => UI.wordBox.classList.remove("error-shake"), 400);
}
}
}
この日問題が起きたのはこんな感じでした。入力分岐無しでもなかなか思った処理が実装できなくてプログラミング難しすぎってなったけど動いた時感動するのでやめられませんね😂
ここからどんどん変な挙動やエラーの沼に入り、苦戦していく日々が続きますが今日はこの辺にしておきます!
ここまで読んでいただきありがとうございました!