トップページ > 記事閲覧
タッチパネルの反応
名前:platypus 日時: 2016/04/14 22:19

いつもDxLibを使わせてもらっています、platypusと申します。 タッチパネルを使う音楽ゲームを開発しているのですが、 10点タッチに対応しているSurface Pro 4で 複数(大体8本以上)の指を使って高速で連打すると、 2重反応やラグのようなものが発生しました。 関数リファレンス上のGetTouchInputNumのサンプルソースも 試してみたのですが、同様の現象が発生します。 ハードウェアの仕様かと思い、 連打を要求しないゲーム設計で我慢していたのですが、 先日Windows 10に標準で搭載されているペイントソフトで 高速連打を試したところ、ラグが全くなかったため、 少なくとも原因はコンピューターにないことがわかりました。 以上から、DxLibまたはDxLibが依存しているWindows関連のプログラムに ラグの原因があるのではと踏んでいます。 できればこの現象を修正していただけると幸いです。 最後に、蛇足かと思いますが、 各タップの座標・長押しされたフレーム数・IDを printfDxで出力するソースコードを載せたいと思います。 #define APPENDをコメントアウトすると関数レファレンスの サンプルソースと同じ動作をします。 #include "DxLib.h" #include <map> //追加プログラムを動作させたい場合はAPPENDを#defineしてください #define APPEND //タップデータを管理する構造体 //x,y=座標 frame=タッチされたフレーム数 struct Tap { int x, y,frame; Tap() = default; Tap(int x_, int y_, int frame_) { x = x_; y = y_; frame = frame_; } Tap(Tap&) = default; }; // プログラムは WinMain から始まります int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { //タップデータの集合 std::map<int, Tap>tap; if (DxLib_Init() == -1) // DXライブラリ初期化処理 { return -1; // エラーが起きたら直ちに終了 } // メインループ while (ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == FALSE) { // 画面のクリア ClearDrawScreen(); clsDx(); #ifdef APPEND //タップデータの一時的な保管場所 std::map<int, Tap> temp_tap; // タッチされている箇所の数だけ繰り返し for (int i = 0; i < GetTouchInputNum(); i++) { int PosX, PosY, ID; // タッチされている箇所の座標を取得 GetTouchInput(i, &PosX, &PosY, &ID, NULL); //全フレームのタッチデータの中からタッチIDを探す if (tap.find(ID) == tap.end()) { //見つからない; /* std::pair<const int, Tap> temp_p(ID, Tap(PosX, PosY, 1)); tap.insert(temp_p); */ temp_tap[ID] = Tap(PosX,PosY,1); } else { //見つかる temp_tap[ID] = Tap(PosX,PosY,tap[ID].frame+1); } } //データを反映 tap = std::move(temp_tap); for (auto& t_ : tap) { auto& t = t_.second; // タッチされている箇所の座標に円を描画 DrawCircle(t.x, t.y, 40, GetColor(255, 255, 255), TRUE); //タッチ個所の座標、タッチされたフレーム数、タッチIDを表示 printfDx("%d %d %d ID:%d\n", t.x, t.y, t.frame, t_.first); } #else int PosX, PosY; // タッチされている箇所の数だけ繰り返し for (int i = 0; i < GetTouchInputNum(); i++) { // タッチされている箇所の座標を取得 GetTouchInput(i, &PosX, &PosY, NULL, NULL); // タッチされている箇所の座標に円を描画 DrawCircle(PosX, PosY, 40, GetColor(255, 255, 255), TRUE); } #endif // 裏画面の内容を表画面に反映 ScreenFlip(); } DxLib_End(); // DXライブラリ使用の終了処理 return 0; // ソフトの終了 } よろしくお願いします。
メンテ

Page: 1 |

Re: タッチパネルの反応 ( No.1 )
名前:たろう 日時:2016/04/17 13:34

もしかすると・・・全指で画面をバタバタしまくると動作が恐ろしく遅くなって、 ソフトを終了してもPCをシャットダウンするまでモッサリが治らなくなる症状でしょうか?
メンテ
Re: タッチパネルの反応 ( No.2 )
名前:platypus 日時:2016/04/17 14:01

たろう さん、 >動作が恐ろしく遅くなって、 あくまで、タッチパネルを叩いてからそれが反映されるまで 恐ろしいほどのラグが発生するだけであり、 他の処理(僕の音楽ゲームの場合、音符の移動や表示など) は通常通りに実行されます。 >ソフトを終了してもPCをシャットダウンするまでモッサリが治らなくなる症状 特にそのような症状は確認されていません。 ただ、購入したばかりのPCのためソフトを余り入れていない状態なので、 モッサリが露骨に出ていないだけなのかもしれません。 以上のように、僕の場合はたろうさんの仰った症状から外れているのですが、 その症状にはどのような解決法が存在するのですか?
メンテ
Re: タッチパネルの反応 ( No.3 )
名前:たろう 日時:2016/04/17 14:15

例えば指を一本画面においてキープしたまま、他の指でバタバタしまくって、一分くらい続けると スーパーもっさりになりませんか?その状態になると一旦指をはなしても、その後指を置くだけで またモッサリになるというのが私の場合の症状です。 症状が違うようなので、もっと良い解決策があると思いますが、 一応私のケースでの解決法は・・・ DxLib_Init()のあとでUnregisterTouchWindow(GetMainWindowHandle())でタッチ対応を解除して ウィンドウズ8以降でのみ使えるWM_POINTER〜でタッチ入力を受け取るようにするというものです。 ウィンドウズタブレットはwin7のものも有りますが、ほとんど普及していないと思うので、 タッチ対応は8以降だけでも問題ないと思います。 あとはwin7でもタッチ操作非対応で使えるように、WM_POINTER関連の関数をdllにして GetOsVersion();でosが6.2以上かどうかを確認した上で関数ポインタで受け取るようにします。
メンテ
Re: タッチパネルの反応 ( No.4 )
名前:platypus 日時:2016/04/17 14:35

たろう さん、 >例えば指を一本画面においてキープしたまま、 あくまでタップの反応がすごく遅いだけであり、 アプリを終了した後は特に変化は有りませんでした。 >一応私のケースでの解決法は・・・ どうしてもほかの解決策が見つからない場合は たろうさんの方法を採用しようと思います。 ただ、僕自身余りWindowsのイベントなどの プログラミングに慣れてないため、 極力DxLibのみでゲーム製作を行いたいと思っています。 管理人様に現象を確認して頂き、 可能であれば修正をして頂ければこれ以上は望みません。 これは単なる疑問なのですが、 GetTouchInput関連の関数はたろうさんがおっしゃっている WM_POINTER関連の関数(?)以外の手法で実装されているのでしょうか?
メンテ
Re: タッチパネルの反応 ( No.5 )
名前:たろう 日時:2016/04/17 14:50

UnregisterTouchWindowで解除出来たので、たぶんWM_TOUCH系を受け取っていると思いますが すみません知識が足りずよく分かりません。詳しい方を待ちましょう^^;
メンテ
Re: タッチパネルの反応 ( No.6 )
名前:管理人 日時:2016/04/18 00:31

すみません、作業時間が確保できなくてまだ手元で何も確認できていないのですが ( それを除いても手元には Surface Pro 3 しかないので現象の確認は出来ないかもしれませんが ) DXライブラリは大量のウインドウメッセージが来た場合にフレーム落ちの原因とならないように 一度の ProcessMessage 関数呼び出して処理するウインドウメッセージの数をかなり制限しているのですが、 もしかしたらそれが原因でタッチメッセージの受け取りに遅延が発生しているのかもしれません なので、とりあえず一度の ProcessMessage で処理するウインドウメッセージの数の制限を撤廃した バージョンをアップしてみましたので、よろしければこちらでも遅延が発生してしまうかお試しください m(_ _;m https://dxlib.xsrv.jp/temp/DxLibVCTest.exe // VisualC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCCTest.exe // BorlandC++ 用 https://dxlib.xsrv.jp/temp/DxLibGCC_DevCppTest.exe // Dev-C++ 用 https://dxlib.xsrv.jp/temp/DxLibGCC_MinGWTest.exe // MinGW 用 https://dxlib.xsrv.jp/temp/DxLibDotNet.zip // .NET用 https://dxlib.xsrv.jp/temp/DxLibMakeTest.exe // ソース (中身を既存のライブラリのファイルに上書きして、BCCをお使いの 場合は『再構築』を、VCをお使いの場合は『リビルド』を、 Dev-C++をお使いの方は「Rebuild All(Ctrl+F11)」をして下さい) この変更でも症状に変化がありませんでしたら、たろうさんご提案の WM_POINTER を使用した実装を 試してみたいと思います
メンテ
Re: タッチパネルの反応 ( No.7 )
名前:platypus(解決) 日時:2016/04/18 19:02

管理人様、 改善されたバージョンのDxLibを使い、 Visual Studioでビルドしてみたところ、 問題なくタップの座標が読み込めていました。 遅延も全くなく、快適に遊べるようになりました。 たろうさん、WM_POINTERの提案ありがとうございました。 勉強不足で今回は管理人さんに頼る形になりましたが、 機会があったら勉強してみたいと思います。 ところで、僕の問題自体はこれで解決となったのですが、 次のDxLibのバージョンアップにはProcessMessageのウインドウメッセージの 処理数の上限を撤廃するのでしょうか? フレーム落ちという立派な理由があって上限を付けたわけですし、 簡単に変えるものではないように見えるのですが、 もしそのままにしたバージョンが上がった場合は 再度提示版にて相談してもいいでしょうか? スレッドはこれで解決とします。
メンテ
Re: タッチパネルの反応 ( No.8 )
名前:管理人(解決) 日時:2016/04/24 02:37

> 次のDxLibのバージョンアップにはProcessMessageのウインドウメッセージの > 処理数の上限を撤廃するのでしょうか? はい、そうしようと思います メッセージの処理数に制限を加えた当時よりもPCの性能はずっと上がっていますので 制限を加えることによる処理落ち確率低下の効果は少なくなったと思いますし、 何よりタッチパネルの反応が悪くなるというデメリットが大きすぎますので…
メンテ
Re: タッチパネルの反応 ( No.9 )
名前:platypus(解決) 日時:2016/04/24 16:00

対応ありがとうございました。 これで安心してゲーム作りに勤しむことができます。
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存