Open yumetodo opened 7 years ago
メッセージはSAVEDATA_LOAD()
関数から出ている。これが呼ばれるのはGAMEMENU_CHOICE()
, SHORTCUT_KEY()
, TITLE_MENU_CHOICE()
関数からで、概ねいずれも
//ロード
if (GAME_y == (game_menu_base_pos_y * 2) && CheckHitKey(KEY_INPUT_RETURN) == 1 || GAME_y == (game_menu_base_pos_y * 2) && ((GetMouseInput() & MOUSE_INPUT_LEFT) != 0)) {
//セーブデータロード処理
SAVEDATA_LOAD();
WaitTimer(300);
}
のようなコードである。
つまり、「戻りますか?」で「はい」にカーソルを合わせ、Enterを押したときの判定が残っているため、と考えられる。
キー判定が残っていることの対策は戻る前にキー判定がすべて消えるのを待つことになるが、コードが煩雑になるため、できれば #21 のアプローチでfixしたい。
以前、開発途中で同じ現象に遭遇したことがあります。
カーソルの位置とEnterでのメニュー選択をしていたことによって、メッセージボックスでのEnter入力をメニュー画面のキー判定と認識して処理していたことが原因でした。
その時は、WaitTimer()
を使用して、処理をストップさせてキー入力が行われないように処理しましたね。
おそらく、他なメッセージを呼び出しているものでも同様のケースが考えられますね。
ちなみに、確認した限りでは、ゲームメニュー関連は問題ありませんでした。
が、タイトルでEscapeキーでのゲーム終了メッセージでも同様の現象が確認されました。
マストドンの方で気になっていたので見てみました。 マウス操作の場合は左クリックの「ダウン→アップ」という2操作で次の状態に進みますが、キー操作の場合「ダウン」という1操作で次の状態に進んでいて、これが次の状態でも効いてしまっているようです(キーを押した指が上がっていない)。 キー操作でも「ダウン→アップ」の2操作を要するようにすればユーザの操作を拾いやすくなるのかな、と思いました。
加えて、TITLE_MENU_CHOICEの中でSAVEDATA_LOAD_LOOPが回っているようなので、
とした方が良いのでは、と思いました。
ゲームのwhileはひとつにする
これはコードが管理不能になってしまうので避けたいです。状態が分離していません。ループの中から別のループに行ってしまうのは問題ですが
左クリックの「ダウン→アップ」という2操作で次の状態に進みますが
これはどういうことでしょうか?離されたことを検知するような機能をDxLib::GetMouseInput()
は有していないはずなので押下しているかのみを拾っているはずです
左クリックの「ダウン→アップ」という2操作で次の状態に進みますが
これはどういうことでしょうか?
正確には、MessageBoxYesNoに対する操作が、マウスでは「ダウン→アップ」の「アップ」時に効いてるのに対して、キーでは「ダウン」時に効いているという事です。
マウスでは「ダウン→アップ」の「アップ」時に効いてるのに対して
えっ、DxLib::GetMouseInput()
ってそういう挙動するんですか・・・?
いや、ちょっと違うようですね……
DxLib::GetMouseInput()
自体は、クリックされた段階(ダウン時)のみを判定しているようです。
ref:http://dxlib.o.oo7.jp/function/dxfunc_input.html#R5N8(`GetMouseInput()`の項目参照)
実際に、LINKS ver 3.20で動作確認しましたが、wakinさんが仰られている
「ダウン→アップ」の「アップ」時に効いている
という挙動は確認されています。
恐らく、メッセージボックスを表示させている関数 MessageBox()
が原因じゃないかと思うのですが……
メッセージボックスはDxLibの範疇にないし、こちらから制御のしようもないわけですが(そのくせキー判定が暫く残る)、メッセージボックス上での挙動の話です・・・?
恐らくは、それ臭いんですよねぇ……
たぶん、MessageBox()
上ではマウスの場合は「ダウン→アップ」という挙動で、キー操作の場合「ダウンのみ」なのかも……?
メッセージボックス上のことを言っているのでしたらそのとおりですが、その挙動にDxLib側で合わせても問題の解決にはならないし、 #28 を超えるコード量が必要になるので、何を言いたいんだろう感
28 を超えるコード量
というのは、実質.NETのWindowsFromにあるようなkeyeventとかボタンのイベントをだいたい実装しないと実現できないという意味です
それは……結構な量ですね……
あと、wakin さんとしては、「キー操作も、キーを離したときを拾うようにすればよいのでは?」と意見を述べられたかったのだと思います。
それは……結構な量ですね……
むしろGUIライブラリ作るような作業。
「キー操作も、キーを離したときを拾うようにすればよいのでは?」
メッセージボックスの挙動に干渉できる方法があるならぜひ実装してコードを投げていただきたい。
ふうむ…
とりあえずは、yumetodoさんのKeyStateクラスを使っていく方向しかないですね
なんかあれを作っていると、結局ノベルゲーに必要だったのはゲームライブラリじゃなくてGUIライブラリなんじゃないかと切実に感じる(WPFとか!)
確かに確かに…
そういう意味では、GUIでノベルゲームが作れるティラノビルダーとかLight.vnとかはどうやってるのやら…
WindowsFormとかWPFとかWin32GUIアプリからMessageBox呼んでもこの手の問題が起きないのは、DxLibがDirectInput/XInput という低レイヤを直接見に行っていて、Win32が内部的に持っているバッファを無視しているからだろうなぁ
それが、こういった形で表に出てきたわけですなぁ……
高速化のためのコラテラル・ダメージ
再現手順
6でマウスや
N
キーを押した場合は無限ループしないが、そもそも「ロード画面に移行しますか?」がでるのがおかしい。