シューティングゲームをC++で製作しているのですが、
その際、この「龍神録プログラミングの館」を参考に、
csvファイルを読み込む関数を製作しています。
配列の苦い思い出もあり、できる限りSTLを使って製作しているので、
多少変更がありますが、基本的には同じです。
ただ、根本的に違うのが、キャラや弾を派生クラスとして作成して、
クラスの継承での多態性を利用して、ゲームを作ろうとしている点です。
たとえば、
class BaseVehicle { float x,y; virtual void Move(); void Draw(); } class EnemyA :public BaseVehicle { void Move(); } class BulletA :public BaseVehicle { ・・・・・このような感じです。
問題なのは、読み込み用の関数なんです。
今、キャラ・弾・アイテムなどは、全て std::list で管理していますが、
多態性を実装するために、上にだした例に従うと、
std::list<BaseVehicle *> enemylist; enemylist.push_back( new EnemyA() ); enemylist.push_back( new EnemyB() );このように、派生クラスのオブジェクトを動的確保して渡しています。
csv形式のファイルには、座標・出現時間・速度などが記述されていますが、
敵の種類などを記述する手立てがありませんでした。(どの派生クラスのものか)
(要は、敵の情報はその敵に対応する派生クラスのオブジェクトに記録しなければいけないが、
その敵がどの派生クラスなのか分からないため、オブジェクトを作成できない)
いろいろと思考錯誤をしてみて考えた結果、std::mapを利用することを思いつきました。
たとえば、csvファイルに敵の種類を記述する列を設け(利用する派生クラス名)
std::map<std::string, BaseVehicle *> enemymap のようなstd::mapを作り、
そこに、make_pair("EnemyA", new EnemyA() ) のように、ペアを作成して、
読み込んだ文字列をfindで検索する、という形をとろうと思いました。
つまるところ、csvから読み込んだ、cx,cy,cstring(これが派生クラス名)のような変数を
std::map<std::string, BaseVehicle *>::iterator it; it = enemymap.find(cstring); (*it).second->x = cx; (*it).second->y = cy; enemylist.push_back( (*it).second );このように、マップに登録されているオブジェクトそのものに値を代入し、
そのオブジェクトをstd::listへ登録する、というものです。
しかし、std::listは基底クラスのポインタなので、ポインタにstd::mapのオブジェクト
のアドレスを渡すことになり、結果的に最後に読み込んだ情報が全て上書きされてしまう、
ということを招いてしまいました(こう考えているんですが、もしかして間違ってますかね?)
私が知りたいのは、
・基底クラスを派生クラスにキャストする方法
・クラスの型が決まらない状態で、あとから決められる方法
・この問題を根本的に解決する手段
このどれかのことが分かれば、解決できると思っています(3番目は投げやりですが;)
ソースを添付しておきますので、
気が向きましたら、回答お願いします。