スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

ローグライクゲームを作ってみよう!  その9 ~アーカイブ読み込み+α~

さて、引き続きゲーム制作の前提となるシステム作りの解説を行ってまいります。

今回やるのは、下記の二つ!
-----------------------------------------
【1】アーカイブファイル読み込み
【2】入力管理システムの構築

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

まず、アーカイブファイルの読み込みです。

※アーカイブファイルの作成、読み込み自体は前回解説したので、
こちらをお読みください。

【参考URL】アーカイブファイル作成ファイルを作ってみた!



■アーカイブファイルからの読み込み
読み込み方は極めて単純です。

まず、今までファイル読み込み用のCLoaderFileクラスを使用していたのですが、
同様に、アーカイブファイルから読み込む為のCLoaderArchiveクラスを作成します。
※CLoaderBaseを継承。

【参考画像】
SampleRogue4_1.jpg

で、読み込みクラスを生成する部分で、
CLoaderBaseにCLoaderArchiveをnewして代入する部分を作ります。
(ただのswitch文への追記ですね。)

int t_ClassType = t_ParamVec[ t_OffSet + 1 ];

std::tr1::shared_ptr< CLoaderBase > t_LoaderBase;
switch( t_ClassType ){
case 1: t_LoaderBase.reset( new CLoaderFile() ); break;
case 2: t_LoaderBase.reset( new CLoaderArchive() ); break;
default:break;
}


で、後はCLoaderArchiveクラスの中身を作るだけです。

CArchiveクラスという、アーカイブファイルを管理するクラスを作成しているので、
このクラスからファイルサイズとファイルポインタを取得し、
1)ファイルサイズを超えるまでint型の変数を読む
2)すべて読み込み終わったら、Factoryクラスに読み込んだ値を渡す

という部分を作れば完成です。

int CLoaderArchive::Init( std::vector< int >& t_ParamVec, int t_Offset )
{
int result = -1;

//変数4つ分の要素数があれば
if( ( int )t_ParamVec.size() > t_Offset + 3 ){
//各データを変数に代入
m_Priority = t_ParamVec[ t_Offset ];
m_LoadNum = t_ParamVec[ t_Offset + 1 ];
m_CreateNum = t_ParamVec[ t_Offset + 2 ];
int t_FileNameNum = t_ParamVec[ t_Offset + 3 ];

//ファイル名の分の要素数があれば。
if( ( int )t_ParamVec.size() > t_FileNameNum + t_Offset + 3 ){
//ファイル名のデータは、t_Offsetの位置から4つ後ろの変数から開始するので、t_Offset + 4と指定。
std::vector< char > t_FileNameVec;
ChangeIntToStr( t_FileNameVec, t_ParamVec, t_Offset + 4, t_FileNameNum );

CArchive& t_Archive = CArchive::getInstance();
m_FileSize = t_Archive.GetFileSize( &t_FileNameVec[ 0 ] );
m_pFile = t_Archive.GetPointer( &t_FileNameVec[ 0 ] );


//ファイルが正常に読み込めていれば
if( m_FileSize > 0 && m_pFile != NULL ){
result = 0;
}
}
}
return( result );
}

int CLoaderArchive::GetValue()
{
int result = -1;
int t_Value = 0;
int t_Flag = 0;
int t_State = 0;

for( ; m_NowVecNum < m_FileSize; m_NowVecNum++ ){
if( m_pFile[ m_NowVecNum ] >= '0' && m_pFile[ m_NowVecNum ] <= '9' ){
t_Value = ( t_Value * 10 ) + ( m_pFile[ m_NowVecNum ] - '0' );
t_State = 1;
}else if( t_State == 0 && m_pFile[ m_NowVecNum ] == '-' ){
t_Flag = 1;
t_State = 1;
}else if( t_State == 1 ){
if( t_Flag == 0 ){
result = t_Value;
}else{
result = -t_Value;
}
break;
}
}
//現在の添え字がファイルデータの要素数を超えた場合、オブジェクト生成モードに移行
if( m_NowVecNum >= m_FileSize ){
m_LoaderState = LOAD_OBJECT;
}
return( result );
}


んで、今回のアーカイブファイル読み込み作成クラスを作成したことにより、
テクスチャデータのcsvファイル記載形式が変わりました。

★今まで
SampleRogue4_3.jpg

★今回
SampleRogue4_2.jpg


2番目にLoadTypeが加わっただけです。
※LoadType … 読み込み方法を切り替えるフラグです。フラグは下記の2種類。
1:ファイルから読み込み、2:アーカイブファイル読み込み


プログラムの方は、下記の様に変更されています。

★今まで
if(画像分割するなら){
LoadDivGraph( //省略);
}else{
LoadGraph(//省略);
}

★今回
switch( t_ClassType ){
case 1:
if(画像分割するなら){
LoadDivGraph( //省略);
}else{
LoadGraph(//省略);
}
break;
case 2:
if(画像分割するなら){
CreateDivGraphFromMem( //省略);
}else{
CreateGraphFromMem(//省略);
}
break;
}



■入力管理システムの構築
まず入力判定をする場合のことを考えます。

例えば、「Enterキーを押したらゲーム開始」と決めたとします。
例:
if( Key[ KEY_INPUT_RETURN ] == 1 ){
//何らかの処理
}


ここで「やっぱりZキーでゲーム開始にしよう」
仕様変更が入ったとします。

この場合、当然ソースコードの書き換えが必要になり、
また、入力判定の書き換え忘れ等が発生する可能性があります。

なので、上記の可能性を考えると、
固定値を記載するのはマズイという結論に至りました。


そこで、下記の様な仕組みにしました。

<準備>
const int KEY_TYPE_MAX = 256;
char m_KeyFlag[ KEY_TYPE_MAX ];
int m_KeyCount[ KEY_TYPE_MAX ];
std::vector< int > m_KeyVec;

・GetHitKeyStateAll関数で、m_KeyFlagに押されているかどうかのフラグをセット
・KeyFlagが1であればm_KeyCountの値を加算、0ならm_KeyCountも0にする。
・初期化の際、m_KeyVecをKEY_TYPE_MAXの値だけ拡張しておく。
・初期化の際、m_KeyVecの0~255の添え字には、0~255を入れておく。
・キーが押されているかを判定する際、m_KeyCountの値を直接確認するのではなく、
 m_KeyVecの値を介して確認する。


赤字の部分が重要です。
図で見た方が分かり易いかもしれないので、画像を貼ってみます。

★今まで
RogueSample4_4.jpg


★今回
RogueSample4_5.jpg


要はm_KeyVecの値をm_KeyCountの添え字として使っている訳です。
これ、何のメリットがあるの?というと、
キーコンフィグ機能が実装できる
のです。

例えば、KEY_INPUT_Q = 16、 KEY_INPUT_P = 25 なのですが、

下記の様に、あらかじめKeyVecに値を代入しておくことにより、
「Qを押したら処理A実行」の部分を、「Pを押したら処理A実行」
動作を変える事が出来るのです。

//事前に代入しておく。
m_KeyVec[ 16 ] = 25;

int CheckKey( int t_KeyNum ){
int result = -1;

result = m_KeyCount[ m_KeyVec[ t_KeyNum ] ]

return( reuslt );
}

int main(void){
//代入されたので、「P」が押された際に処理A実行
if( CheckKey( KEY_INPUT_Q ) == 1 ){
//処理A
}
return( 0 );
}
※配列の範囲外チェックは省いています。


また、それだけではなく、
オリジナルのキーを作ることも出来ます。

例えば、m_KeyVecを要素数500に拡張します。
そして、m_KeyVec[499] = 25 と代入しておけば、

プログラム中の下記の記載がある部分は、「Pを押したら実行」という動作になります。
if( CheckKey( 499 ) == 1 ){

}


で、m_KeyVecに代入する値を外部ファイルに押し出してやれば、
コンパイルせずに、入力に反応するキーを
変える事が出来る
という寸法です。

今回は、
257 = 「M」
258 = 「N」
259 = 「O」
260 = 「P」 という事にしました。

実際のソースコードは下記の通り。
if( t_InputManager.CheckInput( 257 ) == 1 ){
//「M」キーを押した際に実行される。 (描画優先順位変更)
t_Manager.ChangePriority( 2, 2 );
}else if( t_InputManager.CheckInput( 258 ) == 1 ){
//「N」キーを押した際に実行される。 (描画状態変更)
t_Manager.ChangeDrawState( 0, 2 );
}else if( t_InputManager.CheckInput( 259 ) == 1 ){
//「O」キーを押した際に実行される。 (描画状態変更)
t_Manager.ChangeDrawState( 0, 1 );
}else if( t_InputManager.CheckInput( 260 ) == 1 ){
//「P」キーを押した際に実行される。 (テクスチャ変更)
t_Manager.ChangeTexture( 0, 0, 3 );
}


将来的には、入力番号257~260はゲームパッドの入力を受け付ける、
という風にしても良い
かもしれません。
その内、改良してみようと思います。

外部ファイルは下記の様になっているので、
KeyVecNumとKeyTypeを任意の値に書き換えれば動作が変わるはずです。

■InputData.csv
RogueSample4_6.jpg




★注意事項
今回からアーカイブファイル読み込みを実装したので、それに対する注意。
----------------------------------------------------------------------
【1】ファイルを個別に読み込む場合、プログラム中のInit.csvを読み込む部分の
   2番目の引数を1にしてください。
int t_Param[] = { 2, 1, 1, 100, 100 };
【2】アーカイブファイルから読み込む場合は、2番目の引数を2にして下さい。
int t_Param[] = { 2, 2, 1, 100, 100 };
【3】TextureData.csvには、ファイル読み込みタイプを指定するフラグがあります。
(2列目の"LoadType"の項目)
 こちらもファイル読み込みの場合は1、アーカイブからの場合は2を指定して下さい。

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

なので、開発の際は下記の手順になると思われます。
----------------------------------------------------------------------------
【1】TextureData.csvの、"LoadType"の項目は1に指定。
【2】プログラム中のInit.csvを読み込む部分の、2番目の引数を1に指定。
【3】プログラム中に、MyArchive.arcを読み込む部分があるので、そこはコメントアウト。
【4】開発中は、各.png.jpgなどのファイルを個別に読み込んで実行

【5】TextureData.csvの"LoadType"の項目を2に指定。
【6】任意のフォルダに、アーカイブにするファイルとあーかいば.exeを入れる。
   あーかいば.exeを起動して、MyArchive.arcを作成
【7】プログラム中の、MyArchive.arcを読み込む部分のコメントアウトを外す
【8】プログラム中のInit.csvを読み込む部分の、2番目の引数を2に指定。

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

【ソースコード一式】http://rudora3.web.fc2.com/RogueSample4.zip
スポンサーサイト

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

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



上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。