ページ 11

コンパイルエラー

Posted: 2012年5月05日(土) 05:16
by pot

コード:

龍神録の50章とゲームプログラミングの館の3.4章のプログラムを使用し、

コード:

メニュー画面を作成するためにmenu.cppを作り以下のようなプログラムを書いたのですがエラーが出ます。

menu.cpp(37) : error C2059: 構文エラー : 'while'
menu.cpp(37) : error C2143: 構文エラー : ';' が '{' の前にありません。
menu.cpp(37) : error C2447: '{' : 対応する関数ヘッダーがありません (旧形式の仮引数リスト?)

どうすれば上記のエラーが無くなるでしょうか?
OSはWindowsでコンパイラは VC++ 2008EEを使用しています。
C言語の知識は簡単な関数しか理解出来ない程度です。

コード:

#include "../include/GV.h"

int Key[256]; // キーが押されているフレーム数を格納する

// キーの入力状態を更新する
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 ;


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

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

                // 計算フェーズ 

                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++ ){              // メニュー項目数である5個ループ処理
				if( i == SelectNum ){          // 今処理しているのが、選択番号と同じ要素なら
					MenuElement[i].x = 80; // 座標を80にする
				} else {                       // 今処理しているのが、選択番号以外なら
					MenuElement[i].x = 100;// 座標を100にする
				}
			}
		}
		

		// 描画フェーズ

		for( int i=0; i<5; i++ ){ // メニュー項目を描画
			DrawFormatString( MenuElement[i].x, MenuElement[i].y, GetColor(255,255,255), MenuElement[i].name );
		}
		}

Re: コンパイルエラー

Posted: 2012年5月05日(土) 07:35
by みけCAT
このソースコードを見る限り、while文が関数の外に書かれているので、エラーになっているようです。
もしきちんと関数の中に書いているのであれば、ソースコード全体を貼ってください。

Re: コンパイルエラー

Posted: 2012年5月05日(土) 08:24
by beatle
恐らくインデント(字下げ)をきちんと行えば防げるエラーだと感じます。
チェック3 : インデントを揃えよう

Re: コンパイルエラー

Posted: 2012年5月05日(土) 13:33
by pot
http://dixq.net/g/03_04.html
上記のプログラムをmenu.cppにコピペしてとりあえず正常に動作するか確認したのですがエラーになります

> #include "DxLib.h"

> int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){

この行で問題が起こるみたいなんですがどのように書き換えれば正常に動作するでしょうか?

Re: コンパイルエラー

Posted: 2012年5月05日(土) 14:04
by だんごさん
pot さんが書きました:http://dixq.net/g/03_04.html
上記のプログラムをmenu.cppにコピペしてとりあえず正常に動作するか確認したのですがエラーになります
どういうエラーが出ますか?
もしかするとDxLibの設定を行っていない可能性があります。
こちらを参考にすればいいと思います。

最初の質問でのプログラムは関数で囲まれていないためエラーが出ます。

Re: コンパイルエラー

Posted: 2012年5月05日(土) 16:21
by pot
DxLib.hは参照元が間違っていたみたいなので解決しましたが

1>menu.obj : error LNK2005: _WinMain@16 は既に main.obj で定義されています。
1>menu.obj : error LNK2005: _WinMain@16 は既に main.obj で定義されています。
fatal error LNK1169: 1 つ以上の複数回定義されているシンボルが見つかりました。

このようなエラーが出てしまいます。
どのような関数を使えば解決出来るでしょうか?

Re: コンパイルエラー

Posted: 2012年5月05日(土) 16:26
by softya(ソフト屋)
1>menu.obj : error LNK2005: _WinMain@16 は既に main.obj で定義されています。

これはWinMain関数が多重定義されていた時に出ますので根本的に書き方が間違ってい可能性が高いです。
ソースコードを全部貼り付けてもらった方が良いでしょう。

Re: コンパイルエラー

Posted: 2012年5月05日(土) 17:11
by pot
龍神録の50章を使用し、その中にmenu.cppを作成し以下のプログラムを書きました。

> int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){

この文がmain.cppでも定義されてるため多重定義となってのでしょうか?
その場合どのように書き換えれば正常に動作しますか?

コード:

#include "../../../include/DxLib.h"

int Key[256]; // キーが押されているフレーム数を格納する

// キーの入力状態を更新する
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つ作る
        MenuElement_t MenuElement[5]={
                {  80, 100, "ゲームスタート" }, // タグの中身の順番で格納される。xに80が、yに100が、nameに"ゲームスタート"が
                { 100, 150, "おまけ" },
                { 100, 200, "ヘルプ" },
                { 100, 250, "コンフィグ" },
                { 100, 300, "ゲーム終了" },
        };
        int SelectNum = 0; // 現在の選択番号

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

                // 計算フェーズ 

                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++ ){              // メニュー項目数である5個ループ処理
				if( i == SelectNum ){          // 今処理しているのが、選択番号と同じ要素なら
					MenuElement[i].x = 80; // 座標を80にする
				} else {                       // 今処理しているのが、選択番号以外なら
					MenuElement[i].x = 100;// 座標を100にする
				}
			}
		}

		// 描画フェーズ

		for( int i=0; i<5; i++ ){ // メニュー項目を描画
			DrawFormatString( MenuElement[i].x, MenuElement[i].y, GetColor(255,255,255), MenuElement[i].name );
		}

	}

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

Re: コンパイルエラー

Posted: 2012年5月05日(土) 17:41
by softya(ソフト屋)
1つのプログラムにWinMainはひとつしか存在できませんので残念ながら無理です。
メニュー処理も本編と無関係に動けるわけはないので、龍神録本編のWinMainからメニュー処理を関数の一つとして呼び出すように記述する必要があります。
その時に次の点にも注意して下さい。
「新・C言語 ~ゲームプログラミングの館~ [DXライブラリ]  補足資料.11章 書いてはいけない4つの処理」
http://dixq.net/g/h_11.html

【補足】
練習としては、ゲームプログラミングの館の3.4章のプログラムをメニュー部分だけを別ファイルの別関数に分離する事から始められてはどうでしょうか?

Re: コンパイルエラー

Posted: 2012年5月05日(土) 19:08
by pot
ありがとうございます。頑張ってみます