ページ 1 / 1
インスタンスのたらい回しがイヤ
Posted: 2014年7月21日(月) 22:28
by マント
C++で簡単なアクションゲームを作っております
キーボード操作用のクラスを設けたのですがキーボードの状態を知りたいクラスがたくさんあり、
その為、キーボード操作用のインスタンスのポインタをたらい回しにする設計にしようと思ったのですが
下層のクラスの為に、キーボード操作用のインスタンスが必要ない上層のクラスまでもが
仮引数にそのポインタを持たなくてはいけなくなりました
コードがとても見づらいです
投げやりで申し訳ないのですが効率的な方法や、そのヒントがあれば教えてください
よろしくお願いします
Re: インスタンスのたらい回しがイヤ
Posted: 2014年7月21日(月) 22:52
by h2so5
キーボードの処理を上層のクラスで完結させたほうがいいかもしれません。
Re: インスタンスのたらい回しがイヤ
Posted: 2014年7月21日(月) 22:56
by nullptr
末端のクラスがキーボードの状態を知らなくてはならないような設計とは?
Re: インスタンスのたらい回しがイヤ
Posted: 2014年7月21日(月) 23:05
by hide
キーボードの入力を処理するクラスは Zキーが押された という情報をしる必要がありますが、
操作対象のキャラクターのようなクラスは、 ジャンプを命令された という程度でいいはずです。
逆に操作対象のキャラクターが Zキーが押された という情報を知ってしまうと、
コントローラーで操作できなくなります。
Re: インスタンスのたらい回しがイヤ
Posted: 2014年7月21日(月) 23:16
by マント
返信ありがとうございます
私はプログラミング初心者で一昨日、C++の入門サイトを見終わったということを追記しておきます
C++の設計から成っていないと思いますが現在、キー入力により分岐する部分全てを
if(Key->Getter(何かキー)) //Getterはキーの入力状態を返すメソッド
このように記述しています
ジャンプを命令ということはどういうことですか
キャラクタークラスとキー入力クラスの間に何かが存在するのでしょうか
Re: インスタンスのたらい回しがイヤ
Posted: 2014年7月22日(火) 00:02
by マント
さっきの私の解答がおかしかったので訂正します
キー入力クラスは毎フレーム、入力状態を更新して、
キーが押されているかどうかのフラグを利用したい場合は
利用したがっているクラスからキー入力クラスのgetter関数を呼び出します
キーボードの状態を末端のクラスが知らずにキー入力で処理を分岐させるやり方は
見当も付きません
どの道、ポインタのたらい回し(寄り道)は避けては通れないのでしょうか
Re: インスタンスのたらい回しがイヤ
Posted: 2014年7月22日(火) 00:30
by softya(ソフト屋)
最初にC++らしさと言うかオブジェクト指向にこだわり過ぎると完成しなくなる恐れが高いので、ほどほどに。
> どの道、ポインタのたらい回し(寄り道)は避けては通れないのでしょうか
ポインタは止めましょう。せめて参照に。
>ジャンプを命令ということはどういうことですか
上位のクラスがキーボードの入力がジャンプか判定すればキャラクタクラスのジャンプ・メソッドを呼ぶだけで良いので、キャラクタクラスがキーボードの状態を知る必要はないですね。
更にどのキーがジャンプか知っているべきなのはキーボード管理クラスだけです(キーの抽象化。コンフィグにも応用化)
そのクラスが知るべきでない情報は与えないがキーワードです。
Re: インスタンスのたらい回しがイヤ
Posted: 2014年7月22日(火) 21:58
by taketoshi
同様の壁にぶち当たり考えた末に、入力関係をシングルトンで実装しました。
しかし、そのあとになって、入力関係をカプセル化して必要なクラスがそれを継承すればよかったと後悔しています。
お好きな方法を試してみてください。
► スポイラーを表示
コード:
#pragma once
#include "std.h"
//////////////////////////////////////////////////////////////////////////
//
// CInputTask
//説明:入力を制御するクラス
//親:---
//後々拡張できるように抽象クラスにする
//////////////////////////////////////////////////////////////////////////
class CInputTask{
public:
virtual int CalcMenuUpAndDown(int *lpSelectNum,int MenuElementNum) = 0;
virtual int CalcMenuRightAndLeft(int *lpSelectNum,int MenuElementNum) = 0;
virtual int CalcMenuRectangle(int *lpSelectNum,int MenuElementNum,int col) = 0;
virtual int ReturnZtoResultOK() = 0;
virtual int ReturnXtoResultOK() = 0;
virtual int ReturnStoResultOK() = 0;
};
//////////////////////////////////////////////////////////////////////////
//
// CInput
//説明:入力を制御するクラス
//親:CInputTask
//シングルトンで使用
//////////////////////////////////////////////////////////////////////////
class CInput : public CInputTask{
private:
CInput(){;}
CInput(const CInput& rhs);
CInput& operator=(const CInput& rhs);
static int rKey[256];
static int gpKey[256];
public:
int ReturnInputKeyCounter(int key){return gpKey[key];}
int ReturnInputKey(int);
int gpUpdateKey();
int CalcMenuUpAndDown(int *lpSelectNum,int MenuElementNum) override;
int CalcMenuRightAndLeft(int *lpSelectNum,int MenuElementNum) override;
int CalcMenuRectangle(int *lpSelectNum,int MenuElementNum,int col) override;
int ReturnZtoResultOK() override;
int ReturnXtoResultOK() override;
int ReturnStoResultOK() override;
int Return_gpKey(int Key){
if(gpKey[Key] != 0) return nResultOK;//0以外の時は押されている
if(gpKey[Key] == 0) return nResultNG;//0の時は押されていない
}
// 唯一のアクセス経路
static CInput* GetInstance()
{
static CInput instance; // 唯一のインスタンス
return &instance; // 参照を返却する
}
};
//使う時はこんな感じで呼び出す
CInput *lpInput;
lpInput = CInput::GetInstance();//static変数への参照を取得する
if(lpInput->ReturnXtoResultOK() == nResultOK){
//Xボタンが押された時の処理をここに施す
}
Re: インスタンスのたらい回しがイヤ
Posted: 2014年7月23日(水) 10:03
by usao
>下層のクラスの為に、キーボード操作用のインスタンスが必要ない上層のクラスまでもが
どういう状態なのかわかりませんが
main()とか(操作状態取得) → 上層 → 下層
みたいな構成ならば
その「上層」っていう奴の役割には 「下層」を管理することが含まれていて,当然その中には
【操作状態に応じて 下層の奴に然るべき振る舞いをさせる】 ことが含まれている 気がするので
mainとかの側から 操作状態を表すもの が「上層」に伝達されてくるってのは自然な形であり,
>必要ない
という話にならないような…?
Re: インスタンスのたらい回しがイヤ
Posted: 2014年7月23日(水) 10:10
by softya(ソフト屋)
> main()とか(操作状態取得) → 上層 → 下層
でマントさんの現状が下層がキーボードの情報を見ているので、上層は見もしないキーボードの情報がただ通過するだけって事でしょうね。
他の人の提案は、キーボードの情報を見るのは上層だけで下層は見なくて良いってことかと。
Re: インスタンスのたらい回しがイヤ
Posted: 2014年7月23日(水) 10:28
by usao
実際どこの層までスルーさせてどこで解釈するかは別として そういう層構成になっている以上
「単にスルーさせること」もその層の大切な役目であり「必要な処理である」っていうか,そんな話です.単に.
Re: インスタンスのたらい回しがイヤ
Posted: 2014年7月27日(日) 20:53
by マント
教えてもらう側なのに返信が遅くなってしまったことお詫び申し上げます。
今、自分がすぐにでも導入することが出来るやり方はtaketoshi様が挙げてくださったシングルトンでしょうか
しかし、このやり方はクラス内の2つのメンバ変数をグローバル変数のように扱えてしまうように見え、少し気になります
私が作るゲームは小さいものしかありませんので、さして問題ないかもしれませんが
usao様の仰るとおり、上層のクラスは下層のクラスの管理をするというのも納得できます
しかし、私はキーボードというのは主人公の操作に使用したり、
メニュー画面での選択に使用したりすると思ったので、クラスの最上層辺りに位置させました
その為、だいたいのクラスがキークラスをスルーさせなくてはいけなくなり、想像以上に醜くなりました
この設計自体が破綻しているのかなと思い始めたので、もう少し考えてみます