メニュー画面について

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

メニュー画面について

#1

投稿記事 by marth » 14年前

 前回、「MenuElement_tの変数の寿命が~」ということを受け、static MenuElement_tにしましたが、まだ画面が動かないです。使用しているのはWindows7のVisualC++とDxlibです。ソースコードを載せますので、どこが違うか教えてください。

コード:


#include "DxLib.h"

int Key[256];
int menunum;
int menuNo=0;
int z=1;


// キーの入力状態を更新する
int gpUpdateKey(){
        char tmpKey[256]; // 現在のキーの入力状態を格納する
        GetHitKeyStateAll( tmpKey ); // 全てのキーの入力状態を得る
        for( int i=0; i<256; i++ ){ 
                if( tmpKey[i] != 0 ){ // i番のキーコードに対応するキーが押されていたら
                        Key[i]++;     // 加算
                } else {              // 押されていなければ
                        Key[i] = 0;   // 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 ); //ウィンドウモード変更と初期化と裏画面設定

        // メニュー項目要素を5つ作る
        static MenuElement_t MenuElement[6]={
                {  80, 100, "ゲームスタート" }, // タグの中身の順番で格納される。xに80が、yに100が、nameに"ゲームスタート"が
                { 100, 150, "?????" },
                { 100, 200, "?????" },
                { 100, 250, "レコード" },
                { 100, 300, "オプション" },
				{ 100, 350, "ゲーム終了"},
        };
        int SelectNum = 0; // 現在の選択番号

        // while(裏画面を表画面に反映, メッセージ処理, 画面クリア, キー更新)
        while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && gpUpdateKey()==0 && z<180){

                // 計算フェーズ 

                if( Key[ KEY_INPUT_DOWN ] == 1 ){ // 下キーが押された瞬間だけ処理

                        SelectNum = ( SelectNum + 1 ) % 6; // 現在の選択項目を一つ下にずらす(ループする)
                }

		if( Key[ KEY_INPUT_UP ] == 1 ){ // 上キーが押された瞬間だけ処理

			SelectNum = ( SelectNum + 5 ) % 6; // 現在の選択項目を一つ上にずらす(逆ループする)
		}

		if( Key[ KEY_INPUT_DOWN ] == 1 || Key[ KEY_INPUT_UP ] == 1 ){ // 下キーか、上キーが押された瞬間
			for( int i=0; i<6; i++ ){              // メニュー項目数である5個ループ処理
				if( i == SelectNum ){          // 今処理しているのが、選択番号と同じ要素なら
					MenuElement[i].x = 80; // 座標を80にする
				} else {                       // 今処理しているのが、選択番号以外なら
					MenuElement[i].x = 100;// 座標を100にする
				}
			}
		}
		// 描画フェーズ
		for( int i=0; i<6; i++ ){ // メニュー項目を描画
				DrawFormatString( MenuElement[i].x,    MenuElement[i].y, GetColor(255,255,255), MenuElement[i].name );
		}
		if(Key[KEY_INPUT_Z]==1 && z==1)
		{
			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;
				case 5:
					DxLib_End();
					break;
			}
		}
		if(Key[KEY_INPUT_X]==1 && z>1 )
		{
			z--;
		}
		if(Key[KEY_INPUT_Z]==1)
		{
			z++;
		}
		if(Key[KEY_INPUT_Z]==1 && z==2)
		{
			if(menunum==0){
				static MenuElement_t MenuElement[4]=
				{
					{80,100,"Easy(徒歩級)"},
					{100,150,"Normal(自転車級)"},
					{100,200,"Hard(乗用車級)"},
					{100,250,"HardPlus(在来線級)"},
				};
			}else if(menunum==1){
				static MenuElement_t MenuElement[3]=
				{
					{80,100,"???"},
					{100,150,"???"},
					{100,200,"???"},
				};
			}else if(menunum==2){
				static MenuElement_t MenuElement[2]=
				{
					{80,100,"???"},
					{100,150,"???"},
				};
			}else if(menunum==3){
				static MenuElement_t MenuElement[3]=
				{
					{80,100,"成績"},
					{100,150,"ランキング"},
					{100,200,"獲得称号リスト"},
				};
			}else if(menunum==4){
				static MenuElement_t MenuElement[3]=
				{
					{80,100,"BGM音量"},
					{100,150,"SE音量"},
					{100,200,"サウンドテスト"},
				};
			}
		}
	}

	DxLib_End(); // DXライブラリ終了処理
	return 0;
}
これでもダメなら、基本的なシステムから作り直すことにします。

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

Re: メニュー画面について

#2

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

前回に書きましたが、変数のスコープと寿命が理解されいないと思います。
http://dixq.net/forum/viewtopic.php?f=3 ... 054#p76054

同じ名前の変数が出てきますが、
static MenuElement_t MenuElement
これらは全部違うスコープを持つ変数なのでお互いに影響を与えません。
同じ名前にすれば入れ替わると思われている事が、そもそも大きな間違いと言うことになります。

MenuElementを全部違う名前にしてポインタで差し替えるとか別の方法が必要ですが、今のままだと別のバグを更に生む可能性があります。
あとインデント(字下げ)を正確に行わないとこれもバグの原因になります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

marth

Re: メニュー画面について

#3

投稿記事 by marth » 14年前

変数のスコープと寿命か…一時期メニューの部分を多次元配列にできないかな?とは思っていたんですけど、とりあえずメイン関数の作り方と「変数のスコープと寿命」を学び直すことにします。作りかけのメニュー画面の方はいったん削除して作り直すことにします。

アバター
bitter_fox
記事: 607
登録日時: 15年前
住所: 大阪府

Re: メニュー画面について

#4

投稿記事 by bitter_fox » 14年前

marth さんが書きました:変数のスコープと寿命か…一時期メニューの部分を多次元配列にできないかな?とは思っていたんですけど、とりあえずメイン関数の作り方と「変数のスコープと寿命」を学び直すことにします。作りかけのメニュー画面の方はいったん削除して作り直すことにします。
グラフィカルに変数のスコープと寿命を表してみました。
1.png
下線と同じ色で囲まれた□の範囲のみで有効となります。
ですので、緑・黄緑・青・水色・群青で囲まれた範囲で宣言された変数はその範囲を除いた赤で囲まれた範囲では有効となりません。
緑・黄緑・青・水色・群青で囲まれた範囲を除いた赤で囲まれた範囲でMenuElementを参照するとそれは赤下線のMenuElementとなります。

閉鎖

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