【ウディタ講座】自作システム:自作ウィンドウでの入力受付~マウス&キーボード両対応~

過去2回にわたり、自作システムのパーツの話をしてきました。

https://donichi-game.com/howto-gage/

https://donichi-game.com/howto-scrollbar/

ですが……

ふつうは「ピクチャを描画し、入力を検知したら選択肢カーソルが動いて……」という基礎から触れるべきところでしたね。

こんな感じの。

ウディタの入門書でだいたい把握できる内容なのですが、この記事では、キーボードとマウス、どちらの入力にも対応できる組み立て方をしてみましょう。

なお、ウディタはデフォルトでゲームパッドにも連動しています。キーボード対応をふつうにこなせば、パッドでもしっかり動いてくれるはず。

下準備として

この項目はとばして、「自作ウィンドウの基本的な流れ」からはじめても大丈夫です。

使うボタンは少ないほうが良い

はじめに決まり事を確認しておくと、組み立て時に迷いません。

今回は、マウスとキーボードどちらでも同じように動く自作ウィンドウを作ります。なので、使うキーはテンキー(十字キー)と決定ボタン(Z)、取消ボタン(X)に限ってしまいます。

マウスでは左クリック、右クリック、ホイールですね。

 

なぜかと言えば、PCのキーボードはボタンが多いからって、むやみに使えるキーを増やすのは作るほうにとっても、遊ぶほうにとっても大変なことです。

ネトゲに多い、WASDで移動してマウスで対象を選んでクリックで行動して道具や装備の換装は登録ショートカットで……というのは、よほどおもしろいゲームでもない限り、敷居が高すぎる操作系統です。

PCゲームであれ、TVゲームの基本とおなじく「十字キーとA/Bボタン」がメインで、それ以外のボタンはどうしても必要なものにだけ割り当てるのが良いでしょう。

デバッグ用のキーチェックコモン

デバッグやテストプレイGIFでの確認に便利そうなので、こんなコモンを用意してみました。

<SQUARE>で簡単に偽のパッドとマウスの画像を出して、入力があったら、画面上の対応位置が点灯してくれます。

注意点としては、「キー入力」コマンドは、1キーに対して1コマンド(変数)を使うということ。こうしておかないと同時に複数キー入力があっても、最初に入力したキーしか光りません。

 

自作ウィンドウの基本的な流れ

では、やっていきましょう。

基本的な流れは次の通りです。

ループ
 【画像の更新】選択中の選択肢(カーソル)を点灯させる
 【キー入力受付】カーソル移動や選択肢の決定を行う
 【ウェイト:1フレーム】緑帯(50万エラー)を避けるため
ループここまで

キー入力を待って、選択中の選択肢の位置(なんというのか)を変更。それに合わせて表示(ピクチャの状態)を切り替える……というのを、ウィンドウが閉じられる(キャンセル入力など)まで繰り返すのですね。

 

今回はマウス対応のため、「マウスカーソルが合っている選択肢(画像)をセレクト中とする」仕様としました。どちらかというとメインはマウスでプレイするゲームのやり方ですね。

 

というわけで、上のフロー(やることリスト)に赤字の処理が加わります。

ループ
 【画像の更新】選択中の選択肢(カーソル)を点灯させる
 【キー入力受付】カーソル移動や選択肢の決定を行う
 【セレクト位置位置】マウスオーバー(オンカーソル)判定
 【ウェイト:1フレーム】緑帯(50万エラー)を避けるため
ループここまで

これをウディタで組み立てると、こんな感じ。

 

では、それぞれ説明していきましょう。

描画

 

・ウィンドウに必要な画像を表示(初回描画以外は瞬間表示)
・オンカーソル中=セレクト中の画像は赤く光らせる(色調変化)
・2回目以降の描画で、オンカーソル位置が変わらないなら、即中断

最初にウィンドウを表示するときは、瞬間表示では味気ないですね。

ただのフェードインでもちょっとゆっくり描画する方がよさげなので、初回描画かどうか判定をし、描画時のフレーム数を変数で調整しています(2回目以降はセレクト位置を光らせるだけなので、フレーム数=0の瞬間表示)。

 

さて、この仕様だと、1フレームごとにウィンドウ関係の画像が常に再描画され続けています。

瞬間表示なので見た目は一緒ですが、扇風機の羽のような状態です。常にPCに仕事をさせているわけですから、「2回目以降の描画で、オンカーソル位置が変わらないなら、即中断」という分岐を足して、適度に休みをあげましょう。

 

オンカーソル検知

選択肢の個数ぶんの回数ループをし、選択肢ウィンドウの画像ひとつひとつに「この画像はマウスカーソルと重なっているか」をチェックします。

重なっているものがあれば、そこで処理を終了。

重なっている画像が無いままループが終われば、結果は「-1」。どこにもオンカーソルしていないことを意味します。

 

この結果が、おおもとのフローである「サンプル」コモンに返り、「サンプル」コモンから「┣描画」へ受け渡されて、画面の更新(選択位置の点灯)が行われます。

 

キー受付

複雑そうに見えますが、やっていることはシンプルです。

・キーボード入力があればその結果を返す
・キーボード入力がなく、マウス入力がある場合、次のようにする
 ・左クリックをZボタン扱い
 ・右クリックをXボタン扱い
 ・上下ホイールを上下テンキー扱い
ちなみに、変数+で取得したホイールの変化量は、-1なら下回転、+1なら上回転となっています。

カーソル移動

基本は、入力キーの上下方向に合わせてオンカーソルのピクチャ番号をプラマイ1すること。

これだけですね。

上方向ならピクチャ番号に「-1」が加算されるので、選択肢2オンカーソル中なら、選択肢1へ飛びます。

選択肢1オンカーソル中の場合、存在しない「選択肢0」行きになってしまうので、この場合は逆ハジとなる一番下の選択肢3行きと変えると便利ですね。選択肢3から下へ行く場合も同様です。

これを「循環」と言ったりするようです。コモンの下の方でやっていますね。

 

また、選択中=オンカーソル中の画像を変えるコモンなので、この中でマウスカーソルの移動も行っています。

ジャンプしたい画像の番号がわかっていれば、これは簡単。

変数+でピクチャの座標を取得し、システム変数71,72のマウス位置(カーソル座標)へ代入すればOKです。

一瞬でカーソルが飛ぶと見失いやすくもなるので、手をかけたい場合は現在のカーソル位置からジャンプ先のカーソル位置まで、ゆるやかに変化するコモンを組んでもよいでしょう。

座標(0,10)から(90,4)へ飛ぶとして、1フレームごとに座標を(+30,-2)する処理を3回繰り返すイメージです。

 

できあがり

 

コメントはお気軽にどうぞ!