シナリオシーンの作り方について教えてください

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
taketoshi
記事: 222
登録日時: 13年前
住所: 日本国

シナリオシーンの作り方について教えてください

#1

投稿記事 by taketoshi » 11年前

こんにちは。お世話になります。

現在SRPGのシナリオシーンの勉強をしています。
ここを参考にhttp://dixq.net/g/50.html
サウンドノベル風に文字を描写するクラスを作ったところです。
ここから文章の進行具合にあわせて背景を描写していけばシナリオシーンが作れると思うのですが
シナリオを外部ファイルにまとめる方法とクラス設計についてご質問があります。

外部csvファイルにシナリオを纏める場合
テキスト + 表示する画像ファイル情報 + 画像の位置
を書き込むと思うのですが、どの様に書き込めば良いでしょうか?
正直にすべて書くと物凄く冗長になると思うので、何か良い方法があったら教えて頂きたいです。

また、シナリオクラス?はどの様に設計すればよいでしょうか。
今はテキストを表示するクラスを作っただけなのですが、
このクラスのスーパークラスとして進行状況を管理するクラスを作ればよいですか?
どの様に管理クラスを構築すればよいか教えていただきたいです。

よろしくお願いいたします。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: シナリオシーンの作り方について教えてください

#2

投稿記事 by softya(ソフト屋) » 11年前

シナリオをどう実行するのかは、色々とアプローチがあります。
CSVにテキストを書いただけのモノもあれば、条件分岐など複雑な制御も含めてシナリオで制御するためスクリプトを使っている場合も多いです。
Lua言語も使っているパターンもあります。

>テキスト + 表示する画像ファイル情報 + 画像の位置
>を書き込むと思うのですが、どの様に書き込めば良いでしょうか?
>正直にすべて書くと物凄く冗長になると思うので、何か良い方法があったら教えて頂きたいです。

シナリオにどんな機能が必要かを設計するのが先です。
例えば、画像の位置を固定すれば座標も必要ありませんし、画像ファイル名ではなく番号で済ますこともできます。
ただし、ウィンドウを上下に移動出来たりとか、条件分岐などを考慮したりとかを始めると複雑になってきます。

● シナリオのエンジン例を紹介しておきます。
「ゲーム作りで学ぶ! 実践的C言語プログラミング - karetta.jp」
http://karetta.jp/book-cover/game-programming
「DXライブラリ置き場 サンプルゲームダウンロードページ」 スクリプトプレーヤー
http://homepage2.nifty.com/natupaji/DxLib/dxsample.html
「マイ 日記 • C言語交流フォーラム ~ mixC++ ~」 手前味噌。途中のウィンドウ編から。
http://dixq.net/forum/blog.php?u=114&sd=a&c=2

>また、シナリオクラス?はどの様に設計すればよいでしょうか。
>今はテキストを表示するクラスを作っただけなのですが、
>このクラスのスーパークラスとして進行状況を管理するクラスを作ればよいですか?
>どの様に管理クラスを構築すればよいか教えていただきたいです。

シナリオとゲーム本編が、どのように連携するかで設計が変わると思います。
悩んでいてもしょうが無いので、とりあえず最初は自分でベターだと思うので作ってみてください。
こうしなければいけない! と言う定番は無いように思います。

スーパークラスを作る必要が有るのかも疑問なんですけどね。
単なるコンポジション関係(他のクラスのインスタンスを持つだけ)でも良いような。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

taketoshi
記事: 222
登録日時: 13年前
住所: 日本国

Re: シナリオシーンの作り方について教えてください

#3

投稿記事 by taketoshi » 11年前

>>softyaさん

ご返信ありがとうございます。

>シナリオにどんな機能が必要かを設計するのが先です。
>例えば、画像の位置を固定すれば座標も必要ありませんし、画像ファイル名ではなく番号で済ますこともできます。
>ただし、ウィンドウを上下に移動出来たりとか、条件分岐などを考慮したりとかを始めると複雑になってきます。

ウインドウとテキスト表示位置は固定とし、
テキストの表示進行順に従って背景絵(舞台となる陸地の地図を表示するつもりです)を
目的地に動かし、辿ってきた進行ルートを簡単に表示して、出発地には味方ユニットのバストアップ画像を表示し
目的地には敵のバストアップ画像などを表示する機能にしたいです。

表してみると感覚がつかめたので、まだ解決とせず、
提示していただいたURLを読みながら、画像素材が整ったら、とりあえず自分で書いてみます。

詰まったらまた質問させてください。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: シナリオシーンの作り方について教えてください

#4

投稿記事 by softya(ソフト屋) » 11年前

>ウインドウとテキスト表示位置は固定とし、
>テキストの表示進行順に従って背景絵(舞台となる陸地の地図を表示するつもりです)を
>目的地に動かし、辿ってきた進行ルートを簡単に表示して、出発地には味方ユニットのバストアップ画像を表示し
>目的地には敵のバストアップ画像などを表示する機能にしたいです。

これだとテキストにはパラメータとセリフだけ記述して、あとはプログラム側でやってしまっても良い気がします。
何処までをプログラムの担当にして、シナリオデータに何処までの情報・機能を持たせるかは色々と考えて決めてください。

【補足】
例えばファイヤーエンブレムあたりだと、戦闘マップ中でもイベントでシナリオが動作します。
特定のキャラが出現とかボスとか、特定のキャラと特定のキャラが隣に立っただけでもとかですね。
あと戦闘に、そのキャラが参加しているかだけでもシナリオが変化します。
ここまで考えると複雑な機能を持ったシナリオ・スクリプトが便利な場合があるのです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

taketoshi
記事: 222
登録日時: 13年前
住所: 日本国

Re: シナリオシーンの作り方について教えてください

#5

投稿記事 by taketoshi » 11年前

時間が経ってしまいましたが、詰まってしまったので質問させてください。

csvにシナリオテキストと背景画像の表示位置を記述し
行ごとに読み込んでいく形で、FEみたいなシナリオシーンを半分くらい再現できました。

テキストファイルの進行具合にしたがって
背景画像をDrawRotaGraph2関数でぐりぐり拡大縮小して
動かしているのですがその中で質問があります。

DrawRotaGraph2関数の引数に拡大率で浮動小数点が使われておるのですが
背景画像の拡大縮小の計算の中floatの比較を行っております。

floatを比較すると浮動小数点なので全くうまくいきません。
何か良い方法はないでしょうか・・・?

コード:

//-----------------------------------------------------------------------------
// 名前 : Updata
// 引数: row = 現在DrowNobelクラスのUpdata関数で表示している行数
// 戻り値: 正常終了	= 0
//			受け取った配列の表示終了	= false
// 関数の説明:表示している文章に沿って背景画像を動かしていく
//-----------------------------------------------------------------------------
int CDrawEventBG::Updata(int row){

	static int nDistanceX = 0,nDepatureX = 0;
	static int nDistanceY = 0,nDepatureY = 0;
	static float nDistanceA = 0,nDepatureA = 0;
	static int counter = 0;

	//もしX座標が現在表示されている座標と異なったら移動距離を計算する
	if(cx != tempdata.cx[row]){
		if(cx > tempdata.cx[row]){
			nDistanceX = -1;
		}else{
			nDistanceX = 1;
		}
	}
	//もしY座標が現在表示されている座標と異なったら移動距離を計算する
	if(cy != tempdata.cy[row]){
		if(cy > tempdata.cy[row]){
			nDistanceY = -1;
		}else{
			nDistanceY = 1;
		}
	}

	//もし倍率が現在表示されている数値と異なったら拡大距離を計算する
	if(angle != tempdata.angle[row]){
		if(angle > tempdata.angle[row]){
			nDistanceA = -0.01;
		}else{
			nDistanceA = 0.01;
		}
	}

	//加速具合が0でなければ画面を動かす
	/*angle = floatの判定方法を調べる*/
	if(nDistanceX != 0 || nDistanceY != 0){//本来ならばここにfloatの比較演算結果を float != floatのような形で盛り込みたい
		cx += nDistanceX;//X方向の画面を動かす
		if(cx == tempdata.cx[row])nDistanceX = 0;//目的値と一緒になれば増加量を0にリセットする
		
		cy += nDistanceY;//Y方向の画面を動かす
		if(cy == tempdata.cy[row])nDistanceY = 0;//目的値と一緒になれば増加量を0にリセットする
		
		angle += nDistanceA;//画像を拡大していく:floatのangleをそのまま比較するとだめだから何か良い方法はないか?
		//ここでもif(float == float) nDistancdA = 0;のように記述したい

		return -1;//-1を返却してテキスト描写処理を止める
	}


	//デバッグ
	DrawFormatString(0,0,RGB(255,255,255),"cx = %d,cy = %d,angle = %2f",cx,cy,angle,true);
	DrawFormatString(320,0,RGB(255,255,255),"dx = %d,dy = %d,da = %2f",nDistanceX,nDistanceY,nDistanceA,true);
	DrawFormatString(0,460,RGB(255,255,255),"dpx = %d,dpy = %d,dpa = %2f",nDepatureX,nDepatureY,nDepatureA,true);

	counter++;


	return 0;
}

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: シナリオシーンの作り方について教えてください

#6

投稿記事 by softya(ソフト屋) » 11年前

floatの==や!=は成功しないのでやらないでください。誤差のため一致することはまずありません。
差分が一致値以下だったら同じとみなすとか、<= or >= を終了条件とします。
差分が一致値以下を調べる関数を作るとかが良いんじゃないでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

taketoshi
記事: 222
登録日時: 13年前
住所: 日本国

Re: シナリオシーンの作り方について教えてください

#7

投稿記事 by taketoshi » 11年前

!=もだめなのですね。

差分を計算してスタートゴールを考えて見ます。

usao

Re: シナリオシーンの作り方について教えてください

#8

投稿記事 by usao » 11年前

floatな変数の役割がわかりませんが,intで管理し,

>DrawRotaGraph2関数の引数に拡大率で浮動小数点が使われておるのですが

この関数に渡すときだけ本来の浮動小数点数になおす,というのではダメでしょうか?
(例えば,0.0~1.0の値が必要なのだとすれば,データは0~100の整数で扱い,使用時に *0.01f する)

taketoshi
記事: 222
登録日時: 13年前
住所: 日本国

Re: シナリオシーンの作り方について教えてください

#9

投稿記事 by taketoshi » 11年前

>>usaoさん

アドバイスありがとうございます。
その方法も考えたのですが、既にあちこちfloatでコードしてあり
すべて書き直すのは大変だったので実装しませんでした。
次実装するときはint型の数値をカウンターとしてプログラム側で調整したほうが楽かとも思いました。

今回は以下のように判定用の関数を書き直しました

コード:

//-----------------------------------------------------------------------------
// 名前 : FloatCalc
// 引数: 
// 戻り値: 差分許容内	= TRUE ( 1 )
//			許容外		= FALSE ( 0 )
// 関数の説明:float同士の差分を計算する
//-----------------------------------------------------------------------------
bool CDrawEventBG::FloatCalc(float angle, float tempangle){
	//fabs(A - B) <= 精度情報 * A
	//精度情報を変更すると許容範囲が変わる
	const float precision = 0.01;

	if(fabs(angle - tempangle) <= precision * angle)
		return true;
	else 
		return false;
}

taketoshi
記事: 222
登録日時: 13年前
住所: 日本国

Re: シナリオシーンの作り方について教えてください

#10

投稿記事 by taketoshi » 11年前

解決を保留していましたが、無事FEのような
幕間イベントシーンを再現できたので、このトピックを解決にします。

アドバイスいただきありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る