ステージの開始時間

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
えっと

ステージの開始時間

#1

投稿記事 by えっと » 16年前

龍神録プログラミングの館50章の段階では、プログラムを実行したとき、いきなりステージ画面から始まりますが、その前にキャラクター選択画面などを挿入したいときどう変えればいいのでしょうか?
つまりステージ0の開始時間を自分で設定するにはどこをどういじればいいのでしょう・・。

Dixq (管理人)

Re:ステージの開始時間

#2

投稿記事 by Dixq (管理人) » 16年前

まずメイン関数の仕様を確認してください。スイッチ文で実行したい関数を制御していますよね?
func_stateの値を任意に変更することで、呼びたい関数が制御できます。

例えばメニューを表示する関数をmenu()として作ったとして、
func_stateが10の時にmenu()を呼びたいとします。

初期化処理が済んだとき、func_stateを10にするようにしてください。
すると初期化が済んだとき、この関数が呼ばれます。
シューティング画面にしたいときは、シューティングの画面の関数を呼ぶ値にfunc_stateを変更してください。
このことをプログラムを見ながら確認してみます。

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){
	ChangeWindowMode(TRUE);//ウィンドウモード
	if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化

	while(ProcessLoop()==0){//メインループ
		music_ini();
		switch(func_state){
			case 0://初回のみ入る処理
				load();		//データロード
				first_ini();//初回の初期化
				func_state=99;
				break;
			case 99://STGを始める前に行う初期化
				ini();
				load_story();
				func_state=100;
				break;
			case 100://通常処理
						 enter_func_tm("最初");
				calc_ch();       enter_func_tm("キャラ計算");
				ch_move();       enter_func_tm("キャラ移動");
				cshot_main();    enter_func_tm("自機ショットメイン");
				enemy_main();	 enter_func_tm("敵処理メイン");
				boss_shot_main();enter_func_tm("ボスショットメイン");
				shot_main();	 enter_func_tm("ショットメイン");
				out_main();  	 enter_func_tm("当たり判定");
				effect_main();   enter_func_tm("エフェクトメイン");
				calc_main();	 enter_func_tm("計算メイン");
				graph_main();    enter_func_tm("描画メイン");
				bgm_main();	 enter_func_tm("BGMメイン");
				if(boss.flag==0)
					stage_count++;
				break;
			default:
				printfDx("不明なfunc_state\n");
				break;
		}
		music_play();		enter_func_tm("音楽再生");
		fps_wait();		enter_func_tm("待機した時間",1);
		if(CheckStateKey(KEY_INPUT_ESCAPE)==1)break;//エスケープが入力されたらブレイク
		ScreenFlip();//裏画面反映
		count++;

	}
	DxLib_End();//DXライブラリ終了処理
	return 0;
}

処理は最初case 0に入ってデータのロードや色々と最初の初期化処理がされます。
func_state=99;
があるので、次は99に入ります。
ここではシューティングゲームについての初期化やシューティングの設定のロードなどが行われます。
func_state=100;
があるので、次には100に入ります。
100で普通にシューティングの処理がされています。

では先ほど言ったようにcase 10でメニューの処理をしてみます。

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){
	ChangeWindowMode(TRUE);//ウィンドウモード
	if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化

	while(ProcessLoop()==0){//メインループ
		music_ini();
		switch(func_state){
			case 0://初回のみ入る処理
				load();		//データロード
				first_ini();//初回の初期化
				func_state=10;
				break;
			case 10:
				DrawString(0, 0,"メニュー表示しています。",GetColor(255,255,255));
				DrawString(0,20,"Zキーを押すとシューティングを開始します。",GetColor(255,255,255));
				if( CheckStatePad(configpad.shot ) == 1 ){
					func_state = 99;
				}
				break;
			case 99://STGを始める前に行う初期化
				ini();
				load_story();
				func_state=100;
				break;
			case 100://通常処理
								 enter_func_tm("最初");
				calc_ch();       enter_func_tm("キャラ計算");
				ch_move();       enter_func_tm("キャラ移動");
				cshot_main();    enter_func_tm("自機ショットメイン");
				enemy_main();	 enter_func_tm("敵処理メイン");
				boss_shot_main();enter_func_tm("ボスショットメイン");
				shot_main();	 enter_func_tm("ショットメイン");
				out_main();  	 enter_func_tm("当たり判定");
				effect_main();   enter_func_tm("エフェクトメイン");
				calc_main();	 enter_func_tm("計算メイン");
				graph_main();    enter_func_tm("描画メイン");
				bgm_main();		 enter_func_tm("BGMメイン");
				if(boss.flag==0)
					stage_count++;
				break;
			default:
				printfDx("不明なfunc_state\n");
				break;
		}
		music_play();			 enter_func_tm("音楽再生");
		fps_wait();				 enter_func_tm("待機した時間",1);
		if(CheckStateKey(KEY_INPUT_ESCAPE)==1)break;//エスケープが入力されたらブレイク
		ScreenFlip();//裏画面反映
		count++;

	}
	DxLib_End();//DXライブラリ終了処理
	return 0;
}

このようにcaseで好きな処理を分けてください。
fps制御や音楽ファイル管理などは共通しているので、毎回呼ばれるようになっています。
 

えっと

Re:ステージの開始時間

#3

投稿記事 by えっと » 16年前

ありがとうございます。
caseで場合分けすれば良かったんですね。
私はメニューの処理をシューティングのところに無理やり押し込もうとしていました・・。

えっと

Re:ステージの開始時間

#4

投稿記事 by えっと » 16年前

解決のマークを出してしまいましたが、続けて質問させていただきます。
上に書いてくださったcase10のところで、”メニューを表示しています。”と”Zキーを押すとシューティングを開始します。”という文章が同時に表示されていますが、これを、”メニューを表示しています”と表示したあとにshotキーを押すと”Zキーを押すとシューティングを開始します。”という文に切り替わるようにしたいです。
case 10:
  				DrawString(0, 0,"メニュー表示しています。",GetColor(255,255,255));
                if( CheckStatePad(configpad.shot ) == 1 ){
				DrawString(0,20,"Zキーを押すとシューティングを開始します。",GetColor(255,255,255));
				}
				if( CheckStatePad(configpad.shot ) == 1 ){
					func_state = 99;
				}
				break;
としてみたのですが、一度shotキーを押すと一気にcase99に飛んでしまい、上手くいきません。
試しに下のようにshotキーではなく、bomキーでやってみたのですが、
case 10:
  				DrawString(0, 0,"メニュー表示しています。",GetColor(255,255,255));
                if( CheckStatePad(configpad.bom ) == 1 ){
				DrawString(0,20,"Zキーを押すとシューティングを開始します。",GetColor(255,255,255));
				}
				if( CheckStatePad(configpad.shot ) == 1 ){
					func_state = 99;
				}
				break;
”Zキーを押すとシューティングを開始します。”という文が、キーを押した瞬間しか表示されません。
ifの部分に原因があると思いますが、どのように変更すれば上手くいくでしょうか?

ibis

Re:ステージの開始時間

#5

投稿記事 by ibis » 16年前

例えばこういうのとか。
擬似コードですが勘弁。
case 10:
    "メニューを表示しています。"を表示;
    if(shotキー押下){
        func_state = 11;
    }
case 11:
    "メニューを表示しています。"を表示;
    "Zキーを押すとシューティングを開始します。"を表示;
    if(Zキー押下){
        func_state = 99;
    }

Dixq (管理人)

Re:ステージの開始時間

#6

投稿記事 by Dixq (管理人) » 16年前

最初はだいたいの説明をするので、自分で調べて解決してみて下さい。
その方が今後の為になると思いますので。

まず、関数の仕様を確認して下さい。
CheckStatePad
ってどういう関数でしたっけ?返って来るのは何でしたっけ?

後、

if(条件式1){
   //1;
}

if(条件式1){
   //2;
}

と書くと1も2も同時に実行されてしまいますよね。実行する条件が同じなんですから。

この辺に気をつけて書いてみて下さい。
 

えっと

Re:ステージの開始時間

#7

投稿記事 by えっと » 16年前

ibisさんありがとうございます。
そのように書いてみたところ、上手く表示させることができました。
(case11では "メニューを表示しています。"という文は消すという意味でした。その一文をcase11から取り除くと、意図したように出来ました。)

ただ、caseを分けずに、同じcase内で文を切り替えることは出来ないのでしょうか?
もし、case100内(STG内)でそのようにしたいとき、困ってしまうと思うので。

えっと

Re:ステージの開始時間

#8

投稿記事 by えっと » 16年前

管理人さんありがとうございます。考えてみます。

やそ

Re:ステージの開始時間

#9

投稿記事 by やそ » 16年前

おおぉ、すでに回答がたくさん付いておるわい。やそじいさんじゃ。
横から入るのは瓦版(掲示板)だけはいいのじゃ!
じゃが、バス停で並んでいる所に横入りはけしからんのじゃ!入っていいのはうちのタマだけなのじゃ。

えっと殿よ、
一瞬しか表示しないのは仕様なのぢゃっ!(嘘・・・じゃないですわい)
メインループ処理はその名の通りメインなので1秒のうち何十回どころの騒ぎじゃないほど
るーぷしてるのぢゃぞ。そりゃもう大騒ぎなのぢゃっ!裏の大吉じじいの通夜ぐらいの大騒ぎなのじゃ!!

なのじゃからして毎回ProcessLoop()が実行されて、その中でGetHitKeyStateAll_2();//現在のキー入力処理を行う
を行っているのじゃぞ?
そうしたら前回押したキーの情報なぞ、もう古いに決まっておろうが。
となりの梅婆さんの漬けた梅干くらいに古すぎるんじゃ。ふぉっふぉっふぉ。

じゃからして、メニュー画面を段階的に制御したければ一工夫するしかないわいのぉ。
若者よ、あせらずじっくり考えるのじゃ。

とりあえず、
8のきーこんふぃ○○、ふがふがっ!

(ゴキッ!)

・・・

ピーポーピーポー!!(退場!!)

(削除パス:fuga)

Dixq (管理人)

Re:ステージの開始時間

#10

投稿記事 by Dixq (管理人) » 16年前

何の一人芝居っすか^^;
しかも削除パスまで公開されているw

やそ

Re:ステージの開始時間

#11

投稿記事 by やそ » 16年前

この大不況やさぐれ時代を生きるためには気分転換も必要なのら。
ここの掲示板もだいぶ回答者側に疲れが見えてきて、ささくれが痛い季節になってきたのだぴょん。
(ささくれの原因はビタミン不足で季節は関係ないけどね~)

一人で仕事してるとつまらないので掲示板見て、ただ回答するのもつまらないから
以前のツンデレバージョンがマニアに受けたので、
これからの高齢者社会の予行演習(?)ということで「じじいバージョン」を作ってみたッス。

評判が悪いなら消せるようにと削除キー(パス)も載っけておいた。
(つーか、スルーされて終わりだな(笑))
(削除パス:fuga)

えっと

Re:ステージの開始時間

#12

投稿記事 by えっと » 16年前

やそじいさんありがとうございますww
じじいバージョン凄く良いと思います!!
普通に説明されるよりもわかり易かったような気がしますw
(最初見たときちょっとびっくりしました。意表を突かれた感じで)
とりあえず第2弾期待しています!
(ツンデレバージョンも気になる・・過去ログあさってみようかなw)

私の理解力が乏しすぎるせいで返信するのが遅くなってしまいました。
管理人さんが示してくれたifの用法と、やそさんのおっしゃったメインループ処理、曖昧にしていたこれらの内容をなんとか理解できたかと思います。
メニュー画面の段階的な制御についてですが、ibisさんが答えてくださったcaseを増やす方法が一番良いような気がします。同じcase内で制御を行いたかったら、その内部でswitch文を使えばいいですよね。
switch文を使わないシンプルな方法がありましたら教えてください。

8章はkeyやpadに関する関数が多く登場して頭が混乱してます。
一つずつ整理していこうと思います。

Dixq (管理人)

Re:ステージの開始時間

#13

投稿記事 by Dixq (管理人) » 16年前

if文、スイッチ文などの使い方がC言語のごく基本的な部分なので、
もしこの辺が曖昧ならまだゲームに手を出さない方がいいかもしれません。

今回の場合だけ特別で、分からなかっただけだと言う場合はよいかもしれませんが、
背伸びすると余計に時間がかかる場合があります。
龍神録の館には少し難しい書き方も出てきます。1から10まで説明していない部分もあります。
なんでも基礎が大事と言いますが、基礎がしっかりしていないと、読んでも理解が困難である場合が多いと思います。
もしよくわからなければ、さしあたりC言語入門系のサイトを見て、サンプルを沢山実行し、読み、理解し、演習し、C言語に慣れて下さい。
一通りC言語を勉強し、慣れてからもう一度ゲーム制作に戻れば随分違ってくると思います。

閉鎖

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