5年前C++でのリプレイの実装の続きとなっております。続きの場合、どう書いて良いかわからないのでテンプレートを使用させて頂きます。自分が今行いたい事は何かキー入力クラスやゲームパッドクラスの設計をしたい。詳しくは、上のURLを参照して下さい。どのように取り組んだか(プログラムコードがある場合記載)前のトピックにいくつかコードがあります。全て記載するとかなり長くなるので記載しません。載せろ、との場合でしたら記載致します。どのようなエラーやトラブルで困っているか(エラーメッセージが解る場合は記載)良い設計がわからない。今何がわからないのか、知りたいのか適切なキー入力クラス、ゲームパッドクラスなどの設計についてです。・どの程度C言語を理解しているかC++ですが、一年程度勉強しております。理解度等は前のトピックのコードを見て下さればわかると思います。・ライブラリを使っている場合は何を使っているかDxライブラリを使用しています。なにか、不備がありましたらご指摘お願いします。5年前いったんDXライブラリの実装から離れて考えるべきだと思います。ひとつのキーボードを複数のキーボードが重なったものと見なせるように設計する使うキーが異なれば、物理的に複数の装置からの入力と見なす使うキーが同じなら、物理的にすべての装置に入力されたと見なす逆にキーボードとゲームパッドをひとつの入力装置と見なせるように設計する現実のキーボードとスクリーンキーボードをひとつの装置と見なすのも同じといったふうのがわたしの考える装置に対する抽象化です。逆のことを同時にやろうとしているわけですが、入力クラスとコントローラークラスそれぞれの役割を抽象化し組み合わせることで無理のない実装になります。5年前まずは設計をしっかり固めましょうプレイする人数は1人固定なのか複数人対応するのか。それぞれのプレイヤーで使用できる入力装置の種類は。それは一つだけか、複数の入力装置が必要なのか。どのように制御するのか。5年前ISLe()さん、へにっくすさん返信ありがとうございます>ISLe()さん例えばひとつのキーボードを複数のキーボードが重なったものと見なせるように設計する使うキーが異なれば、物理的に複数の装置からの入力と見なす使うキーが同じなら、物理的にすべての装置に入力されたと見なす逆にキーボードとゲームパッドをひとつの入力装置と見なせるように設計する現実のキーボードとスクリーンキーボードをひとつの装置と見なすのも同じといったふうのがわたしの考える装置に対する抽象化です。>キーボードとゲームパッドをひとつの入力装置と見なせるように設計するは、ゲームパッドをキーボードのキーが増えただけ、と解釈しましたが、>ひとつのキーボードを複数のキーボードが重なったものと見なせるようにがまったく想像できません。>へにっくすさんプレイする人数は1人固定なのか複数人対応するのか。それぞれのプレイヤーで使用できる入力装置の種類は。それは一つだけか、複数の入力装置が必要なのか。どのように制御するのか。これをまとめてみては?考えてみましたが、分からない部分があります。キーボードとゲームパッドの二つ(各一つずつ。複数のゲームパッド、キーボードには対応しない。)ここまでは思いつきましたが、>どのように制御するのかがよくわかりません。5年前マルチインスタンスはオブジェクト指向の根本を成すものなんですよね。3D_3Dさんが1人で両手を使って1つのキーボードを使っている3D_3Dさんが2人いて右手と左手それぞれの担当に分かれて1つのキーボードを使っている3D_3Dさんが2人いて右手用のキーボードと左手用のキーボードに分かれてそれぞれ使っているというのはぜんぶ結果としては同じことなんですよ。2人いる3D_3Dさんや2つあるキーボードをそれぞれ別のものとして扱うことができれば、そのままいくつも増やしていけます。想像できますか?キーボードやゲームパッドを上から見てませんか?3D_3Dさんが2人いるとした場合、3D_3Dさんが2人の3D_3Dさんを動かすのではないですよ。2人の3D_3Dさんが途中で入れ替わっても、入れ替わってるところが見えなければ、外からは分からないのです。2人の3D_3Dさんがものすごい速さで入れ替わっていたら、それは重なっていることになります。キーボードの多重化は、参考にしたというJavaのコードで既にやっていることなんですよね。前トピックに書きましたけど、それをコントローラークラスの中で実装してしまっているのが良くなかったんですよね。あの時点ではコントローラークラスの汎用化にまで意識が行ってませんでした。キーリスナーもコントローラークラスではなく、入力クラスそれぞれで登録するのが本来正しいし。>どのように制御するのかがよくわかりません。押されているかどうかを返す、入力フレームを返す、など、ボタンを押されているかどうかで判断するという解釈であっていますか?ほらそこが入力装置にしか意識いってない証拠。それは入力クラスで行えばよいことだと思います。私が言ってるのは、ゲームの進行のために必要な操作、つまりスタートボタン/プレイヤー1のボタン/プレイヤー2のボタン・・・などの割り当てをどうするかを言ってます。前のトピックの(No.28)でゲームパッドとキーボードを自動的に切り替えると記述してましたがそれはコントローラーで行うことではありません。入力クラス内の処理で行うことだと思います。コントローラーはその入力クラスから、知りたいボタンの状態をただ読みとるだけ。ISLeさんも書かれていますが、複数の入力装置だろうが、一つの入力装置だろうが一人だけそのゲームに参加しているのであれば、結果としてゲームの進行を行っている人は一人です。そこのところを区別する必要があります。5年前ISLe()さん、へにっくすさん返信ありがとうございます。>ISLe()さん3D_3Dさんが1人で両手を使って1つのキーボードを使っている3D_3Dさんが2人いて右手と左手それぞれの担当に分かれて1つのキーボードを使っている3D_3Dさんが2人いて右手用のキーボードと左手用のキーボードに分かれてそれぞれ使っているというのはぜんぶ結果としては同じことなんですよ。2人いる3D_3Dさんや2つあるキーボードをそれぞれ別のものとして扱うことができれば、そのままいくつも増やしていけます。想像できますか?キーボードやゲームパッドを上から見てませんか?なんとなくですがイメージできました。うまく言葉にできないので完璧には理解できていないと思いますが、若干は理解できました。キーボードの多重化は、参考にしたというJavaのコードで既にやっていることなんですよね。前トピックに書きましたけど、それをコントローラークラスの中で実装してしまっているのが良くなかったんですよね。あの時点ではコントローラークラスの汎用化にまで意識が行ってませんでした。キーリスナーもコントローラークラスではなく、入力クラスそれぞれで登録するのが本来正しいし。部分は、キーコードは知らなくてもよいですね。キーリスナーとは、Javaのコードのコントローラークラスのコンストラクタ内で行っていることですか?>へにっくすさんほらそこが入力装置にしか意識いってない証拠。それは入力クラスで行えばよいことだと思います。私が言ってるのは、ゲームの進行のために必要な操作、つまりスタートボタン/プレイヤー1のボタン/プレイヤー2のボタン・・・などの割り当てをどうするかを言ってます。前のトピックの(No.28)でゲームパッドとキーボードを自動的に切り替えると記述してましたがそれはコントローラーで行うことではありません。入力クラス内の処理で行うことだと思います。コントローラーはその入力クラスから、知りたいボタンの状態をただ読みとるだけ。こちらも、なんとなくですが理解できました。ここまで真剣にコントローラクラスやキー入力クラスを設計したことがないので四苦八苦していますが、完成出来るように頑張ります。コードが書けましたら、また載せる予定なのでご指導よろしくお願いします。5年前ここ最近とても忙しく、コードを書く時間が全く取れずに返信が遅れてしまいました。忙しいなりに色々考えてみましたが、やはり理解が出来ていないようで、空き時間などを利用してコードを書いてみましたが、ISLe()さんのおっしゃっていたDxライブラリのラッパーにしか見れません。諦めたわけではないですが、正直、思いつく気がしません。これからさらに忙しくなり、返信が更に遅れると思います。なんとしてでも完成はさせます。5年前C++で上手く書けないのでC言語で一度書いてみました。C言語といってもC++の機能を若干使用しています。今までのコードをすべて忘れて書きました。5年前いったんクラスを取っ払いましたね。若干C++使ってますと言われても、もともとDxLib.hをインクルードすると、C言語ではコンパイルできないので許容範囲ですwざっと見ましたが、いちいちビットシフトしてるのが気に入りませんね。WinMainでGetPadState関数で使用する配列csKeyListを持ってきてるのも変です。完全に隠れてませんよ。WinMain側(ゲームメイン側)からは、eKeyTypeのみで判定したいのですよね?ちょっと修正させてもらいました。5年前>へにっくすさん返信ありがとうございます。いちいちビットシフトしてるのが気に入りませんね。WinMainでGetPadState関数で使用する配列csKeyListを持ってきてるのも変です。完全に隠れてませんよ。WinMain側(ゲームメイン側)からは、eKeyTypeのみで判定したいのですよね?ビットシフトがなくなってだいぶ読みやすくなりました。enumってこんな風にも書けるのか、と思いましたが、よく考えたら代入しているものは2の累乗になるから代入出来るのはあたりまえですよね。配列や関数は、わたしの変な癖で、一旦main.cppに全て書いてからファイル分けをしていくスタイルをとっていることが原因です。頭の中では「これは外部からアクセスさせない」とか「これは公開する」など、一通りわかっています。メインからは見えていても使わないようにしているつもりです。配列や関数は、わたしの変な癖で、一旦main.cppに全て書いてからファイル分けをしていくスタイルをとっていることが原因です。頭の中では「これは外部からアクセスさせない」とか「これは公開する」など、一通りわかっています。メインからは見えていても使わないようにしているつもりです。ファイル分割をちゃんとすればいい話ですが...隠すべきcsKeyListをWinMainで使ってたところをみてもちょっと怪しい印象がぬぐえませんが・・・(^^;クラス化、がんばってください。隠すべきcsKeyListをWinMainで使ってたところをみてもちょっと怪しい印象がぬぐえませんが・・・(^^;クラス化、がんばってください。意味で使用していたのですが。#追記GetPadState関数で更新処理と取得処理をまとめて書いてしまいました。C++版は修正してありますので明日以降に投下します。意味で使用していたのですが。No.9のあなたが掲示したコードの61行目から64行目は以下の通りです。条件内にcsKeyList、使ってますよね?No.10の私のコードと混同しないでください。(怒)これでもcsKeyListを使ってなかったと言えるのか。自分の書いたコードを確認もしないで理解していたと書いていても、信用できないですよ?そのことを言ってます。5年前すいません、混同してました。ファイル分割して書き直した際に、ついでに書き直してたのを忘れてました。配列や関数は、わたしの変な癖で、一旦main.cppに全て書いてからファイル分けをしていくスタイルをとっていることが原因です。頭の中では「これは外部からアクセスさせない」とか「これは公開する」など、一通りわかっています。メインからは見えていても使わないようにしているつもりです。5年前コードの確認を怠り、投稿したコードと書きなおしたコードを混同してしまい申し訳ありませんでした。クラス化したものです。ゲームパッドクラス、コントローラークラスも実装してみました。コントローラークラスのGetState関数ではゲームパッドかキーボードのどちらかの入力か関係なく返すようにしました。スマートポインタなど色々使用してますが、これは、C++の他の機能の勉強も兼ねているからで、とくに理由はありません。);}CGamepadInput::~CGamepadInput(){}/**頭の中で考えたことをそのままコードにしました。*リファクタリングも何もしていません。そのうち綺麗にします。参考にされてるJavaのコードで、入力情報をビットにパックしているのは、4方向デジタル入力を前提にしているからなんです...デジタル入力しか扱わない、という前提で話が進んでいるという認識で良いのでしょうか。トピックのタイトルに『設計』とあるのに実装が主体で、前提となる仕様策定がぜんぜん進んでいない気がするのです。あと、いまさらかもしれませんが、コントローラークラスというのは、MVCアーキテクチャでいうところのコントローラーです。入力装置としてのゲームコントローラーではありません。Javaのサンプルコードを投稿したトピックの趣旨がそれなんですけどね。リプレイの話題から派生しているので、プレイヤーキャラのコントローラーで話題は進んでいますが、画面にメニューが出ているとき操作するためのメニューコントローラーとか操作対象(MVCアーキテクチャでいうところのビュー)に応じて特殊化したコントローラーが必要になることでしょう。リプレイのトピックでもコントローラーの派生あたりの話は出ましたが、どのように受け取られているのでしょうかね。5年前>ISLe()さん返信ありがとうございます。参考にされてるJavaのコードで、入力情報をビットにパックしているのは、4方向デジタル入力を前提にしているからなんです...デジタル入力しか扱わない、という前提で話が進んでいるという認識で良いのでしょうか。トピックのタイトルに『設計』とあるのに実装が主体で、前提となる仕様策定がぜんぜん進んでいない気がするのです。考えてしまっていたことが原因です。仕様もよく考えておらず、キーボードとゲームパッドからの入力を受け付ければいいや程度のことしか考えていませんでした。リプレイの話題から派生しているので、プレイヤーキャラのコントローラーで話題は進んでいますが、画面にメニューが出ているとき操作するためのメニューコントローラーとか操作対象(MVCアーキテクチャでいうところのビュー)に応じて特殊化したコントローラーが必要になることでしょう。リプレイのトピックでもコントローラーの派生あたりの話は出ましたが、どのように受け取られているのでしょうかね。メニューが出ている状態のことを全く考えずに、ゲーム内でのプレイヤーのコントローラーだけ考えていましたが、よくよく考えるとメニューやそのほかの部分でも必要になりますね。深く考えていませんでした。リプレイのトピックでも、派生はゲーム内の話だけで、他は無関係だと思っていましたし、考えてもいませんでした。5年前コントローラーはアプリケーションに依存しますから、コントローラーだけで設計を決めるということ自体が難しいのですよね。アプリケーションフレームワークというアプリケーション全体の骨組みを固定する形まで持っていけば可能ですが。インプットクラスは、GetJoypadInputState関数の戻り値に合わせたものでも、XInput準拠のものでも、単独で作ることはできます。それを使うときにはそのまま使えないのは同じことで。GetJoypadInputState関数をそのまま使うよりかはどんなメリットがあるかという点を考えないといけませんね。実際に使っているところを想像してください。想像したものから制作に必要な情報を引き出してください。どれだけ具体的に想像できるかがキモです。さん、返信ありがとうございます。このごろ忙しく、返信が遅れてしまいました。コントローラーはアプリケーションに依存しますから、コントローラーだけで設計を決めるということ自体が難しいのですよね。アプリケーションフレームワークというアプリケーション全体の骨組みを固定する形まで持っていけば可能ですが。フレームワークですか。興味があるので一生のうちに一度は作ってみたいと思っています。関係のない質問ですが、フレームワークとやらはライブラリとは違うのでしょうか?根本的に違うのか、途中までは同じような用途で、使用するタイミングが違うのか、そのあたりの認識があいまいです。インプットクラスは、GetJoypadInputState関数の戻り値に合わせたものでも、XInput準拠のものでも、単独で作ることはできます。それを使うときにはそのまま使えないのは同じことで。GetJoypadInputState関数をそのまま使うよりかはどんなメリットがあるかという点を考えないといけませんね。わたしの語彙力がないため、伝わりにくいかもしれませんが、DxライブラリやXInput?などを意識しないで書けるので、使用するライブラリ等に変更があっても、インプットクラスを変更するだけで済む、でしょうか。5年前フレームワークというのは、コールバックをメインに、あらかじめ決められた手順で使うようにデザインされたライブラリのことです。手順だけを指していう場合もあります。アプリケーションの起動から終了まで扱うものだけを指すように言われますが、それに限ったものではありません。「意識しないで書ける」という表現には具体性が無いですね。語彙力がないというのは免罪符になりません。具体的なメリットを挙げることがいま必要なのですから。これはもはや企画...設計以前の問題です。してそれをやらなければいけないのか、という話です。他のライブラリを使うことになったら、DXライブラリのラッパ関数を作るだけで元からあるコードをまったく変更しなくて済むかもしれません。使用するライブラリを変更できるというメリットはそんなに重要でしょうか。これまで提示されたコードがDXライブラリ以外でも使えるという保証もないですし。5年前ISLe()さん。返信ありがとうございます。何度も返信が遅れてしまい、申し訳ありません。これからも返信が遅れてしまうと思います。「意識しないで書ける」という表現には具体性が無いですね。語彙力がないというのは免罪符になりません。具体的なメリットを挙げることがいま必要なのですから。これはもはや企画...設計以前の問題です。してそれをやらなければいけないのか、という話です。他のライブラリを使うことになったら、DXライブラリのラッパ関数を作るだけで元からあるコードをまったく変更しなくて済むかもしれません。使用するライブラリを変更できるというメリットはそんなに重要でしょうか。これまで提示されたコードがDXライブラリ以外でも使えるという保証もないですし。「キーコンフィグで割り当てるキーを変更しても、実際にプレーたときやリプレイを見るとき、キーの割り振りを知らなくてよい」がメリットだと思います。直接キーの入力状態を取得してしまうと、キーコンフィグを実装したときに面倒なことになると考えました。リプレイを自分なりに作ってみて、直接キーコードをいじると面倒なことになることを実感しました。新しくコードを書いてみました。キー入力クラスと、入力されたキーコードを仮想キーコードに変換するクラス、そしてコントローラクラスです。定義した仮想キーコードを使用したくなかっただけです。問題点などがありましたら教えてください。以前、同じインターフェースを持つオブジェクトをパイプで繋ぐように結び付けることで変換等を実装できるという話をしましたよね。いうかそもそもそのあたりの話からこのトピックに繋がっているのではなかったでしたっけ。コントローラークラスが変換クラスに依存しているので、入力クラスに対する変換クラスが常に必要ですよね。これはどうして必須なのでしょうか。CKeyInputはKEY_INPUT_*を、CGamepadInputはPAD_INPUT_*を直接指定するようになってます。仮想キーコードを使いたくないというだけでCKeyInput/CGamepadInput各単体での存在意義がほとんどありません。CKeyInput/CGamepadInputを無くして、CConvKeyCode/CConvPadCodeに統合すべきかと。いうわけで堂々巡りですね。ゴールを設定してください。ゴールがないまま走っていたら永遠に終わらないですよ。キーコンフィグやリプレイで影響を受けない・与えないというのではなくて、どれだけ既存のコードに手を入れずにそれらを実装できるとか、ここでは逆に実装時のメリットをあげて欲しいところです。あと、ひとつのキーボードで複数プレイヤー対応とか、このトピックで新たに出た課題はまだ後回しということで良いのでしょうか。5年前ISLe()さん、返信ありがとうございます。以前、同じインターフェースを持つオブジェクトをパイプで繋ぐように結び付けることで変換等を実装できるという話をしましたよね。いうかそもそもそのあたりの話からこのトピックに繋がっているのではなかったでしたっけ。コントローラークラスが変換クラスに依存しているので、入力クラスに対する変換クラスが常に必要ですよね。これはどうして必須なのでしょうか。仮想キーコードのみを扱うというのでしっかり分けておこうと考えましたが、よく考えたら必要ないですよね。扱いたくないと思いましたが、結局混ぜてしまうので要らないですね。ゴールを設定してください。ゴールがないまま走っていたら永遠に終わらないですよ。どこをゴールにしてよいかわかりませんが、後で機能を追加しても、機能専用のコードを書かなくてよいようなものをゴールにして頑張ります。あと、ひとつのキーボードで複数プレイヤー対応とか、このトピックで新たに出た課題はまだ後回しということで良いのでしょうか。こちらに時間が回せないので、後回しになります。統合してコードを書いてみました。問題点などがありましたら教えてください。どこをゴールにしてよいかわかりませんが、後で機能を追加しても、機能専用のコードを書かなくてよいようなものをゴールにして頑張ります。したら「後で機能を追加しても、機能専用のコードを書かなくてよ」くなるかを考えて組み立てるのが設計というものですが。試行錯誤と行き当たりばったりは違いますよ。統合してコードを書いてみました。問題点などがありましたら教えてください。No.17あたりとそっくりですね。ゲームパッド対応のコードがなくなった分後退してますかね。時間が巻き戻ったような感じです。ここは無限ループの二周目といったところでしょうか。指摘内容は一周目と同じです。このトピックを最初から読み直してみてください。5年前ゲームの仕様を以下のようにまとめました。入力装置の種類:キーボード、ゲームパッド(各一つだけ対応。複数は対応しない)(現時点で)ゲームの進行に必要なキー(プレイヤーの操作のみ):ショット、ボム、スロー、方向キー(4つ)現時点では、ゲームパッドのアナログ入力は対応しない。今後、対応するとすれば、特定の値以上倒していたら入力があったとみなす。したら「後で機能を追加しても、機能専用のコードを書かなくてよ」くなるかを考えて組み立てるのが設計というものですが。試行錯誤と行き当たりばったりは違いますよ。何を以てゴールにしようか悩んでいます。このトピックに入る前のトピックのリプレイは、もともとC++でリプレイは実装できるのか試してみたいと思い、サンプルとして書き始めたものでした。ゴールを決めていなかったので今痛い目を見ています。以下はソースコードです。http://dixq.net/forum/viewtopic.php?t=8433#p69002のISLeさんの返信を元に書いてみました。コントローラクラスを抽象化しました。キー入力クラスとゲームパッドクラスはそれを継承して、とあるキーが押されたら仮想コントローラーの入力状態を変化させるようにしました。メインで、押されたという証拠の文字の表示に変化をつけたくてキー入力で動くプレイヤーを追加しました。キーテーブルを直接操作していましたが、なんとなく嫌だったので若干修正しました。していたのですが、これもなんとなく嫌なので修正しました。目に付いた個人的に嫌なところは修正しました。これ以外の場所は変化なしです。(ゲーム内では区別するが)両方"決定"に関するボタンである。よって、"決定"に関するボタンが押されたら、区別しないでフラグを立てる。5年前コントローラークラスとインプットクラスを分ける意味は、以前説明したと思うのですが。5年前コントローラークラスはキー入力とゲームパッドクラスの入力を総括するクラスと考えています。コントローラークラスとキー入力クラスは分ける必要がないのでしょうか。完全に混乱しています。キー入力クラスは押されているキーコードから自分で定義した仮想キーコードの入力に変換しているつもりです。}}の部分が変換になると思っていますが、違うのでしょうか?以前に貼ったhttp://dixq.net/forum/viewtopic.php?t=8433#p69002のISLeさんの理想コントローラークラスを継承したクラスでキーボード入力から変換するような実装にすれば、キーボード以外の入力装置に差し替えるのも簡単です。参考に書いたのが最後に載せたコードです。引用した部分での理想コントローラークラスです。リプレイのトピックでキークラスやゲームパッドクラスは、ネイティブな入力を仮想ステータスに変換します。いう部分を「理想ゲームパッドクラスを継承したキークラスやゲームパッドクラス内で、直接の入力があれば、そのキーコードに対応した仮想キーコードが押されたとする」と考え、投稿したコードになりましたが、何がどうだめなのか分かりません。わたしの解釈違いでしょうか?また、メニュー画面、ポーズ画面、ゲーム画面、・・・などの画面ごとのコントローラーはすべて統一してしまおうと考えています。ゲーム画面ではショットに対応するキーはメニュー画面では決定キーにする。同様に、ゲーム画面ではボムに対応するキーはメニュー画面ではキャンセルキーにする。入力装置を総括したいなら、入力装置の範疇でするべきでしょう。コントローラーを巻き込んではいけません。インプットクラスがコントローラークラスに通知するのは、仮想であっても物理的なキーやボタンが押されたという情報です。コントローラークラスがアプリケーションに通知するのは、アプリケーションで定義されるイベントやシグナルです。右へ移動するためのキーやボタンが押された、というのと、プレイヤーを右へ動かす要求がされた、というのは異なるものです。コントローラーは、あくまでもアプリケーション(内のオブジェクト)をコントロールするのが主目的です。AIが制御するコントローラーであれば外部装置の入力を必要としません。コントローラークラスもインプットクラスもCVirtualControllerを継承するようにしてしまいました。aですから、コントローラーもインプットもCVirtualControllerだということです。これは設計として分かれていないですよね。現在のコントローラークラスの実装が入力情報をスルーしているだけのものだから同じものとしてしまっているのではないでしょうか。将来的にも実装で仕様の違いを何とかしよう・何とかできると思っているのではないでしょうか。それが実装でモノを考えているということなのです。理想コントローラークラスと書いたとき、コントローラーとはゲームコントローラー、入力装置のことを想定してました。ゲームパッドではなくゲームコントローラーという呼称のほうが自分の中ではメジャーなもので、気を付けてはいるつもりなのですが、用語の意味が場所によって異なっていることがあるのは申し訳ないです。過去のトピックから読み直してみたのですが、わたしがコントローラークラスに対して総括とか理想とかいう単語を出していますね。その単語だけに集約されて、さらに過去のトピックと混ざって、別のモノに置き換わってしまっている印象です。わたしの投稿には、上記の単語だけでなく、具体的な説明もあるのですが、そちらはまったく意識に残っていないようです。3D_3Dさんに限らず、日本語で説明したことがまったく見向きもされないというのを、以前からしばしば感じていましたが、わたしの文章はわたしが思っている以上にヒドいのかもしれません。前のトピック「C++でのリプレイの実装」に書かれているhttp://dixq.net/forum/viewtopic.php?f=3&t=15513インプット、コントローラー、リプレイについて書いてみました。5年前ISLe()さん、Tatuさん。返信ありがとうございます。>ISLe()さん入力装置を総括したいなら、入力装置の範疇でするべきでしょう。コントローラーを巻き込んではいけません。インプットクラスがコントローラークラスに通知するのは、仮想であっても物理的なキーやボタンが押されたという情報です。コントローラークラスがアプリケーションに通知するのは、アプリケーションで定義されるイベントやシグナルです。右へ移動するためのキーやボタンが押された、というのと、プレイヤーを右へ動かす要求がされた、というのは異なるものです。コントローラーは、あくまでもアプリケーション(内のオブジェクト)をコントロールするのが主目的です。AIが制御するコントローラーであれば外部装置の入力を必要としません。して、わたしは今まで勘違いをしていたかもしれませんし、これも勘違いかもしれませんが、コントローラークラス(ゲームパッドではない方)はインターフェースクラスでしょうか?だとすると、わたしは「コントローラークラスは2つの入力装置からの入力をひとつの入力装置からの入力とみなして、お互いの入力を統合したステータスを返す」ようなものだと思っていました。違うのならば考えなおしてみます。過去のトピックから読み直してみたのですが、わたしがコントローラークラスに対して総括とか理想とかいう単語を出していますね。その単語だけに集約されて、さらに過去のトピックと混ざって、別のモノに置き換わってしまっている印象です。わたしの投稿には、上記の単語だけでなく、具体的な説明もあるのですが、そちらはまったく意識に残っていないようです。このトピック内でコントローラーがどのコントローラーを指すのか分からなくなる時があります。複数の意味を持つコントローラーのせいなのでしょうね。>Tatuさんインプット(キー入力クラス・ゲームパッドクラス)使用されるかどうかを問わず、全てのキー、ボタンの情報(No:16の「ネイティブな入力」)を管理(No:18)ネイティブな入力からステータスへの変換を行う(No:16)キーコンフィグの影響を受ける(No:16)変換されたステータスを渡す機能を持つ(No:16)ステータスの定義はコントローラーで行われている(No:18)コントローラーユーザー操作のステータスを渡す機能を持つ(No:4)インプットから受け取ったステータスの変換・合成を行う(No:16、No:30)リプレイ(No:4)コントローラーを継承ユーザー操作のステータスを渡す機能については記録時は元のコントローラーのステータスを取得・記録し、元のステータスをそのまま要求元に返す再生時は記録を読み出し要求元に返すというようにする前トピックの入力周りの要点をまとめてくださりありがとうございます。今後このトピックを参考にするであろう方々が、いちいち前トピックに飛ばなくても大まかな流れがつかめると思います。5年前このトピックは、良い設計をしたい、という主旨ではなかったのでしょうか。Tatuさんの書いたように、3D_3Dさん自身がまとめることをずっと期待していたのですが。インターフェースかどうかは重要なのでしょうか。まとめも大事ですが、前のスレの話の流れもよく見てください。入力とコントローラーを分離する、という話題の提供から始まっているのです。入力とコントローラーを分離する、というのは大前提なのです。いまは入力装置のコントローラーのことは、ゲームコントローラーと書くようにしています。5年前ISLe()さん、返信ありがとうございます。このトピックは、良い設計をしたい、という主旨ではなかったのでしょうか。Tatuさんの書いたように、3D_3Dさん自身がまとめることをずっと期待していたのですが。あせりすぎていて、すべきことをしていませんでした。あせり、更に混乱すると何をすべきなのか分からなくなる悪い癖です。落ち着いてするべきことを見てみます。インターフェースかどうかは重要なのでしょうか。まとめも大事ですが、前のスレの話の流れもよく見てください。入力とコントローラーを分離する、という話題の提供から始まっているのです。入力とコントローラーを分離する、というのは大前提なのです。インターフェースというのは抽象化するという意味で言ったので深い意味はありません。コードを書いてみました。入力装置基底クラスを継承し、入力をまとめてみました。仮想コントローラークラスを継承し、複数の入力装置からの入力をひとつの入力装置からの入力とみなすようにしました。キー入力で動くプレイヤーのサンプルと適当に動くAIのようなものを作ってみました。考え方はこれであっているでしょうか。5年前CInputDeviceMgrは複数の入力装置からの入力をひとつにまとめてもなお入力装置だと思いますが。3D_3Dさんが何をしたいのか分かりません。あっているかと尋ねられても答えようがありません。ここでDeviceという単語を使うのは個人的にはお勧めしません。「入力装置」としたのが良くなかったでしたかね。「入力」としたほうが良かったか。キーボードに複数の十字キーを割り当てるような場合、それぞれの入力装置クラスでいちいちハードウェアのキーの状態を取得してチェックするのは効率が悪いので、現実においての物理的なハードウェアは一箇所で管理したほうが良い。デバイスドライバの仕様で排他的にしかアクセスできないような場合もありますし。Deviceという単語はそういうハードウェアリソースにアクセスする部分で使うのが良いと思いますが。・キーボード入力クラスやゲームパッド入力クラスで自分で定義した仮想キーコードとDxLib.hで定義されているキーコードの対応表を作ることは良いのか悪いのか。(ゲームパッドで使用している数字は、龍神録プログラミングの館の「キーコンフィグに対応させてみよう」で使用しているような数字です。インスタンスを作成して良いのか。(以前、コントローラークラスでキー入力クラスのインスタンス化はよくないと言っていた気がしましたので。)よくないならどこでインスタンス化すれば良いのか。入力状態の更新をしつつ、自分で定義した仮想キーコードに変換してよいのか。現在のわたしが疑問に思っている点です。わたし自身何がしたいかよくわからなくなっています。落ち着いて何がしたいのかよく考えてみます。ここでDeviceという単語を使うのは個人的にはお勧めしません。「入力装置」としたのが良くなかったでしたかね。「入力」としたほうが良かったか。キーボードに複数の十字キーを割り当てるような場合、それぞれの入力装置クラスでいちいちハードウェアのキーの状態を取得してチェックするのは効率が悪いので、現実においての物理的なハードウェアは一箇所で管理したほうが良い。デバイスドライバの仕様で排他的にしかアクセスできないような場合もありますし。Deviceという単語はそういうハードウェアリソースにアクセスする部分で使うのが良いと思いますが。入力よりは入力装置としたほうが分かりやすいだろう、と考えたことがあだになってしまいました。・キーボード入力クラスやゲームパッド入力クラスで自分で定義した仮想キーコードとDxLib.hで定義されているキーコードの対応表を作ることは良いのか悪いのか。(ゲームパッドで使用している数字は、龍神録プログラミングの館の「キーコンフィグに対応させてみよう」で使用しているような数字です。)入力クラスで完結することなので、好きなように実装すれば良いと思います。入力モジュール間の共通化等考慮してください。インスタンスを作成して良いのか。(以前、コントローラークラスでキー入力クラスのインスタンス化はよくないと言っていた気がしましたので。)よくないならどこでインスタンス化すれば良いのか。それをすると、コントローラーが入力の実装に依存するので、コントローラーと入力の分離という大前提が崩れます。説明したことですが、将来的に、現実に接続される装置と複数プレイヤーへの対応などのマネージメントが必要になります。それはコントローラーの役割ではないので、外部からコントローラーモジュールと入力モジュールのアタッチやデタッチができるように考慮しておくべきです。分離できていれば新たに考慮することはないとも言えます。入力状態の更新をしつつ、自分で定義した仮想キーコードに変換してよいのか。コントローラーに対して必要な出力ができれば、実装はどうでも良いです。動作に癖が出る可能性は否定できませんが。わたしには、どうでもいいことで悩んでいるようにしか見えません。設計して仕様を決めれば、自ずと決まることばかりではないでしょうか。前のトピックから、良い設計ということで、たくさんの要件を出してきました。直前に提示されたコードの問題点を指摘しているだけではないのです。すべてを満たす方法を考えてください。ソースコードのコメントに、そのコードを書く意図を書きましょう。すれば堂々巡りになることは少なくなるのではないでしょうか。5年前usaoさんは読み違えてませんよ。コマンド技とかの複合操作になれば違いははっきりします。前のトピックに出てたダッシュ操作とか。連続押しの場合、入力モジュールからコントローラーモジュールに対しては、歩くボタンが連続で押されたという通知です。コントローラーモジュールからアプリケーションに対しては、『歩け』『走れ』という命令(イベント)が発せられるわけです。『走れ』はアプリケーションに対して必要なイベントであって、イベントコードは必要ですが、ボタンの仮想コードはなくても良いのです。『走るボタン』というものを入力モジュール側とのやり取り用に用意しても構いませんが。オプションでダッシュの連続押し受付時間を変更できるとしたら、プレイヤーモジュールでボタンの状態を判定するとリプレイ時に設定が異なるとダッシュしなかったり暴発したりすることになります。したら、オプションの内容もリプレイに記録するのか、ということになります。イベントを記録すれば、余計なことを考えなくて済みます。コントローラーモジュールまでで解決するので、プレイヤーモジュールは、そもそもコマンド技や複合操作が存在するということすら知らずに済みます。知らずに済むというのはコードが汚染されないということです。ユーザーの操作が正しく反映されるかどうか、という部分と、画面のキャラクターが正しく振る舞うかどうか、という部分を分離独立してコーディング・デバッグできるわけです。5年前コントローラーはMVCアーキテクチャのCのことです。プレイヤーコントローラー以外に、メニューコントローラーなど場面(ビュー)ごとに対応するコントローラーは必要になります。複数切り替えるだけでなく、コントローラーの共通インターフェースで数珠つなぎにして拡張することもできます。これらの説明は既出です。設計が主旨であるはずのトピックで、要件定義すらされないのが問題だと思うのです。それを回答者がやってしまったら丸投げ、というか設計を軽く見ることを助長すると思うのです。GUIプログラミングを知っていたら『コントローラー』という単語だけで全部理解できるかとも思うのですがデザインパターン然り実際のところ単語を知っているだけでは何も通じないのかもしれません。返信ありがとうございます。返信が遅れてしまって申し訳ありません。設計が主旨であるはずのトピックで、要件定義すらされないのが問題だと思うのです。それを回答者がやってしまったら丸投げ、というか設計を軽く見ることを助長すると思うのです。要件定義は、たとえばコード:・キーボードとゲームパッドの入力は統合するのようなものでしょうか。今まで特に考えずにやってきたのでこの程度でよいのか、根本的に違うのか、全く分かりません。それをすると、コントローラーが入力の実装に依存するので、コントローラーと入力の分離という大前提が崩れます。説明したことですが、将来的に、現実に接続される装置と複数プレイヤーへの対応などのマネージメントが必要になります。それはコントローラーの役割ではないので、外部からコントローラーモジュールと入力モジュールのアタッチやデタッチができるように考慮しておくべきです。分離できていれば新たに考慮することはないとも言えます。「外部からコントローラーモジュールと入力モジュールのアタッチやデタッチができるように考慮しておくべきです。「キーボードとゲームパッドの入力は統合する」というのは、それをするために必要な事柄を表していません。「キーボードとゲームパッドの入力は統合したい」というところが本当だと思いますがそれは『要求』です。要件定義とは、要求に合わせて行うものです。要件定義を行うためには、要求をまとめなければいけません。要求をまとめることを、企画と呼ぶ場合もあります。要求があいまいということは、何がやりたいのか分かっていない、ということです。要件定義は、要求を実現するために必要そうなことを洗い出してまとめることです。実装に違い部分もありますが、矛盾がないかどうかといったところを論理的に検討する作業です。設計についての書籍やネットの記事、補助ツールなどたくさんあります。調べてみてはいかがでしょうか。「外部からコントローラーモジュールと入力モジュールのアタッチやデタッチができるように考慮しておくべきです。」の部分ですが、コントローラークラスでインスタンス化しないとなると、どこで入力装置からの入力を取得すれば良いのでしょうか?メインでインスタンス化して、引数に渡す、といった感じでしょうか?これまで何回も書いてますが、コントローラークラスのコントローラーというのは入力装置のことではありません。現実の周辺機器は環境依存のものなので、それを管理するモジュールは当然分離されるべきです。コントローラーは常に抽象化された対象を扱います。新たにゲームパッドが接続されたことを検出するのは、いままで話題になっていない第三のモジュールです。その装置に対応するインプットモジュールを具体化し、コントローラーモジュールにアタッチします。コントローラーモジュールは、新たにアタッチされたインプットモジュールを一定のルールでオブジェクトの操作に割り当てます。どのプレイヤーの操作に割り当てるか指定してアタッチする形態もあるでしょう。これまで話題にならなかったのは必要なかったからですね。コントローラーの中で具体化するのは適当でないということだけは書きましたけど。必要ないといっても、やらなくて良いこと、あるいはやってはいけないことをやってしまうのは後に面倒を残すだけです。予測で手を付けるな、というYAGNIの原則というのがありますが、備えておかなくても良いとは言ってないと思います。返信ありがとうございます。要求があいまいということは、何がやりたいのか分かっていない、ということです。小さいサンプルで書いていたものなので、やりたいことがあやふやというのもあり、手間取りました。直接のキーコードは自分で定義した仮想キーコードに変換する。複数の入力装置は、ひとつの入力装置からの入力とみなす。