押し続けの回避処理

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

押し続けの回避処理

#1

投稿記事 by フィア » 11年前

うまく質問しづらいのですが、ある場所をクリックして画面を切り替え、さらにクリックして画面を切り替える、さらにクリックして画面を切り替える・・・エンドレス

画面を切り替えるのはいいのですが問題なのはクリックを押し続けた状態で画面が切り替わった後、切り替わった後の画面で画面が切り替わる場所にマウスを持っていった場合画面が切り替わってしまいます。

これを避けるのに押し続けていますよ の スイッチを事前に入れるようにしたのですが、判定箇所が8箇所 と 24箇所 と 2箇所 と 右クリックかXボタン が混在している画面で 判定箇所を設定するために forを使って ループさせているのですが 押し続けてますよの判定をうまく設定できません。

どのようにしたら設定できますか?

わかりづらい質問で申し訳ありません

問題のコードは載せますが、全部のコードを見せたほうがいいかもしれません。

コード:

 
	int i,j;
	static int s_Nu;
	static bool u_bousi = false;
	static bool d_bousi = false;
	static bool But_sw = false;

	if( ( Br_M == 2 ) && ( s_MOVE == 0 ) ){

		for( j = 0; j < ki; j++ ){
			if( ki_sl == j ){
				switch( sin_next ){
					case brown_1_i:
						Bu_PointX_next = j;
						if( Bu_PointX != Bu_PointX_next ){
							Bu_PointX = Bu_PointX_next;
							
							switch( Bu_PointX ){
								case 0:
									Bu_Nu = B1;
									for( i = 0; i < Bu_Nu; i++ ){
										Bu_Fl[i] = Build_1_FL[i];
									}
									break;

								case 1:
									Bu_Nu = B2;
									for( i = 0; i < Bu_Nu; i++ ){
										Bu_Fl[i] = Build_2_FL[i];
									}
									break;

								case 2:
									Bu_Nu = B3;
									for( i = 0; i < Bu_Nu; i++ ){
										Bu_Fl[i] = Build_3_FL[i];
									}
									break;

								case 3:
									Bu_Nu = B4;
									for( i = 0; i < Bu_Nu; i++ ){
										Bu_Fl[i] = Build_4_FL[i];
									}
									break;

								case 4:
									Bu_Nu = B5;
									for( i = 0; i < Bu_Nu; i++ ){
										Bu_Fl[i] = Build_5_FL[i];
									}
									break;

								case 5:
									Bu_Nu = B6;
									for( i = 0; i < Bu_Nu; i++ ){
										Bu_Fl[i] = Build_6_FL[i];
									}
									break;

								case 6:
									Bu_Nu = B7;
									for( i = 0; i < Bu_Nu; i++ ){
										Bu_Fl[i] = Build_7_FL[i];
									}
									break;

								case 7:
									Bu_Nu = B8;
									for( i = 0; i < Bu_Nu; i++ ){
										Bu_Fl[i] = Build_8_FL[i];
									}
									break;
							}

							d_mode = d_second_md;

						}
						break;

					//case brown_3_i:
					//	Wa_PointX = i;
					//	break;

					//case brown_4_i:
					//	Tr_PointX = i;
					//	break;
				
				}				
			}
		}
		
		//スリップしてしまうバグがある とりあえず目立たなくはさせている
		if( Bu_Nu >30 ){ s_Nu = 2; }
		else if( Bu_Nu >24 ){ s_Nu = 1; }
		else{ s_Nu = 0; }

		if( ( ( CheckHitKey( KEY_INPUT_UP ) == 1 ) || ( Br_y == 1 ) ) && ( Bu_PointY[ Bu_PointX ] > 0 ) ){
			//if( But_sw == false ){
				if( u_bousi == true ){
					u_bousi = false;
					Br_y = 0;
				}

				else{
					s_MOVE = 1;
					Br_SY = -1;
					//But_sw = true;
				}
			//}
		}

		if( ( ( CheckHitKey( KEY_INPUT_DOWN ) == 1 ) || ( Br_y == 2 ) ) && ( Bu_PointY[ Bu_PointX ] < s_Nu ) ){
			//if( But_sw == false ){
				if( d_bousi == true ){
					d_bousi = false;
					Br_y = 0;
				}

				else{
					s_MOVE = 1;
					Br_SY = 1;
			//		But_sw = true;
				}
			//}
		}

		if( ( CheckHitKey( KEY_INPUT_X ) == 1 )||
		    ( ( GetMouseInput() & MOUSE_INPUT_RIGHT ) != 0 )	
		  ){
			if( But_sw == false ){
				Br_M = 1;
				Br_M_next = 1;
				But_sw = true;
			}

		}

		else{
			But_sw = false;
		}

		if( s_MOVE == 1 ){
			BrSmollCounter = 0;
		}

		for( i = 1; i < 25; i++ ){
			if( But_sw == false ){
				if( s_m_sl == i ){

					if( Bu_Fl[ i - 1 + Bu_PointY[ Bu_PointX ] * 6 ] == 1){
						bu_sn = i - 1 + Bu_PointY[ Bu_PointX ] * 6;
						Br_M = 1;
						Br_M_next = 2;
						But_sw = true;
					}

					else{
						But_sw = false;
					}

				}
			}
		}

		s_m_sl = 0;

	}

taketoshi
記事: 222
登録日時: 13年前
住所: 日本国

Re: 押し続けの回避処理

#2

投稿記事 by taketoshi » 11年前

WM_LBUTTONDOWNみたいな処理が必要ということでしょうか?

こちらが参考になると思います。
一つ前のフレームのボタンの押し下げ状態を変数に記録しておきましょう

http://hpcgi2.nifty.com/natupaji/bbs/pa ... ew&no=1196

フィア
記事: 82
登録日時: 11年前

Re: 押し続けの回避処理

#3

投稿記事 by フィア » 11年前

質問のないようだとわかりづらいと思うので

http://dixq.net/g/02_09.html

こちらのサイトに乗ってる事は
判定箇所が キーのみ で
押し続ける事によって 変化を与えるプログラム

について書かれているのですが

私が聞きたいのは
判定箇所が キー と クリック箇所 で
押し続ける事けても 変化させたくない プログラム
をききたいのです。

質問の仕方がおかしくてすみませんね

フィア
記事: 82
登録日時: 11年前

Re: 押し続けの回避処理

#4

投稿記事 by フィア » 11年前

そうです

まさしくwin32APIの
WM_LBUTTONDOWN

の処理です。

フィア
記事: 82
登録日時: 11年前

Re: 押し続けの回避処理

#5

投稿記事 by フィア » 11年前

参考として教えていただいたことは知っていました

私の場合フレームではなくスイッチを使ってますけれどね。

問題は判定箇所が複数あって for をつかって判定箇所が 複数あった場合 どのように回避すればいいの? という問題がわかりません。

フィア
記事: 82
登録日時: 11年前

Re: 押し続けの回避処理

#6

投稿記事 by フィア » 11年前

ああよくかんがえたらボタンを離したらの処理ではありませんでした

それはフレームを使わずに判定箇所を解除してるので解決していました
申し訳ありません

フィア
記事: 82
登録日時: 11年前

Re: 押し続けの回避処理

#7

投稿記事 by フィア » 11年前

問題の箇所となっている場所を抜き出してきました

http://kie.nu/XQu

一週間ほどダウンロード可能です。

bese.cpp の bese_manege 関数 if( ( Br_M == 2 ) && ( s_MOVE == 0 ) ) 時の処理ですね。

フィア
記事: 82
登録日時: 11年前

Re: 押し続けの回避処理

#8

投稿記事 by フィア » 11年前

現状は

建設をクリック そのままの状態でマウスを 採取施設 などの上8箇所
したの画面の 絵が描かれている建物 24箇所
上下ボタン の2箇所 

( xキーか右クリックを押すと 前の状態に戻る )

のどれか(判定箇所)に持っていくと画面が切り替わる

のですが、このような状態にしたいのではなく

建設をクリック そのままの状態でマウスを 判定箇所 にもって行っても画面を切り変えず、クリックを離して、再度クリックしたら次の画面に進むようにしたいのです。

ホヅミ
記事: 110
登録日時: 13年前

Re: 押し続けの回避処理

#9

投稿記事 by ホヅミ » 11年前

今ならまだ修正は利くと思うのでサンプルにある通りフレームカウント方法でシステム部分を書きなおしてみたらどうでしょうか?
一点物ならいいでしょうが、今後もゲーム作りを続けていくならばフレームカウントのほうがスマートな気がします。

フィア
記事: 82
登録日時: 11年前

Re: 押し続けの回避処理

#10

投稿記事 by フィア » 11年前

わかりましたフレーム形式でやってみます。

私としてはフレーム形式もスイッチ形式も同じだとは思うのですけどね。

次のフレームに移った時はの処理 == スイッチが入っている時の処理

だと思うので。

ホヅミ
記事: 110
登録日時: 13年前

Re: 押し続けの回避処理

#11

投稿記事 by ホヅミ » 11年前

キーボードでもマウスでもボタンが押されている間にカウントアップをさせて、カウント数に応じたステータス設定を行うのでコードも長くなりにくいかなと思います。

カウント0:FREE
カウント1:PUSH
カウント2~:HOLD
カウント1→0:PULL

といった感じにしてみてはいかがでしょうか?

フィア
記事: 82
登録日時: 11年前

Re: 押し続けの回避処理

#12

投稿記事 by フィア » 11年前

ってよく考えたらフレーム形式にしたとしても肝心の部分がわかっていません。

現在大体こうなっています

for( j = 0; j < 8; j++){
 if( jの判定箇所にあるなら ){
  //こう処理します
  スイッチを入れます→これをフレーム形式にする
 }
}

for( i = 0; i < 24; i++){
 if( iの判定箇所にあるなら ){
  //こう処理します
  スイッチを入れます→これをフレーム形式にする
 }
}

if(上ボタンが押されたら){
 //こう処理します
 スイッチを入れます→これをフレーム形式にする
}

if(下ボタンが押されたら){
 //こう処理します
 スイッチを入れます→これをフレーム形式にする
}

if( X キーが押される もしくは 右クリックが押される 時){
 if(スイッチが入っていないなら){
  //こう処理します
  スイッチを入れます→これをフレーム形式にする
 }
}

else{ //X キーを離す もしくは 右クリックをはなす 時
 スイッチを切ります
}

わからないのはfor 文 を使う時に if(スイッチが入っていないなら) の判定と スイッチを切るの処理をどうやればもっていけるか?
がわからないのです。

フィア
記事: 82
登録日時: 11年前

Re: 押し続けの回避処理

#13

投稿記事 by フィア » 11年前

11のを参考に作ってみます。

がfor 文の処理がTT

仮に何かの判定箇所をクリックしたとしても別の箇所がクリックされていないからという事でフレーム形式にしたとしても 1になってもすぐ0に戻ってしまいます。

そのためどうやればいいかを考えても思いつかないのです

ホヅミ
記事: 110
登録日時: 13年前

Re: 押し続けの回避処理

#14

投稿記事 by ホヅミ » 11年前

ゲームプログラミングの館
http://dixq.net/g/
40a. キーがどれ位押されたかを監視する関数
40b. マウスがどれ位押されたかを監視する関数

が参考を参考にするとだいぶスマートなのではないでしょうか?

フィア
記事: 82
登録日時: 11年前

Re: 押し続けの回避処理

#15

投稿記事 by フィア » 11年前

っとそれとすっごくおもったのですが
フレーム形式は大体11の感じでやるじゃないですか

でも2~ 

があるように無駄にカウントする理由がわからなかったためスイッチ形式にしました。

フレーム形式を薦める方は何故この 無駄にカウント するのを薦めるのですか?
シューティングゲームやアクションゲームとかならボタンを押し続けてアクションの仕方を変えるという理由でわかりますが、画面の切り替えの場合は変化させたいわけではないのでカウントする必要性が全くわからなかったのです。

フィア
記事: 82
登録日時: 11年前

Re: 押し続けの回避処理

#16

投稿記事 by フィア » 11年前

14を参考にやってみます。

ありがとうございました。

ホヅミ
記事: 110
登録日時: 13年前

Re: 押し続けの回避処理

#17

投稿記事 by ホヅミ » 11年前

確かに今回の場合は無駄カウントと言われてしまってはそうなってしまいます。
9でも言った通り一点物ならばカウントさせなくてもできます。
私が言いたいのは、次回のゲーム作りがあるならば経験上カウントのほうがいいかなと思ったのです。

カウントにするとどういうことができるかといいますとFREE,PUSH,HOLD,PULLが取れるのはもちろん、
キーが押されてから何フレーム目で処理を行うというものも作れるからです。

プログラミング中にBSキーを押してコードを削除することがあると思います。
BSキーは押された瞬間に1文字決し、少し間を開けてから次々と文字を消していくというものを見たことはないでしょうか?

カウントはこういった処理や他にもいろいろなことに応用ができます。

フィア
記事: 82
登録日時: 11年前

Re: 押し続けの回避処理

#18

投稿記事 by フィア » 11年前

それは、必要だと思った時にはフレームカウント形式をとりますよ。
そうしないと作れませんからね。

もちろん練習するためでしたらそれ用のプログラムはつくります。

もちろん次回も視野に入れてますが、今回作るゲームはめちゃくちゃ長そうなのでいつになるのか検討がつきません。
(おそらく何度かゲームを作る事があっても私はシューティングもアクションも練習するために作る事はあっても本格的なものは作らないと思いますが)

<<BSキーは押された瞬間に1文字決し、少し間を開けてから次々と文字を消していくというものを見たことはないでしょうか?

見たことありますよ。

<<カウントはこういった処理や他にもいろいろなことに応用ができます。

アドベンチャーの一文字づつ表示だとか(これも練習用に作った事はある)、私の今作っているゲームではスクロールや明暗処理をするときに使ってますよ

そのため、カウンターの必要性や性質は理解はしています。

カウンターを勧めていたのははホヅミさんなりに心配していただいたのですね。
心配していただきありがとうございました。

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

Re: 押し続けの回避処理

#19

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

汎用性が効きそうな処理は、汎用性の高い処理として作っておいたほうが後々使い回しが効いて便利です。
スイッチ式に比べてカウントの処理コストが掛かるように思えませんが如何でしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: 押し続けの回避処理

#20

投稿記事 by ISLe » 11年前

カウント式が嫌ならこんな感じで。

コード:

#include "DxLib.h"

static int mouse_input_old = 0;
static int mouse_input_new = 0;
int GetMouseInputTrigger() {
	return mouse_input_old ^ GetMouseInput();
}
int GetMouseInputTriggerOn() {
	return GetMouseInputTrigger() & GetMouseInput();
}
int GetMouseInputTriggerOff() {
	return GetMouseInputTrigger() & ~GetMouseInput();
}
void UpdateMouseInputTrigger() {
	mouse_input_old = mouse_input_new;
	mouse_input_new = GetMouseInput();
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	ChangeWindowMode(TRUE);
	if (DxLib_Init() != 0) return 0;
	SetDrawScreen(DX_SCREEN_BACK);

	int mouse_lbuttondown = 0;
	int mouse_lbuttonup   = 0;
	while (ProcessMessage() == 0 && ScreenFlip() == 0 && ClearDrawScreen() == 0) {
		UpdateMouseInputTrigger();
		if (GetMouseInputTriggerOn() & MOUSE_INPUT_LEFT) {
			++mouse_lbuttondown;
		}
		if (GetMouseInputTriggerOff() & MOUSE_INPUT_LEFT) {
			++mouse_lbuttonup;
		}
		DrawString(0,0,"マウスの左ボタンを",GetColor(255,255,255));
		DrawFormatString(0,25,GetColor(255,255,255),"押した回数[%d]離した回数[%d]",mouse_lbuttondown,mouse_lbuttonup);
	}
	
	DxLib_End();
	return 0;
}
インターフェース(この場合は関数名)をあらかじめ決めてしまえば、中身がカウント式だろうがスイッチ式だろうが関係ありません。

わたしは同じ場所から2回コピペしたら汎用化を検討し、3回コピペしたら汎用化を実施しなければいけないと考えます。
同じようなコードを何回も書くコストのほうがはるかに無駄で、無駄を放置する姿勢こそが未来永劫無駄を供給し続けるからです。

(追記)
GetMouseInputTrigger*関数では、GetMouseInput()関数を呼ばすにmouse_input_newを使うべきかな。

フィア
記事: 82
登録日時: 11年前

Re: 押し続けの回避処理

#21

投稿記事 by フィア » 11年前

#汎用性が効きそうな処理は、汎用性の高い処理として作っておいたほうが後々使い回しが効いて便利です。

それは確かにそうですね

#スイッチ式に比べてカウントの処理コストが掛かるように思えませんが如何でしょうか?
処理コストというのがよくわかりません

フィア
記事: 82
登録日時: 11年前

Re: 押し続けの回避処理

#22

投稿記事 by フィア » 11年前

<<ISLeさん
今回もコードを書いていただきありがとうございます。

初見では何を書いているのかわかりませんが、またじっくり眺めていじりまくって勉強したいと思います。

<<わたしは同じ場所から2回コピペしたら汎用化を検討し、3回コピペしたら汎用化を実施しなければいけないと考えます。
同じようなコードを何回も書くコストのほうがはるかに無駄で、無駄を放置する姿勢こそが未来永劫無駄を供給し続けるからです。

なるほど、汎用的な関数を作る事は確かにしたほうがいいかもしれませんね。
書いているうちに自然と似たようなコードができてきたためあまり意識しませんでした。

今後は汎用性が必要と感じたらつくって見ますね

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

Re: 押し続けの回避処理

#23

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

フィア さんが書きました: 処理コストというのがよくわかりません
処理時間の事です。
カウント式を避けたい理由は処理時間では無いのでしょうか?他に理由があったら教えて下さい。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

フィア
記事: 82
登録日時: 11年前

Re: 押し続けの回避処理

#24

投稿記事 by フィア » 11年前

今のところ処理時間がどうのこうのは実感ができないのであまり意識していません。

無駄にカウントを増やす理由がない。

のが最大の理由です。

何らかの理由があるからするのはわかるのですが、理由がなくてするのは何故なの? と疑問が飛ぶのです。

もちろんキーを押し続けた時間経過による変化をつけるのであればそうしたい理由ができてくるので何の疑問も持たずにカウンターフレーム形式にするのです。

もちろんカウンターフレーム形式を使って一定以上カウントしない処理をすれば無駄にカウントをし続けなくする事は可能ですよ。

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

Re: 押し続けの回避処理

#25

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

そうですね。
私ならカウント式がifなど分岐・関数の量・コード量が少ないなどの点で優れているなら採用します。
[追記]わざわざカウントを止めるのはコード的にバグを生みそうで要注意です。更に汎用性が下がると思います。
シンプル・コードの量が少ないのは何よりもバグの点でメリットだからです。

【補足】処理を見て分かりづらいとか、それも候補外にする理由でしょうか。
フィアさんにとってはカウントは気持ち悪いと表現して良い処理だと思いますので採用しないのも、それもフィアさんにとっての正解だと思います。

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

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: 押し続けの回避処理

#26

投稿記事 by ISLe » 11年前

わたしの場合、自作や標準ではない特定のライブラリ関数を直接呼ぶコードは移植性が下がるので避けます。
それと実装無しのプロトタイプで関数名など決めてしまうので、自然とインターフェースができていて、中身を実装するときはそもそもコピペの必要性が低いです。

例えばマウスの左ボタンが押された瞬間を判定したいところには、
if (isMouseLeftButtonTriggerOn()) {
}
というふうにあらかじめ書いておくわけです。
そして動かすために必要なところから中身の実装を進めていきます。
わたしはこれを汎用化のためにやっているわけではありません。
可読性も上がると思いますが、作業量を見通しやすかったりモチベーションを維持しやすいのでこういうやり方をしています。

掲示板に投稿するときは冗長になるのでしません。

フィア
記事: 82
登録日時: 11年前

Re: 押し続けの回避処理

#27

投稿記事 by フィア » 11年前

大体コードの内容がわかって、こんな表現もあるのか!
っと思っていて改良の仕方がわかったのですがどうしてもわからないところがあります。

int GetMouseInputTrigger() {
return mouse_input_old ^ GetMouseInput();
}

この部分の ^ はどういう動きをしているのかがわかりません。
両方のビットが異なるときに結果を 1 にするビット演算なのはわかるのですが、それを使うとどうして制御できるようになるのかがわからないです。

そういう仕組みだとは理解できたので改良は可能であれこれできるのですが疑問点が残っているのは問題なので質問させていただきました。

フィア
記事: 82
登録日時: 11年前

Re: 押し続けの回避処理

#28

投稿記事 by フィア » 11年前

softya(ソフト屋) さんが書きました:そうですね。
私ならカウント式がifなど分岐・関数の量・コード量が少ないなどの点で優れているなら採用します。
[追記]わざわざカウントを止めるのはコード的にバグを生みそうで要注意です。更に汎用性が下がると思います。
シンプル・コードの量が少ないのは何よりもバグの点でメリットだからです。

【補足】処理を見て分かりづらいとか、それも候補外にする理由でしょうか。
フィアさんにとってはカウントは気持ち悪いと表現して良い処理だと思いますので採用しないのも、それもフィアさんにとっての正解だと思います。

【さらに追記】
bese_manegeが気になったので。
base_manageだと思います。
・・・・・え、カウンター止めるとバグがでるんですか?
止める方向で改良してみたのですが・・・・。

っと言いますかカウンター止めないと無限に増えてしまうためオーバーフローしませんか?
ただのカウンターが気持ちが悪いのではなく、「無限に」の部分が気持ち悪いのですね

私にとっては正解な事をやってるから一般的な書き方からどんどん離れていくのですね。
わかりますがやめられない。

#bese_manege
あら?確かにそのとおりですね
指摘ありがとうございます

あっちこっち修正しないといけませんね

フィア
記事: 82
登録日時: 11年前

Re: 押し続けの回避処理

#29

投稿記事 by フィア » 11年前

ISLe さんが書きました:わたしの場合、自作や標準ではない特定のライブラリ関数を直接呼ぶコードは移植性が下がるので避けます。
それと実装無しのプロトタイプで関数名など決めてしまうので、自然とインターフェースができていて、中身を実装するときはそもそもコピペの必要性が低いです。

例えばマウスの左ボタンが押された瞬間を判定したいところには、
if (isMouseLeftButtonTriggerOn()) {
}
というふうにあらかじめ書いておくわけです。
そして動かすために必要なところから中身の実装を進めていきます。
わたしはこれを汎用化のためにやっているわけではありません。
可読性も上がると思いますが、作業量を見通しやすかったりモチベーションを維持しやすいのでこういうやり方をしています。

掲示板に投稿するときは冗長になるのでしません。
つまりISLeさんは先読みして計画性があるのですね。

私の場合、その場その場になった時にどういう方針で行くか考えて決めるから計画性がないのですね
全くある程度どうするか決めていないわけではないのですが、その場になった時こういう風にすれば面白いのではないか? っと思いついたら即実行するため計画を練っても変わっちゃうのは問題かもしれませんね。

フィア
記事: 82
登録日時: 11年前

Re: 押し続けの回避処理

#30

投稿記事 by フィア » 11年前

えっとISLeさんに非常に悪いのですが私の汎用関数のソースコードができました。
ISLeさんのソースコードを元に(してたんですが原型が残ってません)作ってみました。

カウンター式がカウンター止めるとバグがでるとのことなのでカウンター式ではなくスイッチ式です。
普通の方にとっては汎用性はないのかもしれませんが改良はしやすいので、カウンターをとめるとバグが出るというのを解決できるのならカウンター式も作りますね。

コード:

#include "DxLib.h"

void Push_Judge( int *Push_m , int *Flont_p , int *Back_p ){

		if( *Push_m ){
			if( ( ( GetMouseInput() & MOUSE_INPUT_LEFT ) != 0 ) || ( CheckHitKey( KEY_INPUT_Z ) == 1 ) || ( CheckHitKey( KEY_INPUT_RETURN ) == 1 ) ){
				*Flont_p = 1;
			}

			if( ( ( GetMouseInput() & MOUSE_INPUT_LEFT ) == 0 ) && ( CheckHitKey( KEY_INPUT_Z ) != 1 ) && ( CheckHitKey( KEY_INPUT_RETURN ) != 1 ) ){
				*Flont_p = 0;
			}
		}
		
		else{
			if( ( GetMouseInput() & MOUSE_INPUT_LEFT ) != 0 ){
				*Flont_p = 1;
			} 

			if( ( GetMouseInput() & MOUSE_INPUT_LEFT ) == 0 ){
				*Flont_p = 0;
			}
		}

		if( ( ( GetMouseInput() & MOUSE_INPUT_RIGHT ) != 0 ) || ( CheckHitKey( KEY_INPUT_X ) == 1 ) || ( CheckHitKey( KEY_INPUT_ESCAPE ) == 1 ) ){
            *Back_p = 1;
        }

        if( ( ( GetMouseInput() & MOUSE_INPUT_RIGHT ) == 0 ) && ( CheckHitKey( KEY_INPUT_X ) != 1 ) && ( CheckHitKey( KEY_INPUT_ESCAPE ) != 1 ) ){
            *Back_p = 0;
        }

}
 
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    ChangeWindowMode(TRUE);
    if(DxLib_Init() != 0) return 0;
    SetDrawScreen(DX_SCREEN_BACK);
 
	int Push_m = 1; // 0の時:マウスのみ 1の時:マウスとキー 

	int Flont_p = 0;
	int Back_p  = 0;

    while (ProcessMessage() == 0 && ScreenFlip() == 0 && ClearDrawScreen() == 0) {
		Push_Judge( &Push_m , &Flont_p , &Back_p );

		DrawString( 0 , 0 , "進行ボタンが" , GetColor( 255 , 255 , 255 ) );
		if( Flont_p ){
			DrawString( 0 , 25 , "押されている" , GetColor( 255 , 255 , 255 ) );
		}
		else{
			DrawString( 0 , 25 , "押されていない" , GetColor( 255 , 255 , 255 ) );
		}

		DrawString( 0 , 50 , "戻るボタンが" , GetColor( 255 , 255 , 255 ) );
		if( Back_p ){
			DrawString( 0 , 75 , "押されている" , GetColor( 255 , 255 , 255 ) );
		}
		else{
			DrawString( 0 , 75 , "押されていない" , GetColor( 255 , 255 , 255 ) );
		}
    }
    
    DxLib_End();
    return 0;
} 

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

Re: 押し続けの回避処理

#31

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

>ただのカウンターが気持ちが悪いのではなく、「無限に」の部分が気持ち悪いのですね

カウントのオーバーフローは2147483647カウント後に発生します。
これが何時起こるかですが、一秒間に60フレームで一時間で60x3600カウントですから9942時間後に発生します。
9942時間/24時間で414日後となります。まぁ、事実上は無視出来る時間だと思います。

>・・・・・え、カウンター止めるとバグがでるんですか?
>止める方向で改良してみたのですが・・・・。

必要もないコード入れるのはバグの元になると言う話だけです。
少なくとも私にとってはカウンターストップは必要がありません。
汎用性も失うことになりますので。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: 押し続けの回避処理

#32

投稿記事 by ISLe » 11年前

フィア さんが書きました:

コード:

int GetMouseInputTrigger() {
    return mouse_input_old ^ GetMouseInput();
}
この部分の ^ はどういう動きをしているのかがわかりません。
両方のビットが異なるときに結果を 1 にするビット演算なのはわかるのですが、それを使うとどうして制御できるようになるのかがわからないです。
mouse_input_oldには(UpdateMouseInputTrigger関数を呼び出した時点で)前回のGetMouseInput()関数の戻り値が入ります。
なので、ビットが異なるときというのは、
1.前回押されていたボタンが今回離されていたとき
2.前回離されていたボタンが今回押されていたとき
となります。
その状態変化がそのまま各ボタンのビットに反映される仕組みです。

つまり

コード:

int GetMouseInputTrigger() {
    int mouse_input_tigger = 0;
    if (((mouse_input_old & MOUSE_INPUT_LEFT) == 0) && ((GetMouseInput() & MOUSE_INPUT_LEFT) != 0)
     || ((mouse_input_old & MOUSE_INPUT_LEFT) != 0) && ((GetMouseInput() & MOUSE_INPUT_LEFT) == 0)) {
        // 前回離されていたボタンが今回押されていたとき、あるいは
        // 前回押されていたボタンが今回離されていたとき、対象ボタンのビットを立てる
        mouse_input_tigger |= MOUSE_INPUT_LEFT;
    }
    if (((mouse_input_old & MOUSE_INPUT_RIGHT) == 0) && ((GetMouseInput() & MOUSE_INPUT_RIGHT) != 0)
     || ((mouse_input_old & MOUSE_INPUT_RIGHT) != 0) && ((GetMouseInput() & MOUSE_INPUT_RIGHT) == 0)) {
        mouse_input_tigger |= MOUSE_INPUT_RIGHT;
    }
    // 以下マウスのボタンの数だけ繰り返し
    return mouse_input_tigger;
}
というのを^演算子1つで済ませているわけです。

ついでに将来MOUSE_INPUT_*というシンボルが増えたとしても32ボタンまで変更なしに対応できるはずです。

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: 押し続けの回避処理

#33

投稿記事 by ISLe » 11年前

フィア さんが書きました:つまりISLeさんは先読みして計画性があるのですね。

私の場合、その場その場になった時にどういう方針で行くか考えて決めるから計画性がないのですね
全くある程度どうするか決めていないわけではないのですが、その場になった時こういう風にすれば面白いのではないか? っと思いついたら即実行するため計画を練っても変わっちゃうのは問題かもしれませんね。
わたしも思い付いたことをその場で実装することはしょっちゅうあります。

ただ何をしたいかを具体的にしてからコーディングするようにしているだけです。

わたしが書いていることを読んでいたら分かると思いますが、わたしは基本的にコーディングが好きではありません。
できるだけコードを書きたくないので紙と鉛筆(比喩表現)を使って落書きしている時間のほうが長くなります。

さらに、このままコーディングを続けたらコピペスパイラル等の地獄に陥ると思ったら、すべてを一から書き直します。
そこにはまったく計画性などありません。

(追記)
わたしがあらかじめ決めるのは方針ではなく、目標(ゴール)です。
方針は常に変化します。
最後に編集したユーザー ISLe on 2013年4月17日(水) 18:11 [ 編集 1 回目 ]

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: 押し続けの回避処理

#34

投稿記事 by ISLe » 11年前

フィア さんが書きました:えっとISLeさんに非常に悪いのですが私の汎用関数のソースコードができました。
押しているあいだずっと押していると判定されるだけのように見えますけど。
これでは最初の問題の解決に繋がらないのでは?

わたしのコードでカウントが上がるのは押した瞬間だけで、押しっぱなしでは上がりませんよ。

『何をしたいのか』が最初から明らかでない、あるいは途中で見失うからこういうことが起こるのではないですか?


あと、毎回引数でキーボードを使うかどうかのパラメータを渡すのは使いにくいと思います。

フィア
記事: 82
登録日時: 11年前

Re: 押し続けの回避処理

#35

投稿記事 by フィア » 11年前

softya(ソフト屋) さんが書きました:>
カウントのオーバーフローは2147483647カウント後に発生します。
これが何時起こるかですが、一秒間に60フレームで一時間で60x3600カウントですから9942時間後に発生します。
9942時間/24時間で414日後となります。まぁ、事実上は無視出来る時間だと思います。
9942時間後なら問題ないですね
カウンター式にしてみますね

フィア
記事: 82
登録日時: 11年前

Re: 押し続けの回避処理

#36

投稿記事 by フィア » 11年前

ISLe さんが書きました: 1.前回押されていたボタンが今回離されていたとき
2.前回離されていたボタンが今回押されていたとき
その状態変化がそのまま各ボタンのビットに反映される仕組みです。
なるほどそういう仕組みなのですね
便利なのは非常にわかるのですが使われるところを見ているのに
使いこなせる気がしません。

使う場面の経験がもう少しほしいところですね。
ISLe さんが書きました: ついでに将来MOUSE_INPUT_*というシンボルが増えたとしても32ボタンまで変更なしに対応できるはずです。
マウスにボタンがぼこぼこについているんですね
多目的マウス・・・ってそれくらいならキーボードのキーを増やしてほしい気も

フィア
記事: 82
登録日時: 11年前

Re: 押し続けの回避処理

#37

投稿記事 by フィア » 11年前

ISLe さんが書きました:わたしも思い付いたことをその場で実装することはしょっちゅうあります。

ただ何をしたいかを具体的にしてからコーディングするようにしているだけです。

わたしが書いていることを読んでいたら分かると思いますが、わたしは基本的にコーディングが好きではありません。
できるだけコードを書きたくないので紙と鉛筆(比喩表現)を使って落書きしている時間のほうが長くなります。

さらに、このままコーディングを続けたらコピペスパイラル等の地獄に陥ると思ったら、すべてを一から書き直します。
そこにはまったく計画性などありません。

(追記)
わたしがあらかじめ決めるのは方針ではなく、目標(ゴール)です。
方針は常に変化します。
つまり一呼吸おくかおかないかの違いですね。

フィア
記事: 82
登録日時: 11年前

Re: 押し続けの回避処理

#38

投稿記事 by フィア » 11年前

ISLe さんが書きました:押しているあいだずっと押していると判定されるだけのように見えますけど。
これでは最初の問題の解決に繋がらないのでは?

わたしのコードでカウントが上がるのは押した瞬間だけで、押しっぱなしでは上がりませんよ。

『何をしたいのか』が最初から明らかでない、あるいは途中で見失うからこういうことが起こるのではないですか?
やっぱりせっかく作っていただいたのに原型すら残さないコードになった事を怒ってるんですね。

いろいろ書いているうちにこうなってしまったんです。ごめんなさいね。

ですが、今回ISLeさんが書いていただいたコードは無駄じゃなかったのですよ。
おかげで問題解決できたのです。

もちろんコードでカウントが上がるのは押した瞬間だけで、押しっぱなしでは上がらない部分は確認済みですよ。

ですがキーボードを組み合わせようとするとうまくいかなかったのです。

私が今回一番問題だったのはfor文の時にどうすればいいかが全くわからなかったのですが、
質問して答えていただいたおかげで無事に解決できたのです。

ですからそれには大変感謝していますよ。
ISLe さんが書きました:あと、毎回引数でキーボードを使うかどうかのパラメータを渡すのは使いにくいと思います。
マウスのみでも操作は可能ですが補助的にキーボードを使ってもある程度補助できるようにしたかったのです。

これはプレイヤーを意識していたためです。
何らかの事情でマウスが使えなくなる場合もあるかと思うのでその処置ですね
(私自身がたまにマウスを使えなくなるので困ったものです)。

ウィンドウズもマウスが使えなくてもキーボードを使って操作を多少できるので、私もそんな処置をしておきたかったのです。

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

Re: 押し続けの回避処理

#39

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

>やっぱりせっかく作っていただいたのに原型すら残さないコードになった事を怒ってるんですね。

ISLe さんは怒っているんじゃなくて、冷静に指摘しているだけだと思います。
最初の主旨からズレているのでは?って事です。こんな事で怒るようなISLe さんではありません。

ISLe さんのコードは押しっぱなしでも0→1→0と変化します。つまり押した瞬間の1フレームだけ1なのです。
フィアさんのコードは押している間ずっと1です。

誤動作を直したかったハズですので、ISLe さんの実装のほうが正しく見えますが如何なのでしょうか?

>マウスのみでも操作は可能ですが補助的にキーボードを使ってもある程度補助できるようにしたかったのです。

こちらもインターフェイスが良くないと指摘しているだけです。
もっと良い設計はないかという問いかけです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: 押し続けの回避処理

#40

投稿記事 by ISLe » 11年前

画面が変わった先でカーソルの下に押せるパーツがあったとき、押しっぱなしだとそれも押したことになってしまわないですか?
最初の質問はそういうことだと思ってました。
なのでどうしてあのコードで解決できたのか不思議だと思いました。
たまたま思ったとおりになっただけでなければ良いですが。

引数で渡すためには引数で渡す内容をあちこちへ引きずり回さなくてはいけなくなります。
キーボードを使う使わないを切り替える関数を別に用意して、ふだんはどちらが選択されているかというか切り替え機能の存在そのものも意識しないで使えるようにしたほうが良いのではないでしょうか?
仮にゲームパッドも使えるようにしたいと思ったら再びあちこち直して回るのですか?

キーボードの扱いは、キーと処理をそのまま結び付けずに、キーと機能、機能と処理と分ければ良いと思います。
決定やカーソル上下といった機能ごとにビットに割り当てて管理すれば、ビット演算が使えますよ。
仮にゲームパッドも使えるようにしたいと思ったとき、機能をセットするだけでその先は変更する必要がありません。

余談ですが、ビット演算を使ってチャタリングを回避することもできます。
カウンタ方式でもビット演算を併用する場合があります。

フィア
記事: 82
登録日時: 11年前

Re: 押し続けの回避処理

#41

投稿記事 by フィア » 11年前

#誤動作を直したかったハズですので、ISLe さんの実装のほうが正しく見えますが如何なのでしょうか?

あの関数のおかげで完全に誤動作を全て解決できました。
ただ、カウンター形式を使い始めたらいらないとわかったので大きな関数に組み込みました。

#こちらもインターフェイスが良くないと指摘しているだけです。
もっと良い設計はないかという問いかけです。

上で言った大きな関数にくみこんだ時にそこら辺を修正してみました。
まだまだ改良の余地はありそうなので少しづつ改良しています。

フィア
記事: 82
登録日時: 11年前

Re: 押し続けの回避処理

#42

投稿記事 by フィア » 11年前

質問の仕方がどうやって言えば伝えられるかをわからなかったので、回答者に捉え方が違ってしまったのは申し訳ありません。

私の元のスイッチ形式ですが無限数を扱わないだけで、カウンタフレーム形式と同様の処理をしていました。

ですので、たまたまっと言うわけではありません。

今は薦められたカウンター形式を使っているため、
ああこの関数全くいらんわとわかったので、大きな関数に組み込んでますけどね
(カウンター形式だと大分ソースコードが短くなりました)

問題はfor文の時にスイッチ形式でやる場合どうすればいいかわからなかったのですが、今回の回答でこうすればいいのかっとわかりました。
ISLe さんが書きました:引数で渡すためには引数で渡す内容をあちこちへ引きずり回さなくてはいけなくなります。
そうですね。
引数で渡して~っと言うのは本来なら別のファイルに値を渡す時にやるべきでしたね。

予断ですが
別のファイルに値を渡すために関数にやたらといろいろ引数を渡しまくったら長くなりまくった関数がひとつあります。

これも改良した方がいいと思うのですが『どうすればいいかわからん』状態です。
ISLe さんが書きました: キーボードを使う使わないを切り替える関数を別に用意して、ふだんはどちらが選択されているかというか切り替え機能の存在そのものも意識しないで使えるようにしたほうが良いのではないでしょうか?
仮にゲームパッドも使えるようにしたいと思ったら再びあちこち直して回るのですか?
大きな関数でどちらを使うかを選択できるようにしてみました。
まだまだ改良の余地はありそうなので少しづつ改良しています。

ゲームパッドは使わないです。
キーボードとマウスはどのPCにもついている標準装備だと思うので処理は必要だと思うのですが、ゲームパッドはわざわざゲームのため(? それ以外に使えるのかどうかはわからない)に購入する必要があるため、標準的なものではないと考えています。

確かにゲームパッドがあれば操作の豊富さは増えるかもしれませんが、持ってない人だっていることを考えたら必要ないかな っと思いゲームパッドは使いません。
ISLe さんが書きました:余談ですが、ビット演算を使ってチャタリングを回避することもできます。
カウンタ方式でもビット演算を併用する場合があります。
ビット演算は確かに使いこなせればいろいろ可能性はあると思います。
これは思いつかなかった方法も探せばいろいろとありそうですね
(今回の ^ もそうですね)

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: 押し続けの回避処理

#43

投稿記事 by ISLe » 11年前

「キーボードとマウスは標準装備なので必要」というのと「ゲームパッドは標準装備ではないので不要」というのはコストが同じだと思いますが。
前からわたしは「要・不要を考えること自体が不要」だということを言っているのですがどうにも伝わらないようです。

フィア
記事: 82
登録日時: 11年前

Re: 押し続けの回避処理

#44

投稿記事 by フィア » 11年前

グローバル変数や他の関数の参照とかは勘弁してください
あっちこっちたどらないといけなくなるため
このような感じで回避しました

コード:

 
void bese_point( void ){

	int i;
	static int saX , saY;
	struct Build data[31];

	static int Build_now , Build_next;

	if( ( Br_M == 2 ) && ( s_MOVE == 0) ){
		if( CheckHitKey( KEY_INPUT_UP ) == 1 ){ Br_y = 1; }
		if( CheckHitKey( KEY_INPUT_DOWN ) == 1 ){ Br_y = 2;}
	}

	//ここから常時監視用
	if( ( Br_M == 3 ) && ( Move == 0 ) ){
		GetMousePoint( &MouX, &MouY );

		POINT pt = { MouX, MouY };

		if( sin == brown_2_i ){
			if( PtInRect( &gr_rc[100] , pt ) ){			
				for( i = 0; i < 100; i++){
					if( PtInRect( &gr_rc[i] , pt ) ){
						gr_sle = i;
					}
				}
			}

			else{
				gr_sle = 100;
			}
		}

		else{
			build_data( data , Bu_PointX );
			Build_next = data[ bu_sn ].shape[ 3 ];

			if( Build_now != Build_next ){
				Build_now = Build_next;

				switch( Build_now ){
					case 1: saY =  0; saX =  0; break;
					case 2: saY =  0; saX = 32; break;
					case 3: saY = 32; saX = 32; break;
					case 4: saY =  0; saX = 64; break;
					case 5: saY = 32; saX = 64; break;
				}
				
				bwt_rc[400].left   =  52 + saX;
				bwt_rc[400].top    =  40 + saY;
				bwt_rc[400].right  = 692;
				bwt_rc[400].bottom = 680;
			
			}

			if( PtInRect( &bwt_rc[400] , pt ) ){			
				for( i = 0; i < 400; i++){
					if( PtInRect( &bwt_rc[i] , pt ) ){
						bwt_sle = i;
					}
				}
			}

			else{
				bwt_sle = 400;
			}
		}

	}

	if( Br_M == 5 ){
		GetMousePoint( &MouX, &MouY );

		POINT pt = { MouX, MouY };

		if( hen_num % 2 ){
			if( PtInRect( &hen_rc[14] , pt ) ){
				for( i = 6; i < 13; i++ ){
					if( PtInRect( &hen_rc[i] , pt ) ){
						hen_sle = i;
					}
				}
			}

			else{
				hen_sle = 13;
			}
		}

		else{
			if( PtInRect( &hen_rc[13] , pt ) ){
				for( i = 0; i < 6; i++ ){
					if( PtInRect( &hen_rc[i] , pt ) ){
						hen_sle = i;
					}
				}
			}

			else{
				hen_sle = 13;
			}
		}	
	}

	//ここからマウス 決定用
	if( ( GetMouseInput() & MOUSE_INPUT_LEFT ) != 0 ) {
		GetMousePoint( &MouX, &MouY );

		POINT pt = { MouX, MouY };

		if( ( Br_M == 0) && ( Move == 0 ) ){

			if( PtInRect( &brown_1_rc , pt ) ){
				sin = brown_1_i; //茶1ボタン
				ki = 8;
			}

			if( PtInRect( &brown_2_rc , pt ) ){
				sin = brown_2_i; //茶2ボタン
			}

			if( PtInRect( &brown_3_rc , pt ) ){
				sin = brown_3_i; //茶3ボタン
				ki = 5;
			}

			if( PtInRect( &brown_4_rc , pt ) ){
				sin = brown_4_i; //茶4ボタン
				ki = 5;
			}

			if( PtInRect( &aqua_1_rc , pt ) ){
				sin = aqua_1_i; //水1ボタン
			}

			if( PtInRect( &aqua_2_rc , pt ) ){
				sin = aqua_2_i; //水2ボタン
			}

			if( PtInRect( &green_1_rc , pt ) ){
				sin = green_1_i; //緑1ボタン
			}

			if( PtInRect( &green_2_rc , pt ) ){
				sin = green_2_i; //緑2ボタン
			}

			if( PtInRect( &green_3_rc , pt ) ){
				sin = green_3_i; //緑3ボタン
			}
		}

		if( ( Br_M == 2 ) && ( s_MOVE == 0) ){
			if( PtInRect( &y_u_rc , pt ) ){
				Br_y = 1;
			}

			if( PtInRect( &y_d_rc , pt ) ){
				if( Bu_Nu > 24){
					Br_y = 2;
				}
			}

			for( i = 0; i < ki; i++ ){
				if( PtInRect( &ki_rc[i] , pt ) ){
					ki_sl = i;
				}
			}

			for( i = 0; i < 24; i++ ){
				if( PtInRect( &s_m_rc[i] , pt ) ){
					s_m_sl = i+1;
				}
			}
		}

		if( ( Br_M == 3 ) && ( Move == 0 ) ){
			if( sin == brown_2_i ){
				for( i = 0; i < 100; i++){
					if( PtInRect( &gr_rc[i] , pt ) ){
						gr_sl = i;
					}
				}
			}

			else{			
				for( i = 0; i < 400; i++){
					if( PtInRect( &bwt_rc[i] , pt ) ){
						bwt_sl = i;
					}
				}
			}
		}

		if( Br_M == 5 ){
			switch( hen_num ){
				case 4:
					for( i = 1; i < 5 ; i++ ){
						if( PtInRect( &hen_rc[i] , pt ) ){
							hen_sl = i -1;
						}
					}
					break;

				case 5:
					for( i = 7; i < 12 ; i++ ){
						if( PtInRect( &hen_rc[i] , pt ) ){
							hen_sl = i - 7;
						}
					}
					break;

				case 6:
					for( i = 0; i < 6; i++ ){
						if( PtInRect( &hen_rc[i] , pt ) ){
							hen_sl = i;
						}
					}
					break;

				case 7:
					for( i = 6; i < 13; i++ ){
						if( PtInRect( &hen_rc[i] , pt ) ){
							hen_sl = i - 6;
						}
					}
					break;

			}

		}
		
		Flont_p += 1;
	}

	//ここから決定 キー用 もしかしたら拠点画面では使わんかも
	if( ( CheckHitKey( KEY_INPUT_Z ) == 1 ) || ( CheckHitKey( KEY_INPUT_RETURN ) == 1 ) ){
		Flont_p += 1;
	}

	if( ( ( GetMouseInput() & MOUSE_INPUT_LEFT ) == 0 ) && ( ( CheckHitKey( KEY_INPUT_Z ) != 1 ) && ( CheckHitKey( KEY_INPUT_RETURN ) != 1 ) ) ){
		Flont_p = 0;
	}

	//キャンセル用
	if( ( ( GetMouseInput() & MOUSE_INPUT_RIGHT ) != 0 ) || ( CheckHitKey( KEY_INPUT_X ) == 1 ) || ( CheckHitKey( KEY_INPUT_ESCAPE ) == 1 ) ){
        Back_p += 1;
    }

    if( ( ( GetMouseInput() & MOUSE_INPUT_RIGHT ) == 0 ) && ( CheckHitKey( KEY_INPUT_X ) != 1 ) && ( CheckHitKey( KEY_INPUT_ESCAPE ) != 1 ) ){
        Back_p = 0;
    }
}

コード:

 
void bese_manage( void ){

	int i,j;
	static int s_Nu;
	static bool u_bousi = false;
	static bool d_bousi = false;
	static int hen_suu;

	// 移動中じゃない場合キー入力とコマンドを受け付ける
	if( ( Move == 0 ) && ( Br_M == 0) ){

		bese_scroll();

		if( ( sin == brown_1_i ) ||
			( sin == brown_3_i ) ||
			( sin == brown_4_i ) ){
			if( Flont_p == 1 ){
				Br_M = 1;
				Br_M_next = 0;
				d_mode = d_second_md;
			}
		}

		if( sin == brown_2_i ){
			if( Flont_p == 1 ){
				Br_M = 3;
				d_mode = d_second_md;
			}
		} 

		if( Move == 1 ){
			MoveCounter = 0;
		}
	}

	if( Br_M == 1 ){
		
		if( Br_M_next == 0 ){
			BrCounter++;
		}

		else{
			BrCounter--;
		}

		switch( Br_M_next ){
			case 0:
				if( BrCounter == Br_FRAME ){
					Br_M = 2;
					s_m_sl = 0;
				}

				else{
					Br_L = 256 * BrCounter / Br_FRAME;
				}
				break;
 
			case 1:
				if( BrCounter == 0 ){
					Br_M = 0;
					sin = other_i;
				}

				else{
					Br_L = 256 * BrCounter / Br_FRAME;
				}
				break;

			case 2:
				if( BrCounter == 0 ){
					Br_M = 3;
				}

				else{
					Br_L = 256 * BrCounter / Br_FRAME;
				}
				break;
		}

	}

	if( ( Br_M == 2 ) && ( s_MOVE == 0 ) ){
		for( j = 0; j < ki; j++ ){
			if( Flont_p == 1 ){
				if( ki_sl == j ){
					switch( sin ){
						case brown_1_i:
							Bu_PointX_next = j;
							if( Bu_PointX != Bu_PointX_next ){
								Bu_PointX = Bu_PointX_next;
								
								switch( Bu_PointX ){
									case 0:
										Bu_Nu = B1;
										for( i = 0; i < Bu_Nu; i++ ){
											Bu_Fl[i] = Build_1_FL[i];
										}
										break;

									case 1:
										Bu_Nu = B2;
										for( i = 0; i < Bu_Nu; i++ ){
											Bu_Fl[i] = Build_2_FL[i];
										}
										break;

									case 2:
										Bu_Nu = B3;
										for( i = 0; i < Bu_Nu; i++ ){
											Bu_Fl[i] = Build_3_FL[i];
										}
										break;

									case 3:
										Bu_Nu = B4;
										for( i = 0; i < Bu_Nu; i++ ){
											Bu_Fl[i] = Build_4_FL[i];
										}
										break;

									case 4:
										Bu_Nu = B5;
										for( i = 0; i < Bu_Nu; i++ ){
											Bu_Fl[i] = Build_5_FL[i];
										}
										break;

									case 5:
										Bu_Nu = B6;
										for( i = 0; i < Bu_Nu; i++ ){
											Bu_Fl[i] = Build_6_FL[i];
										}
										break;

									case 6:
										Bu_Nu = B7;
										for( i = 0; i < Bu_Nu; i++ ){
											Bu_Fl[i] = Build_7_FL[i];
										}
										break;

									case 7:
										Bu_Nu = B8;
										for( i = 0; i < Bu_Nu; i++ ){
											Bu_Fl[i] = Build_8_FL[i];
										}
										break;
								}

								d_mode = d_second_md;

							}
							break;

						//case brown_3_i:
						//	Wa_PointX = i;
						//	break;

						//case brown_4_i:
						//	Tr_PointX = i;
						//	break;
					
					}				
				}
			}
		}
		
		//スリップしてしまうバグがある とりあえず目立たなくはさせている
		if( Bu_Nu >30 ){ s_Nu = 2; }
		else if( Bu_Nu >24 ){ s_Nu = 1; }
		else{ s_Nu = 0; }

		if( ( Br_y == 1 ) && ( Bu_PointY[ Bu_PointX ] > 0 ) ){
			//if( Flont_p == 1 ){
				if( u_bousi == true ){
					u_bousi = false;
					Br_y = 0;
				}

				else{
					s_MOVE = 1;
					Br_SY = -1;
				}
			//}
		}

		if( ( Br_y == 2 ) && ( Bu_PointY[ Bu_PointX ] < s_Nu ) ){
			//if( Flont_p == 1 ){
				if( d_bousi == true ){
					d_bousi = false;
					Br_y = 0;
				}

				else{
					s_MOVE = 1;
					Br_SY = 1;
				}
			//}
		}

		if( Back_p == 1 ){
			Br_M = 1;
			Br_M_next = 1;
		}

		if( s_MOVE == 1 ){
			BrSmollCounter = 0;
		}

		for( i = 1; i < 25; i++ ){
			if( Flont_p == 1 ){
				if( s_m_sl == i ){
					if( Bu_Fl[ i - 1 + Bu_PointY[ Bu_PointX ] * 6 ] == 1){
						bu_sn = i - 1 + Bu_PointY[ Bu_PointX ] * 6;
						Br_M = 1;
						Br_M_next = 2;
					}
				}
			}
		}

		s_m_sl = 0;

	}

	if( s_MOVE == 1 ){
		BrSmollCounter++;
		if( Br_y == 1 ){ u_bousi = true; }
		else if( Br_y == 2 ){ d_bousi = true; }
		Br_y = 0;

		if( BrSmollCounter == BrSmoll_FRAME ){
			s_MOVE = 0;
			BrSmollCounter = 0;

			switch( sin ){
				case brown_1_i:
					switch( Bu_PointX ){
						case 0: Bu_PointY[0] += Br_SY; break;
						case 1: Bu_PointY[1] += Br_SY; break;
						case 2: Bu_PointY[2] += Br_SY; break;
						case 3: Bu_PointY[3] += Br_SY; break;
						case 4: Bu_PointY[4] += Br_SY; break;
						case 5: Bu_PointY[5] += Br_SY; break;
						case 6: Bu_PointY[6] += Br_SY; break;
						case 7: Bu_PointY[7] += Br_SY; break;
					}
					break;

				case brown_3_i:
					Wa_Point += Br_SY;
					break;

				case brown_4_i:
					Tr_Point += Br_SY;
					break;
			}

			// 停止中は画面のスクロールは行わない
			s_ScrollY = 0;
		
		}

		else{
			s_ScrollY = -(Br_SY * 120 * BrSmollCounter / BrSmoll_FRAME);
		}
	}

	if( ( Br_M == 3 ) && ( Move == 0 ) ){
		bese_scroll();

		if( Move == 1 ){
			MoveCounter = 0;
		}

		if( ( GetMouseInput() & MOUSE_INPUT_LEFT ) != 0 ){
			if( ( gr_sl != -11 ) && ( sin == brown_2_i ) ){
				if( Flont_p == 1 ){
					gr_sn = gr_sl;
					Br_M = 4;
					Br_M_next = 0;
					GroundPointX = MapDrawPointX + 1 + ( gr_sn % 10 );
					GroundPointY = MapDrawPointY + 1 + ( gr_sn / 10 );
					gr_num = MapData[ GroundPointY ][ GroundPointX ];
					gr_sl = -11;
				}
			}
		}

		
		if( sin == brown_2_i ){
			if( Back_p == 1 ){
				Br_M = 0;
				sin = other_i;
				SetMouseDispFlag( TRUE );
			}
		}

		else{
			if( Back_p == 1 ){
				Br_M = 1;
				Br_M_next = 0;
			}
		}

	}

	if( Move == 1 ){

		MoveCounter++;

		// 移動処理が終了したら停止中にする
		if( MoveCounter == MOVE_FRAME ){

			Move = 0;

			// プレイヤーの位置を変更する
			PlayerX += MoveX;
			PlayerY += MoveY;

			// 停止中は画面のスクロールは行わない
			ScrollX = 0;
			ScrollY = 0;

		}

		else{
			//経過時間からスクロール量を算出
			ScrollX = -( MoveX * MAP_SIZE * MoveCounter / MOVE_FRAME );
			ScrollY = -( MoveY * MAP_SIZE * MoveCounter / MOVE_FRAME );
		}
	}

	if( Br_M == 4){
		if( Br_M_next == 0 ){
			BriCounter++;

			if( BriCounter == Bri_FRAME ){
				Br_M = 5;
				d_mode = d_third_md;
			}

			else{
				br_bc = 256 - ( 224 * BriCounter / Bri_FRAME );			
			}


		}

		if( Br_M_next == 1 ){
			BriCounter--;
		
			if( BriCounter == 0 ){
				Br_M = 3;
				SetMousePoint( MAP_SIZE * ( (gr_sn % 10 ) + 1 ) + 20 , MAP_SIZE * ( ( gr_sn / 10 ) + 1 ) + 12 );
			}

			else{
				br_bc = 256 - ( 224 * BriCounter / Bri_FRAME );			
			}
		}

	}

	if( Br_M == 5){
		if( Flont_p == 1 ){
			hen_data( &hen_suu , &gr_num , &hen_sl );
			MapData[ GroundPointY ][ GroundPointX ] = hen_suu;
			Br_M = 4;
			Br_M_next = 1;
		}

		if( Back_p == 1 ){
			Br_M = 4;
			Br_M_next = 1;
		}

	}

	switch( sin ){
		case green_1_i:
			move = honb_sn;
			mode = move_md;
			break;

		case green_2_i:
			move = aria_sn;
			mode = move_md;
			break;

		case green_3_i:
			move = wold_sn;
			mode = move_md;
			break;

		default:
			break;
	}
} 

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

Re: 押し続けの回避処理

#45

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

コードについてはざっとですが理解したつもりです。
ボタンにカウンタがあるのではなくて別にカウンタがあるので、それで連続して押されるのを防いでいるのですね。
理解しやすい形で実現されたのだと思いますし確かにガードは出来ていると思いますが、ISLeさんのものよりもかなり面倒なことをしていると思います。

そして、非常に申し訳ないですが、現状は全体的にコードが冗長でバグになりやすくメンテナンスが困難だと思います。
似たようなコードがアチコチに見受けられますので、関数化やループ化(情報配列の利用)など工夫の余地が沢山あるのではないでしょうか。
同じこと実現するのに、たぶん1/2から1/3のコード(もしかしたら、もっと短く出来るかもしれません)で実現できてメンテナンス性もよく出来ると思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

閉鎖

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