ポーズ画面への移動と処理

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
無双贄
記事: 15
登録日時: 13年前

ポーズ画面への移動と処理

#1

投稿記事 by 無双贄 » 13年前

自分は簡単な縦シューティングゲームを作っています。
おおかたゲームの基盤となるものは出来たのでポーズ画面を少し書き足してみたのですが、うまく機能しません。
ゲーム画面からスペースキーを押すとポーズ画面へ飛ぶようにしたのですが、ゲーム中にスペースキーを押しても
「ポーズ中です」の文字がチラッと表示されるだけで、ゲームの処理自体は勝手に進んでしまいます。(敵は落ちてくるし、自機も移動できます)

自分の理想は、ゲーム中にスペースキーを押すと、ポーズ画面へ移動して自機処理や敵処理は行わない
ポーズ中にもう一度スペースキーを押すと自機処理、敵処理を再開するというようにしたいです。

OSはwindows vista, コンパイラは VC++ 2008, ライブラリはDXライブラリを使用しています。

回答よろしくおねがいします。

コードの161~166, 181~190のところがポーズ画面の処理です。

コード:

#include "DxLib.h"
#include <stdlib.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;
}

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
        ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK ); //ウィンドウモード変更と初期化と裏画面設定
		//=====================色取得=====================
		int Cr;
		Cr = GetColor(255,255,255);

		//========================自機画像保存========================
		int Handle;

		//========================敵画像保存========================
		int EHandle;

		//========================自機弾画像保存========================
		int BuHandle;

		//========================自機初期座標&自機サイズ========================
		int JikiX, JikiY, JikiW, JikiH;
		JikiX = 300;
		JikiY = 380;

		JikiW = 100;
		JikiH = 100; 

		//=====================自機弾初期座標&自機弾サイズ&自機弾フラグ=====================
		int BuX, BuY, BuW, BuH, BuFlag;
		BuW = 2;
		BuH = 16;

		BuX = (JikiW - BuW) / 2 + JikiX;//弾をセット
		BuY = (JikiH - BuH) / 2 + JikiY;

		BuFlag = 0;

		//========================敵の初期座標&敵サイズ&敵再配置フラグ========================
		int TekiX, TekiY, TekiW, TekiH, TekiFlag;
		TekiX = rand() * (640 - 100) / RAND_MAX;;
		TekiY = 0;

		TekiW = 100;
		TekiH = 100;

		TekiFlag = 0;

		//========================ゲーム画面のフラグ========================
		int GameState;
		GameState = 0;

		//========================スコア初期化========================
		int Score;
		Score = 0;
		

		if(GameState == 0 && TekiFlag == 0){
			while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && gpUpdateKey() == 0 )
			{

				//=====================自機関係画像読み込み=====================
				Handle = LoadGraph("画像/自機.bmp");
				BuHandle = LoadGraph("画像/弾.bmp");

				//=====================敵画像読み込み=====================
				EHandle = LoadGraph("画像/敵.bmp");

				//=====================ゲーム本体画面=====================
				if(GameState == 0)
				{
					//===========================自機操作===================================
					//if(Key[KEY_INPUT_UP] == 1) JikiY -= 2;
					//if(Key[KEY_INPUT_DOWN] == 1) JikiY += 2;
					if(Key[KEY_INPUT_LEFT]) JikiX -= 5;
					if(Key[KEY_INPUT_RIGHT]) JikiX += 5;

					//===========================自機が画面外に出そうなら===========================
					if(JikiX < 0) JikiX = 0;
					if(JikiX > 640 - 100) JikiX = 640 - 100;

					//=====================自機描画=====================
					DrawGraph(JikiX,JikiY,Handle,FALSE);

					//=====================敵の落下処理(落下スピードはここで調整)=====================
					
					TekiY += 3;

					//=====================敵描画=====================
					DrawGraph(TekiX,TekiY,EHandle,FALSE);
					DrawFormatString(0,100,Cr,"X座標 = %d, Y座標 = %d, 再配置フラグ = %d", TekiX, TekiY, TekiFlag);

					//=====================自機ショット判定処理=====================
					//Zキーを押して1フレーム後かつ弾フラグが0の場合
					if(Key[KEY_INPUT_Z] >= 1 && BuFlag == 0)
					{
						BuX = (JikiW - BuW) / 2 + JikiX;//弾をセット
						BuY = (JikiH - BuH) / 2 + JikiY;

						BuFlag = 1;//フラグを1にする
					}

					//=====================自機ショット描画処理=====================
					if(BuFlag == 1)//フラグが1なら
					{
						BuY -= 15;//弾スピード調整
						if(BuY < 0)	//弾が画面外に出たら
						{
							BuFlag = 0;//弾フラグを0に
						}
						DrawGraph(BuX,BuY,BuHandle,FALSE);//弾を描画
					}


					//=========================当たり判定(上段は弾と敵、下段は自機と敵)===================================
					if( ( ( BuX > TekiX && BuX < TekiX + TekiW ) ||( TekiX > BuX && TekiX < BuX + BuW ) ) &&( ( BuY > BuY && BuY < TekiY + TekiH ) ||( TekiY > BuY && TekiY < BuY + BuH ) ) )
					{
						DrawString(0,140,"呼び出しました!(当たり判定)",Cr);
						TekiFlag = 1;
						Score = Score + 10;
							
					}else 
						if( ( ( JikiX > TekiX && JikiX < TekiX + TekiW ) ||( TekiX > JikiX && TekiX < JikiX + JikiW ) ) &&( ( JikiY > TekiY && JikiY < TekiY + TekiH ) ||( TekiY > JikiY && TekiY < JikiY + JikiH ) ) )
						{
							DrawString(0,0,"敵と接触しています!",Cr);
							Score--;
							//GameState = 2;
						}
				
					//=====================敵の落下限界判定=====================
					//敵が画面外(Y座標が480以上)に出たら初期座標に戻す(X座標はランダム)
					if(TekiY > 480)
					{
						DrawString(0,160,"呼び出しました!(敵落下限界判定)",Cr);
						Score = Score - 5;

						//X座標が画面外(X座標が540以上)に出たらもう一度計算
						if(TekiX > 640 - 100)
						{
							DrawString(0,180,"呼び出しました!(敵落下限界判定(画面外))",Cr);
							TekiFlag = 1;
						}else{
							TekiFlag = 1;
						}
					}

					//=====================ポーズ画面移動判定=====================
					//スペースキーを押して5フレーム経過後
					if(Key[KEY_INPUT_SPACE] == 1)
					{
						GameState = 1;//ポーズ画面へ移動
					}

					//========================スコア描画処理========================
					DrawFormatString(0,0,Cr,"スコア = %d",Score);
				}

				//=====================敵再配置フラグ処理=====================
				if(TekiFlag == 1)
				{
					TekiX = rand() * 500 / RAND_MAX;
					TekiY = 0;
					TekiFlag = 0;
					DrawString(0,120,"呼び出されてます!(再配置フラグ)",Cr);
				}

				//=====================ポーズ画面=====================
				if(GameState == 1)
				{
					DrawString(200,200,"ポーズ中です",Cr);
					//スペースキーを押して5フレーム経過後
					if(Key[KEY_INPUT_SPACE] == 1)
					{
						GameState = 0;//ゲーム画面へ戻る
					}
				}

				//=====================ゲームオーバー画面=====================
				if(GameState == 2)
				{
					DrawString(150,200,"残念!ゲームオーバーです",Cr);
					DrawString(150,250,"もう一度プレイするならスペースキーを押してください",Cr);
					DrawString(150,300,"終了するならESCキーを長押ししてください",Cr);

					//スペースキーを押して1フレーム経過後
					if(Key[KEY_INPUT_SPACE] == 1)
					{
						GameState = 0;//ゲーム画面へ戻る
					} 
				}

				//=====================ゲーム終了処理=====================
				if(Key[KEY_INPUT_ESCAPE] == 10)//ESCキーを押して10フレーム経過後
				{
					DxLib_End();//DXライブラリを終了する
				}

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

jay
記事: 314
登録日時: 14年前
住所: 大阪市
連絡を取る:

Re: ポーズ画面への移動と処理

#2

投稿記事 by jay » 13年前

うわぁ、これは下手したら恐怖の一本ソースに…w

それはさておき
これは処理状態をGameState変数で決めているようですね
GameStateが0の時はゲームのメイン処理
1の時はポーズ画面ですね

そしてメイン処理中にKey[KEY_INPUT_SPACE] == 1の条件を満たした時にゲーム処理からポーズ処理に移行する訳ですが
GameStateの変数の判定を全部if文でやってしまっているのが問題ですね

Key[KEY_INPUT_SPACE] == 1の条件を満たしてGameStateの値が1になるのですが
そのままポーズ画面に移行してしまってポーズ画面でもKey[KEY_INPUT_SPACE] == 1の条件をまた満たしてしまうのですぐにGameStateが0に戻る、つまりメイン処理に移行しているのだと思います。
こう言う時の値の判定はif文ではなくswitch~case文を使うといいですよ
♪僕たちは まだ森の中 抜け出そう 陽のあたる場所へ

無双贄
記事: 15
登録日時: 13年前

Re: ポーズ画面への移動と処理

#3

投稿記事 by 無双贄 » 13年前

jayさん回答ありがとうございます。
アドバイス通りにswitch文を使ってコードを作り直してみました。
GameState変数で管理するのは少し見づらかったので、GameStateを列挙型で宣言しました。

載せるコードはゲームのメイン画面からポーズ画面への移動とポーズ画面の処理だけに限定したものを載せます。

コード:

#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;
}

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
        ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK ); //ウィンドウモード変更と初期化と裏画面設定

        
		enum Screen{GAME_MAIN, GAME_PAUSE} GameState;

		 GameState = GAME_MAIN;

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

			   switch(GameState)
			   {
				   case GAME_MAIN:
					   DrawString(0,0,"ゲーム画面です", GetColor(255,255,255));

					   if(Key[KEY_INPUT_SPACE] == 1)
					   {
						   GameState = GAME_PAUSE;
					   }
					   break;
					   
				   case GAME_PAUSE:
					   DrawString(150,150,"ポーズ画面です", GetColor(255,255,255));

					   if(Key[KEY_INPUT_SPACE] == 1)
					   {
						   GameState = GAME_MAIN;
					   }
					   break;
			   }

        }

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

UN
記事: 18
登録日時: 14年前
住所: 神奈川県

Re: ポーズ画面への移動と処理

#4

投稿記事 by UN » 13年前

一応解決してるようなきがします。
強いていえばGetHitKeyStateAllで
対象のキーが押されている間中1になっているとするならば
1フレーム目はポーズに移行しても、2フレーム目に
押しっぱなし状態が継続され、即座に通常ゲームに戻ちゃうくらいじゃないでしょうか。
人間の感覚で1フレームを押し分けるというのは中々困難です。
仮にそうだとしたらフラグをもたせるなりして制御、
そうじゃなければこんなイメージでいいと思いますよ。

無双贄
記事: 15
登録日時: 13年前

Re: ポーズ画面への移動と処理

#5

投稿記事 by 無双贄 » 13年前

UNさん回答有難うございます。ひとまず自分の目的は達成されているのでコードはこれでいいかなと思っています。

ポーズ画面の処理コードが完成した後、「ファイルを分割して作ったらどうなるのかな」と思い上記コードの分割バージョンを書いてみました。
しかし、実行は問題なく出来るのですが、ゲームメイン画面からのポーズ移動が出来なくなってしまいました。

回答よろしくお願いします。

main.cpp

コード:

#include "DxLib.h"
#include "Pause.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;
}
 
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
        ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK ); //ウィンドウモード変更と初期化と裏画面設定
 
        
        enum Screen{GAME_MAIN, GAME_PAUSE} GameState;
 
         GameState = GAME_MAIN;
 
        // while(裏画面を表画面に反映, メッセージ処理, 画面クリア, キーの状態更新)
        while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && gpUpdateKey()==0 ){
 
               switch(GameState)
               {
                   case GAME_MAIN:
                       DrawString(0,0,"ゲーム画面です", GetColor(255,255,255));

					   Pause_Check();

                       break;
                       
                   case GAME_PAUSE:
                      DrawString(150,150,"ポーズ画面です", GetColor(255,255,255));

					  Pause_Screen();

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

コード:

#include "DxLib.h"
#include "Pause.h"

enum Screen{GAME_MAIN, GAME_PAUSE} GameState;
extern int Key[];

void Pause_Check()
{
	if(Key[KEY_INPUT_SPACE] == 1)
	{
		GameState = GAME_PAUSE;
	}
}

void Pause_Screen()
{
	DrawString(150,150,"ポーズ画面です", GetColor(255,255,255));

	if(Key[KEY_INPUT_SPACE] == 1)
	{
		GameState = GAME_MAIN;
	}
}
Pause.h

コード:


void Pause_Check();
void Pause_Screen();


UN
記事: 18
登録日時: 14年前
住所: 神奈川県

Re: ポーズ画面への移動と処理

#6

投稿記事 by UN » 13年前

main.cppのenum Screen{GAME_MAIN, GAME_PAUSE} GameState;と
Pause.cppのenum Screen{GAME_MAIN, GAME_PAUSE} GameState;は
別メモリに配置されたものなので、同一のものじゃないからです。
(人間でいうならAさんとBさんは同姓同名ですが別人です)
直すとしたら、GameStateをグローバル変数化してexternする、
またはGet関数を用意してそのグローバル変数の値を返す、
引数にGameState*を渡して直接書き換える、といくつか方法ありますが、
汎用的にシンプルに考えるなら、ポーズの判定部分は

コード:

 
#include "DxLib.h"
#include "Pause.h"

extern int Key[];

bool IsPushPause()
{
	bool ret = false;
    if(Key[KEY_INPUT_SPACE] == 1)
    {
		ret = true;
    }
	return ret;
}
 
とポーズボタン判定だけをするといったようにして

コード:

 
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
        ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK ); //ウィンドウモード変更と初期化と裏画面設定
 
        
        enum Screen{GAME_MAIN, GAME_PAUSE} GameState;
 
         GameState = GAME_MAIN;
 
        // while(裏画面を表画面に反映, メッセージ処理, 画面クリア, キーの状態更新)
        while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && gpUpdateKey()==0 ){
 
               switch(GameState)
               {
                   case GAME_MAIN:
                       DrawString(0,0,"ゲーム画面です", GetColor(255,255,255));
 
                       if( IsPushPause() )
					   {
						   GameState = GAME_PAUSE;
					   }
 
                       break;
                       
                   case GAME_PAUSE:
                      DrawString(150,150,"ポーズ画面です", GetColor(255,255,255));
 
                      if( IsPushPause() )
					   {
						   GameState = GAME_MAIN;
					   }
 
                      break;
               }
 
        }
 
        DxLib_End(); // DXライブラリ終了処理
        return 0;
}

このようにゲームのState部分の制御などは、
こちらのソースで完結させるとかいうのがシンプルなきはします。
内部的にStateかえちゃいますと、GAME_MAIN以外でもポーズがほしくなったときに
Pause_Check関数がその数だけ増やさないといけないなんてことになりかねないですしね。

一応ご参考までに。

UN
記事: 18
登録日時: 14年前
住所: 神奈川県

Re: ポーズ画面への移動と処理

#7

投稿記事 by UN » 13年前

連投すいません。とりあえずファイル分割してもできるようになりたいって意味に
感じられたので、一応一例だけ書いておきます。
グローバル変数化は極力避けたほうがいいとおもいますので、引数で変更やりかただと
main.hを用意し、その中で

コード:

 
enum Screen
{
	GAME_MAIN, 
	GAME_PAUSE
};
を定義、Pause.cppでmain.hをincludeし、

コード:

 
void Pause_Check( Screen* pState )
{
    if(Key[KEY_INPUT_SPACE] == 1)
    {
		*pState = GAME_PAUSE;
    }
}
 
void Pause_Screen( Screen* pState )
{
    DrawString(150,150,"ポーズ画面です", GetColor(255,255,255));
 
    if(Key[KEY_INPUT_SPACE] == 1)
    {
        *pState = GAME_MAIN;
    }
}
main.cppで

コード:

 
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
        ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK ); //ウィンドウモード変更と初期化と裏画面設定
 
        
        Screen GameState;
 
         GameState = GAME_MAIN;
 
        // while(裏画面を表画面に反映, メッセージ処理, 画面クリア, キーの状態更新)
        while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && gpUpdateKey()==0 ){
 
               switch(GameState)
               {
                   case GAME_MAIN:
                       DrawString(0,0,"ゲーム画面です", GetColor(255,255,255));
 
                       Pause_Check( &GameState );
 
                       break;
                       
                   case GAME_PAUSE:
                      DrawString(150,150,"ポーズ画面です", GetColor(255,255,255));
 
                      Pause_Screen( &GameState );
 
                      break;
               }
 
        }
 
        DxLib_End(); // DXライブラリ終了処理
        return 0;
}
といったようにGameStateのアドレスを渡して、
Pause_Check関数等で直接書き換えるようにする、といった方法が考えられます。

以上、連投すいませんでした。

無双贄
記事: 15
登録日時: 13年前

Re: ポーズ画面への移動と処理

#8

投稿記事 by 無双贄 » 13年前

UNさん、回答ありがとうございます。

IsPushPause関数を用いたコードは、問題なく実行出来ましたが、2つめのポインタを用いたコードをコピーして実行しましたが
以下のようなエラーが出てしまいます。

main.cpp(36) : error C2660: 'Pause_Check' : 関数に 1 個の引数を指定できません。
main.cpp(42) : error C2660: 'Pause_Screen' : 関数に 1 個の引数を指定できません。

引数の名前が違うのかなと思い、名前を同じにしたり、void型なので引数を指定しないようにしてみましたがうまくいきません。

回答よろしくお願いします。

main.h

コード:

enum Screen
{
	GAME_MAIN,
	GAME_PAUSE
};
main.cpp

コード:

#include "DxLib.h"
#include "Pause.h"
#include "main.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;
}
 
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
        ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK ); //ウィンドウモード変更と初期化と裏画面設定
 
        Screen GameState;//列挙型Screenの変数を宣言
 
        GameState = GAME_MAIN;
 
        // while(裏画面を表画面に反映, メッセージ処理, 画面クリア, キーの状態更新)
        while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && gpUpdateKey()==0 ){
 
               switch(GameState)
               {
                   case GAME_MAIN:
                       DrawString(0,0,"ゲーム画面です", GetColor(255,255,255));

					   Pause_Check(&GameState);

                       break;
                       
                   case GAME_PAUSE:
                      
					   Pause_Screen(&GameState);

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

コード:


void Pause_Check();

void Pause_Screen();

Pause.cpp

コード:

#include "DxLib.h"
#include "main.h"

extern int Key[];
Screen* pState;

void Pause_Check( Screen* pState )
{
    if(Key[KEY_INPUT_SPACE] == 1)
    {
        *pState = GAME_PAUSE;
    }
}
 
void Pause_Screen( Screen* pState )
{
    DrawString(150,150,"ポーズ画面です", GetColor(255,255,255));
 
    if(Key[KEY_INPUT_SPACE] == 1)
    {
        *pState = GAME_MAIN;
    }
}

とっち
記事: 56
登録日時: 13年前
住所: 岡山

Re: ポーズ画面への移動と処理

#9

投稿記事 by とっち » 13年前

Pause.hの関数がおかしいです。

コード:

void Pause_Check();
void Pause_Screen();

コード:

void Pause_Check( Screen* pState );
void Pause_Screen( Screen* pState );
ですね。
main.cppの立場になって考えてみましょう。
WinMain関数内でPause_Check関数を使おうとします。
関数を使うには宣言が必要です。

つまり、

コード:

void test();
// もしくは
extern void test();
みたいなものが必要です。

Pause_Check関数の宣言はPause.hのなかにあるのですが、void Pause_Check();
と、引数がありません。
WinMain関数内にPause_Check( &GameState );と引数ありで使おうとしているので、
main.cpp(36) : error C2660: 'Pause_Check' : 関数に 1 個の引数を指定できません。
というエラーが出ます。

無双贄
記事: 15
登録日時: 13年前

Re: ポーズ画面への移動と処理

#10

投稿記事 by 無双贄 » 13年前

とっちさん回答ありがとうございます。

ご指摘頂いたとおりPause.hファイルのプロトタイプ宣言に引数を指定したところ無事実行出来ました。
コードを載せますので、もしおかしいところがあればコメントしていただけるとありがたいです。

あと、自分はポインタをあまり使ったことがないので変数pStateと Pause_Check(&GameState)の&GameStateがどういう役割で
どういう働きをしているのでいまいちイメージ出来ません。
そこに関しても教えていただけるとありがたいです。

よろしくお願いします。

main.h

コード:

#ifndef DEF_MAIN_H
#define DEF_MAIN_H
//列挙型Screenの宣言
enum Screen
{
	GAME_MAIN,
	GAME_PAUSE
};

#endif
main.cpp

コード:

#include "DxLib.h"
#include "Pause.h"
#include "main.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;
}
 
int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
        ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK ); //ウィンドウモード変更と初期化と裏画面設定
 
        Screen GameState;//列挙型Screenの変数を宣言
 
        GameState = GAME_MAIN;
 
        // while(裏画面を表画面に反映, メッセージ処理, 画面クリア, キーの状態更新)
        while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && gpUpdateKey()==0 ){
 
               switch(GameState)//変数GameStateの中身が・・・
               {
                   case GAME_MAIN://GAME_MAINなら
                       DrawString(0,0,"ゲーム画面です", GetColor(255,255,255));

					   Pause_Check(&GameState);//Pause_Check関数へ移動

                       break;
                       
                   case GAME_PAUSE://GAME_PAUSEなら
                      
					   Pause_Screen(&GameState);//Pause_Screen関数へ移動

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

コード:

#ifndef DEF_PAUSE_H
#define DEF_PAUSE_H

#include "main.h"//これをincludeしないと以下の関数の引数であるScreenとpStateが定義されていないと言われる

void Pause_Check( Screen* pState );
void Pause_Screen( Screen* pState );

#endif
Pause.cpp

コード:

#include "DxLib.h"
#include "main.h"

extern int Key[];
Screen* pState;//ポインタ型pStateを宣言

void Pause_Check( Screen* pState )
{
    if(Key[KEY_INPUT_SPACE] == 1)
    {
        *pState = GAME_PAUSE;
    }
}
 
void Pause_Screen( Screen* pState )
{
    DrawString(150,150,"ポーズ画面です", GetColor(255,255,255));
 
    if(Key[KEY_INPUT_SPACE] == 1)
    {
        *pState = GAME_MAIN;
    }
}

UN
記事: 18
登録日時: 14年前
住所: 神奈川県

Re: ポーズ画面への移動と処理

#11

投稿記事 by UN » 13年前

ポインタの説明を一言でするのは難しいです。
そしてpStateのような働きという表現は
少し間違っています。

ひとまず
http://c-production.com/contents/c/sec10.html
上記様のオページなどでポインタについての理解を深めることをお勧めします。

無双贄
記事: 15
登録日時: 13年前

Re: ポーズ画面への移動と処理

#12

投稿記事 by 無双贄 » 13年前

UNさん回答ありがとうございます。

ポインタの質問は直接このトピックとは関係ありませんので、ひとまずここで解決!とさせて頂きます。

回答をくださった皆さんありがとうございました。

閉鎖

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