Upload
vahe
View
39
Download
1
Embed Size (px)
DESCRIPTION
インタラクティブ・ゲーム制作 < プログラミングコース>. 第 8 回 ファイル 入出力と アルゴリズム. 今日の内容. やるや る言いつつできなかった ファイル入出力 本質で は ない けど見た目もこだわる 石 のアニメーション アルゴリズムをガチで考える 置ける 場所とひっくり返し判定. こ、今度こそ!. ファイル入出力. ファイル 入出力の重要性. セーブ/ロードをしたいなら必須処理 ソース 中 にパラメータを直書きするのは 「 ハードコーディング」と言われて、 現場では忌み嫌われる 行為 - PowerPoint PPT Presentation
Citation preview
インタラクティブ・ゲーム制作<プログラミングコース>
第 8 回ファイル入出力と
アルゴリズム
今日の内容
• やるやる言いつつできなかった–ファイル入出力
• 本質ではないけど見た目もこだわる–石のアニメーション
• アルゴリズムをガチで考える–置ける場所とひっくり返し判定
ファイル入出力こ、今度こそ!
ファイル入出力の重要性
• セーブ/ロードをしたいなら必須処理
• ソース中にパラメータを直書きするのは「ハードコーディング」と言われて、現場では忌み嫌われる行為–ちょっとマップを手直しするのにもビルドが
必要= Visual Studio が必要=マップも自分で作らなくてはいけなくなる=あばばばばばb
読み書きのターゲットは
• とりあえずテキストファイル–特に 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 型も OKout_file << x << “,” << y << endl;
// 書き込み終わったら close して終了
out_file.close();
読み込みもただ読み込むだけなら簡単だ!
• インスタンス生成時にファイル名指定
• is_open() で開けているかチェック
• getline() で1 行ずつ取り出し、処理する
• 最後は close()
ifstream in_file(“ ファイル名” );
string lineStr;vector<string> 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 クラスは基本的な機能し
かないので、ちょっと高度なことをやろうとすると、自前で頑張るか、 boost などに頼ることになります。
• 最低限の処理を使えるようになり、データを取り出しやすいファイル構造を作ろう
区切り取り出し関数実装例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, nextPos-
curPos));curPos = nextPos+argToken.size();
}
return retStrArray;}
区切って取り出す
• fk_StrSplit() 関数–第1引数の文字列を、第2引数の文字で
区切り、バラした結果を返す– vector<string> 型で受け取る
• FKUT/Misc.h で定義してあるので、利用する場合はこれをインクルードする
整数値・実数値変換
• C の標準関数をなんだかんだで使う– atoi() が整数変換にあたる– atof() が実数変換にあたる
• ただし string 型の変数は直接引数に渡せないので、 c_str() 関数を使う– atoi(anyStr.c_str()) のようにする
• 実数値は誤差に厳しいものだと変換時に値がズレることがあるので注意
データ形式を仮決めしよう
• 次のようなテキストファイルを作ることにする–最初の行に [MY BOARD DATA] と表記する–次の行に石の個数を記述する– 3 行目以降から、
1 行で石 1 個分を表すことにする• X 座標 , Z 座標 , 色指定 ( とりあえず英語で )
データの例
[BOARD DATA]4-5.0, -5.0, Black5.0, -5.0, White5.0, 5.0, Black-5.0, 5.0, White
石のアニメーションで使っているテクニック
細かいところだけど重要な
ポイントになるもの
• update() 関数の利用–毎フレーム呼び出して動きを更新する–アニメーションの進行状態が分かるように
メンバ変数を持たせておく• 三角関数おいしい!–一番好きな関数です!–時間経過に応じて 0~ 1 の値を得るのに便利
動きを付ける時によくやるやり方
• 線形補間P = (1 - t)*(startPos) + t*(endPos)
• 半分半分また半分P = 0.5*(nowPos) + 0.5*(endPos)
• 色々な数式や関数の特徴を覚えておくと、色んな場面で役立ちます!
置ける場所とひっくり返し判定本日のメインディッシュ
置ける場所の定義 (1)
• 置くことでひっくり返せること– そのためには、
置く場所の周囲 8 マスに相手の石が置かれているのが前提条件になる
– 初手で黒が置けるのは、
前提条件のみだと右の赤いセル
○ ●● ○
あるセルにおける周囲の情報を得るには
• cellInfo[x][y] の周囲 8 セル– [x-1][y-1], [x][y-1], [x+1][y-1]– [x-1][y], [x+1][y]– [x-1][y+1], [x][y+1], [x+1][y+1]
• 範囲外 (0未満、 8 以上 ) の場合は対象外• これをこのままコーディングすると
ださいので、座標のペアを配列にしまってループで処理できるとクール
置ける場所の定義 (2)
• 相手の石があった方向の先に、自分の石があること– 端に到達した場合は
その時点で NG– 隣接する相手の石が複数存在した場合は、それぞれの方向で判定
– 初手の場合青いセルが最終的に OK になる
○ ●● ○
実装方針
• 位置と方向を与えて、その方向を調べる関数を作る
• 先ほどリストアップした隣接した相手の石リストを関数に流し込んでいく
• あとは実演!
TO BE CONTINUED…