こんばんは、ちうといいます。
今回横スクロールゲームの作成を予定しています。
そこで、変数のアクセス方法について、2つ質問が浮かびましたので回答をお願いします。
まずは画像をご覧ください。
私はゲームを作る際にはいつもMainLoopというシングルトンクラスを生成し、
そこをルートとする木の様な構造を取っています。
例えばEnemyクラス内でPlayerのX座標を知りたいとしたら、
MainLoop *mML = MainLoop :: getInstance();//シングルトンの唯一ポインタを得る
int player_ x = mML -> GameMain -> Play -> Player -> getX();
となります
ここで、いくつか問題点が出てきます。
・階層が深くなればなるほど、上記のようにコードが長くなってします。
・メインループをルートとして、すべての変数のアクセスできてしまうため、独立性が非常に低い。
・同階層同士(プレイヤーと敵のような関係)なのに、いちいちメインループを介さなければいけない。
2つの質問に対する私なりの考えです
1.firendを用いて、アクセスを局所化できるかとも思いましたが、そうすると
いたるところがfriendだらけになってしまい、可読性が低くなってしまうと予想できます。
2.アクセス範囲を親クラスと子クラス間に限定して、
(メインループとタイトル、ロード、オプション、ゲームメイン)(プレイとアイテム、プレイヤー、エネミー)のように
質問1の解決策を適応すればアクセス範囲が親と子間での狭いものになります。
しかし、プレイヤークラスの変数にアクセスする際はメインループからプレイヤーにアクセスできず、プレイヤークラスに直接アクセス、またはプレイクラスにアクセスする必要があります。
プレイヤークラスにアクセスするのは論外ですしプレイクラスにアクセスするのも「アクセスの制限が低すぎる。
結局はメインループから辿ってアクセスするのと大差ない様な気がします。
ここで質問です。
質問1:プレイヤーと敵の様な同じ親クラスを持つクラス同士で変数をいちいちメインループから辿らずにアクセスにはどのような方法があるでしょうか?
質問2:質問1と似ていますが、今回の私のように、ルートから変数をたどっていくようなアクセス方法以外にどのようなアクセス方法があるでしょうか。
特に2は少々なげやりのような質問で申し訳ありませんが、参考になるサイト、またはヒントになるようなワードだけでも回答していただければと思います。
C++ 変数のアクセス方法について
-
peot
Re: C++ 変数のアクセス方法について
敵クラス内にプレイヤクラスのポインタ変数をつくって
プレイクラスから、それを渡したらどうでしょうか。
プレイクラスから、それを渡したらどうでしょうか。
//プレイクラス
class GamePlay
{
public:
void Init(){ enemy.SetPlayer( &player ); }
private:
Player player;
Enemy enemy;
};
//プレイヤークラス
class Player
{
public:
int GetX(){ return positon_x; }
int GetY(){ return positon_y; }
private:
int positon_x;
int positon_y;
};
//敵クラス
class Enemy
}
public:
void Update()
{
//Enemyクラス内でPlayerのX座標を知る
int player_x = player->GetX();
}
void SetPlayer( Player* pointer )
{
player = pointer;
}
private:
Player* player;
};
Re: C++ 変数のアクセス方法について
というのが、例えば衝突判定をしたいのだとすると、Playクラスで衝突判定を実装すれば、EnemyがPlayerの情報を知る必要はなくなります。ちう さんが書きました:例えばEnemyクラス内でPlayerのX座標を知りたいとしたら、
PlayクラスはEnemyとPlayerのインスタンスを両方持っている訳ですから、いちいちルートから辿らなくてもOKです。
オブジェクト指向的に考えると、クラス間の関連性が疎なほど良いです。
EnemyはEnemyだけの処理、PlayerはPlayerだけの処理、と分離すれば、自分のクラス内だけで完結します。
それが、今の設計のように、Enemyクラスが何故かPlayerクラスの内部情報を必要とするのは、クラス設計がまずいのかなと思いました。
Re: C++ 変数のアクセス方法について
既に指摘がありますが、当たってるとかどっちにいるとかは、同階層にアクセスしないで、上にお伺いを立てるようにするのが理想です。
抽象化というと難しくなりますが、実装レベルでいうと、Playerのインスタンスが無くても有っても、Playerの座標がどこであっても、Playが当たったよと言えば当たった処理のテストができる、とかそんな感じにすることです。
抽象化というと難しくなりますが、実装レベルでいうと、Playerのインスタンスが無くても有っても、Playerの座標がどこであっても、Playが当たったよと言えば当たった処理のテストができる、とかそんな感じにすることです。
-
ちう
Re: C++ 変数のアクセス方法について
回答ありがとうございます。
>peotさん
最初に一回だけポインタを渡してしまうという方法ですね。
確かにこれならルートから辿るようなアクセスをする必要もありませんね。
アクセス範囲がぐっと狭まったことが良くわかりました。
>beatleさん
>ISLeさん
確かに敵が味方のインスタンスを保持しているというのは、現実的にもおかしいですよね。
あたり判定が味方、敵を知ることで、味方は敵の、敵は味方の情報を知らなくてよいことになって、
独立性がより高まりますね。
ISleさんの「上にお伺いを立てるようにするのが理想」というのは非常にためになるお言葉です。
おそらくあたり判定以外においてもこの考えが適応できそうな気がします。
>peotさん
最初に一回だけポインタを渡してしまうという方法ですね。
確かにこれならルートから辿るようなアクセスをする必要もありませんね。
アクセス範囲がぐっと狭まったことが良くわかりました。
>beatleさん
>ISLeさん
確かに敵が味方のインスタンスを保持しているというのは、現実的にもおかしいですよね。
あたり判定が味方、敵を知ることで、味方は敵の、敵は味方の情報を知らなくてよいことになって、
独立性がより高まりますね。
ISleさんの「上にお伺いを立てるようにするのが理想」というのは非常にためになるお言葉です。
おそらくあたり判定以外においてもこの考えが適応できそうな気がします。

