マウスを押した瞬間だけ処理を実行したいのですが・・・

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

マウスを押した瞬間だけ処理を実行したいのですが・・・

#1

投稿記事 by Bun » 12年前

DXライブラリを使ってます。
Visual Studio 2012 Express です。

コード:

 



#include "DxLib.h"

#define a 1   //////速度確認用に時間の値にaをかけています。
              //////aの定義を2にすると2倍速で時が進みます。
              //////aの定義を60にして1時間の■の移動を1分で確認などに使えます。

#define Line1 "-------------------------------------------------------------------"//-は67個
#define Line2 "|"
#define error 15
#define GameStart "タイマーはEnterを押して開始        終了はEsc"//はじめの画面

#define TitleGOif MouseY<=210 && MouseY>=30 && MouseX<=210 && MouseX>=30
#define ExitGOif MouseY<=210 && MouseY>=30 && MouseX<=440 && MouseX>=260
#define TimerResetif MouseY<=130 && MouseY>=40 && MouseX<=630 && MouseX>=450
#define TimerStartif MouseY<=240 && MouseY>=60 && MouseX<=270 && MouseX>=90
#define TimerExitGO2if MouseY<=240 && MouseY>=60 && MouseX<=500 && MouseX>=320


//////////////////////関数の宣言/////////////////////
void MouseInitialize();
void Initialize();
void TimeInitialize();
void Color();
void GraphLoad();
void Draw();
void DrawLine();
void Time();
void TimerStart();
void Start();
void Exit();
void MouseF();
void TimerReset();
void TimerStartClick();
//void Position();
//int x=0,y=0;    //←位置調整

//////////////////////変数の宣言//////////////////////

////画像用
int ExitGraph,TimerResetGraph,TitleGoGraph,TimerStartGraph;

////終了用
int ExitN;

////マウス用
int Mouse;
int MouseX,MouseY;

////if文用
int startA;
int startB;

////time用
int starttime;
int Positionmsec;
int Positionsec;
int Positionmin;
int Positionhou;
int msec,sec,min,hou;

////色用
int White,Red;
int Blue,Green,Orange,Pink;
////←遅い           速い→

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



// マウスの入力状態を更新する
int gpUpdateMouse(){
	return 0;
}

// キーの入力状態を更新する
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, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
	
	ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK ); //ウィンドウモード変更と初期化と裏画面設定

	///////////////初期化関数
	Initialize();

	while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 && ExitN ){

		MouseInitialize();

		if(CheckHitKey(KEY_INPUT_ESCAPE)==1 || CheckHitKey(KEY_INPUT_BACK)==1){

			////////終了するための変数の初期化関数
			Exit();
		}

			if(startA){

				/////////タイマースタート
				TimerStart();
				TimerStartClick();

			}

		
		
		
			if(startB){

				if(CheckHitKey(KEY_INPUT_END)==1 || CheckHitKey(KEY_INPUT_1)==1 || CheckHitKey(KEY_INPUT_NUMPAD1)==1 ){

					////////はじめに戻るための変数の初期化関数
					Start();

				}

				/////////時間
				Time();
				/////////描画
				Draw();
				
				////////////マウス用の関数
				MouseF();

				/////////位置修正
				//Position();
			}
		
	
	}
	
	DxLib_End(); // DXライブラリ終了処理
	return 0;
}  


                                                     //////////////////////////////////
                                         //////////////////////////////////////////////
                          /////////////////////////////////////////////////////////////
            ///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////


///////////////////////////////********関数********////////////////////////////////////


void Initialize(){

	startA=1;
	startB=0;

	GraphLoad();

	Color();

	TimeInitialize();

	ExitN=1;

	Start();
}


void GraphLoad(){

	TimerResetGraph=LoadGraph("TimerReset.jpg");
	TimerStartGraph=LoadGraph("TimerStart.jpg");
	TitleGoGraph=LoadGraph("TitleGoGraph.jpg");
	ExitGraph=LoadGraph("Exit.jpg");

}

void TimeInitialize(){

	Positionmsec=0;
	Positionsec=0;
	Positionmin=0;
	Positionhou=0;
	msec=0;
	sec=0;
	min=0;
	hou=0;

}

void Color(){

	White=GetColor(255,255,255);
	Green=GetColor(0,255,0);
	Red=GetColor(255,0,0);
	Blue=GetColor(0,0,255);
	Orange=GetColor(255,130,0);
	Pink=GetColor(255,0,255);

}

void MouseInitialize(){

	SetMouseDispFlag( TRUE );
	GetMousePoint( &MouseX, &MouseY);
	Mouse=GetMouseInput();

}


///////////////////////////////////////////////////////////////////////////////////////
void Draw(){

	/////線の描画
	DrawLine();

	//////////////////////////////ミリ秒
	DrawFormatString(Positionmsec,230,Pink,"■");

	//////////////////////////////秒
	DrawFormatString(Positionsec,250,Orange,"■");

	//////////////////////////////分
	DrawFormatString(Positionmin,270,Green,"■");

	//////////////////////////////時間
	DrawFormatString(Positionhou,290,Blue,"■");

	DrawFormatString(200,230,Red,"%d",msec);
	DrawFormatString(200,250,Red,"%d秒",sec);
	DrawFormatString(200,270,Red,"%d分",min);
	DrawFormatString(200,290,Red,"%d時間",hou);


	DrawFormatString(100,350,White,"%d秒",((GetNowCount()-starttime)/1000));
	DrawFormatString(30,400,White,"タイトル画面へは1 終了はBackspace");
	DrawFormatString(330,400,White,"またはタイトル画面はEnd 終了はEsc");
	DrawFormatString(320,350,White,"%d時間%d分%d秒.%d",hou,min,sec,msec);

	DrawRotaGraph(120,120,1.0,0.0,TitleGoGraph,FALSE);
	DrawRotaGraph(350,120,1.0,0.0,ExitGraph,FALSE);
	DrawRotaGraph(540,85,0.5,0.0,TimerResetGraph,FALSE);
}


///////////////////////////////////////////////////////////////////////////////////////
void Time(){

	///////////////////////////////////////////////表示する値
	msec=((GetNowCount()-starttime)*a)%1000;

	sec=((GetNowCount()-starttime)/(1000/a))%60;

	min=((GetNowCount()-starttime)/(1000/a)/60)%60;
	
	hou=((GetNowCount()-starttime)/(1000/a))/3600;

	///////////////////////////////////////////////移動する■
	Positionmsec=((((GetNowCount()-starttime)/1))*a%600)-error;//←1ミリ秒=1000分の1秒
	
	Positionsec=((((GetNowCount()-starttime)/10)*6*a)%600)-error;//←1秒
	
	Positionmin=((((GetNowCount()-starttime)/100)*a)%600)-error;//←1分
	
	Positionhou=((((GetNowCount()-starttime)/6000)*a)%600)-error;//←1時間

}



//////////////////////////////////////////////////////////////////////////////////////
/*void Position(){
	DrawFormatString(0,0,White,"■0");
	DrawFormatString(-1,20,White,"■1");
	DrawFormatString(-2,40,White,"■2");
	DrawFormatString(-3,60,White,"■3");
	DrawFormatString(-4,80,White,"■4");
	DrawFormatString(-5,100,White,"■5");
	DrawFormatString(-6,120,White,"■6");
	DrawFormatString(-7,140,White,"■7");
	DrawFormatString(-8,160,White,"■8");
	DrawFormatString(-9,180,White,"■9");
	DrawFormatString(-10,200,White,"■10");
	DrawFormatString(-11,300,White,"■11");
	DrawFormatString(-12,320,White,"■12");
	DrawFormatString(-13,340,White,"■13");
	DrawFormatString(-14,360,White,"■14");
	DrawFormatString(-15,380,White,"■15");
	DrawFormatString(-16,400,White,"■16");
	DrawFormatString(-17,420,White,"■17");
	DrawFormatString(x,y,Green,"■");
	DrawFormatString(x+10,y+10,Green," %d , %d ",x,y);
	if(CheckHitKey(KEY_INPUT_LEFT)==1){
		x--;
	}
	if(CheckHitKey(KEY_INPUT_RIGHT)==1){
		x++;
	}
	if(CheckHitKey(KEY_INPUT_UP)==1){
		y--;
	}
	if(CheckHitKey(KEY_INPUT_DOWN)==1){
		y++;
	}

}*/


////////////////////////////////////////////////////////////////////////////////////
void TimerStart(){

	DrawRotaGraph(180,150,1.0,0.0,TimerStartGraph,FALSE);
	DrawRotaGraph(410,150,1.0,0.0,ExitGraph,FALSE);
	DrawFormatString(100,350,White,GameStart);
	
	if(CheckHitKey(KEY_INPUT_RETURN)==1){

		ClearDrawScreen();

		startA=0;//if文startAの処理をやめて
		startB=1;//if文startBの処理をはじめる

		starttime=GetNowCount();

	}
}


///////////////////////////////////////////////////////////////////////////////////
void Start(){
	startA=1;
	startB=0;
}
//////////////////////////////////////////////////////////////////////////////////
void Exit(){
	startA=0;
	startB=0;

	ExitN=0;
}


/////////////////////////////////////////////////////////////////////////////////
void MouseF(){

	if(Mouse & MOUSE_INPUT_LEFT){
		///////////////**タイトル画面へ**をクリックすると
		if(TitleGOif){
			Start();
		}
		//////////////**終 了**をクリックすると
		if(ExitGOif){
			Exit();
		}
		//////////////**タイマーリセットをクリックすると
		if(TimerResetif){
			TimerReset();
		}

		DrawFormatString(MouseX+10,MouseY+10,Red," %d , %d ",MouseX,MouseY);
			
	}
}


void TimerStartClick(){
	
	MouseInitialize();

	if(Mouse & MOUSE_INPUT_LEFT){
	
		///////////////**タイマースタートへ**をクリックすると
		if(TimerStartif){
					
			ClearDrawScreen();
			
			startA=0;//if文startAの処理をやめる
			startB=1;//if文startBの処理をはじめる
			
			starttime=GetNowCount();
			
		}	

		//////////////**終 了**をクリックすると
		if(TimerExitGO2if){
			Exit();
		}
				
		DrawFormatString(MouseX+10,MouseY+10,Red," %d , %d ",MouseX,MouseY);
	}
}

////////////////////////////////////////////////////////////////////////////////
void DrawLine(){
	////////////////////-----------------←これ
	DrawFormatString(-1,220,White,Line1);	
	DrawFormatString(-1,240,White,Line1);
	DrawFormatString(-1,260,White,Line1);
	DrawFormatString(-1,280,White,Line1);
	DrawFormatString(-1,300,White,Line1);
	///////////////////    | ←これ
	DrawFormatString(595,230,White,Line2);	
	DrawFormatString(595,250,White,Line2);
	DrawFormatString(595,270,White,Line2);	
	DrawFormatString(595,290,White,Line2);	
}


///////////////////////////////////////////////////////////////////////////////
void TimerReset(){
	starttime=GetNowCount();
	TimeInitialize();
}


こんな感じのコードです。

まず、タイマーの作成がこれであってるかどうかなのですが。。。


本題なんですが、
この状態ですとタイマースタートを左クリックした瞬間に
「タイマースタート」と「タイトル画面」の処理が一緒に行ってしまいます。

左クリック押したら
一度目はタイマースタート
二度目はタイトル画面へ
これをやりたいのです。


自分自身で解決しようとしましたがどうしてもうまくいきません。


簡単に質問すると。
「左クリック押した瞬間だけ処理を実行させるにはどうしたらよいのでしょうか?」

回答いただけるとありがたいです。

OS Windows7 HomePremium 64bit
パソコンの性能はそれなりにあるので問題はないかと
使ってるものはVisual Studio 2012 Express

C++の知識はあまりありませんがC言語の知識は入門書程度にあります。
また、リファレンスページを見ながら上のコードは自力で作る程度の能力です。

アバター
usao
記事: 1892
登録日時: 13年前
連絡を取る:

Re: マウスを押した瞬間だけ処理を実行したいのですが・・・

#2

投稿記事 by usao » 12年前

>この状態ですとタイマースタートを左クリックした瞬間に
>「タイマースタート」と「タイトル画面」の処理が一緒に行ってしまいます。

これが「なぜそうなるのか」がご自身でわかっているのでしょうか.
それとも原因からわからない状況でしょうか.

例えば,クリックが「何回目」なのかを数えるとしたら
 ボタンが押された(1回目)→離された→再度押された(2回目)→…
ということを判定する必要があるでしょう.
 ボタンが押されている(1回目)→引き続き押されている(2回目)→…
みたくならないようにする必要がありますよね.
(マウスボタンを「押し続けている間」延々とカウント値が増えていくようでは困る)

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

Re: マウスを押した瞬間だけ処理を実行したいのですが・・・

#3

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

ここのコンテンツのゲームプログラミングの館は読まれましたか?
その中にキーボードを押している時間をカウントする処理があったのを覚えていらっしゃいますか?
あれと同様のことをマウスのボタンでやれば、押した直後の判定が可能です。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

Bun

Re: マウスを押した瞬間だけ処理を実行したいのですが・・・

#4

投稿記事 by Bun » 12年前

原因はおそらくですがクリックしたままの状態でも左クリックの処理が動くせいだと思います、
なので3番さんがいう通りにやろうと思ったのですが

マウスのそういった関数ってありませんよね?
どうすればよいのでしょうか?

そういった関数とは
全部押すという関数のことです。

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

Re: マウスを押した瞬間だけ処理を実行したいのですが・・・

#5

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

押す?イマイチ意味が不明ですが、この関数ではダメなのですか。
「DXライブラリ置き場 リファレンスページ  GetMouseInput」
http://homepage2.nifty.com/natupaji/DxL ... .html#R5N8
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

Bun

Re: マウスを押した瞬間だけ処理を実行したいのですが・・・

#6

投稿記事 by Bun » 12年前

すこし誤解を招く書き方だったんでしょうか。わかりませんが


いまのタイマーの仕様は

タイマーが起動すると

画面に
タイマースタートと終了の画像がでます。
(そこをクリックするとそれぞれの処理に移ります。)

タイマースタートをクリックすると
タイマーがスタートします。

つまり、
タイトル、選択画面とタイマー画面の2つの画面が
ClearDrawScreen
とif文のおかげで両立しています。

でタイマー画面では
タイトル画面へと終了とタイマースタートの3つの画像があり
そのうちタイトル画面へとタイマースタートの画像が重なっています。


なので、ifで条件(座標の)をつけて
左クリックしたらその画像に書いてある処理をされるようにしたのですが
重なっていたため高速でどちらも処理されてしまうのです。

MidRock

Re: マウスを押した瞬間だけ処理を実行したいのですが・・・

#7

投稿記事 by MidRock » 12年前

あなたがsoftyaさんより文章の理解力があるなら
この程度の問題は紹介されたサイトを見れば解決できるはずです

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

Re: マウスを押した瞬間だけ処理を実行したいのですが・・・

#8

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

やるべき事は2つです。
1.マウスのボタンが押されてからの押されたいる間のフレーム数を得る処理を作ります。離されたら0に戻します。これはLeftとRight別に処理します。
ようするにgpUpdateKeyと似た処理です。 カウントが1なら押された直後と判定できます。

2.タイトル画面、終了画面、タイマスタート画面のどの状態なのかを示す変数を1つ作ります。
この変数を見ればどの画面か分かるので、それぞれの画面処理に分岐できます。
それぞれの画面処理に分かれていれば、判定すべきボタンは自ずと絞りこまれます。
※ 同じフレーム内にタイトル画面とタイマスタート画面の処理を同時に行わない工夫は必要です。

この2つをちゃんとすれば、ボタンを操作が誤動作することは無くなります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

閉鎖

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