タイピングゲーム制作記2 | Unityを使った3Dゲームの作り方(かめくめ)

タイピングゲーム制作記2

タイピングゲーム制作記の第2弾になります。

前回から約1年経ってますが・・・・、制作を再開したのはつい最近であまり進んでいないですね。(´Д`)

前回までで問題文を出力し、それをタイピングするというところまで作りました。

Unityで自作のタイピングゲームの進捗をお知らせするページです。なんとかタイピングオブザデッドに近づかせたいなぁ、(´Д`)

あらかじめ作成したローマ字を問題文として出力し、正解した時、失敗した時の処理を作りました。

スポンサーリンク

今回までに作成したもの

今回は前回の記事の最後に書いた入力がどんな方法であっても正解するような処理を作成すると書いたので、その機能を作成してみました。

前回はあらかじめ作成したローマ字の問題文を出力していましたが、そこを「平仮名」→「ローマ字」へと変換することで、あらかじめ固定の入力法のローマ字を出力せず、平仮名からローマ字の変換テーブルを作成し、その法則にしたがってローマ字を作成する機能を作成しました。

変換テーブルは入力法を変えた時に更新し、最新の入力方法で平仮名からローマ字に変換します。

またタイピングが成功したかどうかはその平仮名によって入力方法が複数ある為、どの入力方法でも正解を判別出来るようにしました。

それらの機能について少し言及しておきます。

平仮名からローマ字の作成

平仮名からローマ字を作成する手順はこうしました。

平仮名からローマ字へと変換する法則を変換テーブルとして用意します。

平仮名をキーとし、対応する入力方法をListで作成し、Dictionary型のkeyTableに保持します(上記の変換テーブルは一部だけです)。

上の例で「う」という入力方法は「u」、「wu」、「whu」という入力方法があり、最新の入力方法(タイピングした人の最後の入力法)は「u」なので、「う」をローマ字に変換する時は「u」を出力します。

例えば

「かめくめちゃん」という平仮名からローマ字を作成すると

「か」→「ka」、「め」→「me」、「く」→「ku」、「ちゃ」→「cha」、「ん」→「nn」

と平仮名と対応するローマ字を連結して一つの問題文を作成し、

「kamekumechann」

というローマ字を作成します。

実際の問題文は平仮名の問題文「かめくめちゃん」とローマ字の問題文「kamekumechann」をstring型で持つのではなく、それぞれの平仮名とローマ字に対応するstring型のListを作成し個別に入れておきます。

たとえば平仮名から変換したローマ字は

「ka」「me」「ku」「me」「cha」「nn」

と個別にListに保存します。

なぜこれをしているかというと、例えば「ka」をタイピングする時に「ca」でも入力出来る為、平仮名に対応する入力方法毎に判別する必要があり便利になると思ったからです。

ただ平仮名「きゃ」等は平仮名二文字で一つのキーとする為、変換テーブルの二文字のキーから先に変換し、次に一文字のキー(「か」等)で変換という手順にしました。

変換テーブルの一部例外

単純に変換テーブルを用いれば簡単!と思いきや、平仮名の「っ」や「ん」を変換する時は厄介なことが起きます。

「っ」は「tt」等の続き文字で入力したり「ltu」や「xtu」でも入力出来、「ん」は問題文の途中で現れる時は「n」+「次の平仮名の入力方法」でも入力出来ますが、次の平仮名の入力方法で最初に「n」が来るときは「n」で短縮出来ないというのがあるからです。

例えば「っ」の例を見ていくと、

「きゃっかん」→「kyakkann」、「kyaltukann」等
「くったく」→「kuttaku」等

と同じ「っ」を変換するにも次の平仮名によって出力するべきローマ字が変わります。

「ん」の場合で見ると、

「うんぱん」→「unpann」、「unnpann」等
「しんにん」→「shinnninn」等(shinninnは出来ない)

「shin」の時点でスペースキー等を押して一旦変換したり、ファンクションキー等を押せば変換出来ますが、そういったことまで判定するのはかなり面倒なので排除しました。(^_^;)

叫び等の言葉や記号などについて

叫び声、例えば「きゃぁぁぁ」といった小さい文字が出る場合も平仮名を変換する場合も多少うまく変換出来るようにしましたが、完全に出来たとは言えません。

「はっっっ」みたいに日本語として成立していない場合もある程度変換出来るようにしましたが、こちらも完全とは言えません。

記号については今のところ対応してません(これはまぁ後で出来ると思いますが)。

入力方法をどれにしても正解とする機能

平仮名からローマ字を作成する手順は基本的に最新の入力方法で変換するだけでしたが、入力方法がどれでも正解とする処理はなかなか難しくなりました。

当初考えていたアルゴリズムが破綻してしまった為、行き当たりばったりな処理になった感が否めません。(^_^;)

考え方としては今見ている平仮名のListのローマ字の入力方法と現在までに入力している文字列とが一致していれば正解、当てはまらなければ失敗という処理をします。

例えば「か」「め」という問題文は

「ka」「me」
「ca」「me]

という入力が出来、現在「か」の平仮名のListを入力しているとしたら、「ka」でも「ca」でも正解とします。

その為に今どのListの平仮名を見ているか?その何文字目を見ているか?といった情報を保持しておきます。

例えば「ka」の「a」の入力をしている時は、

indexOfListは0
indexは1
inputOfListは「k」もしくは「c」

となります。

「今まで入力した文字列」と「変換テーブルの入力方法を今まで入力した文字列の数分」比較し、一致したら正解とします。

入力方法を変えた場合は今入力した方法を変換テーブルの先頭に移動させ、それを最新の入力方法とします。

問題文の途中で入力方法を変えた場合、例えば「kamekame」を入力する場合に途中まで

「kame」と「か」を「ka」と入力していて途中から現れる「か」を「ca」と入力した場合は問題のローマ字を変換する時に途中から

「kamecame」

と表示するようにします。

問題文のローマ字をstring型のListで保持しているので、途中の「か」だけを「ca」とする時にも「平仮名」→「ローマ字」へと変換するメソッドでListの途中の「か」だけを「ca」と対応出来るようになっています。

判別が難しい処理

入力方法が変換テーブルにあれば正解とするだけならいいですが、平仮名からローマ字を作成した時と同様に「っ」と「ん」の処理が難しくなってきます。

「っ」の場合は現在見ているListの次の平仮名の入力方法を見なくてはいけないのと「ん」の場合は「n」で短縮し次の平仮名の入力方法の最初のアルファベットをタイピングしても正解と出来るからです。

これらの処理によって処理がだいぶ複雑になっていきました。(^_^;)

全部の入力方法のローマ字を作成し判別する方法もあり?

問題文自体が短ければ全部の入力方法を使った文字列を全部作成し、その文字列と比較する方法も出来るのかな?と思いました。

例えば「かめくめ」という問題であれば、

「kamekume」
「kamecume」
「camekume」
「camecume」

という4つの文字列を変換テーブルから作り、「現在までに入力した文字列」と「問題文の現在までに入力した文字数分」を比較し一致していれば正解、一致しなければ不正解とします。

ただ問題文が長ければ長いほど作成する文字列が増えるので効率は悪くなりそう・・・(´Д`)

「どうしてこうもねむいのかそれがもんだいだ」

という問題分であれば768?この問題文を作成する事になります。

入力法が多い平仮名が多くなる、または問題文自体が長くなればそれだけ作成する文字列も膨れ上がりますね。

StringBuilder等を使えば効率が良くなるかも?

今度試しに作って処理速度を計算してみようかな・・・・( ..)φメモメモ

そもそも入力方法を変えたら正解としない

入力方法を変えて正解にするよりも、入力方法をあらかじめ設定してもらってその入力方法以外は不正解とする処理にすれば、「平仮名」→「ローマ字」という変換処理だけで済むので楽だったかもしれません。

そうするとゲームというよりソフトという意味合いが強くなりそうですけどね。(´Д`)

今回の成果物

今回までに出来たものは、

上のような感じになります。

色々な問題文を作成して、おかしい所がないか調べる必要はありますがとりあえずは出来たという感じです。

動画を作成する時に早速バグを発見し修正しました・・・・。

次回作成するもの

後は伸ばし棒(ー)や数字、記号の問題の処理を入れていないのでそれを入れていけたらと思います。

あ・・・伸ばし棒は既に作ってある模様(謎)

あとは複数の問題文の排他制御を入れる事ですかね。( ..)φメモメモ

タイピングオブザデッドのような複数の問題文が出た時にどの問題からでも入力が出来て、一旦入力したらその問題文以外は入力出来ないような排他的な処理を作成していきたいと思います。

入力を始めてもキャンセルキー(まだどのキーにするか決めていない)を押したらその問題の入力をやめて他の問題文を選べるような処理も入れていく必要もありそうですね。

4回目以降は

今回の記事では同じ問題文が何度も出てきているので、毎回違う問題を表示する機能、それが出来たらタイピングの処理部分が完成し、後は敵の登場等の処理ですね。

タイピングオブザデッドの場合は問題文は常に前面のUIとして表示されてますが、それらを制御するのは難しそうなので、敵の大きさに応じてUIの大きさも変わる(敵がUIを保持)仕様にしよう(*‘∀‘)と思います。

おわりに

今回の機能はある程度出来ましたが、処理の中身はあまり褒められたものではなく分かり辛いです。

わたくしが以前買ったC#の「実戦で役立つ C#プログラミングのイディオム/定石&パターン」

の中で「どうやるか?」ではなく「なにをやるか?」という視点でコードを書くというのがありますが、正にそれ!

今回の機能は「どうやるか?」といった処理のゴリ押しをして作ってしまいました。(^_^;)

いずれリファクタリングをしてわかりやすく「なにをやるか?」の視点のコードに直したいと思います。(-_-)

スポンサーリンク

記事をシェアして頂ける方はこちら

フォローして頂くとやる気が出ます