ページ 11

タイピングゲームを作っています。

Posted: 2011年10月12日(水) 19:49
by marth
現在、学校でVisualC++2010とDxlibを用いてタイピングゲームを作っていて、タイトルに表示するメニュー6項目(ゲームスタート・???・???・コンフィグ・オプション・ゲーム終了)は完成しています。あと、メニュー画面からの移動と、データの読み書き機能(改ざん対策・オートセーブあり)と、ボスキャラ48人分のプログラム・成績(お手つき回数・ボス戦勝率・ミスタイプ率・完勝回数)・入力判定機能があります。5ステージごとに行われるボス戦では、問題に規定数正解すれば勝利になるクイズ形式と、某名曲をどちらが先に打ち終わるかの1本勝負があります。なお、ボスはプレイヤーの成績に応じて変化(良い成績ほど強い)し、規定数正解すれば次のステージへ(相手が1本も取れず、かつプレイヤーがお手つきなしで規定数勝利すれば残機が1アップ)、敗北した場合は残機が1以上なら残機を1消費してリベンジできます(ボス戦でない場合、もしくは残機がない場合はゲームオーバー)。通常ステージでは、1語にかける時間は15秒で、Easy~VHardでは10語、隠し難易度では、易しい方から20語・30語・50語うてばクリア、時間切れで残機1消費となります。初期設定では小文字単体で打つことができない(小文字単体入力許可がfalseの状態)ようになっています。そこで、本題なのですが、ボスキャラ別にファイルを作る場合、「cppファイル単体」か、「hファイル単体」か、「それ以外」のどれがいいですか?ちなみに、自分はcppファイルとhファイルを人数分作ろうと思っています。OSはWindows7です。

Re: タイピングゲームを作っています。

Posted: 2011年10月12日(水) 20:17
by うしお
「そこで、本題なのですが-」、と入るまでの情報がかなり冗長ではないですか?
せいぜい重要な情報は
・VisualC++2010
・Dxlib
くらいです。(さらに最後の遠く離れた場所でOSを付け加えています)
問題点をシンプルにまとめられた方が解決は早いかと思います。

本題です。
ヘッダ(.h)とソース(.cpp)のセットで一つ、というのがひとまず基本かと思います。
とはいえ、「ボスキャラ1人」だからファイルを1つ、というのはかなり曖昧な基準ではないでしょうか?
複雑なボスを作るのに、いくつもファイルを使うのはおかしくありませんし、
単純なら少ないファイルに纏めるのも自然です。
機能ごとに、より柔軟に捉えてみてはいかがでしょうか?

Re: タイピングゲームを作っています。

Posted: 2011年10月13日(木) 00:49
by ISLe
「それ以外」
問題等外部データにしてボス戦前にでも読みこむようにすればプログラムは共通化できます。
掛け合いとかはスクリプトデータに。

Re: タイピングゲームを作っています。

Posted: 2011年10月13日(木) 19:36
by marth
>>うしおさん
「少ないファイルにまとめる」ですか…頑張ります。
>>ISLeさん
対戦項目の一つである百人一首(上の句を聞いて、下の句を打つ)をテキストファイルで作っています。

Re: タイピングゲームを作っています。

Posted: 2011年10月19日(水) 13:12
by marth
現在、僕はメニュー画面を作っている最中なのですが、画面の移動ができずに困っています。メニュー画面はhttp://dixq.net/g/03_04.html(新・C言語~ゲームプログラミングの館~3-4)と、http://dixq.net/forum/viewtopic.php?f=3 ... %A2#p75597(C言語何でも質問掲示板「画面移動について」)を参考にして作っています。使用OSはwindows7で、C++と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つ作る
        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++ ){ // メニュー項目を描画
                        if( i == SelectNum ){
                                DrawFormatString( MenuElement[i].x-20, MenuElement[i].y, GetColor(255,255,255), MenuElement[i].name );
			} else {
				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;
			}
			z++;
		}
		if(Key[KEY_INPUT_X]==1 && z>1 )
		{
			z--;
		}
		if(Key[KEY_INPUT_Z]==1 && z==2)
		{
			if(menunum==0)
			{
				MenuElement_t MenuElement[4]=
				{
					{ 80,100,"Easy(徒歩級)"},
					{100,150,"Normal(自転車級)"},
					{100,200,"Hard(乗用車級)"},
					{100,250,"HardPlus(在来線級)"},
				};
			}else if(menunum==1){
				MenuElement_t MenuElement[3]=
				{
					{ 80,100,"???"},
					{100,150,"???"},
					{100,200,"???"},
				};
			}else if(menunum==2){
				MenuElement_t MenuElement[2]=
				{
					{ 80,100,"???"},
					{100,150,"???"},
				};
				z++;
			}else if(menunum==3){
				MenuElement_t MenuElement[2]=
				{
					{80,100,"成績"},
					{100,150,"ランキング"},
				};
				z++;
			}else{
				MenuElement_t MenuElement[2]=
				{
					{80,100,"BGM音量"},
					{100,150,"SE音量"},
				};
			}
		}
	}

	DxLib_End(); // DXライブラリ終了処理
	return 0;
}
目的:zボタンを押すとページを移動する
変更点:4項目目をコンフィグからレコードに

【注】コードタグの使い方が間違っていたので修正しました。c++ではなくcppです。必ずプレビューして確認してくださいね。 by softya(ソフト屋)

Re: タイピングゲームを作っています。

Posted: 2011年10月19日(水) 14:22
by softya(ソフト屋)
MenuElementを書き換えているつもりかも知れませんが、残念ながら目的は達成できません。
変数の寿命とスコープを理解する必要があります。

[変数の寿命]
変数は基本的に{}で示されるブロック内の寿命であるが、staticを付けた場合はプログラム起動から終了までの寿命となり初期化も起動時の一度しか行われない。逆にstaticがないと毎回初期化される。それと関数外に宣言した場合は、これもプログラム起動から終了までの寿命となる。

[変数のスコープ]
ローカルスコープ:関数内や{ブロック}内のローカル変数として宣言した場合。そのブロック{}内でしか参照できない。更に中のブロックに同じ名前の変数を宣言した場合は、それは別の変数として扱われる。
ファイルスコープ:関数外でかつstatic宣言した場合。そのコンパイル単位であるファイル内からしか参照できない。無闇にファイルスコープにするのは避けるべきである。
グローバルスコープ:関数外でかつ、staticを付けなかった場合。extern宣言をすると別cppからでも参照可能になる。ただし無闇にグローバルスコープにするのは避けるべきである。
それと全スコープの共通点として変数を宣言した後ろにある命令しか参照できない。

MenuElementは複数あっても別の変数として扱われて、ブロックが終わると消滅しますので複数宣言しても意味がありません。
こう言う場合は、ポインタ変数にして切り替えるとか、そもそもメニューを関数にして引数でメニューを配列を受けるとか工夫が必要です。

Re: タイピングゲームを作っています。

Posted: 2011年10月19日(水) 19:05
by marth
つまり、「MenuElementを何回も使わないでメニュー画面を作れ」って事ですね。
新・C言語~ゲームプログラミングの館~の「ゲームプログラミング設計」を読んでもっと精進しようと思います。
今回はありがとうございました。

Re: タイピングゲームを作っています。

Posted: 2011年10月19日(水) 19:08
by softya(ソフト屋)
どちらかと言うとC言語の文法と応用テクニックの問題なので、分からないことがあったら聞いてください。