ページ 1 / 1
キャラを動かすってだけのクラス設計
Posted: 2017年6月25日(日) 17:45
by ウーパールーパー山田
「キーボードからの入力で画面のキャラクターを上下左右に動かす」
このような動作をさせたい場合、どのようなクラスが考えられますか?
この文章から見たまま抽出するのであれば「キーボード入力のためのクラス」「キャラクターを管理するクラス」が必要なのかな?と思います。
しかし他のサイトには同じ動作のはずなのに、さらに「画像クラス」「スプライトクラス」「コントローラクラス(?)」などたくさんのクラスが必要だと書いてありました。
まったく意味が分かりません。どれから作り始めればよくて、どれとどれがどんな関係にあるのか、さっぱりでございます。
私にクラス設計の考え方を教えてもらえませんか?
まずは簡単な例を、と思いまして上記の「」内の動作を想定して作りたいです。
オフトピック
C++入門サイトは読み終わっております。が、応用して何かを制作する力はまだありませぬ。
Re: キャラを動かすってだけのクラス設計
Posted: 2017年6月25日(日) 22:46
by purin52002
こんにちは
クラス作成にはセンスが必要らしいです。
そのセンスが足りていない、ということを依然言われたことがあります^p^
センスの足りてない私の意見ですが、
画像ハンドルをメンバ変数に、指定の位置に画像を表示する関数をメンバ関数に持つ「画像クラス」
自身の座標(と向きもいるかな?)をメンバ変数に、指定された方向に指定された長さだけ移動する関数をメンバ関数にもつ「キャラクタークラス」
キャラクタークラスにはメンバ変数として画像クラスを持たせるか、画像クラスを継承させます。
(継承するなら座標は画像クラスに持たせたほうがいいかも?)
メンバ変数として画像クラスを持たせる場合、前方宣言などで余計なインクルードを省略できます。(c++の場合)
画像クラスを継承させる場合は、画像クラスの配列に格納することができるようになるのでまとめて処理ができるようになります。
私個人の意見としましては、メンバ変数として持たせるのがいいかと思います。
(継承させても画像クラスの配列に格納したことが今までなかったため^^;)
入力クラスも実装したら便利なのかもしれませんが、今回のような場合でしたら、クラスにするまでもないとおもいます。
[hr]
というわけで、今回必要なのはキャラクタークラスと画像クラスだとおもいます^^
Re: キャラを動かすってだけのクラス設計
Posted: 2017年6月26日(月) 09:50
by usao
オフトピック
> 「キーボード入力のためのクラス」「キャラクターを管理するクラス」
これらは,【具体的に】何をするのですか? ということをもっと考えてみてはどうでしょうか.
このように何か言葉を列挙すれば,一見物事を決めたように感じられるかもしれませんが,
「~のための」とか「管理する」とかいう言葉では,その役割を全く言えていません.
例えば,
「管理する」と一言で言っている事柄が,より詳細には「AとBとCをする」なのであれば,
実際はそれぞれの仕事をする3つのクラスに分かれるかもしれませんよね.
どこかのサイトに 必要だと書いてあった からといって,それがあなたにも必要かどうかはわかりません.
あなたの作るプログラム に必要な要素を事細やかに列挙して考えてみると良いでしょう.
「キャラクターを動かす」
→キャラクターの座標がデータとして必要そう
→座標データはどこに置かれるのか? 誰がその座標値データを変更する役割を持つのか? 初期値は誰が決めるのか?
→キャラクターを画像で表示したい
→画像データが必要そう
→画像データは誰がいつどうやって用意&破棄するのか? どこに置かれるのか?
→描画処理を担うのは誰か? 画像の描画座標を誰がどうやって決めるのか?
「キーボードからの入力で」
→入力の取得手段は? 誰がいつ入力情報を取得する?
→どんなキー操作でキャラクターがどの方向にどれだけ動くのか を決定するのは誰か?
→どうやって 「キャラクタのーの座標を変更する役割を持つ誰か」に,その移動方向を通達するのか?
こういうことを(好きに)決めれば,結果として,
> どれとどれがどんな関係にあるのか
といったことが決まってくるでしょう.
> どれから作り始めればよくて
については,あまりこだわらなくても良いと思いますが,
「キーボードからの入力で」→「キャラクターが動く」という関係であれば,
前提側である「キーボードの入力」側から作るとわかりやすいかもしれません.
Re: キャラを動かすってだけのクラス設計
Posted: 2017年6月27日(火) 19:25
by ウーパールーパー山田
返信ありがとうございます。
>purinさん
ああっ!そうなんですね!
てっきり画像クラスは継承させて使うものだとばかり思い込んでいたので
メンバ変数として使うとは分かりませんでした。(C++入門者失格かも、、、)
たしかに画像クラスを配列にする状況はあんまり思いつかないかもです。
ちょっと分からないところがあって、
メンバ変数として画像クラスを持たせる場合、前方宣言などで余計なインクルードを省略できます。(c++の場合)
と、ありますがどういう意味ですか?
メンバ変数として画像クラスのポインタを持たせる、という意味でしょうか?
それから、
入力クラスも実装したら便利なのかもしれませんが、今回のような場合でしたら、クラスにするまでもないとおもいます。
と、ありますがクラスに属さない関数というのはアリなのでしょうか?
実は例題のプログラムを考えていて一番迷っているのがここでして、確かにクラスに属さないタダの関数にしてしまえば色々楽なのですが
それはオブジェクト指向的には許されているのかという入門者にしてはちょっと生意気な疑問が湧きまして足踏みしている状態です。
Re: キャラを動かすってだけのクラス設計
Posted: 2017年6月27日(火) 19:26
by ウーパールーパー山田
返信ありがとうございます。
>usaoさん
チャートがすごく分かりやすくて捗ります。
せっかく分かりやすいチャートなので自分の中の考えを整理するために利用させていただきました。
ただ、その中で分からなかったのが
→どんなキー操作でキャラクターがどの方向にどれだけ動くのか を決定するのは誰か?
→どうやって 「キャラクタのーの座標を変更する役割を持つ誰か」に,その移動方向を通達するのか?
キャラクターがどの方向にどれだけ動くのかを決定するのはキャラクタークラス自身ではないのですか?
キャラクタークラスが現在のキーの状態を見るためにキーボードクラスのインターフェースを持っている、という設計を私は想定していました。
……でも実を言うとこの設計はまったく自信がないのでもっと良い設計があればぜひご教授していただきたいのです。
以下、ゲームプログラミングの館からパクってクラス風にしただけの使用予定ソースコードです。
コード:
class CKey : public IKeyGetter{
char KeyBuf[256];
int KeyPushTime[256];
public:
void UpDate();
int Getter(int KeyNumber) override;
};
肝心の例題のプログラムはこれから手を付ける段階なのでこのコードが実際に動作するかはわかりません。
Re: キャラを動かすってだけのクラス設計
Posted: 2017年6月27日(火) 19:40
by usao
オフトピック
>>usaoさん
>
>チャ
はい.(わからん…)
Re: キャラを動かすってだけのクラス設計
Posted: 2017年6月27日(火) 20:20
by ウーパールーパー山田
>usaoさん
ミスったあああ!
(ぼくもわからんです。)編集して修正しておきました。大変失礼しました。
Re: キャラを動かすってだけのクラス設計
Posted: 2017年6月27日(火) 21:14
by usao
> キャラクターがどの方向にどれだけ動くのかを決定するのはキャラクタークラス自身ではないのですか?
「ではないのですか?」 ではなく, 「です!」 と言い切れば,それがその瞬間からあなたの設計です.
あとはそのように作れば良いと思います.
その話だと,
(1)キャラクタークラスからは,何らかの方法によりキーボードクラスのインタフェースへアクセスできる
(2)キャラクタークラスが,キー入力情報を取得しに行く
(3)キャラクタークラスは,「あるキーが押されていたら,自身がどちらの方向にどれだけ動くべき」ということを知っている.
(4)キャラクタークラスは上記仕組みにより(自発的に)に動く
という感じでしょうか.
例えば,私なら
(1)キー入力情報を取得するのは,(キャラクタークラスではない)別の誰か
(2)その誰かが,キーの状態から,キャラクターをどちらの方向にどれだけ動くべきかを決める.
(3)移動方向と移動量がキャラクタークラスに指定される
(4)キャラクタークラスは(自発的にではなく)外から言われたとおりに動く
という別の形を考えるかもしれません.
しかし,どちらが良いか?については,いろんな側面があるでしょうから,
ご自身が良いと思う{好きな,作るのが楽そうな,etc...}方法に決めれば良いかと思います.
Re: キャラを動かすってだけのクラス設計
Posted: 2017年6月27日(火) 22:55
by ウーパールーパー山田
>usaoさん
私の考えなのに私より上手くまとめてくださいました。ありがとうございます。
usaoさんの方法についてですが、一体どういった意図があってそうしているのでしょうか?
(1)の「キーボードクラスとキャラクタークラスの間に誰か仲介人を挟む」というのは
キーコンフィグをしたいときに便利だとか、それに付随して入力デバイスがキーボードじゃなくなったときにメンテしやすいなどの
利点があるのかなーと予想しています。(違ったら教えてください)
それから、(4)のところで
わざわざ「自発的にではなく」と書いてあるということは自発的ではない場合のメリットが何か存在するのか
併せて教えてほしいです。
Re: キャラを動かすってだけのクラス設計
Posted: 2017年6月27日(火) 23:11
by purin52002
前方宣言などでインクルードを省ける、、、という部分ですが、おっしゃる通りメンバ変数にクラスのポインタを持たせることです。
gazou.hファイルに画像クラスの宣言を書いて、
character.hで画像クラスを前方宣言してキャラクタークラスのメンバ変数に画像クラスのポインタを持たせて、
character.cppでgazou.hをインクルードする。
こうすることでgazou.hが変更された場合のリビルド被害が減らせます。
Pimplイディオムなどを使うとメンバ変数をほぼ完全に隠蔽できたりします。
詳しくはググってください^p^
キーボード入力にクラスを使うか使わないかについてなのですが、
今、やむを得ない理由があってオブジェクト指向についての本を読んでいます。
その本では、「オブジェクト指向でプログラムする際、一般的にクラスに属さない普通の関数を作ることはない」と書かれていました。
偉い人が書いた本なのだからきっとクラスに属さない関数を作ることはないのだと思います。
しかし、だからといってすべての関数を無理やりクラスにまとめるのも違うと私は思います。(初心者の意見ですが^^;)
オブジェクト指向というのはプログラミングの手法の一つであって、「オブジェクト指向こそ最強!」というわけではないと思います。
オブジェクト指向を使うと便利になる箇所、普通の関数を使うと楽になる箇所などがきっとあるはず、、、!
つまり何が言いたいかっていうと、適材適所なんじゃないかなあ、ということです。
オブジェクト指向かと思いきや、いきなり普通の関数ばっか出てきてもいいじゃないか、ということです^p^
Re: キャラを動かすってだけのクラス設計
Posted: 2017年6月28日(水) 00:50
by usao
> usaoさんの方法についてですが、一体どういった意図があってそうしているのでしょうか?
> わざわざ「自発的にではなく」と書いてある
操作対象のキャラクターというのは,「操作(命令)されて動くもの」だと思うので
単にそれをそのままの形で考えた,という感じでしょうか.
操作対象のキャラクターを「自発的に動くもの」とした場合,
例えば今後,通れない場所とか,動きが遅くなる場所とか,イベント中には操作入力なしで勝手に動くだとか,その他諸々がやりたくなったときに,
キャラクター自身がそういったことを全て判断せねばならず,
キャラクターが{どこが通れて,どこは動きが遅くなって,今イベント中でどっちに動かないとダメで…}という情報を扱わねばなりません.
(本当にそこまでの役目,責務がキャラクターの内側にあるのだろうか?)
…とかいう「感じ」ですかね.
> 「キーボードクラスとキャラクタークラスの間に誰か仲介人を挟む」
おっしゃるとおりコンフィグ等の話もあるかと思いますが,
どちらかというと上記の事柄によります.
キャラクターが 「キーが押されているから動かなくては」と自分で判断するという形 ではない 別の形を考えたから ですかね.
操作対象のキャラクターは操り人形でしかなく意思を持たない存在だと考えた,ということです.
「キャラクターは自分で判断して動くけれども
キャラクターの脳みそ(意思決定の方法)は誰かが適切なタイミングでとっかえひっかえする」
みたいな別の形も考えられますし,
どんな方法が本当に 実際に作るものに合っているのか は不明ですが,
とにかく 誰が何をするのか を決めれば,
・どんなクラスが必要か
・それらの関係は何か
が定まるのではないでしょうか, というのが最初の質問文に対する私の意見です.
オフトピック
どんな形がよいか? に関しては,何を重要視するか によると思うので,何とも言えません.
個人的には趣味プログラムであれば「もっともやれそうな形」というのに重きをおいて考えます.(自分が作れないと意味無いので)
Re: キャラを動かすってだけのクラス設計
Posted: 2017年6月29日(木) 23:27
by ウーパールーパー山田
御二方、ご返信ありがとうございます。
内容は読ませていただきました。
明日、昼から時間がとれるのでそのときに今までのご指導を踏まえてソースコードを書いてみたいと思います。
手短な返答で申し訳ないです。
Re: キャラを動かすってだけのクラス設計
Posted: 2017年6月29日(木) 23:58
by usao
オフトピック
> ご指導を踏まえて
ちょっと言葉の感じが気になる.
あくまでも{考え,意見}を(好き勝手に)述べているだけであるので,それを
> 指導
と呼ぶのは違う感.
(そこらへんの捉え方を間違えると,行き先が捻じ曲がってしまいかねない気がする)
Re: キャラを動かすってだけのクラス設計
Posted: 2017年7月03日(月) 22:56
by ウーパールーパー山田
>purinさん
Pimplイディオム、初めて聞きました。
確かにこう書けば、ヘッダファイルが簡潔に書けるのとコンパイル時間が短くなりますね!
ヒープを使うのとクラスが増えちゃうのがデメリットって感じでしょうか。
今の私だとクラスがたくさん増えると面倒に見えちゃうんですよね。
もうちょっとうまくクラスを書けるようになりたいです、、、
オブジェクト指向のことで、
実をいうと私、オブジェクト指向を使うと何がどう便利になるのかというのはよくわかっていません。
入門サイトで「こんな機能があって便利である」と言われただけで、まだ実際に使って便利と実感できたわけではないですし。
色々なC言語の入門サイトを読み漁っていると、どのサイトでも大抵最後の方のページに次のステップとしてC++が紹介されているんですよね。
だからpurinさんの言う「オブジェクト指向こそ最強!」的な発想に陥っているのかもしれません。
しっくりくる方法が今後見つかるかは分かりませんが、適材適所という言葉を信じて今回は普通の関数でいくつもりです。
おかげで熱が冷めないうちに作りたいものを作れます。後押ししてくれてありがとうございます。
Re: キャラを動かすってだけのクラス設計
Posted: 2017年7月03日(月) 23:28
by ウーパールーパー山田
>usaoさん
「キーボードからの入力で画面のキャラクターを上下左右に動かす」という最初の例題と並行して
練習として簡易インベーダーゲームをC++で書いています。
(インベーダーゲームに関してはキーボード入力もクラスとして書いています。)
そこでusaoさんに教えていただいた考え方がピタッと一致した感じです。
「player(自機)クラスが外から言われたとおりに動く」という実装にしてkeyboardクラスと離したおかげで
キーボードで動かないenemy(侵略者)クラスやbullet(弾)クラスと同じcharクラスから継承させることができました。
usaoさんの言わんとしていたこととずれてるかもしれませんが、とりあえずパズルのピースがはまった感じで気持ちがいいです。
しかし気持ちよくなった(エクスタシー)だけで、playerを「どんな名前の誰」が動かすのかという根本的な部分が分からないのでもう少し考えてみたいです。
> 指導
と呼ぶのは違う感.
教えていただいている立場なのに指導という言葉はふさわしくなかったと思います。訂正します。
Re: キャラを動かすってだけのクラス設計
Posted: 2017年7月04日(火) 09:36
by usao
オフトピック
> 教えていただいている立場
あまり言葉の雰囲気が変わってないような…?
要するに,
「ある話題に関して 互いに 意見を交換している」だと思うので,
うまく,気軽に(?),内容は取捨選択してほしいし,変なことがあれば「それは違うと思うぜ!」とか言ってほしいという感じです.
(たまに, レスの内容=順守してやらなきゃ! みたく捉えてしまっている感じの方がおられる気がしますが,そうじゃないよねっていうか)
Re: キャラを動かすってだけのクラス設計
Posted: 2017年7月06日(木) 23:42
by inemaru