画面移動について

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

画面移動について

#1

投稿記事 by 山下 » 12年前

始めまして、C言語を使ってRPGを作ろうと思っています。
新・ゲームプログラミングの館の    3.4 簡単な選択画面を作る(マイナス方向のループ) を参考にして、ゲームのスタート画面を作りました。
それで、次にスペースを押したら、選択している文字列によって、異なる計算をさせたいのですが、うまくいきません。

以下コードです。

コード:

#include "DxLib.h"

int Key[256];

int *menunum;
int menuNo = 0;
int z = 0;

int gpUpdateKey(){
	char tmpKey[256];
	GetHitKeyStateAll( tmpKey );
	for( int i=0; i<256; i++ ){ 
		if( tmpKey[i] != 0 ){
			Key[i]++;  
		} else {         
			Key[i] = 0;  
		}
	}
	return 0;
}

typedef struct{
        int x, y;       
        char name[128]; 
} MenuElement_t ;

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
        ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK );

		int handle = LoadSoundMem("音楽/Squall -backing track-.mp3");

		int backgraph = LoadGraph("画像/pipo-pic001.jpg");

      
        MenuElement_t MenuElement[5]={
                {  80, 100, "ゲームスタート" },
                { 100, 150, "おまけ" },
                { 100, 200, "ヘルプ" },
                { 100, 250, "コンフィグ" },
                { 100, 300, "ゲーム終了" },
        };
        int SelectNum = 0; 

		PlaySoundMem(handle,DX_PLAYTYPE_LOOP);

        while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && gpUpdateKey()==0 && menuNo==0){		

			DrawGraph(0,0,backgraph,TRUE);

                if( Key[ KEY_INPUT_DOWN ] == 1 ){ 

                        SelectNum = ( SelectNum + 1 ) % 5; 
                }

		if( Key[ KEY_INPUT_UP ] == 1 ){ 

			SelectNum = ( SelectNum + 4 ) % 5; 
		}

		if( Key[ KEY_INPUT_DOWN ] == 1 || Key[ KEY_INPUT_UP ] == 1 ){ 
			for( int i=0; i<5; i++ ){              
				if( i == SelectNum ){          
					MenuElement[i].x = 80; 
				} else {                       
					MenuElement[i].x = 100;
				}
			}
		}


		for( int i=0; i<5; i++ ){ 
			DrawFormatString( MenuElement[i].x, MenuElement[i].y, GetColor(0,0,0), MenuElement[i].name );
		}

		if( Key[KEY_INPUT_SPACE] ==1){
					DeleteSoundMem( handle ) ;
					switch (SelectNum){
						case 0:
								*menunum = 0;
								break;
						case 1:
								*menunum = 1;
								break;
						case 2: 
								*menunum = 2;
								break;
						case 3:
								*menunum = 3;
								break;
						case 4:
								*menunum = 4;
								break;
					}
					menuNo = 1;
				}
		}
		if (*menunum == 0){
					
		} else if (*menunum == 1) {
			 while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && gpUpdateKey()==0){

			 }
		} else if (*menunum == 2) {
			 while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && gpUpdateKey()==0){
					
			 }
		} else if (*menunum == 3) {
			 while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && gpUpdateKey()==0){
					
			 }
		} else {
			 while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && gpUpdateKey()==0 && z>180){
					DrawFormatString( 300, 240, GetColor(255,255,255),"ゲームを終了させます" );
					z++;
			 }
		}
	DxLib_End(); 
	return 0;
}
まだ、5番目の文字列、ゲーム終了についてしか計算を書いてないので、
5番目の文字列の時スペースを押して、エラーが起きないか試したのですが、計算結果の「ゲームを終了させます」が表示せずにエラーで終了します。
非常に稚拙な質問で恐縮なのですが、答えてくださるとうれしいです。

アバター
御津凪
管理人
記事: 200
登録日時: 13年前
住所: 道内
連絡を取る:

Re: 画面移動について

#2

投稿記事 by 御津凪 » 12年前

質問内容について簡単に答えます。

まず、エラーで終了すると書いていますが、具体的にどのようなエラーが発生したのでしょうか。
もし、このコードで5番目の文字列の時にスペースを押した瞬間に何事もなく終了するのであれば、それは恐らく書いたコードの通りに正常に動作し、正常に終了しています。

次に、「ゲームを終了させます」が表示されない点ですが、

コード:

             while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && gpUpdateKey()==0 && z>180){
の、最後の式、 z>180 の不等号が逆になっています。

これでは z が 180 を超えた値のときにしか中身を処理しません。

よって、5番目の文字列の時にスペースを押してここにきても、中身を処理せずに終了してしまうコードになっています。
This article was written by "Mitsunagi".

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

Re: 画面移動について

#3

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

はじめまして。
まず、int *menunum;がポインタである理由がわかりません。menunumを初期化せずに使っていますので異常終了の原因はこれだと思います。
z>180に関しては、御津凪さんの指摘されたとおりです。

提案としてはDixqさんの講座とは相反しますが座標で管理せずにメニュー番号で管理したほうが良いと思います。
番号から表示位置や決めるのがシンプルで分りやすいからです。それにmenunumをポインタにする必要も無いです。

それとwhile( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && gpUpdateKey()==0){
のループを幾つも作るのは絶対にやっていはいけません。必ずうまく管理できません。
1つのプログラムの1つだけを心がけてください。

あと、インデント(字下げ)をちゃんとやるようにして見てください。
それだけでプログラムが見やすくなりますし、バグが減ります。


手前味噌ながら、RPG講座を書きましたので紹介させて頂きます。
RPG講座。ちょー簡単と書いてますが、簡単ではないです。すいません。
http://dixq.net/forum/blog.php?u=114&sd=a&c=2
→ 今現在サーバーアドレスの切り替え中なので見れない場合はこちら。http://183.181.50.211/forum/blog.php?u=114&sd=a&c=2
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

山下

Re: 画面移動について

#4

投稿記事 by 山下 » 12年前

御津凪さん、softya(ソフト屋)さん、ご教示ありがとうございました。

①menunum
確かに、menunumは、ポインタである必要はないですね。
どう考えても変ですね…
int 変数に訂正しました。

②z
zの不等号も訂正しました。

③whileループ
while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && gpUpdateKey()==0){
のループをたくさんつくるのはよくないとは思ったのですが、ひとつにまとめる方法が思いつきません…

④インデント
インデントは以後、丁寧にやっていこうと思います。


指摘箇所を訂正したら、無事にプログラムをスペースを押すことで終了できました。


RPG講座拝見させて頂きます。


softya(ソフト屋)さんの提案(座標でなくメニュー番号で管理したほうがいい)というのはつまりどういうことでしょうか?

お手を煩わせてしまいますが、答えてくださると助かります。

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

Re: 画面移動について

#5

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

③while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && gpUpdateKey()==0){
のループをたくさんつくるのはよくないとは思ったのですが、ひとつにまとめる方法が思いつきません…

今現在のプログラムでも、複数のwhile( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && gpUpdateKey()==0){は必要ないはずです。
試しに外してみてください。

⑦softya(ソフト屋)さんの提案(座標でなくメニュー番号で管理したほうがいい)というのはつまりどういうことでしょうか?
ごめんなさい勘違いでした。SelectNum で管理されてますね。今のままでOKです。


提案ですが今後の事を考えて、
・別関数にメニュー選択を分離する(whileは増やさない)
・menunum ではなく一般的なstate(状態)という変数名を使う。stateはenumで値を定義する。
をやってみてください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

閉鎖

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