ページ 1 / 2
東方のような会話文の作成
Posted: 2012年8月07日(火) 22:41
by Takumi
東方のようなSTGを造りたいのですが龍神録プログラミングの館を見てみると会話文の作成の解説はないので過去のトピックを見たりググったりして調べて自分なりにソースを書いてみたもののビルドしてみるとエラーは出てきませんでしたが会話を始めるカウントになるとフリーズしてしまい困ってます。
特にアーカイブを利用する処理に関してあまり理解していないためそこら辺が怪しいと思ってます。
関係あるか分かりませんがデバッグのログ(?)に「Cannot find or open the PDB file」という怪しい文が大量にみられました。
会話システム(talk.cpp)
コード:
#include "../include/GV.h"
void talk_story(){
char String[256] ;
int y,x,i=0;
y=350;
x=70;
FileRead_gets( String, 256, FP ) ;//最初に一行自動で表示
DrawFormatString(x,y,GetColor(255,255,255),"%d",String);
i=1;
y=366;
while(FileRead_gets(String,256,FP)!=NULL && stateKey[ KEY_INPUT_Z ] == 1){//現在の行数取得
i++;
if(FileRead_gets(String,256,FP)==NULL)//文字がなければ終了
i=-1;
break;
}
while(i!=-1){//文字があるかぎりループ
FileRead_gets(String,256,FP) ;//文字が一番下でキーを押したら自動的に上から一行表示
if(y==350){
ClearDrawScreen();//前の文字を消す
DrawFormatString(x,y,GetColor(255,255,255),"%d",String);
y+=16;
}
if(FileRead_getc(FP)=='/'&& y<414){//スラッシュならスルー
y+=16;
continue;
}
if(FileRead_getc(FP)=='/'&& y==414&&talk.boss==1&&talk.ch!=1){//4の倍数の行数がスラッシュなら次は上から表示させるようにしてからスルー
talk.ch=1;
talk.boss=0;
y=350;
continue;
}
if(FileRead_getc(FP)=='/'&& y==414&&talk.ch==1&&talk.boss!=1){
talk.ch=0;
talk.boss=1;
y=350;
continue;
}
if(FileRead_getc(FP)!='/'&& y==350&&talk.boss==1&&talk.ch!=1){//コメントごとにキャラの明るさを交代する
talk.boss=0;
talk.ch=1;
}
if(FileRead_getc(FP)!='/'&& y==350&&talk.ch==1&&talk.boss!=1){
talk.boss=1;
talk.ch=0;
}
if(stateKey[ KEY_INPUT_Z ] == 1){//Zが押されたらコメントを描く
DrawFormatString(x,y,GetColor(255,255,255),"%d",String);
y+=16;
}
if(i==-1)//テキストファイルに文字がなければ終了
break;
}
FileRead_close( FP ) ;//ファイルを閉じる
talk.flag=0;//会話を終了
}
void talk_main(){
talk_story();
}
会話文と画像読み込み(load.cpp)
コード:
void load(){
int t,FP;
SetCreateSoundDataType( DX_SOUNDDATATYPE_MEMPRESS ) ;
t=GetNowCount();
img_talk_ch[0]=LoadGraph("../dat/img/char/face0.png"); //会話中の主人公の画像
~略~
img_talk_boss[0]=LoadGraph("../dat/img/char/reimu0.png"); //会話中のボスの画像
~略~
FP=FileRead_open("../dat/csv/39章/test.txt");//テキストファイルの読み込み
~略~
}
画像描画(graph.cpp)
コード:
void graph_talk(){
if(talk.flag==1){//会話が始まったら
if(talk.ch==1){//主人公が話しているなら
SetDrawBlendMode( DX_BLENDMODE_ADD, 255 );//明るくする
DrawGraph(FX-50,FMY-100,img_talk_ch[0],TRUE);//主人公の描画
}
else{//主人公が聞き手なら
SetDrawBlendMode( DX_BLENDMODE_ADD, 128 );//暗くする
DrawGraph(FX-200,FMY-100,img_talk_ch[0],TRUE);//主人公の描画
}
if(talk.boss==1){//ボス
SetDrawBlendMode( DX_BLENDMODE_ADD, 255 );
DrawGraph(FMX-150,FMY-200,img_talk_boss[0],TRUE);
}
else{
SetDrawBlendMode( DX_BLENDMODE_ADD, 128 );
DrawGraph(FMX-150,FMY-100,img_talk_boss[0],TRUE);
}
SetDrawMode(DX_DRAWMODE_NEAREST);
}
}
会話文を始めるタイミング(boss_shot.cpp)
コード:
void boss_shot_main(){
if(stage_count==talk.cnt[0]){//会話開始時間なら
talk.flag=1;//会話を始める
talk.boss=1;//ボスから話す
}
if(stage_count==boss.appear_count[0] && boss.flag==0){//ボス開始時間なら
input_phy_pos(FMX/2,FMY/2, 50);
if(talk.flag==0)//会話がちゃんと終了していれば
enter_boss(0);
~略~
}
会話システムの関数の呼び出し(main.cpp)
コード:
~略~
case 100://通常処理
calc_ch(); //キャラクタ計算
ch_move(); //キャラクタの移動制御
cshot_main();//自機ショットメイン
enemy_main();//敵処理メイン
boss_shot_main();
shot_main(); //ショットメイン
out_main(); //当たり計算
effect_main();//エフェクトメイン
calc_main();//ゲームタイトル表示計算
if(talk.flag==1){
talk_main();//会話システム
}
graph_main();//描画メイン
if(boss.flag==0&&talk.flag==0)//ボスがいなくて会話中でなければステージカウントを進める
stage_count++;
break;
~略~
}
初期化(ini.cpp)
コード:
void ini(){
~略~
memset(&talk,0,sizeof(talk_t));//会話に関する構造体の初期化
~略~
boss.appear_count[0]=500;//中ボスが出現するカウント
talk.cnt[0]=498;//会話を始めるカウント
~略~
}
会話の構造体(struct.h)
コード:
typedef struct{
int flag,boss,ch,cnt[2];
double x,y;
}talk_t;
グローバル変数にしたもの(GV.h)
コード:
GLOBAL talk_t talk;
GLOBAL unsigned int stateKey[256];//会話システムでのキーの監視のために
GLOBAL int FP;//会話文を格納する変数
大してプログラムも書いた事がなく、まだ龍神録プログラミングの館を見始めてから2か月程度しか経ってない初心者のためC++の基礎も知らないのでお手柔らかにお願いします。
Re: 東方のような会話文の作成
Posted: 2012年8月07日(火) 23:00
by へにっくす
何だかFileRead_gets、FileRead_getcをやたらと呼んでますけど大丈夫?
理解してるか?
if ( FileRead_getc(FP) == '/' && …
if ( FileRead_getc(FP) != '/' && …
となっている箇所は同じ文字を比較していないぞ。
FileRead_getc呼ぶごとに一文字読んでいるんだから…
Re: 東方のような会話文の作成
Posted: 2012年8月07日(火) 23:13
by Takumi
へにっくす さんが書きました:何だかFileRead_gets、FileRead_getcをやたらと呼んでますけど大丈夫?
理解してるか?
if ( FileRead_getc(FP) == '/' && …
if ( FileRead_getc(FP) != '/' && …
となっている箇所は同じ文字を比較していないぞ。
FileRead_getc呼ぶごとに一文字読んでいるんだから…
そうなんです、そこら辺を理解してないんで苦労してます。
同じ文字と言う事はFileRead_getcを読んだ回数分一文字ずつ進みながら比較すると言う事でしょう?
ならば
こんにちは
/
/
/
暑いですね。
といった改行する場合には一行ずつ”/"があるかどうかどうやって確認すればいいでしょうか?
Re: 東方のような会話文の作成
Posted: 2012年8月07日(火) 23:18
by softya(ソフト屋)
talk_story()を呼び出してしまうと会話メッセージが終わるまで戻ってこない処理ですね。
ClearDrawScreen()やDrawFormatString()の処理をしていますがScleenFlip()が無いので画面に反映されません。
あとキーをチェックしてますが、キーの更新処理を呼び出していないのでキーの値はtalk_story()に入った時のままとなります。
ただ、ScleenFlip()をここに書くと
「補足資料.11章 書いてはいけない4つの処理」
http://dixq.net/g/h_11.html
に該当しますので根本的な処理構造の見直しが必要です。
(1) メッセージを読んだら必ずすぐさまmainに戻る。 読み込みと表示用の整形は分けたほうが良いでしょう。
(2) メッセージの表示はmainから呼び出す関数で行う。
(3) C言語のインデントは整える。
(4) FileRead_getsとFileRead_getcはちゃんと使う。一度FileReadした部分は読み出せないので配列などから参照。
Re: 東方のような会話文の作成
Posted: 2012年8月07日(火) 23:27
by Takumi
softya(ソフト屋) さんが書きました:talk_story()を呼び出してしまうと会話メッセージが終わるまで戻ってこない処理ですね。
ClearDrawScreen()やDrawFormatString()の処理をしていますがScleenFlip()が無いので画面に反映されません。
あとキーをチェックしてますが、キーの更新処理を呼び出していないのでキーの値はtalk_story()に入った時のままとなります。
ただ、ScleenFlip()をここに書くと
「補足資料.11章 書いてはいけない4つの処理」
http://dixq.net/g/h_11.html
に該当しますので根本的な処理構造の見直しが必要です。
(1) メッセージを読んだら必ずすぐさまmainに戻る。 読み込みと表示用の整形は分けたほうが良いでしょう。
(2) メッセージの表示はmainから呼び出す関数で行う。
(3) C言語のインデントは整える。
(4) FileRead_getsとFileRead_getcはちゃんと使う。一度FileReadした部分は読み出せないので配列などから参照。
返信ありがとうございます。
すいません、「読み込みと表示用の整形は分けたほうが良いでしょう。」と「C言語のインデントは整える。」はどういう意味でしょうか。後は理解できたのですが・・・
Re: 東方のような会話文の作成
Posted: 2012年8月07日(火) 23:31
by へにっくす
FileRead_getsすれば1行ぶん読むから、それを文字列比較すればいいんじゃないか?
呼んだ結果、改行文字含まないようならstrcmpで比較ができる。
コード:
if ( 0 == strcmp(buff, "/") ) { /* 一致 */ }
とゆーか、読んだらFileRead_seek呼ばない限り元に戻れないので、
ふつうはバッファに読み込んでから文字表示の処理をするんですが、、
→「読み込みと表示用の整形は分けたほうが良いでしょう。」がこれに当たります
Re: 東方のような会話文の作成
Posted: 2012年8月07日(火) 23:40
by Takumi
へにっくす さんが書きました:FileRead_getsすれば1行ぶん読むから、それを文字列比較すればいいんじゃないか?
呼んだ結果、改行文字含まないようならstrcmpで比較ができる。
コード:
if ( 0 == strcmp(buff, "/") ) { /* 一致 */ }
とゆーか、読んだらFileRead_seek呼ばない限り元に戻れないので、
ふつうはバッファに読み込んでから文字表示の処理をするんですが、、
→「読み込みと表示用の整形は分けたほうが良いでしょう。」がこれに当たります
strcmpと言うものがあるとは知りませんでした、なるほどとても参考になりました。ありがとうございます。
Re: 東方のような会話文の作成
Posted: 2012年8月07日(火) 23:42
by softya(ソフト屋)
(3) インデントについては、こちらをご覧ください。
「mixcpp/投稿前チェックリスト - PukiWiki」
http://uchan.net/w/index.php?mixcpp%2F% ... 5%B9%A5%C8
(1) 読み込みと表示用の整形は分けたほうが良いでしょう。
読み込んで、そのまま表示用に加工しているのですぐ表示する事態となっています。
(a)メッセージの読み込み。
(b)1フレームごとの表示用メッセージに加工
(c)メッセージの表示処理
と関数を分けたほうが良いでしょう。
Re: 東方のような会話文の作成
Posted: 2012年8月07日(火) 23:55
by Takumi
softya(ソフト屋) さんが書きました:(3) インデントについては、こちらをご覧ください。
「mixcpp/投稿前チェックリスト - PukiWiki」
http://uchan.net/w/index.php?mixcpp%2F% ... 5%B9%A5%C8
(1) 読み込みと表示用の整形は分けたほうが良いでしょう。
読み込んで、そのまま表示用に加工しているのですぐ表示する事態となっています。
(a)メッセージの読み込み。
(b)1フレームごとの表示用メッセージに加工
(c)メッセージの表示処理
と関数を分けたほうが良いでしょう。
URLまで張ってくれてありがとうございます、おかげでインデントについて理解できました。
あと1フレームごとの表示用メッセージに加工と言うのが無知なため、具体的に何をするのか分からないのですが...
Re: 東方のような会話文の作成
Posted: 2012年8月08日(水) 15:00
by softya(ソフト屋)
Takumi さんが書きました:あと1フレームごとの表示用メッセージに加工と言うのが無知なため、具体的に何をするのか分からないのですが...
東方に詳しくないのですが、知らない人にもわかるようにメッセージをどのようなタイミング表示してどのキーに反応させるのか仕様を整理してみてもらえますか?
その仕様を整理していくとプログラムにすることができます。
関連でtest.txtの仕様も説明をお願いします。
Takumi さんが頭の中にある仕様を分かるように書きだして貰うと、こちらもアドバイスがちゃんと出来る様になります。
【補足】
書き方の例。Takumi さんの考えは全く理解してません。
(1)メッセージは一行を一度に表示する。 ※ 一文字づつ表示するなら、そう書いてください。
(2)ボタンが押されると次の行が表示。
(3)4行表示するとメッセージは全部消して一行目から表示。
これよりも出来るだけ細かく書き出すことが大事です。
Re: 東方のような会話文の作成
Posted: 2012年8月08日(水) 15:47
by Takumi
softya(ソフト屋) さんが書きました:Takumi さんが書きました:あと1フレームごとの表示用メッセージに加工と言うのが無知なため、具体的に何をするのか分からないのですが...
東方に詳しくないのですが、知らない人にもわかるようにメッセージをどのようなタイミング表示してどのキーに反応させるのか仕様を整理してみてもらえますか?
その仕様を整理していくとプログラムにすることができます。
関連でtest.txtの仕様も説明をお願いします。
Takumi さんが頭の中にある仕様を分かるように書きだして貰うと、こちらもアドバイスがちゃんと出来る様になります。
【補足】
書き方の例。Takumi さんの考えは全く理解してません。
(1)メッセージは一行を一度に表示する。 ※ 一文字づつ表示するなら、そう書いてください。
(2)ボタンが押されると次の行が表示。
(3)4行表示するとメッセージは全部消して一行目から表示。
これよりも出来るだけ細かく書き出すことが大事です。
書き方は補足に書かれている事とほぼ同じですが細かく言うと
こんにちは
/
/
/
暑いですね
と書いた場合最初に自動で「こんにちは」と表示したあと「/」で埋めた行を何も表示させずテキストでは5行目の「暑いですね」をキーが押されたら「こんにちは」を消して画面では1行目から表示させたいです。
あと4行ごとに主人公と敵の明るさを交代させたいです。
Re: 東方のような会話文の作成
Posted: 2012年8月08日(水) 15:51
by softya(ソフト屋)
仕様としては、やはり良く分かりません。
/は改行だけは了解ですが、次の行になにか書いてあったら一行目と同時に表示するんでしょうか?つまり最大4行がフレーム差なしに同時表示するかって事ですね。
それと明るくする主人公と敵の切り替えはなにか指定があるんでしょうか?それとも必ず主人公から始まる決め打ちですか?
Re: 東方のような会話文の作成
Posted: 2012年8月08日(水) 16:16
by Takumi
softya(ソフト屋) さんが書きました:仕様としては、やはり良く分かりません。
/は改行だけは了解ですが、次の行になにか書いてあったら一行目と同時に表示するんでしょうか?つまり最大4行がフレーム差なしに同時表示するかって事ですね。
それと明るくする主人公と敵の切り替えはなにか指定があるんでしょうか?それとも必ず主人公から始まる決め打ちですか?
いえ、例えば
こんにちは
/
/
暑いですね
と書いた場合画面では
こんにちは
と表示させ、キーを押したら
こんにちは
暑いですね
と表示させたいです。
なので改行については最大4行がフレーム差なしに同時表示となります。
明るくする主人公と敵の切り替えについては画面で何も表記しない行も含めて4行が埋まった時にキーが押されたら切り替えたいと思ってます。
Re: 東方のような会話文の作成
Posted: 2012年8月08日(水) 16:24
by softya(ソフト屋)
???
例ではなくルールとして説明してもらますか?うまく一般化できません。
印象では改行は同時表示、メッセージのある行は1行目を除いてキー待ち後に表示、4行埋まったらキーが押されたあと全部消して一行目に戻る&同時にキャラ切り替え。です。
Re: 東方のような会話文の作成
Posted: 2012年8月08日(水) 16:30
by Takumi
softya(ソフト屋) さんが書きました:???
例ではなくルールとして説明してもらますか?うまく一般化できません。
印象では改行は同時表示、メッセージのある行は1行目を除いてキー待ち後に表示、4行埋まったらキーが押されたあと全部消して一行目に戻る&同時にキャラ切り替え。です。
はい、全くその印象通りのシステムにしたいと思ってます!
Re: 東方のような会話文の作成
Posted: 2012年8月08日(水) 16:40
by softya(ソフト屋)
それは制御が複雑ですね。
その制御を文字列が配列に入っているものとしてプログラムを書けますか?
コード:
char *strArray[4] = {
"こんにちは",
"/",
"/",
"暑いですね"
};
これをmainに必ずすぐ戻る制御関数で何処を表示するか決定させて、表示は表示関数で行なってみてください。
そうですね。環境をシンプルにするために龍神録上ではなく下記をベースに組んでみてください。
「新・C言語 ~ゲームプログラミングの館~ [DXライブラリ]」
http://dixq.net/g/01_09.html
Re: 東方のような会話文の作成
Posted: 2012年8月08日(水) 21:00
by Takumi
softya(ソフト屋) さんが書きました:それは制御が複雑ですね。
その制御を文字列が配列に入っているものとしてプログラムを書けますか?
コード:
char *strArray[4] = {
"こんにちは",
"/",
"/",
"暑いですね"
};
これをmainに必ずすぐ戻る制御関数で何処を表示するか決定させて、表示は表示関数で行なってみてください。
そうですね。環境をシンプルにするために龍神録上ではなく下記をベースに組んでみてください。
「新・C言語 ~ゲームプログラミングの館~ [DXライブラリ]」
http://dixq.net/g/01_09.html
粘ってみましたがそもそも文字をどうやってDrawFormatStringに渡すかがわかりません...
そのままstrArrayを渡すとデータを格納している先頭のアドレスらしきものが出てきてしまいました。
Re: 東方のような会話文の作成
Posted: 2012年8月08日(水) 21:06
by softya(ソフト屋)
それはC言語の基礎なのですがprintfで出力する方法も分かりませんか?
あとソース見てみたら%dって書いてありますね。文字列の時の書式が違います。
ここは原点のC言語のコンソールアプリに立ち返って、printfでコンソール出力するコードを書いてみてください。
これが出来ないと、そもそもDXライブラリで制御することが出来るはずもありません。
【補足】
DXライブラリと書き方は大分違いますがmain関数でforで回しながらprintfするだけで良いです。
Re: 東方のような会話文の作成
Posted: 2012年8月08日(水) 21:19
by Takumi
softya(ソフト屋) さんが書きました:それはC言語の基礎なのですがprintfで出力する方法も分かりませんか?
あとソース見てみたら%dって書いてありますね。文字列の時の書式が違います。
ここは原点のC言語のコンソールアプリに立ち返って、printfでコンソール出力するコードを書いてみてください。
これが出来ないと、そもそもDXライブラリで制御することが出来るはずもありません。
【補足】
DXライブラリと書き方は大分違いますがmain関数でforで回しながらprintfするだけで良いです。
printfで出力した事は何度かありますがそのまま文字を打ち込んだり変数の数値を表記したりなどしかした事がありません。
基本的にC++は龍神録プログラミングの館とC言語~ゲームプログラミングの館~でしか勉強していないのでそこ以外の事はわかりません。
理系の学校に行ったつもりなのですが学校ではプログラミングについて何も教えてくれないので・・・
Re: 東方のような会話文の作成
Posted: 2012年8月08日(水) 21:30
by softya(ソフト屋)
Takumi さんが書きました:softya(ソフト屋) さんが書きました:それはC言語の基礎なのですがprintfで出力する方法も分かりませんか?
あとソース見てみたら%dって書いてありますね。文字列の時の書式が違います。
ここは原点のC言語のコンソールアプリに立ち返って、printfでコンソール出力するコードを書いてみてください。
これが出来ないと、そもそもDXライブラリで制御することが出来るはずもありません。
【補足】
DXライブラリと書き方は大分違いますがmain関数でforで回しながらprintfするだけで良いです。
printfで出力した事は何度かありますがそのまま文字を打ち込んだり変数の数値を表記したりなどしかした事がありません。
基本的にC++は龍神録プログラミングの館とC言語~ゲームプログラミングの館~でしか勉強していないのでそこ以外の事はわかりません。
理系の学校に行ったつもりなのですが学校ではプログラミングについて何も教えてくれないので・・・
学校は理系だからと言ってプログラミングの事を教えてくれる訳ではありません。そのうち学ぶかも知れませんが、それはシラバスを確認してください。ただ、学校で学んだことだけだとゲームプログラムが組めるかどうかも怪しいです。
あと龍神録プログラミングの館とC言語~ゲームプログラミングの館~はゲームプログラミングの講座ではありますがC言語の講座ではありませんのでC言語の基礎は教えてくれません。
つまり、C言語は独学で学んで貰わないとゲームのプログラムを組むことは困難ですから、ここは頑張ってもらう事にしましょう。
苦Cを紹介しますので斜め読みでも良いのでprintfで作ってみてください。
「苦しんで覚えるC言語」
http://9cguide.appspot.com/
ただ、ちゃんと学ぶためには時間を見て全部を理解するようにしたほうが良いです。
本当はC言語の入門書も欲しい所ですが必要なら紹介します。
でも、本格的なC++は難しいので割愛しますよ。
あとコンソールアプリの作り方です。環境に合わせて選んでください。
「太田研究室 > Visual C++ 2008 Express Edition プログラミング入門」
http://cvwww.ee.ous.ac.jp/vc08prog.html
「太田研究室 > Visual C++ 2010 Express プログラミング入門」
http://cvwww.ee.ous.ac.jp/vc10prog.html
【補足】
ここで質問している中学生も沢山いますので学校でC言語を学んでいないのはハンデではありません。
ベクトルやsin/cosを知らない中学生の方が龍神録を理解するのはもっと大変だと思いますよ。
Re: 東方のような会話文の作成
Posted: 2012年8月08日(水) 22:39
by Takumi
softya(ソフト屋) さんが書きました:
学校は理系だからと言ってプログラミングの事を教えてくれる訳ではありません。そのうち学ぶかも知れませんが、それはシラバスを確認してください。ただ、学校で学んだことだけだとゲームプログラムが組めるかどうかも怪しいです。
あと龍神録プログラミングの館とC言語~ゲームプログラミングの館~はゲームプログラミングの講座ではありますがC言語の講座ではありませんのでC言語の基礎は教えてくれません。
つまり、C言語は独学で学んで貰わないとゲームのプログラムを組むことは困難ですから、ここは頑張ってもらう事にしましょう。
苦Cを紹介しますので斜め読みでも良いのでprintfで作ってみてください。
「苦しんで覚えるC言語」
http://9cguide.appspot.com/
ただ、ちゃんと学ぶためには時間を見て全部を理解するようにしたほうが良いです。
本当はC言語の入門書も欲しい所ですが必要なら紹介します。
でも、本格的なC++は難しいので割愛しますよ。
あとコンソールアプリの作り方です。環境に合わせて選んでください。
「太田研究室 > Visual C++ 2008 Express Edition プログラミング入門」
http://cvwww.ee.ous.ac.jp/vc08prog.html
「太田研究室 > Visual C++ 2010 Express プログラミング入門」
http://cvwww.ee.ous.ac.jp/vc10prog.html
いきなりなんですがまず
#include <stdio.h>
int main(void) {
return 0;
}
このプログラムでビルドエラーになります。
エラー内容は
1>LIBCMT.lib(wincrt0.obj) : error LNK2019: 未解決の外部シンボル _WinMain@16 が関数 ___tmainCRTStartup で参照されました。
コンパイラはVC++2010で設定はC言語~ゲームプログラミングの館~と同じようにやりました。
何がいけないんでしょうか・・・
Re: 東方のような会話文の作成
Posted: 2012年8月08日(水) 22:54
by softya(ソフト屋)
Takumi さんが書きました:いきなりなんですがまず
#include <stdio.h>
int main(void) {
return 0;
}
このプログラムでビルドエラーになります。
エラー内容は
1>LIBCMT.lib(wincrt0.obj) : error LNK2019: 未解決の外部シンボル _WinMain@16 が関数 ___tmainCRTStartup で参照されました。
コンパイラはVC++2010で設定はC言語~ゲームプログラミングの館~と同じようにやりました。
何がいけないんでしょうか・・・
DXライブラリはウィンドウアプリなのでコンソールアプリとプロジェクトの作りかたが違います。WinMainとmainと起動関数が変わるのでプロジェクトとソースコードがズレていると出るエラーですね。
プロジェクトの設定を変えても良いんですが、太田研究室 をその為に紹介したのであちらのやり方を読んでいだたけますか?
Re: 東方のような会話文の作成
Posted: 2012年8月08日(水) 23:00
by Takumi
softya(ソフト屋) さんが書きました:
DXライブラリはウィンドウアプリなのでコンソールアプリとプロジェクトの作りかたが違います。WinMainとmainと起動関数が変わるのでプロジェクトとソースコードがズレていると出るエラーですね。
プロジェクトの設定を変えても良いんですが、太田研究室 をその為に紹介したのであちらのやり方を読んでいだたけますか?
すいません、そのままやってました。
なんとかビルドできました。
しかしなぜゲームプログラミングの館の設定ではできないのでしょうか・・・
Re: 東方のような会話文の作成
Posted: 2012年8月08日(水) 23:03
by softya(ソフト屋)
Takumi さんが書きました:softya(ソフト屋) さんが書きました:
DXライブラリはウィンドウアプリなのでコンソールアプリとプロジェクトの作りかたが違います。WinMainとmainと起動関数が変わるのでプロジェクトとソースコードがズレていると出るエラーですね。
プロジェクトの設定を変えても良いんですが、太田研究室 をその為に紹介したのであちらのやり方を読んでいだたけますか?
すいません、そのままやってました。
なんとかビルドできました。
しかしなぜゲームプログラミングの館の設定ではできないのでしょうか・・・
よく見て頂くと関数名が違うと説明してますよ。
あとコンソールウィンドウ(黒いウィンドウ)がコンソールアプリの場合は自動で開きます。
Re: 東方のような会話文の作成
Posted: 2012年8月09日(木) 13:39
by Takumi
softya(ソフト屋) さんが書きました:
よく見て頂くと関数名が違うと説明してますよ。
あとコンソールウィンドウ(黒いウィンドウ)がコンソールアプリの場合は自動で開きます。
ご説明ありがとうございます。
forで回すというのがあまりよく分からないのですがこれでいいでしょうか?
コード:
#include <stdio.h>
int main(){
char *strArray[4]={
"こんにちは",
"/",
"/",
"暑いですね",};
for(int i=0;i<10000;i++)
printf("%s\n%s\n%s\n%s\n",strArray[0],strArray[1],strArray[2],strArray[3]);
fflush(stdin);
getchar();
return 0;
}
Re: 東方のような会話文の作成
Posted: 2012年8月09日(木) 14:15
by オカピーα
Takumi さんが書きました:softya(ソフト屋) さんが書きました:
よく見て頂くと関数名が違うと説明してますよ。
あとコンソールウィンドウ(黒いウィンドウ)がコンソールアプリの場合は自動で開きます。
ご説明ありがとうございます。
forで回すというのがあまりよく分からないのですがこれでいいでしょうか?
コード:
#include <stdio.h>
int main(){
char *strArray[4]={
"こんにちは",
"/",
"/",
"暑いですね",};
for(int i=0;i<10000;i++)
printf("%s\n%s\n%s\n%s\n",strArray[0],strArray[1],strArray[2],strArray[3]);
fflush(stdin);
getchar();
return 0;
}
>>for(int i=0;i<10000;i++)
この部分が無駄です
要素数が分かっているならその数を入力するなどしてみては?
また、for文はその後に続く文が1行だとしても
{ }でくくったほうがミスが少なくていいです
Re: 東方のような会話文の作成
Posted: 2012年8月09日(木) 14:26
by Takumi
オカピーα さんが書きました:
>>for(int i=0;i<10000;i++)
この部分が無駄です
要素数が分かっているならその数を入力するなどしてみては?
また、for文はその後に続く文が1行だとしても
{ }でくくったほうがミスが少なくていいです
ではこれでいいですかね?
コード:
#include <stdio.h>
int main(){
char *strArray[4]={
"こんにちは",
"/",
"/",
"暑いですね"};
for(int i=0;i<4;i++){
printf("%s\n",strArray[i]);
}
fflush(stdin);
getchar();
return 0;
}
Re: 東方のような会話文の作成
Posted: 2012年8月09日(木) 14:32
by オカピーα
それか最初に配列のサイズを指定しないで配列をつくり、
その後sizeofマクロなどでサイズを調べてループさせたほうが楽ですよ
Re: 東方のような会話文の作成
Posted: 2012年8月09日(木) 14:49
by softya(ソフト屋)
(1) /を表示すると仕様と食い違いますね。
(2) 入力待ちの仕様があったはずですが?
getchar(); を使いましょう。
以上を改善してください。
Re: 東方のような会話文の作成
Posted: 2012年8月09日(木) 16:15
by Takumi
softya(ソフト屋) さんが書きました:(1) /を表示すると仕様と食い違いますね。
(2) 入力待ちの仕様があったはずですが?
getchar(); を使いましょう。
以上を改善してください。
なぜか入力されたキーが表示されるだけなんですがどうすればいいでしょうか?
コード:
#include <stdio.h>
#include <stdlib.h>
int main(){
char key;
char *strArray[4]={
"こんにちは",
"/",
"/",
"暑いですね"};
key=getchar();
if(key=='z'){
for(int i=0;i<4;i++){
if(strArray[i]=="/"){
strArray[i]=" ";
}
printf("%s\n",strArray[i]);
}
}
fflush(stdin);
getchar();
return 0;
}
Re: 東方のような会話文の作成
Posted: 2012年8月09日(木) 16:25
by みけCAT
どのような環境ですか?
インデントを整えた方がいいと思います。
http://ideone.com/D7cxP
Re: 東方のような会話文の作成
Posted: 2012年8月09日(木) 16:37
by Takumi
VC++2010です。
見ての通りDXライブラリは使用してません。
Re: 東方のような会話文の作成
Posted: 2012年8月09日(木) 16:48
by softya(ソフト屋)
インデントは整えてくださいね。すごく読みづらいです。
問題点ですが、
(1)何も表示していない段階で、キー入力があるのは仕様と違いますね。
"暑いですね"の表示前にキー入力ですよね?
(2)文字列は==で比較できません。strcmpを使ってください。
(3)配列を書き変えるのは避けたほうが良いでしょう。
改行するだけなら他の方法があります。
Re: 東方のような会話文の作成
Posted: 2012年8月09日(木) 17:27
by Takumi
softya(ソフト屋) さんが書きました:インデントは整えてくださいね。すごく読みづらいです。
問題点ですが、
(1)何も表示していない段階で、キー入力があるのは仕様と違いますね。
"暑いですね"の表示前にキー入力ですよね?
(2)文字列は==で比較できません。strcmpを使ってください。
(3)配列を書き変えるのは避けたほうが良いでしょう。
改行するだけなら他の方法があります。
まだキーを押しても文が出てこないで、押したキーが表示されるのですが・・・
コード:
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
int main()
{
char key;
char *strArray[4]={
"こんにちは",
"/",
"/",
"暑いですね"};
printf("%s\n",strArray[0]);
key=getchar();
if(strcmp(&key,"z")==0){
for(int i=1;i<4;i++){
if(strcmp(strArray[i],"/")==0){
strcpy(strArray[i]," ");
}
printf("%s\n",strArray[i]);
}
}
fflush(stdin);
getchar();
return 0;
}
Re: 東方のような会話文の作成
Posted: 2012年8月09日(木) 17:39
by softya(ソフト屋)
何度も書かれてますがインデントを整えてください。分からなければ質問してください。
※ インデント方法の説明リンクは既に回答済みです。
Re: 東方のような会話文の作成
Posted: 2012年8月09日(木) 17:54
by Takumi
softya(ソフト屋) さんが書きました:何度も書かれてますがインデントを整えてください。分からなければ質問してください。
※ インデント方法の説明リンクは既に回答済みです。
すいません、インデントは開き波カッコを揃える事だけだと勘違いしてました。
これでいいですかね?
コード:
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
int main()
{
char key;
char *strArray[4]=
{
"こんにちは",
"/",
"/",
"暑いですね"
};
printf("%s\n",strArray[0]);
key=getchar();
if(strcmp(&key,"z")==0)
{
for(int i=1;i<4;i++)
{
if(strcmp(strArray[i],"/")==0)
{
strcpy(strArray[i],"");
}
printf("%s\n",strArray[i]);
}
}
fflush(stdin);
getchar();
return 0;
}
Re: 東方のような会話文の作成
Posted: 2012年8月09日(木) 17:56
by Takumi
修正
コード:
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
int main()
{
char key;
char *strArray[4]=
{
"こんにちは",
"/",
"/",
"暑いですね"
};
printf("%s\n",strArray[0]);
key=getchar();
if(strcmp(&key,"z")==0)
{
for(int i=1;i<4;i++)
{
if(strcmp(strArray[i],"/")==0)
{
strcpy(strArray[i],"");
}
printf("%s\n",strArray[i]);
}
}
fflush(stdin);
getchar();
return 0;
}
Re: 東方のような会話文の作成
Posted: 2012年8月09日(木) 17:58
by softya(ソフト屋)
下げなくて良いところで下げていて、下げなければいけないところで下がっていませんね。
{でさがり、}で戻るんです。
ただしくは、となります。
コード:
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
int main()
{
char key;
char *strArray[4]=
{
"こんにちは",
"/",
"/",
"暑いですね"
};
printf("%s\n",strArray[0]);
key=getchar();
if(strcmp(&key,"z")==0)
{
for(int i=1;i<4;i++)
{
if(strcmp(strArray[i],"/")==0)
{
strcpy(strArray[i],"");
}
printf("%s\n",strArray[i]);
}
}
fflush(stdin);
getchar();
return 0;
}
Re: 東方のような会話文の作成
Posted: 2012年8月09日(木) 18:07
by Takumi
softya(ソフト屋) さんが書きました:下げなくて良いところで下げていて、下げなければいけないところで下がっていませんね。
{でさがり、}で戻るんです。
あ、なるほどいくつも見逃していました。
あと問題の方はどうすればいいですかね?
Re: 東方のような会話文の作成
Posted: 2012年8月09日(木) 18:21
by softya(ソフト屋)
コメント書きました。
コード:
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
int main()
{
char key;
char *strArray[8]=
{
"こんにちは",
"/",
"/",
"暑いですね",
"2ページ目です", ← 今後のテストのために追加しました。
"/",
"変則です",
"/"
};
printf("%s\n",strArray[0]); ← 一行目は表示に固定されているのが問題です。改行はありえないのでしょうか?
key=getchar(); ← 1行目だけキー待ちの仕様では無いはずです。あとこちらのミスですが代わりにgetch()でお願いします。
if(strcmp(&key,"z")==0) ← 文字と文字列の比較方法は違います。文字の場合は==や!=dです。処でZキー以外が押された時は終わったらマズイです。
{
for(int i=1;i<4;i++) ← 上の変更で、この仕組だとまずくなります。
{
if(strcmp(strArray[i],"/")==0)
{
strcpy(strArray[i],"");← 書き換えないでください。if() printf(); else printf(); で処理すれば書き換えなくて良いです。
}
printf("%s\n",strArray[i]); ← 表示前にキー入力の仕組みが必要です。
}
}
fflush(stdin);
getchar();
return 0;
}
Re: 東方のような会話文の作成
Posted: 2012年8月09日(木) 20:10
by Takumi
softya(ソフト屋) さんが書きました:コメント書きました。
コメントを参考にさせてもらって書きました。
しかしまだどうやって一度書いた文字を消して上から表示させるのか分かりません。
文字を書く座標を渡さないprintfでもう一度上から表示させる事はできるのでしょうか?
コード:
#include <stdio.h>
#include<string.h>
#include <conio.h>
int main()
{
char key;
char *strArray[8]=
{
"こんにちは",
"/",
"/",
"暑いですね",
"2ページ目です",
"/",
"変則です",
"/"
};
for(int i=0;i<8;i++)
{
if(strcmp(strArray[i],"/")==0)
{
printf("\n");
continue;
}
if(i==0||i%4==0)
{
printf("%s\n",strArray[i]);
continue;
}
key=getch();
if(strcmp(&key,"z"))
{
printf("%s\n",strArray[i]);
}
else
continue;
}
fflush(stdin);
getchar();
return 0;
}
Re: 東方のような会話文の作成
Posted: 2012年8月09日(木) 20:14
by みけCAT
コード:
if(strcmp(&key,"z"))
これは危険です。
素直に
で判定する方がいいと思います。
なお、前者のコードでは、keyをint型にしても環境依存となります。
Re: 東方のような会話文の作成
Posted: 2012年8月09日(木) 20:20
by Takumi
みけCAT さんが書きました:コード:
if(strcmp(&key,"z"))
これは危険です。
素直に
で判定する方がいいと思います。
なお、前者のコードでは、keyをint型にしても環境依存となります。
ご指摘ありがとうございます。
あとこれでは無限ループになってzを押して終えられないのですがどうもうまくzを押して終了させる方法が思い浮かびません。
いろいろ書いてみたら最後の文字が表示されずに終わってしまうなどしてうまくいきません。
Re: 東方のような会話文の作成
Posted: 2012年8月09日(木) 20:38
by softya(ソフト屋)
コメント付けました。
うまく出来たら、こんどは関数化します。
それとDXライブラリに合わせて制御方法が変わる予定です。
コード:
#include <stdio.h>
#include<string.h>
#include <conio.h>
int main()
{
char key;
char *strArray[8]=
{
"こんにちは",
"/",
"/",
"暑いですね",
"2ページ目です",
"/",
"変則です",
"/"
};
for(int i=0;i<8;i++)
{
if(strcmp(strArray[i],"/")==0)
{
printf("\n");
continue;
}
if(i==0||i%4==0)// ← i%4==0だけで良いです。
{
printf("%s\n",strArray[i]);
continue;
}
key=getch();
if(key=='Z')// ← strcmpを使用禁止と書いたはずですが。
{// ← zの時だけ表示なのでしょうか?zキーの役割を説明してください。
printf("%s\n",strArray[i]);
}
else
{// ← elseにも{}を付けましょう。ミスが減ります。
continue;
}
}
fflush(stdin);
getchar();
return 0;
}
Re: 東方のような会話文の作成
Posted: 2012年8月09日(木) 20:50
by Takumi
softya(ソフト屋) さんが書きました:コメント付けました。
うまく出来たら、こんどは関数化します。
それとDXライブラリに合わせて制御方法が変わる予定です。
zキーで一行ずつ会話を進めて会話を終えたらまたzキーを押してキャラや文字などを消して戦闘を開始させたいと思ってます。
Re: 東方のような会話文の作成
Posted: 2012年8月09日(木) 20:52
by softya(ソフト屋)
Takumi さんが書きました:softya(ソフト屋) さんが書きました:コメント付けました。
うまく出来たら、こんどは関数化します。
それとDXライブラリに合わせて制御方法が変わる予定です。
zキーで一行ずつ会話を進めて会話を終えたらまたzキーを押してキャラや文字などを消して戦闘を開始させたいと思ってます。
ではZ以外が押された時の動作は?
Re: 東方のような会話文の作成
Posted: 2012年8月09日(木) 20:55
by Takumi
softya(ソフト屋) さんが書きました:Takumi さんが書きました:softya(ソフト屋) さんが書きました:コメント付けました。
うまく出来たら、こんどは関数化します。
それとDXライブラリに合わせて制御方法が変わる予定です。
zキーで一行ずつ会話を進めて会話を終えたらまたzキーを押してキャラや文字などを消して戦闘を開始させたいと思ってます。
ではZ以外が押された時の動作は?
矢印キーなら自機を移動させたいですがそれ以外は無反応にさせたいです。
Re: 東方のような会話文の作成
Posted: 2012年8月09日(木) 21:03
by softya(ソフト屋)
Takumi さんが書きました:
矢印キーなら自機を移動させたいですがそれ以外は無反応にさせたいです。
いまのコードはcontinueするので次の行に進みます。動作が違いますね。
ヒント:正しいキーが押されるまでwhileループ。
Re: 東方のような会話文の作成
Posted: 2012年8月09日(木) 22:51
by Takumi
softya(ソフト屋) さんが書きました:Takumi さんが書きました:
矢印キーなら自機を移動させたいですがそれ以外は無反応にさせたいです。
いまのコードはcontinueするので次の行に進みます。動作が違いますね。
ヒント:正しいキーが押されるまでwhileループ。
やっとできました!
何度エラー吐かれた事でしょうか...
コード:
#include <stdio.h>
#include<string.h>
#include <conio.h>
int main()
{
int i=0;
char key;
char *strArray[8]=
{
"こんにちは",
"/",
"/",
"暑いですね",
"2ページ目です",
"/",
"変則です",
"/"
};
while(1)
{
if(i<8&&strcmp(strArray[i],"/")==0)
{
printf("\n");
i++;
continue;
}
if(i<8&&i%4==0)
{
printf("%s\n",strArray[i]);
i++;
continue;
}
if(i<8)
{
key=getch();
if(key=='z'){
printf("%s\n",strArray[i]);
i++;}
continue;
}
else
{
key=getch();
if(key=='z')
break;
}
}
return 0;
}
Re: 東方のような会話文の作成
Posted: 2012年8月09日(木) 22:54
by Takumi
インデント修正
コード:
#include <stdio.h>
#include<string.h>
#include <conio.h>
int main()
{
int i=0;
char key;
char *strArray[8]=
{
"こんにちは",
"/",
"/",
"暑いですね",
"2ページ目です",
"/",
"変則です",
"/"
};
while(1)
{
if(i<8&&strcmp(strArray[i],"/")==0)
{
printf("\n");
i++;
continue;
}
if(i<8&&i%4==0)
{
printf("%s\n",strArray[i]);
i++;
continue;
}
if(i<8)
{
key=getch();
if(key=='z')
{
printf("%s\n",strArray[i]);
i++;
}
continue;
}
else
{
key=getch();
if(key=='z')
{
break;
}
}
}
return 0;
}
Re: 東方のような会話文の作成
Posted: 2012年8月09日(木) 23:12
by softya(ソフト屋)
OKです! お疲れ様です。
※ if(i<12は何回も出てくるのでまとめられる気がします。
さて、ここからまたまた難しくなります。
これと同じ動作を下記の条件に中で行なってください。
擬似的にコンソールアプリのまま、DXライブラリ的な処理をさせています。
考えてもらうのは、Ctrl_Message()の中身です。
分からないことは質問してください。 あと私が間違っている可能性もあるのでつっこみも。
コード:
#include <stdio.h>
#include<string.h>
#include <conio.h>
#include <Windows.h>
// メッセージ制御
int Ctrl_Message(int key/*考えて追加を*/)
{
// この関数で抜けない処理をしてはいけません。キー入力待ちでwhileループなど。
// この関数で表示をしてはいけません。
// 戻り値は終了条件を満たすと1になります。それ以外は0です。
return 0;
}
// メッセージ表示
void Draw_Message(char *strArray[],int DrawIndex[4])
{
// 4行の表示
for( int i=0 ; i<4 ; i++ ) {
if( DrawIndex[i]!=-1 ) {
int index = DrawIndex[i]; //表示するメッセージの番号を取り出す。
printf( "%s\n", strArray[index] ); //メッセージ表示
} else {
printf( "\n" ); //改行のみ
}
}
}
int main()
{
char *strArray[8]=
{
"こんにちは",
"/",
"/",
"暑いですね",
"2ページ目です",
"/",
"変則です",
"/"
};
int lineMax = 8;
// メッセージ表示制御用。
int DrawIndex[4] = {-1,-1,-1,-1}; //-1は非表示。それ以外は表示するstrArrayの添字
// 処理ループ
while( 1 ) {
// リアルタイムキー入力。キーはkeyの値以外は使用禁止です。
int key = ' ' ;
if( kbhit() ) {
key = getch();
}
// 途中終了
if( key == 'q' || key == 'Q' ) {
break;
}
// メッセージ制御の関数を呼び出す。
if( Ctrl_Message(key/*考えて追加を*/) ) {
break; // 終了条件での終了。
}
// 画面クリア
system("cls");
// 表示処理
Draw_Message(strArray,DrawIndex);
// 処理時間待ち
Sleep( 50 ); //50ms待つ
}
printf("\n\n終了します。\n");
return 0;
}
Re: 東方のような会話文の作成
Posted: 2012年8月10日(金) 16:09
by Takumi
とりあえずzキーで文字を表示させようと思ったのですが、たぶんループするたび「i」が初期化されてしまいzキーを押しても次に進めません。
そのため「こんにちわ」とだけ表示されてzキーを押しても何も反応しません。どうすればいいでしょうか?
コード:
int Ctrl_Message(int key,int lineMax,int DrawIndex[4])
{
int i;
while(1)
{
for(i=0;i<lineMax;i++)
{
if(i%4==0)
{
DrawIndex[0]=i;
break;
}
if(key=='z')
{
DrawIndex[i%4]=i;
break;
}
}
break;
}
return 0;
}
Re: 東方のような会話文の作成
Posted: 2012年8月10日(金) 21:41
by softya(ソフト屋)
最初に書かれていたコメントでお断りしたはずですがwhileループしてはいけません。回数制限のあるforは可です。
あとローカル変数の寿命は関数を抜けるまでですので、iはCtrl_Messageに来る度に前の状態は忘れると思ってください。
それとキーの値が変化するにはCtrl_Messageを抜ける必要があります。表示するにもCtrl_Messageを抜ける必要があります。
キー入力を待ちCtrl_Message関数に留まることは許されませんが、Zキー待ちかのフラグがあれば制御は可能です。
(1)Zキー入力待ち中。 Zを押すとZキー入力待ち解除。
(2)Zキー入力待ちじゃない。 次の行の表示。 その次の表示があればZキー入力待ち中になる。あとゴニョゴニョが必要。
これらのややこしい制約はすべてDXライブラリでは必要な制限ですので、これに合わせて組んで頂きます。
龍神録の制御は、この制約の中でちゃんと行われているわけですから。
Re: 東方のような会話文の作成
Posted: 2012年8月10日(金) 21:54
by Takumi
softya(ソフト屋) さんが書きました:最初に書かれていたコメントでお断りしたはずですがwhileループしてはいけません。回数制限のあるforは可です。
あとローカル変数の寿命は関数を抜けるまでですので、iはCtrl_Messageに来る度に前の状態は忘れると思ってください。
それとキーの値が変化するにはCtrl_Messageを抜ける必要があります。表示するにもCtrl_Messageを抜ける必要があります。
キー入力を待ちCtrl_Message関数に留まることは許されませんが、Zキー待ちかのフラグがあれば制御は可能です。
(1)Zキー入力待ち中。 Zを押すとZキー入力待ち解除。
(2)Zキー入力待ちじゃない。 次の行の表示。 その次の表示があればZキー入力待ち中になる。あとゴニョゴニョが必要。
これらのややこしい制約はすべてDXライブラリでは必要な制限ですので、これに合わせて組んで頂きます。
龍神録の制御は、この制約の中でちゃんと行われているわけですから。
「キー入力待ちでwhileループなど」と言うのを勘違いしてました。
分かりました、参考にさせていただいてもう一度がんばります。
Re: 東方のような会話文の作成
Posted: 2012年8月11日(土) 12:01
by Takumi
文字を表示する仕組みを理解しようと文字列を11個用意して一つ一つ数を入れて書いてみたのでがなぜか10個目以降がキーを押しても表示されないのですがなぜでしょうか?
コード:
int Ctrl_Message(int key,int lineMax,int DrawIndex[4])
{
if(DrawIndex[0]==-1)
{
DrawIndex[0]=0;
}
if(DrawIndex[1]==-1)
{
if(key=='z')
{
DrawIndex[1]=1;
return 0;
}
}
if(DrawIndex[2]==-1)
{
if(key=='z')
{
DrawIndex[2]=2;
return 0;
}
}
if(DrawIndex[3]==-1)
{
if(key=='z')
{
DrawIndex[3]=3;
return 0;
}
}
if(DrawIndex[0]==0)
{
if(key=='z')
{
DrawIndex[0]=4;
return 0;
}
}
if(DrawIndex[1]==1)
{
if(key=='z')
{
DrawIndex[1]=5;
return 0;
}
}
if(DrawIndex[2]==2)
{
if(key=='z')
{
DrawIndex[2]=6;
return 0;
}
}
if(DrawIndex[3]==3)
{
if(key=='z')
{
DrawIndex[3]=7;
return 0;
}
}
if(DrawIndex[3]==7)
{
if(key=='z')
{
DrawIndex[0]=8;
return 0;
}
}
/*問題の場所*/
if(DrawIndex[1]==5)
{
if(key=='z')
{
DrawIndex[1]=9;
return 0;
}
}
if(DrawIndex[2]==6)
{
if(key=='z')
{
DrawIndex[2]=10;
return 0;
}
}
return 0;
}
Re: 東方のような会話文の作成
Posted: 2012年8月11日(土) 12:17
by softya(ソフト屋)
私のところでは表示されます。
なので間違っているのは別のところではないでしょうか?
追加した文字列が怪しいと思います。
Re: 東方のような会話文の作成
Posted: 2012年8月11日(土) 13:24
by Takumi
softya(ソフト屋) さんが書きました:私のところでは表示されます。
なので間違っているのは別のところではないでしょうか?
追加した文字列が怪しいと思います。
何度も確認しましたがやはり表示されません・・・
コード:
char *strArray[11]=
{
"0",
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"Q"
};
Re: 東方のような会話文の作成
Posted: 2012年8月11日(土) 14:16
by softya(ソフト屋)
あぁ失礼一箇所間違ってます。
ついうっかり直したのを言い忘れました。
よく見れば分かりますが、if文が一箇所変です。
Re: 東方のような会話文の作成
Posted: 2012年8月11日(土) 14:24
by Takumi
softya(ソフト屋) さんが書きました:あぁ失礼一箇所間違ってます。
ついうっかり直したのを言い忘れました。
よく見れば分かりますが、if文が一箇所変です。
ご指摘ありがとうございます!
おかげで表示できるようになりました。
Re: 東方のような会話文の作成
Posted: 2012年8月11日(土) 16:09
by Takumi
最後に「Q」が出てキーを押すとアクセス違反と言われて異常終了しました。どうしてでしょうか?
コード:
int Ctrl_Message(int key,int lineMax,int DrawIndex[4])
{
if(DrawIndex[0]==-1)
{
DrawIndex[0]=0;
}
if(DrawIndex[1]==-1)
{
if(key=='z')
{
DrawIndex[1]=1;
return 0;
}
}
if(DrawIndex[2]==-1)
{
if(key=='z')
{
DrawIndex[2]=2;
return 0;
}
}
if(DrawIndex[3]==-1)
{
if(key=='z')
{
DrawIndex[3]=3;
return 0;
}
}
for(int t=0;t<lineMax;t++)
{
for(int i=0;i<4;i++)
{
if(DrawIndex[i]==t)
{
if(key=='z')
{
DrawIndex[i]+=4;
return 0;
}
}
}
}
if(DrawIndex[0]>=0)
{
for(int j=0;j<lineMax;j++)
{
if(DrawIndex[0]==j*4)
{
if(key=='z')
{
DrawIndex[0]=j;
return 0;
}
}
}
}
return 0;
}
Re: 東方のような会話文の作成
Posted: 2012年8月11日(土) 16:18
by softya(ソフト屋)
Qのタイミングでは無いですね。デバッガを使ってみてください。
「プログラムのデバッグ実行」
http://cvwww.ee.ous.ac.jp/vc10prog.html#7
ブレークポイントは不要です。
今回の場合はライブラリ関数の中で落ちるので、呼出履歴から自分の関数を選んで貰うとどんな情報がライブラリ関数に渡されたか分かると思います。
Re: 東方のような会話文の作成
Posted: 2012年8月11日(土) 19:29
by Takumi
とりあえずエラーは出なくなりましたが妙に長くなったような、こんなものなのでしょうか・・・?
このコードでこれは危ないとかあったらご指摘お願いします。
コード:
int Ctrl_Message(int key,int lineMax,int DrawIndex[4])
{
if(DrawIndex[0]==-1)
{
DrawIndex[0]=0;
}
if(DrawIndex[1]==-1)
{
if(key=='z')
{
DrawIndex[1]=1;
return 0;
}
}
if(DrawIndex[2]==-1)
{
if(key=='z')
{
DrawIndex[2]=2;
return 0;
}
}
if(DrawIndex[3]==-1)
{
if(key=='z')
{
DrawIndex[3]=3;
return 0;
}
}
for(int t=0;t<lineMax;t++)
{
for(int i=0;i<4;i++)
{
if(DrawIndex[i]!=lineMax-1)
{
if(DrawIndex[i]==t)
{
if(key=='z')
{
DrawIndex[i]+=4;
return 0;
}
}
}
else
{
return 0;
}
}
}
if(DrawIndex[0]>=0)
{
for(int j=0;j<lineMax;j++)
{
for(int i=0;i<4;i++)
{
if(DrawIndex[i]!=lineMax-1)
{
if(DrawIndex[0]==j*4)
{
if(key=='z')
{
DrawIndex[0]=j;
return 0;
}
}
}
else
{
return 0;
}
}
}
}
return 0;
}
Re: 東方のような会話文の作成
Posted: 2012年8月11日(土) 19:35
by softya(ソフト屋)
ループで済ませられる事をしていないので明らかに長いのと、"/"かそれ以外かのチェックが行われていませんね。
あと、改ページ時のクリアと最後が自動的に抜けられていません。
制御変数を増やしたほうが良いでしょうね。
※DrawIndexを制御変数代わりにしてますが、制御用と表示用は分けましょう。
Re: 東方のような会話文の作成
Posted: 2012年8月11日(土) 22:41
by Takumi
softya(ソフト屋) さんが書きました:ループで済ませられる事をしていないので明らかに長いのと、"/"かそれ以外かのチェックが行われていませんね。
あと、改ページ時のクリアと最後が自動的に抜けられていません。
制御変数を増やしたほうが良いでしょうね。
※DrawIndexを制御変数代わりにしてますが、制御用と表示用は分けましょう。
DrawIndexを制御変数の代わりにしない場合にはどうのようにしてCtrl_Messageで決めた値をDraw_Messageに渡せばいいのか思いつかないです...
Re: 東方のような会話文の作成
Posted: 2012年8月11日(土) 22:59
by softya(ソフト屋)
Takumi さんが書きました:softya(ソフト屋) さんが書きました:ループで済ませられる事をしていないので明らかに長いのと、"/"かそれ以外かのチェックが行われていませんね。
あと、改ページ時のクリアと最後が自動的に抜けられていません。
制御変数を増やしたほうが良いでしょうね。
※DrawIndexを制御変数代わりにしてますが、制御用と表示用は分けましょう。
DrawIndexを制御変数の代わりにしない場合にはどうのようにしてCtrl_Messageで決めた値をDraw_Messageに渡せばいいのか思いつかないです...
DrawIndexは場合により表示をOFFをしないといけないので-1を入れないわけに行かないですから、現在の表示行を覚えるのには使えません。
そういう意味の制御と表示は分けましょうです。DrawIndexはDraw_Messageに渡す専門にして表示が済んだ行を覚えるのに使ってはいけません。
変数は好きに追加して構いませんので、そこは変更してください。
Re: 東方のような会話文の作成
Posted: 2012年8月12日(日) 14:28
by Takumi
softya(ソフト屋) さんが書きました:
DrawIndexは場合により表示をOFFをしないといけないので-1を入れないわけに行かないですから、現在の表示行を覚えるのには使えません。
そういう意味の制御と表示は分けましょうです。DrawIndexはDraw_Messageに渡す専門にして表示が済んだ行を覚えるのに使ってはいけません。
変数は好きに追加して構いませんので、そこは変更してください。
一から見直して改善しましたが最後にまたエラーを吐かれて異常終了します。
「/」に関する処理を追加してからエラーが発生するので呼び出し履歴の「msvcr100d.dll!strcmp(unsigned char * str1, unsigned char * str2) 行 81 Asm」が怪しいと思うのですがダブルクリックしてそのライブラリを見てみてもよくわからない英字が書いてありどうすればいいかわかりません。
コード:
int Ctrl_Message(int key,int lineMax,int DrawIndex[4],char *strArray[])
{
static int i=-1;
if(i==-1)
{
i=0;
DrawIndex[0]=0;
return 0;
}
if(DrawIndex[i%4]!=lineMax-1)
{
if(strcmp(strArray[i+1],"/")==0)
{
i++;
DrawIndex[i%4]=-1;
return 0;
}
}
if(DrawIndex[i%4]!=lineMax-1)
{
if(key=='z')
{
i++;
DrawIndex[i%4]=i;
if(i%4==0)
{
DrawIndex[1]=-1;
DrawIndex[2]=-1;
DrawIndex[3]=-1;
}
return 0;
}
}
if(i==lineMax-1)
{
if(key=='z')
{
return 1;
}
}
return 0;
}
Re: 東方のような会話文の作成
Posted: 2012年8月12日(日) 14:34
by softya(ソフト屋)
そういう時に使うのがデバッガの呼び出し履歴です。タブにあると思うので選んでみてください。
関数の呼び出しが並んでいますので自分の関数を選べば呼び出した関数と引数が確認できます。
Ctrl_Messageでどの関数を呼び出しているか確認してみてください。
参考。
「デバッガの活用2」
http://www.ced.is.utsunomiya-u.ac.jp/le ... factor.php
Re: 東方のような会話文の作成
Posted: 2012年8月12日(日) 18:32
by Takumi
デバッガの呼び出し履歴でCtrl_Messageでstrcmpが呼び出されている事は確認しました。
しかしstrcmpを使うにあたって何が問題なのか分かりません。いくら調べても考えても何が問題なのか検討がつきません・・・
Re: 東方のような会話文の作成
Posted: 2012年8月12日(日) 18:42
by softya(ソフト屋)
strcmp(strArray[i+1],"/")
だと思いますが"/"が間違っていないとすれば怪しいのはstrArray[i+1]です。
strArrayは文字列の配列ですが、もし添字のi+1が配列外を指していたら動作は保証されません。
なので、まずiの値を調べてみましょう。カーソルをiの上に持ってくと値が表示されるはずです。
あるいは、strArray[i+1]マウスで左クリックしながら選ぶと文字列を表示してくれるはずですが?
さて、どうでしょうか?
Re: 東方のような会話文の作成
Posted: 2012年8月12日(日) 18:51
by Takumi
softya(ソフト屋) さんが書きました:strcmp(strArray[i+1],"/")
だと思いますが"/"が間違っていないとすれば怪しいのはstrArray[i+1]です。
strArrayは文字列の配列ですが、もし添字のi+1が配列外を指していたら動作は保証されません。
なので、まずiの値を調べてみましょう。カーソルをiの上に持ってくと値が表示されるはずです。
あるいは、strArray[i+1]マウスで左クリックしながら選ぶと文字列を表示してくれるはずですが?
さて、どうでしょうか?
デバッガでiの値を見たところ7になっていたため+1すれば8になり配列外になってしまうと考えてiが7になったらこの処理をしないようにもしてみたんですが結果は同じでした・・・
Re: 東方のような会話文の作成
Posted: 2012年8月12日(日) 18:58
by softya(ソフト屋)
Takumi さんが書きました:softya(ソフト屋) さんが書きました:strcmp(strArray[i+1],"/")
だと思いますが"/"が間違っていないとすれば怪しいのはstrArray[i+1]です。
strArrayは文字列の配列ですが、もし添字のi+1が配列外を指していたら動作は保証されません。
なので、まずiの値を調べてみましょう。カーソルをiの上に持ってくと値が表示されるはずです。
あるいは、strArray[i+1]マウスで左クリックしながら選ぶと文字列を表示してくれるはずですが?
さて、どうでしょうか?
デバッガでiの値を見たところ7になっていたため+1すれば8になり配列外になってしまうと考えてiが7になったらこの処理をしないようにもしてみたんですが結果は同じでした・・・
本当に排除できていますか?
私はなにか間違っていると思います。
Re: 東方のような会話文の作成
Posted: 2012年8月12日(日) 19:00
by Takumi
softya(ソフト屋) さんが書きました:
本当に排除できていますか?
私はなにか間違っていると思います。
分かりました、もう一度見直してみます。
Re: 東方のような会話文の作成
Posted: 2012年8月12日(日) 19:16
by Takumi
なぜかelseを使ったらうまくいきました・・・。
コード:
int Ctrl_Message(int key,int lineMax,int DrawIndex[4],char *strArray[])
{
static int i=-1;
if(i==-1)
{
i=0;
DrawIndex[0]=0;
return 0;
}
if(i<lineMax-1)
{
if(strcmp(strArray[i+1],"/")==0)
{
i++;
DrawIndex[i%4]=-1;
return 0;
}
}
else
{
if(key=='z')
{
return 1;
}
}
if(DrawIndex[i%4]<lineMax-1)
{
if(key=='z')
{
i++;
DrawIndex[i%4]=i;
if(i%4==0)
{
DrawIndex[1]=-1;
DrawIndex[2]=-1;
DrawIndex[3]=-1;
}
return 0;
}
}
return 0;
}
Re: 東方のような会話文の作成
Posted: 2012年8月12日(日) 19:24
by softya(ソフト屋)
なんとなくと言うのが一番バグを潜ませるんですよね。いざ公開時にバグったりする厄介者です。
なので原因をはっきりさせておくべきです。
else前は何故落ちたのでしょうか?
Re: 東方のような会話文の作成
Posted: 2012年8月12日(日) 19:29
by Takumi
softya(ソフト屋) さんが書きました:なんとなくと言うのが一番バグを潜ませるんですよね。いざ公開時にバグったりする厄介者です。
なので原因をはっきりさせておくべきです。
else前は何故落ちたのでしょうか?
elseの前はif(i==lineMax-1)を使っていたのでiがlineMax-1より大きくなっていたんだと予想できますが、どこでそんな大きくなったのやら・・・
Re: 東方のような会話文の作成
Posted: 2012年8月12日(日) 19:35
by softya(ソフト屋)
Takumi さんが書きました:softya(ソフト屋) さんが書きました:なんとなくと言うのが一番バグを潜ませるんですよね。いざ公開時にバグったりする厄介者です。
なので原因をはっきりさせておくべきです。
else前は何故落ちたのでしょうか?
elseの前はif(i==lineMax-1)を使っていたのでiがlineMax-1より大きくなっていたんだと予想できますが、どこでそんな大きくなったのやら・・・
それはバグの原因として危険そうですね。
何処で更新されるか探ってみましょうか。
問題はi++;だと思います。これをしているところは少ないので、その後ろでブレークして値を確認してみましょう。
8が確認されたら今回はたまたま動いていた潜在バグです。
あとiは名前として意味を持たないので、ちゃんとした名前を付けましょう。
Re: 東方のような会話文の作成
Posted: 2012年8月12日(日) 19:47
by Takumi
softya(ソフト屋) さんが書きました:
それはバグの原因として危険そうですね。
何処で更新されるか探ってみましょうか。
問題はi++;だと思います。これをしているところは少ないので、その後ろでブレークして値を確認してみましょう。
8が確認されたら今回はたまたま動いていた潜在バグです。
あとiは名前として意味を持たないので、ちゃんとした名前を付けましょう。
ブレークとは何でしょうか?
Re: 東方のような会話文の作成
Posted: 2012年8月12日(日) 19:53
by Takumi
過去のプログラムを見てみたらDrawIndex[i%4]!=lineMax-1が条件式になっていますがこの条件式が真ならDrawIndex[i%4]=-1;が実行されてしまうがために無限ループになりエラーが吐かれたのでしょうか?
Re: 東方のような会話文の作成
Posted: 2012年8月12日(日) 21:02
by softya(ソフト屋)
Takumi さんが書きました:過去のプログラムを見てみたらDrawIndex[i%4]!=lineMax-1が条件式になっていますがこの条件式が真ならDrawIndex[i%4]=-1;が実行されてしまうがために無限ループになりエラーが吐かれたのでしょうか?
ぜひ、確認してみてください。
そして、こういう危険な状態に陥り辛い方法も考えてみましょう。
Re: 東方のような会話文の作成
Posted: 2012年8月12日(日) 22:20
by Takumi
softya(ソフト屋) さんが書きました:Takumi さんが書きました:過去のプログラムを見てみたらDrawIndex[i%4]!=lineMax-1が条件式になっていますがこの条件式が真ならDrawIndex[i%4]=-1;が実行されてしまうがために無限ループになりエラーが吐かれたのでしょうか?
ぜひ、確認してみてください。
そして、こういう危険な状態に陥り辛い方法も考えてみましょう。
やはりelseを付けなくて終了する時の条件がi==lineMax-1のままでも上二つの条件をi<lineMax-1に変えてやれば正常に終了しました。
やっぱりさっき言った無限ループが原因みたいです。
コード:
int Ctrl_Message(int key,int lineMax,int DrawIndex[4],char *strArray[])
{
static int i=-1;
if(i==-1)
{
i=0;
DrawIndex[0]=0;
return 0;
}
if(i<lineMax-1)
{
if(strcmp(strArray[i+1],"/")==0)
{
i++;
DrawIndex[i%4]=-1;
return 0;
}
}
if(i<lineMax-1)
{
if(key=='z')
{
i++;
DrawIndex[i%4]=i;
if(i%4==0)
{
DrawIndex[1]=-1;
DrawIndex[2]=-1;
DrawIndex[3]=-1;
}
return 0;
}
}
if(i==lineMax-1)
{
if(key=='z')
{
return 1;
}
}
return 0;
}
Re: 東方のような会話文の作成
Posted: 2012年8月12日(日) 22:52
by softya(ソフト屋)
とりあえず、良いと思われるコードでいろんな条件でテストしてみてください。
1点気になるのは、
if(i==lineMax-1)
ですかね。
if(i>=lineMax-1)
とすればより安全です。
Re: 東方のような会話文の作成
Posted: 2012年8月12日(日) 23:19
by Takumi
softya(ソフト屋) さんが書きました:とりあえず、良いと思われるコードでいろんな条件でテストしてみてください。
1点気になるのは、
if(i==lineMax-1)
ですかね。
if(i>=lineMax-1)
とすればより安全です。
elseを使った方もelseを使わない方もいろいろな文字列でテストしましたが異常はありませんでした。
しかしelseを使った方は文字がチラチラしませんでしたが使わない方は文字がキーを押すたびに少しチラチラしてしまいます。
でも安全面を考えればelseは使わない方がいいと思うのですが・・・
Re: 東方のような会話文の作成
Posted: 2012年8月12日(日) 23:23
by Takumi
あ、elseを使わない方でも終了処理のコードを上の方にもっていったら文字がチラチラしなくなりました。
Re: 東方のような会話文の作成
Posted: 2012年8月13日(月) 17:41
by Takumi
softya(ソフト屋)さん、次は何をするのでしょうか?
Re: 東方のような会話文の作成
Posted: 2012年8月13日(月) 17:47
by softya(ソフト屋)
Takumi さんが書きました:softya(ソフト屋)さん、次は何をするのでしょうか?
>とりあえず、良いと思われるコードでいろんな条件でテストしてみてください。
と書きましたが色々なパターンのデータでテストはされたのでしょうか?
あと上の方に書いてあると思いますがiの名前も変えてくださいね。
残りの作業のロードマップです。
1つ1つ片づけますので、いっぺんにやらないでくださいね。
(1) メッセージ処理をファイル分割。
(2) メッセージの読み込み処理を搭載。
(3) 龍神録に組みこみ。メッセージ表示をDrawFormatString()に切り替える。
Re: 東方のような会話文の作成
Posted: 2012年8月13日(月) 17:51
by Takumi
softya(ソフト屋) さんが書きました:
>とりあえず、良いと思われるコードでいろんな条件でテストしてみてください。
と書きましたが色々なパターンのデータでテストはされたのでしょうか?
あと上の方に書いてあると思いますがiの名前も変えてくださいね。
残りの作業のロードマップです。
1つ1つ片づけますので、いっぺんにやらないでくださいね。
(1) メッセージ処理をファイル分割。
(2) メッセージの読み込み処理を搭載。
(3) 龍神録に組みこみ。メッセージ表示をDrawFormatString()に切り替える。
メッセージ処理をファイル分割とは具体的にどんな事をすればいいでしょうか?
Re: 東方のような会話文の作成
Posted: 2012年8月13日(月) 18:01
by softya(ソフト屋)
このmainのままtalk.cppをもう一度作ると言うことです。
名前を前のに合わせるとCtrl_Messageはtalk_Main()でしょうかね。
Draw_Messageがtalk_Graph()ですね。
今回のtalk関係の関数は、すべてtalk.cppに集めておいてください。
Re: 東方のような会話文の作成
Posted: 2012年8月13日(月) 19:38
by Takumi
softya(ソフト屋) さんが書きました:このmainのままtalk.cppをもう一度作ると言うことです。
名前を前のに合わせるとCtrl_Messageはtalk_Main()でしょうかね。
Draw_Messageがtalk_Graph()ですね。
今回のtalk関係の関数は、すべてtalk.cppに集めておいてください。
talk.cppに集めた関数をどうやってmain.cppのmainで呼べるようにできるか分かりません...
Re: 東方のような会話文の作成
Posted: 2012年8月13日(月) 19:51
by Takumi
これでいいですかね?
main.cpp
コード:
#include <stdio.h>
#include<string.h>
#include <conio.h>
#include <Windows.h>
#include "../include/function.h"
// メッセージ制御
// メッセージ表示
int main()
{
char *strArray[8]=
{
"こんにちは",
"/",
"/",
"暑いですね",
"2ページ目です",
"/",
"変則です",
"/"
};
int lineMax =8;
// メッセージ表示制御用。
int DrawIndex[4] = {-1,-1,-1,-1}; //-1は非表示。それ以外は表示するstrArrayの添字
// 処理ループ
while( 1 ) {
// リアルタイムキー入力。キーはkeyの値以外は使用禁止です。
int key = ' ' ; ///keyをスペースで初期化
if( kbhit() ) { ///何か押されたら
key = getch(); ///押されたキーの値をkeyに
}
// 途中終了
if( key == 'q' || key == 'Q' ) {
break;
}
// メッセージ制御の関数を呼び出す。
if( talk_Main(key,lineMax,DrawIndex,strArray/*考えて追加を*/) ) {
break; // 終了条件での終了。
}
// 画面クリア
system("cls");
// 表示処理
talk_Graph(strArray,DrawIndex);
// 処理時間待ち
Sleep( 50 ); //50ms待つ
}
printf("\n\n終了します。\n");
return 0;
}
talk.cpp
コード:
#include <stdio.h>
#include<string.h>
#include <conio.h>
#include <Windows.h>
#include "../include/function.h"
int talk_Main(int key,int lineMax,int DrawIndex[4],char *strArray[])
{
static int Nowline=-1;
if(Nowline>=lineMax-1)
{
if(key=='z')
{
return 1;
}
}
if(Nowline==-1)
{
Nowline=0;
DrawIndex[0]=0;
return 0;
}
if(Nowline<lineMax-1)
{
if(strcmp(strArray[Nowline+1],"/")==0)
{
Nowline++;
DrawIndex[Nowline%4]=-1;
return 0;
}
}
if(Nowline<lineMax-1)
{
if(key=='z')
{
Nowline++;
DrawIndex[Nowline%4]=Nowline;
if(Nowline%4==0)
{
DrawIndex[1]=-1;
DrawIndex[2]=-1;
DrawIndex[3]=-1;
}
return 0;
}
}
return 0;
}
void talk_Graph(char *strArray[],int DrawIndex[4])
{
// 4行の表示
for( int i=0 ; i<4 ; i++ ) {
if( DrawIndex[i]!=-1 ) {
int index = DrawIndex[i]; //表示するメッセージの番号を取り出す。
printf( "%s\n", strArray[index] ); //メッセージ表示
} else {
printf( "\n" ); //改行のみ
}
}
}
function.h
コード:
int talk_Main(int key,int lineMax,int DrawIndex[4],char *strArray[]);
void talk_Graph(char *strArray[],int DrawIndex[4]);
Re: 東方のような会話文の作成
Posted: 2012年8月13日(月) 20:48
by softya(ソフト屋)
OKですね。
さて次のステップとして、lineMax,DrawIndex,strArrayをtalk.cppに引越しして関数外のstaticな変数にしてください。つまり引数にするのを止めます。
それとNowline外に移します。
あとはステップ(2)の読み込み処理に移りますが、メッセージ読み込みバッファを2次元のcharで取りましょうか。
mallocしたい所ですが簡単なのではじめから配列で確保します。30行ぐらいあれば足りると思いますがどうでしょう?
Re: 東方のような会話文の作成
Posted: 2012年8月13日(月) 21:19
by Takumi
softya(ソフト屋) さんが書きました:OKですね。
さて次のステップとして、lineMax,DrawIndex,strArrayをtalk.cppに引越しして関数外のstaticな変数にしてください。つまり引数にするのを止めます。
それとNowline外に移します。
あとはステップ(2)の読み込み処理に移りますが、メッセージ読み込みバッファを2次元のcharで取りましょうか。
mallocしたい所ですが簡単なのではじめから配列で確保します。30行ぐらいあれば足りると思いますがどうでしょう?
引数にするのをやめる事はできました。
一つの会話には30行あれば十分です。
Re: 東方のような会話文の作成
Posted: 2012年8月13日(月) 21:28
by softya(ソフト屋)
Takumi さんが書きました:softya(ソフト屋) さんが書きました:OKですね。
さて次のステップとして、lineMax,DrawIndex,strArrayをtalk.cppに引越しして関数外のstaticな変数にしてください。つまり引数にするのを止めます。
それとNowline外に移します。
あとはステップ(2)の読み込み処理に移りますが、メッセージ読み込みバッファを2次元のcharで取りましょうか。
mallocしたい所ですが簡単なのではじめから配列で確保します。30行ぐらいあれば足りると思いますがどうでしょう?
引数にするのをやめる事はできました。
一つの会話には30行あれば十分です。
では、指定された会話テキストファイルを引数にして一度に配列に読み込む関数を追加してください。
例えばtalk_Load("ファイル名")と言った感じです。
strArrayを初期値では2次元のchar配列に変えて
#define READ_LINE_MAX (30) /*行数*/
#define READ_STRING_LEN_MAX (100) /*一行の最大文字数*/
を使って定義して下さい。この定数は読みこむ時のオーバーチェックにも使います。
lineMaxには実際に読み込んだ行数を数えて入れてください。
DrawIndexとNowlineは読み込む度に初期化するようにします。
Re: 東方のような会話文の作成
Posted: 2012年8月13日(月) 23:01
by Takumi
softya(ソフト屋) さんが書きました:
では、指定された会話テキストファイルを引数にして一度に配列に読み込む関数を追加してください。
例えばtalk_Load("ファイル名")と言った感じです。
strArrayを初期値では2次元のchar配列に変えて
#define READ_LINE_MAX (30) /*行数*/
#define READ_STRING_LEN_MAX (100) /*一行の最大文字数*/
を使って定義して下さい。この定数は読みこむ時のオーバーチェックにも使います。
lineMaxには実際に読み込んだ行数を数えて入れてください。
DrawIndexとNowlineは読み込む度に初期化するようにします。
ファイル名を引数にしてファイルを読み込む方法が分かりません、fopenでファイルを指定して読み込む方法以外思いつきません。
Re: 東方のような会話文の作成
Posted: 2012年8月13日(月) 23:09
by softya(ソフト屋)
Takumi さんが書きました:softya(ソフト屋) さんが書きました:
では、指定された会話テキストファイルを引数にして一度に配列に読み込む関数を追加してください。
例えばtalk_Load("ファイル名")と言った感じです。
strArrayを初期値では2次元のchar配列に変えて
#define READ_LINE_MAX (30) /*行数*/
#define READ_STRING_LEN_MAX (100) /*一行の最大文字数*/
を使って定義して下さい。この定数は読みこむ時のオーバーチェックにも使います。
lineMaxには実際に読み込んだ行数を数えて入れてください。
DrawIndexとNowlineは読み込む度に初期化するようにします。
ファイル名を引数にしてファイルを読み込む方法が分かりません、fopenでファイルを指定して読み込む方法以外思いつきません。
関数の引数をchar*型にして、そのままfopenの引数にするだけです。
文字列はchar型のポインタで扱えると入門書や入門サイトに書いてあるはずですよ。
※ この機会に文字列ポインタのところをよく読んでみてください。
Re: 東方のような会話文の作成
Posted: 2012年8月14日(火) 13:35
by Takumi
softya(ソフト屋) さんが書きました:
関数の引数をchar*型にして、そのままfopenの引数にするだけです。
文字列はchar型のポインタで扱えると入門書や入門サイトに書いてあるはずですよ。
※ この機会に文字列ポインタのところをよく読んでみてください。
これをmainでファイル名を指定して使ってやればいいですかね?
コード:
void talk_Load(char*text)
{
FILE *file;
file=fopen(text,"r");
}
あとstrArrayの初期値の定義というのは初期化する事だと思って書いてみたんですがうまくいきません。
char *strArray[READ_LINE_MAX][READ_STRING_LEN_MAX]={0};
Re: 東方のような会話文の作成
Posted: 2012年8月14日(火) 14:15
by softya(ソフト屋)
fopenだけでなくtalk_Loadでメッセージを読み込んでcloseまでしてください。
あと
char *strArray[READ_LINE_MAX][READ_STRING_LEN_MAX]={0};
ではなく、*が余分なのと初期値はいらないです。
*があるとcharの2次元配列ではく、char*(文字列)の2次元配列になってしまいます。
【補足】
最初のコードは、FileRead_openを使ってましたが止めたのですか?
Re: 東方のような会話文の作成
Posted: 2012年8月14日(火) 14:22
by Takumi
softya(ソフト屋) さんが書きました:fopenだけでなくtalk_Loadでメッセージを読み込んでcloseまでしてください。
あと
char *strArray[READ_LINE_MAX][READ_STRING_LEN_MAX]={0};
ではなく、*が余分なのと初期値はいらないです。
*があるとcharの2次元配列ではく、char*(文字列)の2次元配列になってしまいます。
【補足】
最初のコードは、FileRead_openを使ってましたが止めたのですか?
FileRead_openはDXライブラリをインクルードしてないと使えませんよね?
Re: 東方のような会話文の作成
Posted: 2012年8月14日(火) 14:23
by softya(ソフト屋)
Takumi さんが書きました:softya(ソフト屋) さんが書きました:fopenだけでなくtalk_Loadでメッセージを読み込んでcloseまでしてください。
あと
char *strArray[READ_LINE_MAX][READ_STRING_LEN_MAX]={0};
ではなく、*が余分なのと初期値はいらないです。
*があるとcharの2次元配列ではく、char*(文字列)の2次元配列になってしまいます。
【補足】
最初のコードは、FileRead_openを使ってましたが止めたのですか?
FileRead_openはDXライブラリをインクルードしてないと使えませんよね?
これは失礼しました。複数回答で混乱したようです。
fopenでやるしか無いですよね。
Re: 東方のような会話文の作成
Posted: 2012年8月14日(火) 14:46
by Takumi
メッセージを読み込むために「file=strArray;」と書いてみたのですがエラーを吐かれます。どうしてでしょうか?
あとDrawIndexとNowlineは読み込む度に初期化するためにtalk_Loadに
DrawIndex[4] = {-1,-1,-1,-1};
Nowline=-1;
と書いてみましたがDrawIndexの方でエラーが吐かれてしまいます。
Re: 東方のような会話文の作成
Posted: 2012年8月14日(火) 14:55
by softya(ソフト屋)
Takumi さんが書きました:メッセージを読み込むために「file=strArray;」と書いてみたのですがエラーを吐かれます。どうしてでしょうか?
あとDrawIndexとNowlineは読み込む度に初期化するためにtalk_Loadに
DrawIndex[4] = {-1,-1,-1,-1};
Nowline=-1;
と書いてみましたがDrawIndexの方でエラーが吐かれてしまいます。
うーん。
もう少しC言語をちゃんと勉強したほうが良いでしょう。
例えfileにstrArrayを代入できても何も起こりません。fgetsを使ってください。
DrawIndexの件はforループで行います。