スポンサーサイト

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

ローグライクゲームを作ってみよう!  その8 ~外部ファイル読み込み~

前回やった内容についてですが、
画像や描画オブジェクトの生成機構を作りました。

で、作ったのはいいのですが、
「このオブジェクトを生成してくれ」とFactoryクラスに依頼するたびに、
下記のコードを書かなければ
なりません。

{
std::vector< int > t_Vec;
std::string t_Str( "grade.jpg" );//grade.jpgは、256×256の画像とする。
int t_Param[] = { 0, 2, 2, 128, 128 };//画像配列番号、x分割、y分割、分割した際の横幅、分割した際の縦幅

CharToInt( t_Str, t_Vec );

for( int i = 0, count = sizeof( t_Param ) / sizeof( t_Param[ 0 ] ); i < count; i++ )
{
t_Vec.push_back( t_Param[ i ] );
}
IFactory::Create( FACTORY_TEXTURE, t_Vec );
}
--------------------------------------------------------
※豆知識。 先頭と最後に謎の{ }があると思いますが、
 これ、変数の有効範囲を決めてます。

 上記の例でいうと、t_Vec、t_Strといった変数は{}の中でのみ存在する事になります。
 for文やif文以外の何でもない所に{}を使って変数の有効範囲を指定できるのです。
--------------------------------------------------------

これは非常に面倒くさいですね。
(画像名などを修正するだけでコンパイルし直さないといけないですし。)

なので、外部ファイルから読み込むクラスを新たに創設し、
外部ファイルを書き換えて、ゲーム内部の動作に反映させるようにします。


イメージとしては下記の様になります。
※下記画像の矢印は、処理の流れを示したものであり、
 classの継承、集約などを示すもの(UMLのクラス図)ではありません。

【参考画像】  ※今まで
RogueSample3_1.jpg



【参考画像】  ※今回
RogueSample3_2.jpg


見ても分かりますが、
下記の様な流れを作ってしまうと、無限ループになります。
IFactory→CLoaderFactory→CLoaderManager→IFactory→繰り返し

なので、Test.csvというファイルに、
「Test.csvを読み込んで下さい」という指示を書く、

などの循環を生み出す記載はしないように注意しましょう。


※正常な流れは下記の通り。

■Test.csvに"Test.jpg"という画像を読み込んでくれという内容を記載した場合。
main→IFactory→CLoaderFactory→CLoaderManager→
IFactory→CTextureFactory→CTextureManager

■Test2.csvに"Test.csv"というファイルを読み込んでくれという内容を記載、
 Test.csvには、"Test.jpg"と"Test.bmp"を読み込んでくれという内容を記載した場合。

main→IFactory→CLoaderFactory→CLoaderManager→ //Test2.csvを読み込むLoaderが登録
IFactory→CLoaderFactory→CLoaderManager→ //Test.csvを読み込むLoaderが登録
IFactory→CTextureFactory→CTextureManager→ //Test.jpgが登録
IFactory→CTextureFactory→CTextureManage //Test.bmpが登録


外部ファイルについて。
外部ファイルを読み込めば良い、と言いましたが、
肝心の外部ファイルについて説明してなかったので、説明をします。
全部で3つです。


■Init.csv
RogueSample3_5.jpg

まず、Init.csv。
どの外部ファイルを読み込むのか?を指定しています。
分かりにくいパラメータだと思うのが、2番目のClassTypeですね。

実は外部ファイルを読み込むLoaderクラスを、派生させる事を想定しています。
現状未実装ですが、
1 … ファイルを開いて読み込む  (CLoaderFile)
2 … アーカイブファイルからデータを引っ張り出して読み込む  (CLoaderArchive)
にしようと思ってます。

CLoaderBaseを継承したCLoaderArchiveクラスの方は未実装なので、
現状、ClassType = 1で固定、と考えて良いです。


■TextureData.csv
RogueSample3_4.jpg

こちらのDrawerTypeについてですが、
こちらも派生の余地を残しております。

2Dではなく、3Dのモデルを描画したい場合、
2Dとは与えるパラメータが全く異なる事が予想される為、
(ライトの設定、背面カリングの設定、Z座標などなど。)
派生で対応しようと思ってます。

こちらも現状未実装なので、
DrawerType = 0で固定と考えてもらってOKです。


あと、VecNumは描画配列の添え字です。
↓こんな感じで、添え字を指定してピンポイントで消去したりする為に必要な情報です。
DeleteDrawer( 0 ); //描画配列の0番に登録されたオブジェクトを削除


■DrawerData.csv
RogueSample3_3.jpg

最後。
テクスチャ情報です。

画像を分割読み込みしない場合は、とりあえず全部-1を指定
分割する場合は、X軸、Y軸それぞれの分割数と、
分割した際に画像の縦幅と横幅のサイズがいくつになるのか
?を指定します。

上記では元の画像が256×256なので、
それぞれ2つずつに分割して、分割後のサイズは128になるよ、と記載しています。


最後に。
今回の付録(?)は下記の様になっています。

■Base
■Factory
┃┣CDrawerFactory.h
┃┣CDrawerFactory.cpp
┃┣CTextureFactory.h
┃┣CTextureFactory.cpp
┃┣CLoaderFactory.h
┃┣CLoaderFactory.cpp
┃┣IFactory.h
┃┗IFactory.cpp
■Manager
┃┣CDrawerManager.h
┃┣CDrawerManager.cpp
┃┣CLoaderManager.h
┃┣CLoaderManager.cpp
┃┣CTextureManager.h
┃┗CTextureManager.cpp
■Resource
┃┣CDrawer2D.h
┃┣CDrawer2D.cpp
┃┣CDrawerBase.h
┃┣CDrawerBase.cpp
┃┣CLoaderBase.h
┃┣CLoaderBase.cpp
┃┣CLoaderFile.h
┃┗CLoaderFile.cpp
■Support
 ┗CSingleton.h
main.cpp

■Resource
┣Init.csv
┣DrawerData.csv
┣TextureData.csv
┗grade.jpg


実行する際は、下記の手順になります。
【1】上記ソースコードがあるフォルダをコピーペースト
【2】リソースがあるフォルダの中身だけを、
   "●●●.vcxproj"とかいうファイルが存在するフォルダにコピーペースト


画像が表示されなかったりしたら、99%リソースの置き場所が間違ってる
と思われるので、フォルダの確認をお願いします。

【ソースコード一式】http://rudora3.web.fc2.com/RogueSample3.zip


【ここから余談】-----------------------------------------------------------
しかし、面白いですね。 こんだけcppやらhやら書きましたが、
ゲーム内部の制作には、ひとつも着手できてない
のです。
※しかも、ゲームの基盤は今回で完成ではありません。まだやる事があります。


知り合いから、
「3か月経ってもゲーム完成しないの?本当は挫折して遊んでるんじゃないの?」
とか言われて憤慨しそうになったことがあるのですが、

是非、上記のような作業が意外と時間がかかる
という事を分かって頂きたい。

※多分、キーボードでどんどん不可逆的に作業を進める、
といったイメージがあるのだろう。

実際には、"そもそものプログラムの構造を考える"時間や、
構造を考えてみたけど破綻したor改良法を見つけたから
作り直しor修正をしたりする手間もあるものである。
--------------------------------------------------------------------------


次回は、
Archiveファイルの読み込み→ゲーム内に反映と、
Moverクラスの実装
を行います。

※Moverクラス … 現状、単純にファイルを読み込んで表示だけをしてます。つまり、
「z」キーを押したら右に動く、といった動作が全く無いのです。
次は、これを実装します。

ちなみに、今作っている描画周りのシステムなどは、
パズルゲームなどにも転用します。

次回もお楽しみに!(`・ω・´)+
スポンサーサイト

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

コメント

描画システムについて

参考にさせてもらってます。解説だけでなく、コードをもアップロードしてもらって感謝感謝です。
それで早速、コードをダウンロードし、vc++2008で実行したのですが

drawermanager.cpp(83) : error C2679: 二項演算子 '=' : 型 'int' の右オペランドを扱う演算子が見つかりません (または変換できません)。
1> c:\program files\microsoft visual studio 9.0\vc\include\memory(1468): 'std::tr1::shared_ptr<_Ty> &std::tr1::shared_ptr<_Ty>::operator =(const std::tr1::shared_ptr<_Ty> &)' の可能性があります。
1> with
1> [
1> _Ty=CDrawerBase
1> ]
1> 引数リスト '(std::tr1::shared_ptr<_Ty>, int)' を一致させようとしているとき
1> with
1> [
1> _Ty=CDrawerBase
1> ]

cdrawermanager.cpp(111) : error C2679: 二項演算子 '=' : 型 'int' の右オペランドを扱う演算子が見つかりません (または変換できません)。
1> c:\program files\microsoft visual studio 9.0\vc\include\memory(1468): 'std::tr1::shared_ptr<_Ty> &std::tr1::shared_ptr<_Ty>::operator =(const std::tr1::shared_ptr<_Ty> &)' の可能性があります。
1> with
1> [
1> _Ty=CDrawerBase
1> ]
1> 引数リスト '(std::tr1::shared_ptr<_Ty>, int)' を一致させようとしているとき
1> with
1> [
1> _Ty=CDrawerBase
1> ]

cdrawermanager.cpp(113) : error C2679: 二項演算子 '=' : 型 'int' の右オペランドを扱う演算子が見つかりません (または変換できません)。
1> c:\program files\microsoft visual studio 9.0\vc\include\memory(1468): 'std::tr1::shared_ptr<_Ty> &std::tr1::shared_ptr<_Ty>::operator =(const std::tr1::shared_ptr<_Ty> &)' の可能性があります。
1> with
1> [
1> _Ty=CDrawerBase
1> ]
1> 引数リスト '(std::tr1::shared_ptr<_Ty>, int)' を一致させようとしているとき
1> with
1> [
1> _Ty=CDrawerBase
1> ]

このようなエラーが出て実行できません。
shared_ptr自体なんなのかいまいち把握できてないため、どこがおかしいのかよくわかりません。
もしよければアドバイスをください。

No title

コメントありがとうございますv-290
原因を確認してみます。

原因が分かった際は、コメントを追記致します。
よろしくお願い致しますv-393

No title

不具合の発生個所が大まかに分かりました。
下記の様な、shared_ptrにNULLを代入する所でエラーが発生している様です。

m_DrawerVec[ t_DrawerVecNum ].m_Drawer = NULL;

上記の部分をコメントアウトすると、
エラーが消えるかもしれません。

また、こちらでは、shared_ptrにNULLを代入しても
エラーは発生しておりません。


もしかすると、開発環境の違いによる問題かもしれません。


こちらの開発環境は、下記になります。
visual c++ 2010 express

また、DXライブラリを使用している為、
下記の手順に従ってプロジェクトを作成しております。
http://homepage2.nifty.com/natupaji/DxLib/use/dxuse_vc2010.html

詳しい原因は分からず申し訳ないのですが、
NULLを代入している部分が怪しいと思いますv-292

No title

お忙しい中コメント返信ありがとうございます!
おっしゃる通り、どうやら開発環境の違いが今回のエラーの原因のようです。
vc++2010で試してみた所正常に動きました。
これを機に2010での開発もやってみようと思います。(もう2012もでてるし)
今回はありがとうございました。これからもゲーム制作頑張ってください!
応援してます!

Re: No title

問題が解決して良かったです!v-290
環境や設定の違いによるエラーは、特定が難しいので厄介ですねv-393

( 各言語の参考書はありますが、
  設定や環境に関する解説書はあまり無いような気がします)

これからも、ゲーム制作を頑張っていきたいと思います。
ご連絡ありがとうございます!
コメントの投稿
管理者にだけ表示を許可する



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