fc2ブログ

ゲーム開発 現状報告 ~10/23~

ゲーム開発周りの現状報告です。
--------------------------------------
・描画機構 作成
・Xファイル読み込み機構 作成
・非同期読み込みクラス 作成
・インバースキネマティクスの学習

--------------------------------------
現在、上記の事をやっております。
開発の根底のシステム作りに終始している感じ。

とりあえず、描画機構は簡単に作り上げてみたので、
現状の描画システムの内部構造を書いてみます。
(まだまだ、やることが一杯あります。一つずつ片付けて行きたい)

■【現状の描画機構】
NowSystem.jpg

※面倒なので、参照数計測ポインタの表記は省略しました。
実際は std::tr1::shared_ptr<CDrawBase> みたいな感じになってます。

見たら分かりますが、主に下記の3種類の情報で管理してます。
------------------------------------------
・描画オブジェクト
・動作オブジェクト
・オブジェクト情報

------------------------------------------
で、どのマネージャーもlistとvectorをセットにしてます。

描画リスト(リストに登録されている順番に描画)は分かると思いますが、
セットになっているvectorの存在意義は?というと、
これ、各情報に直接アクセスさせる為に存在してます。

【例】
敵、主人公、背景など、たくさんの描画オブジェクトがある場合、
その中から敵を削除するとします。

この場合、下記のように検索してたら遅い(面倒くさい)と思い、
for( it = m_DrawList.begin(); it != m_DrawList.end(); it++)
{
//ユニークなIDを持たせておき、ユニークIDと一致するものを検索
if( (*it)->GetUniqID() == t_UniqID ){
    //一致すれば、描画の終了フラグをセット
(*it)->SetDrawState( DRAW_STATE_FINISH );
break;
}
}

以下の仕組みにしてみました。
------------------------------------------------------------
【1】描画リストへ描画オブジェクトを登録
【2】その際、登録したCDrawBaseクラスへのポインタを取得
【3】そのポインタをVectorに登録し、その添え字を描画ハンドルとして返す
【4】削除する際は、そのハンドルを削除関数に渡す

------------------------------------------------------------

例えば、次のデータを登録した場合、
背景、(描画のみ)
敵A、(描画のみ)
敵B、(描画のみ)
敵C、(描画、移動)
主人公 (描画、移動)
システム的には下記の状態になります。

【参考画像】
NowSystem2.jpg


で、下記のような削除関数を用意しておき、

void CDrawManager::Delete( int t_DrawVecNum )
{
if( t_DrawVecNum >= 0 && (int)m_DrawVec.size() > t_DrawVecNum ){
if( m_DrawVec[t_DrawVecNum] != NULL ){
(*m_DrawVec[t_DrawVecNum])->SetDrawState( DRAW_STATE_FINISH );
}
}
}


で、適宜 削除したい場合は下記の様に関数を呼べば、
線形探索しか出来ないlistの要素を一発で消せるという寸法。

t_DrawMaager.Delete( 3 ); //背景を削除
t_MoverManager.Delete( 1 ); //敵Aの移動処理のみ削除

※上記の方法は、ポインタの先がlistの要素の為、問題がありません。
 vectorの場合は、push_backをすると、メモリの配置が変わる可能性があるので、
 その時点でm_DrawVecなどのポインタの配列はダングリングポインタと化します。
 
【駄目な例】
std::vector<CDrawBase> m_DrawVec;
std::vector<CDrawBase> m_pDrawVec //m_DrawVecの、任意要素へのポインタ



上記からも分かるように、
描画、移動、その他ステータスなど と、それだけの構造になってます。

"キャラクタークラス"とか"自機クラス"とかいうのは存在しません。


描画、移動(変数の書き換え)、そして変数(データ)さえあれば、
どんなゲームでも構成できるはずだ、という考えのもと、上記の描画機構を作りました。


ただ欠点としては、要素をバラバラにしているので、
それらを繋ぎ合わせる(各マネージャーに登録)するのが非常に面倒になることです。

ここらへんはFactoryクラスを作って対応しようと思います。
↓登録する部分のコード例
ObjectInfo t_ObjectInfo;

std::tr1::shared_ptr<CDrawBase> t_Draw( CDrawTexture() );
DrawInfo t_DrawInfo;

t_DrawInfo.m_PosX = GetValue();
t_DrawInfo.m_PosY = GetValue();
t_DrawInfo.m_DifX = GetValue();
t_DrawInfo.m_DifY = GetValue();
t_DrawInfo.m_RotaNum = GetValue();
t_DrawInfo.m_ExtendNum = GetFloatValue();
t_DrawInfo.m_TransNum = GetFloatValue();

if (t_Draw->Init( t_DrawInfo ) == INIT_OK ){
CDrawObjectManager& t_DrawManager = CDrawObjectManager::getInstance();
t_ObjectInfo.m_DrawVecNum = t_DrawManager.AddDrawObject( t_Draw );
}

std::tr1::shared_ptr<CMoverBase> t_Mover( CMoverPlayer() );
int t_Param[1024] = {0};
for(int i = 0, count = GetValue(); i < count; i++)
{
t_Param[i] = GetValue();
}
//Moverクラスは、いくつのパラメータが必要になるか分からないので、
//基底クラスで、int型へのポインタを受け取るInit関数を定義(純粋仮想関数)
//派生クラスで、任意のパラメータを、任意のメンバ変数に代入する仕組みにしている

if (t_Mover->Init( t_Param ) == INIT_OK ){
CMoverManager& t_MoverManager = CMoverManager::getInstance();
t_ObjectInfo.m_MoverVecNum = t_MoverManager.AddMoverObject( t_Mover );
}
スポンサーサイト



テーマ : ゲーム製作 関連 - ジャンル : ゲーム

コメント
コメントの投稿
管理者にだけ表示を許可する