プロジェクト演習Ⅳ インタラクティブゲーム制作 プログラミング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行の文字列から””で囲まれた文字列を取 り出す関数を作れ
© Copyright 2024 ExpyDoc