DirectX データ読み込み
あいさつ
11月最終日、皆様いかがお過ごしでしょうか。
私はいつも通り開発しております。はかせです。
今回はCSVデータを読み込んでみたです。
なぜデータ読み込み?
ゲームは大量のデータを扱います。
そのすべてのデータをプログラムに埋め込むのは
現実的ではないですし、よろしくありません。
大体が何かしらのフォーマットで外部でデータを管理し読み込んで使います。
私は今回Google SpreadSheetを使ってCSV形式で管理したいと思います。
理由はオンラインでどこでも編集出来て共有もしやすいからです。
データ読み込み実装
今回はこのデータを読み込んでみたいと思います。
c++でのファイル読み込みはifstreamというものを使って行うそうです。
//タグ enum Tag { PlayerTag = 0, EnemyTag = 1, PlayerBullet = 2, EnemyBullet = 3, }; //データ構造体 struct DATA { std::string Name; DirectX::XMFLOAT3 StartPos; double HP; Tag Tag; }; //ファイルを読み込みデータ構造体に格納 vector<DATA> 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; } if (tag == "Boss") { data.Tag = EnemyTag; } DataTable.push_back(data); } //ファイルクローズ fileStream.close(); return DataTable; }
実行結果が
無事データを読み込めたようです。
ソースコード
今回作ったものは使い捨てのテスト用なのでgithubではなく
ここに全文上げようと思います。
(コピペしやすいようデータ型や名前は合わせてます)
#pragma once #include<stdio.h> #include <string> #include <vector> #include<DirectXMath.h> enum Tag { PlayerTag = 0, EnemyTag = 1, PlayerBullet = 2, EnemyBullet = 3, }; struct DATA { std::string Name; DirectX::XMFLOAT3 StartPos; double HP; Tag Tag; };
#include "Main.h" #include <iostream> #include <fstream> #include <sstream> using namespace std; vector<DATA> LoadData(const char* filePath); int main() { //データ読み込み vector<DATA> DataTable = LoadData("Data/TestData.csv"); //読み込んだデータ表示 for(auto data:DataTable) { cout << data.Name << endl; cout << to_string(data.StartPos.x) << "," << to_string(data.StartPos.y) << "," << to_string(data.StartPos.z) << "," << endl; cout << data.HP <<endl; cout << data.Tag << endl; cout << endl; } getchar(); } //ファイルを読み込みデータ構造体に格納 vector<DATA> 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; } if (tag == "Boss") { data.Tag = EnemyTag; } dataTable.push_back(data); } //ファイルクローズ fileStream.close(); return dataTable; }
あとがき
ファイル操作は大体どの言語も変わらないので、
大して詰まることなくできました。
今回はファイル読み込みのテストということで
空のコンソールアプリケーションで作ってみました。
次回はこれをモジュール化し、
私のゲームに組み込んでみたいと思います。
それでは今回はこの辺でノシ