「雑談」 自分で作ってみたリストについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Tororo

「雑談」 自分で作ってみたリストについて

#1

投稿記事 by Tororo » 15年前

お久しぶりです。 Tororoです。

自分で管理が楽になるようにと、このようなリスト(マップ)を作ってみました。
ただ、まだ使いにくいところや、
「ここは、このほうがいい」
という場所があるのではないかと思いまして、質問させてもらいました。
↓がそのソースです。(Keyのことなどは省いてあります。)

class CGameBase
{
public:
virtual void Run()=0;
};

class CGameApp
{

private:

map<string,CGameBase*> m_MainList;
list<string> m_MapNameList;
public:

void RunMain()
{
map<string,CGameBase*>::iterator it = m_MainList.begin();
list<string>::iterator it2 = m_MapNameList.begin();
while(ProcessMessage()==0 && ClearDrawScreen()==0
&& GetHitKeyStateAll_2()==0 && m_Key[KEY_INPUT_ESCAPE]==0)
{
it = m_MainList.begin();
it2 = m_MapNameList.begin();
while(it != m_MainList.end() && it2 != m_MapNameList.end()){
m_MainList[*it2]->Run();
it++;
it2++;
}
ScreenFlip();
}
}

void AddObject(string key_name, CGameBase *obj)
{
m_MainList.insert(map<string,CGameBase*>::value_type(key_name,obj));
if(m_MainList.size()==0){
m_MapNameList.push_front(key_name);
}else{
m_MapNameList.push_back(key_name);
}
}

void BreakObject(string key_name)
{
map<string,CGameBase*>::iterator it = m_MainList.begin();
list<string>::iterator it2 = m_MapNameList.begin();
while(it != m_MainList.end() && it2 != m_MapNameList.end()){
if(*it2 == key_name){
m_MainList.erase(it++);
m_MapNameList.erase(it2++);
return;
}
it++;
it2++;
}
return;
}


CGameApp(void)
{
ChangeWindowMode(TRUE);
if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0)return;
}

~CGameApp(void)
{
DxLib_End();
}
};


使い方としては、メイン関数内で、
    CGameApp *App = new CGameApp();
App->AddObject("TEST1", new CTEST1()); (CTEST1クラスはCGameObjectから継承している。)
  App->AddObject("TEST2", new CTEST2()); (CTEST2クラスはCGameObjectから継承している。)
  App->AddObject("TEST3", new CTEST3()); (CTEST3クラスはCGameObjectから継承している。)
App->BreakObject("TEST2"); Key_nameが”TEST2”の物を削除
App->RunMain();
とこのような感じです。


改善したほうが良いところや、意見をもらえると幸いです^^;
よろしくお願いしますm(_ _)m 画像

Poco

Re:「雑談」 自分で作ってみたリストについて

#2

投稿記事 by Poco » 15年前

使用方法のサンプルプログラムもあった方が
アドバイス貰い易いですよ。

dic

Re:「雑談」 自分で作ってみたリストについて

#3

投稿記事 by dic » 15年前

プレイヤーの位置や、背景の位置
システム関連の変数はどうやって管理するのでしょうか?

//--------------------------------------------------
小規模なら大丈夫でしょうが
中・大規模になるとデバックが大変なので
呼び出し履歴があるといいですね
画像

めるぽん

Re:「雑談」 自分で作ってみたリストについて

#4

投稿記事 by めるぽん » 15年前

ソースを見る限り、new した CTEST1 や CTEST2 が delete されていないようです。
あと BreakObject 関数ですが、map のキーはソートされていて、list<string> はソートされずに挿入されているため、両方のイテレータを同じように回して erase すると、恐らく
App->AddObject("TEST2", new CTEST2());
App->AddObject("TEST1", new CTEST1());
App->AddObject("TEST3", new CTEST3());
App->BreakObject("TEST2");
としたときに list からは "TEST2" のデータが消され、map からは {"TEST1", CTEST1} のデータが消されてしまって整合性が取れなくなってしまうような気がします。

そもそも list を使う意味が分からないですね。
名前の一覧が欲しいのであれば map のキー部分を回せば手に入るので必要無いと思います。
ということで、
void RunMain()
{
    while(ProcessMessage()==0 && ClearDrawScreen()==0 
        && GetHitKeyStateAll_2()==0 && m_Key[KEY_INPUT_ESCAPE]==0)
    {
        for (map<string, CGameBase*>::iterator it = m_MainList.begin();
            it != m_MainList.end(); ++it)
        {
            (*it)->Run();
        }
        ScreenFlip();
    }
}

void AddObject(string key_name, CGameBase *obj) 
{
    m_MainList.insert(map<string, CGameBase*>::value_type(key_name, obj));
}

void BreakObject(string key_name)
{
    m_MainList.erase(key_name);
}
こんな感じでいいんじゃないかと(まだ delete していない問題は残ってますが)。

Tororo

Re:「雑談」 自分で作ってみたリストについて

#5

投稿記事 by Tororo » 15年前

dicさん
    たしかに違う object1 から object2 を見たい場合は、
    Key_nameでマップ内部のobjectをreturnさせる必要がありそうですね。
    ただ、CGameObject内に X,Yを追加するのも微妙ですね^^;
    難しいです。。

めるぽんさん
    ソートがされていない為同じようにイテレーターを
    回すと、おかしくなるんですね。気づきませんでした^^;


    deleteも使っていないですね。
    デストラクタで全部消去する必要がありそうです。


ちょっと今日は続きが作れないかもしれませんが、
色々考えておきます。。

Tororo

Re:「雑談」 自分で作ってみたリストについて

#6

投稿記事 by Tororo » 15年前

内部から指定された KeyのObject をreturnして、
使いたいクラスにキャストするのは、どうかなと考えてみたりしています。。

ただそのためにincludeする.hが増えてしまいそうです。。


う~ん  うまく作れたかなと思ったら、穴だらけです。

Tororo

Re:「雑談」 自分で作ってみたリストについて

#7

投稿記事 by Tororo » 15年前

>>めるぽんさん
>> for (map<string, CGameBase*>::iterator it = m_MainList.begin();
>> it != m_MainList.end(); ++it)
>> {
>> (*it)->Run();
>> }


この文だと、Runを使用する事が出来ないんですが・・
なぜでしょう?

エラーはこの二つです。

C2819: クラス 'std::pair<_Ty1,_Ty2>' にはオーバーロードされたメンバ 'operator ->' がありません。
C2039: 'Run' : 'std::pair<_Ty1,_Ty2>' のメンバではありません。

>>dicさん
CGameBase* GetObject(string key_name)
{
return *m_MainList[key_name];
}
このような関数で、
  CPlayer *player=GetObject("PLAYER1");
*player->m_X;
のような事を考えています。


けれど、何だか使いにくいかもしれませんが・・

スキマ妖怪

Re:「雑談」 自分で作ってみたリストについて

#8

投稿記事 by スキマ妖怪 » 15年前

とりあえず、エラーは

(*it)->Run();

it->second->Run();

でなくなると思いますよ。

Tororo

Re:「雑談」 自分で作ってみたリストについて

#9

投稿記事 by Tororo » 15年前

>>スキマ妖怪さん

なるほど、secondの使い方はこう言う事だったんですか・・
「要素の値」と言うので使い方が良く分からなかったんで、勉強になりました。。

dic

Re:「雑談」 自分で作ってみたリストについて

#10

投稿記事 by dic » 15年前

>Tororoさん
> CGameBase* GetObject(string key_name)
> {
> return *m_MainList[key_name];
> }
>このような関数で、
>  CPlayer *player=GetObject("PLAYER1");
> *player->m_X;
>のような事を考えています。
>
>
>けれど、何だか使いにくいかもしれませんが・・
>
なるほど、そうやって扱うのですね
ただ、確かに敵を管理するときは使いにくいかもしれないですね
敵の生成や弾の生成、当たり判定など

Tororo

Re:「雑談」 自分で作ってみたリストについて

#11

投稿記事 by Tororo » 15年前

>>dicさん

この方法ぐらいしか、自分には思いつきませんでした・・
ほかに、もっと良い方法があるなら、
教えて欲しいです。。

このリストはゲームよりは、小さなアプリ向きかもしれません。

Tororo

Re:「雑談」 自分で作ってみたリストについて

#12

投稿記事 by Tororo » 15年前

とりあえず、リスト自体はちゃんと動いているので、
一旦、解決とさせてもらいます。

ありがとうございましたm(_ _)m

また、ゲームが完成したら報告させてもらいます。

Tororo

Re:「雑談」 自分で作ってみたリストについて

#13

投稿記事 by Tororo » 15年前

解決踏み忘れました OTL

すいません^^;

dic

Re:「雑談」 自分で作ってみたリストについて

#14

投稿記事 by dic » 15年前

map は結構使わなかったので自信ないですが
下のように CGameBase クラスに仮想関数を作って これを継承させて呼び出すというのはどうでしょうか?
#include <stdio.h>

//======================================================
class CGameBase
{
public:
    virtual    void    Hit();
    virtual    void    EnemyMove();
};

//======================================================
class    CData    :    public    CGameBase
{
private:
    int    m_iPlayerX;
    int    m_iPlayerY;
    int    m_iEnemyX[100];
    int    m_iEnemyY[100];
public:
    void    Hit();    //    ヒット処理
    void    EnemyMove();    //    敵の動作
}:
//======================================================
class    CGameApp    :    public    CGameBase
{
    map<string,CGameBase*>    m_list[10];
public:
    void    AddObject( string name, CGameBase* );
    void    Run();
};
void    CGameApp::AddObject( string name, CGameBase* ) { } 
void    CGameApp::Run()
{
    //    "Data" を取り出す
    //    CGameBase    *data = list[data];

    //    取り出したポインタを元に関数を呼び出す
    //    data->Hit();
}

//======================================================
int main()
{
    CGameApp    *App = new CGameApp();
    app->AddObject( "Data", new CData() );

    app->Run();

    return 0;
}
画像

Tororo

Re:「雑談」 自分で作ってみたリストについて

#15

投稿記事 by Tororo » 15年前

>>dicさん

この方法も少しは考えたのですが、
これでは CGameBase の依存性が高くなって、
再利用(クラス)しにくいように見えたので、

でも、これを見て思ったのですが、
CGameBase から派生させて、
CChara,CItem などとしていくと楽かもしれません。。

dic

Re:「雑談」 自分で作ってみたリストについて

#16

投稿記事 by dic » 15年前

CChara, CItem としても
CChara から CItem へのアクセス方法が・・・

グローバルなインスタンスを使うしか他には思いつかないですね

Tororo

Re:「雑談」 自分で作ってみたリストについて

#17

投稿記事 by Tororo » 15年前

>>dicさん

再利用とか、うんぬんの前に
自分の設計が悪かったのかもしれません。

もう少し考えてみて、リストを書き直すか、
このまま続けるかを決めようと思います。

閉鎖

“C言語何でも質問掲示板” へ戻る