スライド 1

プロジェクト演習Ⅳ
インタラクティブゲーム制作
プログラミング4
2011/10/18
ファイル読み込みと
リソースマネージャ
今日の内容
• ファイルの読み書きができるようになろう
– もうパラメータとかをプログラム中で
ゴリゴリ代入するのはまっぴらだ!
– 「ハードコーディング」と言われて、
現場では忌み嫌われる行為
• 読み込み系の処理を統括しよう
– XNAでは「コンテントパイプライン」として
最初から用意されている
– アーカイバの利用方法
とりあえず音付けをしてみて
• あちこちにファイル読み込み処理を書く
– ファイル名を直接ハードコーディングするこ
とになる
– ばっちい!
• 後でファイル名を変えて別のファイルを
読み込みたい
– いちいちファイル名だけ書き換えてリビルド
とかださすぎて死にそう
ファイルリストを
テキストで用意する
• 音を鳴らしたいイベントをenumで列挙
• enumに対して対応するファイル名を記述
したテキストを読み込む
• プログラム中からは、enumの値で読み込
みや再生のタイミングを指示
– 後はマネージャクラスにお任せ
こんな風にしたい
enum SEEvent {
SE_JUMP,
SE_PUNCH
};
…
seMan.load(SE_JUMP);
seMan.play(SE_JUMP);
[SE File List]
SE_JUMP,se0001.wav
SE_PUNCH,se0002.wav
今の発想が大事
• 「こういう風に出来たらいいのにな」と
いうイメージを描き、それが実現できる
ようにクラスを自作する
• 提供されるクラスを直接つかって何とか
しようとすると、無駄な苦労を重ねるこ
とが多い
• まずは「こういう風にしたいな」をイ
メージするところから始めるべし
読み書きのターゲットは
• とりあえずテキストファイル
– 特にCSVやタブ区切りテキストは扱えると
超便利
• マップデータ、キャラクタパラメータ、
シナリオデータ、セーブデータなどなど
• 「テキストファイルとか見られたら
恥ずかしいし…」とか言うのは後だ!
とりあえず使うもの
• C++の標準機能だけでやってみよう
– 読み込みは「ifstream」
– 書き込みは「ofstream」
• インクルードは以下の通り
– #include <iostream>
– #include <fstream>
– 両方必要なので気をつける
• 必要に応じてusing namespace std;も
書き込みは絶望的に簡単だ!
• インスタンス生成時
にファイル名指定
• is_open()で開けてい
るかチェック
• <<で書き込むデータ
を繋げて流し込む
• 最後はclose()
ofstream out_file(“ファイル名”);
if(out_file.is_open() == false) エラー処理;
out_file << “書き込みたい文字” << endl;
// int値やdouble値も<<で繋いで書ける
// もちろんstring型やchar型もOK
out_file << x << “,” << y << endl;
//書き込み終わったらcloseして終了
out_file.close();
読み込みも
ただ読み込むだけなら簡単だ!
• インスタンス生成時
にファイル名指定
• is_open()で開けて
いるかチェック
• getlineで1行ずつ
取り出し、必要に
応じて処理する
• 最後はclose()
ifstream
string
vector<string>
in_file(“ファイル名”);
lineStr;
readBuffer;
if(in_file.is_open() == false) エラー処理;
// 1行ずつwhileループで読み出す
while(getline(in_file, lineStr) == true) {
// lineStrに1行分入る
// とりあえず配列にしまうならこう
readBuffer.push_back(lineStr);
}
in_file.close();
結局何が面倒って
• 読み込んだ後の文字列処理なんです
• C++のstringクラスはJavaに比べると
機能が正直貧弱です
• 最低限のものは揃っているので、うまく
素材を組み合わせて関数を作ろう
– サンプルあります
• データを取り出しやすいファイル構造を
作ろう
区切り取り出し関数実装例
vector<string> fk_StrSplit(string argStr, string argToken)
{
vector<string>
retStrArray;
string::size_type curPos = 0, nextPos = 0;
while(nextPos != string::npos) {
nextPos = argStr.find(argToken, curPos);
retStrArray.push_back(argStr.substr(curPos, nextPoscurPos));
curPos = nextPos+argToken.size();
}
return retStrArray;
}
区切って取り出す
• fk_StrSplit()関数
– JavaのStringクラスのsplit()のようなもの
– 正規表現は使えないけどカンマ区切り、
タブ区切り程度なら対応可能
• カンマ区切り、タブ区切りはExcelでの
編集が容易なので、出来ておいて損は
ない
– マップやシナリオのエディタをExcelで
代用しているソフトハウスもあります
整数値・実数値変換
• Cの標準関数をなんだかんだで使う
– atoi()がInteger.parseInt()にあたる
– atof()がDouble.parseDouble()にあたる
• ただしstring型の変数は直接引数に
渡せないので、c_str()関数を使う
– atoi(anyStr.c_str())のようにする
• 実数値は誤差に厳しいものだと変換時に
値がズレることがあるので注意
ファイル形式の作り方のコツ
• FK Performerのモーションデータなどを
見てみるとよい
• 「ファイルヘッダ」は必ず付けると
– ファイルの先頭でファイルの種類が
識別できるようにする
• [BEGIN]~[END]で囲っておくと、
データを読み込むべき範囲が
分かりやすくなるので処理しやすい
ファイル入出力のクラス化例
• fkut_ConfigDataクラス
– 「A=B」という記述形式を読み書きすること
に特化したクラス
– 元々はパッドのコンフィグデータ用に作った
が、パラメータ調整などにも使えそう
– ここまでの資料をもとにソースを読み解いて
みると良いかも
読み込み内容に基づく
データ生成
• 例えば読み込んだデータに基づいて
立方体を配置するプログラムを考える
• 個数が固定ならいいが、そうではない
ケースの方が圧倒的に多い
• クラスオブジェクトの動的な生成が必須
一緒にやってみよう
• テキストデータの内容をもとに、
音再生を管理するクラスを作ってみよう
今日の課題
• CSVテキストに基づいて、3D空間中に
立方体を配置するプログラムを作れ
– ファイル形式も自分で決める
– 位置、姿勢、大きさはデータによって決定
– 立方体の個数は任意(ファイル内容次第)
– マテリアルも指定できるならそれもよし
• 1行の文字列から””で囲まれた文字列を取
り出す関数を作れ