初めに
始めまして、エンジニアを目指して奮闘してる者です!
今日はタイピングゲーム制作日記をのほほんとお届けできたらなと思います!
投稿頻度はまちまちですがまったり投稿していきます!
四日目
この日実装した処理は特殊キー無効化と全部緑で正解したら次の単語へまでを実装しました。
この日はそこまで苦戦しませんでしたが、同時に問題点もあり改善しようと思ったのですが、夜遅くなったため撤退えらい自分
実装した地点のコード
// ほかのイベントリスナーの遮断、
e.stopImmediatePropagation();
// 特殊キーや変換キーは無視
if (["Shift", "Alt", "Meta", "Control", "Tab", "CapsLock"].includes(e.key)) return;
if (["Process", "KanaMode", "Conversion", "NonConvert"].includes(e.code)) {
e.preventDefault(); // ここで意図しないゲーム中断の挙動を防いでいる
return;
}
// ------------------------------------------------------------------------------------
// 全て緑色(ミスなし)かチェック
const allGreen = segments.every(s =>
s.typedLog.every(t => t.color === "#4aff50")
);
if (allGreen) {
loadRandom();
} else {
return;
}
この時は何も気にしないで動けばいいや状態だったのでこれでよかったのですが今見たら
特殊キー等を順番に見ているため
// 無効化キーの配列を定数化しておく
// 定数ファイルを作っておくと将来機能変更に強くなる
const DISABLED_KEYS = new Set(["Shift", "Alt", "Meta", "Control", "Tab", "CapsLock"]);
// 順番に見るのではなく一発で指定
if (DISABLED_KEYS.has(e.key)) {
e.preventDefault(); // 略してるが変換キーの抑制
return;
}
// -----------------------------------------------------------------------------------
// 上記だとネストが深いため緑じゃなかったら抜けるガード節
if(!allGreen) return;
// 次の単語へ
loadrandom();
でもよさそう
今はなるべく自力でコード書いて理解を深めたり可読性等の考慮の勉強をしている(今でも覚えても山ほど課題が降ってくるので正解が分からない面白い)ので昔のコード見てるとやばいなんだこれってなりますね(笑)
知識は少しでも持つことは大事ですね反省...
忘れかけてたため📝
e.stopImmediatePropagation();
- 他のリスナーへの遮断: document に対して他にもキーイベントのリスナー(例えばライブラリや拡張機能が設定したもの)があったとしても、この関数が実行された瞬間にそれらをすべて無視させます。
- 前に置く理由は他のイベントリスナーの処理による二重発火を防ぐためです。後ろに置いてしまうとreturnしたらイベントリスナー自体が終わってしまうので他のイベントリスナーは動いてしまい、予期せぬ副作用が起きます。
- 強力だがバグが出た時に修正しづらくなる時があるので使いどころは慎重に
stopPropagation()
- 親要素にイベントが伝わるのを阻止する(バブリング) ほかのイベントリスナーは止めない。
ここ想像がついたけど挙動の理解がかなり難しかったのでたとえ話出来るようにしとかないといけない...
preventDefault()
- これは変換キー(IME)の抑制:
"Process", "KanaMode"...などのガードは、日本語入力がオンになっている時にブラウザの変換ウィンドウが出て、ゲームが中断されるのを防いでいます。ゲーム側は英字を受け取ろうとしてますが、Windows側は日本語を入力してると誤解して仮の入力欄を出してしまう。
それが原因で入力ウィンドウが出てる間は入力権利を奪われてしまい、入力不能になる
※ なんかコード書くだけでなくリクエストだったりブラウザの細かい仕様を理解するの案外大事かもしれない
Backspaceの挙動抑制
-
Backspaceを押した時にブラウザが「前のページに戻る」挙動をしたり、意図しない場所を削除したりするのを防ぎ、ゲーム内の削除処理だけに集中させています。 -
この日の問題点
- !と?の入力でundefiledが呼ばれてしまう。
- shift押すと赤文字になってしまう。入力判定の定義が必要だなと感じた。
五日目
- この日の実装した処理
- お題の追加
- 昨日の単語判定を関数化(allGreen)
- 、。!?を対応する処理
この日はまあまあ進めてた
お題の追加まあこれは簡単ですね
オブジェクトにして書くだけなので(最終的にDB管理になりますが!
const WORDS = [
{ jp: "エンジニア", roma: "enjinia"}
// 略
];
昨日の!?と句読点処理
// 関数の一部
function handlekey (k) {
if (nextChar === "、" && k === ",") k = "、";
if (nextChar === "。" && k === '.') k = '。';
// 変数が二重人格起こして動かないコードおそらくここで迷ってたのかな
if (nextChar === "!") {
if(k === "shift" && k === "1") key = "!"
}
結局これで解決(この辞書を使って別の関数で判定処理等出来るようにする)
const KEY_MAP = {
// 沢山のローマ字
"?": ["?"], "?": ["?"], "!": ["!"]
};
この日は自分で確認したがバグはなく安心して寝た
入門書読んだだけで全然分からないけど出来ないなりに試行錯誤して処理を実装していきました。次の日以降入力分岐で頭を抱える日が続きますがまた次の機会に
終わりに
いきなりゲームは作るもんじゃない!でも 構想通りのタイピングゲームは完成させてやる! ってのがモチベで突っ走ってました(笑)
今は自力で頑張ってアニメーションを書く訓練をしてますがコードの説明がある程度出来るようになっても引数どう渡すっけ?とか基本の処理忘れた文法と書き方忘れた教えてみたいなのは全然あります。難しいけど自分で組み立てられたときはマジで感動するので沼にハマってますね。
まだ覚えることが多くて大変ですが作るのは大好きなのでどんどん実力上げて難しいことも出来るよう精進してまいります!
ここまで読んでいただきありがとうございました!