~秒後に画像を切り替えたい

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

~秒後に画像を切り替えたい

#1

投稿記事 by SINA » 7年前

こんにちは現在Dxlibを使って簡単な野球ゲームを作ろうとしているのですが
バッターがスイングする時の画像の切り替えがうまくいきません。
具体的に言いますとバッター画像を三枚「構え」、「振り始め」、「振り終わり」と用意しており
特定のキーを押すと「構え」→「振り始め」→(0.5秒程経過)→「振り終わり」
という風に切り替えて表示させたいのですが切り替えが早すぎるのか
キーを押していると三枚の画像が全て重なったようになってしまいます。
wait等を使うと全ての処理が止まってしまうのであまり使いたくないのですが
良い方法は無いでしょうか?よろしくお願いします。

以下ソース
/*yakyuu*/

コード:

#include<DxLib.h>
//プロトタイプ宣言
void grand();
// WinMain関数
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
 LPSTR lpCmdLine, int nCmdShow )
{
 	// ウインドウモードに変更
 ChangeWindowMode( TRUE );
 // DXライブラリ初期化
 if( DxLib_Init() == -1 )
  {
	 return 0;
  }
 SetDrawScreen( DX_SCREEN_BACK );
 int i;//ループ用
 /////////////////ゲーム用///////////////////
 int BallG;//ボール画像
 int BallY=200;//ボール高さ
 int BallX=320;//ボール横
 double BallZ=1;//ボール奥行き
 int Cr ;
 int draw;//背景描写用
 bool PUSH=true;
 Cr= GetColor( 255 , 255, 255 ) ;	// 白色の値を取得
 int batter[3];//バッターの画像
 int count;
 LoadDivGraph( "bat.bmp" , 3, 1 , 3, 310 , 270, batter ); // 画像の分割読み込み


 while(1)
 {
	 
	 if( ProcessMessage() != 0 )
	 { 
                  // メッセージ処理
             break;//ウィンドウの×ボタンが押されたらループを抜ける
     }

	 ClearDrawScreen(); // 画面を消す
	 PUSH=true;
	 grand();//グランド描写
	 DrawGraph( 105, 250, batter[0], TRUE ); //バッター画像
	 DrawCircle( BallX , BallY , BallZ , Cr , TRUE) ;// 円を描画
	 if(BallZ<12)
	 {
	 BallZ=BallZ+0.5;
	 }
	 BallY=BallY+8;
	 if( CheckHitKey( KEY_INPUT_Z) == 1 && PUSH==true)//Zが入力されている
	 {
		 PUSH=false;
		 DrawGraph( 105, 250, batter[1], TRUE ); //バッタースイング画像
		 count = GetNowCount();
		 while((  GetNowCount() - count) <= 50)
		 {
			DrawGraph( 105, 250, batter[2], TRUE ); //バッタースイング2画像
		 }

	 }
	 ScreenFlip(); //裏画面を表画面に反映
 }
 DxLib_End() ;			// DXライブラリ使用の終了処理
 return 0;
}

void grand()
{
 int Cr ;
 int Cr2;
 int Cr3;
 int Cr4;
 Cr= GetColor( 255 , 255, 255 ) ;	// 白色の値を取得
 Cr2= GetColor(0,120,0);//緑
 Cr3= GetColor(186,125,50);//茶色
 Cr4= GetColor(136,75,20);//こい茶色

 DrawBox( 0 , 0 , 640 , 480 , Cr2 , TRUE) ;//緑で塗りつぶす
 DrawOval(320,540,1000,500,Cr3,TRUE);//グランド
 DrawOval(320,220,70,20,Cr4,TRUE);//まうんど
 DrawBox(290,425,350,440,Cr,TRUE);//ホームベース
 DrawTriangle( 290, 440, 350, 440, 320, 455, Cr, TRUE);//ホームベース2
 DrawLine(270,410,270,480,Cr,5);//バッターボックス
 DrawLine(270,410,130,410,Cr,5);//バッターボックス2
 DrawLine(130,410,130,480,Cr,5);//バッターボックス3
 DrawBox(370,410,510,480,Cr,FALSE);
 DrawLine(370,410,370,480,Cr,5);//バッターボックス1
 DrawLine(370,410,510,410,Cr,5);//バッターボックス2
 DrawLine(510,410,510,480,Cr,5);//バッターボックス3
 DrawLine(200,410,0,310,Cr,5);//ライン左
 DrawLine(440,410,640,310,Cr,5);//ライン右
}

nil
記事: 428
登録日時: 8年前

Re: ~秒後に画像を切り替えたい

#2

投稿記事 by nil » 7年前

wait系の関数ではなくカウンタ変数を使います。
変数を毎フレームインクリメントすれば、1秒ごとにカウンタが60増えますので、
それを使って処理を遷移させます。

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

Re: ~秒後に画像を切り替えたい

#3

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

そうですね。
まず、インデントに気をつけて見てください。ループや分岐の関係が分かりやすくなります。

で、複数のループが有るプログラムになっているので、まともに動作しないと思います。
[追記・補正]メインループの中のループでタイミングをコントロールするのではなく、一番外側のメインループのループを回る毎にアニメーション・フレームをカウントして、アニメーション・フレームで表示する番号を決めるようにすると綺麗にアニメできるようになります。そうすれば内側のループは不要となります。
アニメーション・フレームをカウントは、「スイング・フラグ」でカウントをするか制御してください。 
「スイング・フラグ」は、KEY_INPUT_Zで有効にします。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

SINA

Re: ~秒後に画像を切り替えたい

#4

投稿記事 by SINA » 7年前

涼雅さんsoftyaさんどうも返信ありがとうございます。ご指摘通りフラッグと
外のループでのカウント増減により上手くいきました!本当にありがとうございます。
下記のようなソースになったのですが何か修正した方が良い点はあるんでしょうか?
よろしくお願いします。

コード:

/*yakyuu*/
#include<DxLib.h>
//プロトタイプ宣言
void grand();
// WinMain関数
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
 LPSTR lpCmdLine, int nCmdShow )
{
 // ウインドウモードに変更
 ChangeWindowMode( TRUE );
 // DXライブラリ初期化
 if( DxLib_Init() == -1 )
  {
	 return 0;
  }
 SetDrawScreen( DX_SCREEN_BACK );
 int i;//ループ用
 /////////////////ゲーム用///////////////////
 int BallG;//ボール画像
 int BallY=200;//ボール高さ
 int BallX=320;//ボール横
 double BallZ=1;//ボール奥行き
 int Cr ;
 int draw;//背景描写用
 bool SWING=false;//スイングフラッグ
 Cr= GetColor( 255 , 255, 255 ) ;	// 白色の値を取得
 int batter[3];//バッターの画像
 int count=0;//アニメーション管理用
 LoadDivGraph( "bat.bmp" , 3, 1 , 3, 310 , 270, batter ); // 画像の分割読み込み
 	 

 while(1)
 {
	 ClearDrawScreen(); // 画面を消す
	 grand();//グランド描写
	 if(SWING==true)
	 {
	 count++;
	 }
	 if( ProcessMessage() != 0 )
	 { 
		 // メッセージ処理
         break;//ウィンドウの×ボタンが押されたらループを抜ける
     }
	 if( CheckHitKey( KEY_INPUT_Z) == 1)//Zが入力されている
	 {
		 SWING=true;
	 }
	 if(SWING==true&&count<=60)//スイングの構えと途中の切り替え
	 {
		DrawGraph( 105, 250, batter[1], TRUE ); //バッタースイング画像
	 }
	 
	 else if(SWING==true&& 60<count && count<120)//スイングして1秒後に振り終わりに
	 {
		DrawGraph( 105, 250, batter[2], TRUE ); //バッタースイング2画像
	 }
	 else if(SWING==true&&120<count)//振り終わって1秒後にフラッグをfalse
	 {
		 SWING=false;
		 count=0;
	 }
	 else
	 {
		DrawGraph( 105, 250, batter[0], TRUE ); //バッター画像
	 }

	 DrawCircle( BallX , BallY , BallZ , Cr , TRUE) ;// 円を描画
	 if(BallZ<12)
	 {
	 BallZ=BallZ+0.5;
	 }
	 BallY=BallY+8;
	 ScreenFlip(); //裏画面を表画面に反映
 }
 DxLib_End() ;			// DXライブラリ使用の終了処理
 return 0;
}

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

Re: ~秒後に画像を切り替えたい

#5

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

ProcessMessage()→ClearDrawScreen()→いろいろな処理→ScreenFlip()の順序が良いと思います。
それとelse if(SWING==true&&120<count)//振り終わって1秒後にフラッグをfalse
は条件間違ってません? 振り終わって1秒後ってことは180ではないかと。

あとインデントに気をつけてくださいね(結構乱れています)。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

SINA

Re: ~秒後に画像を切り替えたい

#6

投稿記事 by SINA » 7年前

どうもご指摘ありがとうございます。
インデントには気をつけているんですがどうしても見落としがちになってしまうので
気をつけたいと思います。
ご指摘頂いた部分を改善してこの質問を解決にしたいと思います。
お二方どうも有難うございました!

閉鎖

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