質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.36%
Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

デザインパターン

デザインパターンは、ソフトウェアのデザインでよく起きる問題に対して、解決策をノウハウとして蓄積し再利用出来るようにした設計パターンを指します。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

2604閲覧

StateパターンでContextクラスを継承するときの設計について

yukisyuki

総合スコア1

Visual C++

Microsoft Visual C++はWindowsのCとC++の統合開発環境(IDE)であり、コンパイラやデバッガを含んでいます。

デザインパターン

デザインパターンは、ソフトウェアのデザインでよく起きる問題に対して、解決策をノウハウとして蓄積し再利用出来るようにした設計パターンを指します。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/11/03 10:05

編集2020/11/03 10:15

前提・実現したいこと

現在デザインパターンの勉強としてStateパターンを使ってゲームを作っています。
StateパターンのContextをCharacterとし、Stateという抽象クラス(インターフェイス)を作って。そこからidle,runや,jump,sliding,Climb...といった感じに派生して作っています。そしてCharacterクラスでStateを持って、、、といったおそらく普通のStateパターンを組んでいます。

しかし、今回はContextであるCharacterクラスを継承してPlayer、enemyクラスを作ることにしました。Player、enemyも同じステータスが必要です。
現在悩んでいることはPayerにしか必要ないが、stateに渡してその中で変更したい変数をどうするかというのに悩んでいます。

該当のソースコード

C++

1//stateの抽象クラス 2#include "Character.h" 3 4class Character; 5class State 6{ 7public: 8 virtual ~State() {}; 9 virtual State* handleInput(Character& chara,int input) = 0;//inputを受け取って次のステータスを返す 10 virtual void update(Character& chara) = 0;//更新処理 11 virtual void enter(Character& chara) = 0;//ステータス変更時に一回だけ呼ばれる 12}; 13 14

C++

1//Characterの抽象クラス player,enemyクラスに継承 2class Character 3{ 4protected: 5/* 6*座標や回転など基本的な情報 7*/ 8 State nowState; 9 10/*!!playerにしかいらない変数!!*/ 11int height 12 13public: 14 virtual ~Character() {}; 15 virtual void Initialize() = 0;//初期化 16 virtual void handleInput();//state->handleInputから帰ってきたステータスをnowStateに格納 17 virtual void update();//nowState->update 18 void render(); 19 20

試したこと

現在はCharacterクラスの中に入れましたが、明らかに間違いだと思います。
そもそもstateパターンを使うべきではないのか、別々に作る必要があるのか、知らないだけで回避方法があるのか自分では判断がつかないため質問させてもらいました。

補足情報(FW/ツールのバージョンなど)

今回はplayerが座標をカメラに渡すためのゲッターがあり、座標のy軸+変数heightでカメラの座標を決めます。
heightはsliding時に小さくなって、ほかのステータスに行くときに戻る、といった感じです。

他にもplayerにしか必要のない変数はありますが今回は省略しています。

もしよろしければ回答のほどよろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

(1)

playerにしか必要のない変数

に関して,「Stateがどうの」という関係ない話を抜きにして考えてみる.

  • Characterクラスを継承してPlayer、enemyクラスを作る
  • playerにしか必要のない変数がある

この条件で,「playerにしか必要のない変数」をCharacterに持たせるんですか?っていう.
Playerに必要なものはとりあえずPlayerに持たせればどうか.

(2)

あとは,「Stateがどうの」の話を解決する.
「CharacterのState」という話の括りで扱える話なのか?という.
「PlayerのState」「enemyのState」という話にすることも考えられると思うが,それではダメなのか.

投稿2020/11/03 15:06

fana

総合スコア11978

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yukisyuki

2020/11/03 23:01

と言うことは、例えば全く同じ内容ならtemplateなどを使って書いてplayer用とenemy用で別なものは別に書くみたいな感じですかね?
fana

2020/11/04 01:13

事情がよくわからんけど, PlayerはPlayerの,enemyはenemyの,それぞれ何か固有の事情等々があるのろうから, それぞれ個別に自由に実装すればいいわけで. 対して,今の形は「Character を継承すると,Stateパターンがもれなく付いてきます」という "縛り" を設けることによって不自由しているように見える. 不自由になるなら Stateパターン とか要らないのでは. Player の内部実装の具体的な手段として Stateパターン を使うのだとして, そのことを無関係な enemy にまで強要しなくてもよいのでは? enemyもまた実装手段に Stateパターン を用いるかもしれないけれども,それはたまたまであって,「共通の事柄」として括り出すようなことではないのでは. (Playerとenemyは「どちらも Character である」という関係であって,「どちらも Character であり,且つ,その内部実装は Characterに実装されている State パターンによってどうのこうの」という関係にまでする必要が無いのではないかと.)
fana

2020/11/04 01:37 編集

Playerやenemyにどれだけの数の状態があるのか知らないけれども, "Stateパターン" を持ちこむことで,{実装難易度,可読性,保守性,etc}にどれだけ良いことがあるのかを考えた方が良いかもしれない. (e.g. 「Stateを切り替える方法はどうするのか?」とか無意味に考えることだけが増えてしまって利の方が少ない,とかならやめる) ・状態数はたかだか数パターンであって ・必要な状態の種類は既にほぼ出揃っており(今後どんどん未知の状態が増えていくようことはない) ・状態による分岐があると言ってもまぁ単純な処理分岐でしかなくて ・現状態を参照する分岐が現れるのは,せいぜい Update(), Render() の2か所である みたいな話であれば,「それもう switch とかで書いても良くね?」というのも有りなのではないかな,とか. (まぁ,「現在デザインパターンの勉強として…」という話なので,パターンを使うことがまず前提としてあるのかもしれないけれども,使ってみるなら別の場所,例えば「ゲーム全体の状態」とかに使うとか…)
yukisyuki

2020/11/04 03:03

実際シーンの遷移にもこのパターンを使っていて、うまく行ったかなと思ったので今度はキャラクターで挑戦してみた次第です。 今回はplayerもenemyも使うstate、stateの実装の中身の大部分が同じで、一部のstateのほんの一部だけ違うという状況でした。 stateも割と数がありますし、追加する予定もあります。 自分の中であまり同じ内容を複数回書くのはよくないのかなと言う考えでしたのでこの実装になってしまいました。 今の話ですと、今は同じだったとしても今後の調整でそれぞれ別の実装になる可能性もあるのでそれぞれを完全に分離すべきということでいいですかね? たしかに使うことを目標にしすぎて手段が目的になってしまっている感じは指摘されて気づきました、、、
fana

2020/11/04 03:45

どういう形が良いかは実情次第でしょうけど…… 今現在の様子が,「共通にしようとしているがために→問題が出ている」のだと思うので,その共通化自体が実情に合ってないんじゃないかな?と. とりあえず一旦分離してみて「やっぱコレ,こうすれば纏められるじゃん!」とかなったら再度まとめてやるのでも良いのではないでしょうか.
yukisyuki

2020/11/04 03:48

なるほど、ありがとうございます。 一度設計を見直してみます。 丁寧な回答ありがとうございます。
fana

2020/11/04 03:50

同様に(もしも不明瞭なのであれば,ですが), "Stateパターン" を用いずに実装した場合にはどんな(どれだけ凄惨な)状態になるのだろうか? というのも一度やってみても良いかもしれません.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問