はかせのラボ

私の頭の中を書いていく雑記ブログです

DirectX データ読み込み実装

あいさつ

前回やるやる詐欺をしてしまったはかせです。
今回はちゃんとやります。

やることのおさらい

この記事でデータの読み方がわかりました。
hakase0274.hatenablog.com

今回はこれでやったことを私のシューティングゲームに組み込み、
データの変更のみでゲームの調整を出来るようにしたいと思います。

実装

vector<DATA> CSVLoader::LoadData(const char * filePath)
{
	//返す配列
	vector<DATA> dataTable;

	//ファイルオープン
	ifstream fileStream(filePath);
	if (!fileStream)
	{
		cout << "ファイルオープン失敗" << endl;
		return dataTable;
	}

	//何行目か
	int i = 0;

	//ファイルが終わるまで読み込み
	while (!fileStream.eof())
	{
		i++;
		string bufferString;
		fileStream >> bufferString;
		//1行目は列名でデータではないためスキップ
		if (i <= 1) continue;

		//データを項目ごとに抽出
		istringstream stringStream(bufferString);
		vector<string> datas;
		string tmp;
		//カンマ区切りでデータを切り分け
		while (getline(stringStream, tmp, ','))
		{
			datas.push_back(tmp);
		}
		//切り分けたデータを構造体に格納
		DATA data;
		data.Name = datas[0];
		data.StartPos.x = strtof(datas[1].c_str(), NULL);
		data.StartPos.y = strtof(datas[2].c_str(), NULL);
		data.StartPos.z = strtof(datas[3].c_str(), NULL);
		data.HP = strtod(datas[4].c_str(), NULL);
		auto tag = datas[5];
		if (tag == "Player")
		{
			data.Tag = PlayerTag;
			data.Category = CategoryPlayer;
		}
		if (tag == "Boss")
		{
			data.Tag = EnemyTag;
			data.Category = CategoryBossEnemy;
		}
		if (tag == "Normal")
		{
			data.Tag = EnemyTag;
			data.Category = CategoryNormalEnemy;
		}
		data.Wave = strtol(datas[6].c_str(), NULL, 10);
		dataTable.push_back(data);
	}
	//ファイルクローズ
	fileStream.close();
	return dataTable;
}

以前作ったものをコピペしてちょっとだけ直したものです。
やってることは変わらないので説明は割愛します。

それで読んだデータを使うやつです。

auto dataTable = mDXRescourceManager->LoadData("Data/Data.csv");
//何ウェーブまであるのか
int maxWave = 0;
for(auto data:dataTable)
{
	if (data.Wave > maxWave) maxWave = data.Wave;
}

//ウェーブ分配列を用意する
for(int i = 0;i < maxWave;i++)
{
	std::vector<DXGameObject*> enemyList;
	mEnemyWaveList.push_back(enemyList);
}

//読み込んだデータに従って自機と敵を作る
for(auto data:dataTable)
{
	switch (data.Category)
	{
	case CategoryPlayer:
		CreatePlayer(data);
		break;
	case CategoryBossEnemy:
		CreateBossEnemy(data);
		break;
	case CategoryNormalEnemy:
		CreateNormalEnemy(data);
		break;
	default:
		break;
	}
}

読み込んだデータを配列で受け取り、
オブジェクト生成メソッドへデータを流しています。

オブジェクト生成メソッドではオブジェクトを生成し、
渡されたデータを生成したオブジェクトにあてがっています。

これでデータを読み込みオブジェクトを生成する機能の実装が出来ました。
実際の挙動を動画で見てみましょう。

1つ目は次のデータを読み込んでいます。
f:id:hakase0274:20181202214515p:plain
雑魚敵→ボスという流れで敵が出てきます。
youtu.be
2つ目は次のデータを読み込んでいます。
f:id:hakase0274:20181202214731p:plain
雑魚敵→雑魚敵→ボスという流れで敵が出てきます。
youtu.be
このように渡すデータを変えるだけで敵の数やウェーブを変更できます。

あとがき

最初に考えてた時はここまで実装できるなんて思っていませんでした。
ただ本気でやれば意外とできるんだなぁと体感しました。

もちろんまだ実装が荒かったり、
弾幕シューティングとしては至らないところも多々あります。

それでもシェーダーのコンパイルさえできていなかった時と比べると
大分成長できたと思っています。

今後の開発については少し迷っています。

何について迷っているかというと、
①開発を閉めてまた1から別のものを作る
②今作っているものをより作りこむ
どちらにしようかということです。

1から別のものを作れば今回とはまた違った気づきや困難にぶつかり、
そこでまた解決してってなるので学習には適していると思います。

ただ1つ自分の全力を込めてもうこれ以上は今の自分には作れません、
というものを作り別の誰かにやってもらい意見をもらう。
こちら方がより良いものを作る技術やセンスは磨かれる気がします。

どちらのほうが今後の自分にとって良いのか、
しっかり考えたうえで結論を出したいと思います。

そんな感じで、今回はこの辺で終わります。
それではノシ

今回作ったものはgithubに上げました
github.com