画面に表示した点をクリックした座標まで移動させる

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

画面に表示した点をクリックした座標まで移動させる

#1

投稿記事 by コーヒー牛乳 » 14年前

初めてこの掲示板を利用させていただきます
ゲームプログラミングに興味をもって一年ほど前からC++の入門書(やさしいC++第3版)に手をつけていて
挫折を繰り返しつつも何とかプログラムを動かすことが出来るようになったのでdxライブラリを導入してみました。
そこで最近作ったのが画面に表示した点をクリックした座標まで移動させるプログラムなのですが
実際に動かしてみると、クリックした座標の手前で点が止まってしまうことがあります。
どこを直せばクリックで得た座標まできちんと移動するでしょうか?
他にもプログラムに無駄な所や間違っているところがあれば指摘を頂けると幸いです


申し訳ありません、コードを貼り付けようと思ったら
「投稿が禁止されている単語が見つかりました。」という表示が出てしまいました。
禁止されている単語がどこに含まれているのか見付けることが出来なかったので
ファイルを添付させていただきます。
・・・・・・cppっていうので良いんでしょうか?
添付ファイル
DrawPixel.cpp
(3.42 KiB) ダウンロード数: 155 回

アバター
h2so5
副管理人
記事: 2212
登録日時: 14年前
住所: 東京
連絡を取る:

Re: 画面に表示した点をクリックした座標まで移動させる

#2

投稿記事 by h2so5 » 14年前

角度によってはX座標やY座標(の整数値)が先にクリック位置に到達してしまい、移動が止まってしまいます。

if((int)BoxX != MouseX && (int)BoxY != MouseY)
のようにまとめてしまわないで、X座標Y座標の一致を個別にチェックした方がよいです。

つまり、
X座標がクリック位置に到達していない → X座標にSx加算
Y座標がクリック位置に到達していない → Y座標にSy加算
両方とも到達 → 停止

追記:
Ax = MouseX-BoxX ;
Ay = MouseY-BoxY ;

Ax = (double)MouseX-BoxX ;
Ay = (double)MouseY-BoxY ;

にした方が良いです。左辺が整数だと結果も整数になってしまいます。

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

Re: 画面に表示した点をクリックした座標まで移動させる

#3

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

今の条件だと座標が一致した時に点を描画していないからではないでしょうか?
それと、あちこちにWaitKey() ;があるので気になりますので、出来れば状態遷移と言う考え方を取り入れられるとコードがすっきりすると思います。

参考。
http://dixq.net/g/37.html
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

コーヒー牛乳
記事: 9
登録日時: 14年前

Re: 画面に表示した点をクリックした座標まで移動させる

#4

投稿記事 by コーヒー牛乳 » 14年前

h2so5 さんが書きました: 角度によってはX座標やY座標(の整数値)が先にクリック位置に到達してしまい、移動が止まってしまいます。

if((int)BoxX != MouseX && (int)BoxY != MouseY)
のようにまとめてしまわないで、X座標Y座標の一致を個別にチェックした方がよいです。

つまり、
X座標がクリック位置に到達していない → X座標にSx加算
Y座標がクリック位置に到達していない → Y座標にSy加算
両方とも到達 → 停止
有難うございます
指摘されたとおりに直したらきちんと移動するようになりました
softya(ソフト屋) さんが書きました: 今の条件だと座標が一致した時に点を描画していないからではないでしょうか?
それと、あちこちにWaitKey() ;があるので気になりますので、出来れば状態遷移と言う考え方を取り入れられるとコードがすっきりすると思います。

参考。
http://dixq.net/g/37.html
参考ページを見てもいまいち状態遷移について理解できなかったのですが
関数を使って処理を分けて、メイン関数をすっきりさせればいいんでしょうか?
やってみたものの、結局WaitKey() ;はほとんど減らせませんでした

また修正したものを添付しておきます
添付ファイル
DrawPixel.cpp
(3.85 KiB) ダウンロード数: 153 回

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

Re: 画面に表示した点をクリックした座標まで移動させる

#5

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

Menue関数を例に上げますが、他も同様にしてください。

・Menue()の説明とサークルの表示は別の関数に分けてください。
・ClearDrawScreen() ;とScreenFlip() ;はメインループに移動してください。
・WaitKey();の代わりにCheckHitKeyAll()を使ってください。
例えば、
 function_status = 1;
 WaitKey();
だと
if( CheckHitKeyAll() ) {
function_status = 1;
}
となります。

こうすることで常に処理が毎フレームメインループにもどることになり、適切にコードを直せばESCキーによる終了も何時でも出来るように修正できるはずです。
※ いまだと最初の説明が出ているときにESCキーで終了できませんよね?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

コーヒー牛乳
記事: 9
登録日時: 14年前

Re: 画面に表示した点をクリックした座標まで移動させる

#6

投稿記事 by コーヒー牛乳 » 14年前

softya(ソフト屋) さんが書きました:Menue関数を例に上げますが、他も同様にしてください。

・Menue()の説明とサークルの表示は別の関数に分けてください。
・ClearDrawScreen() ;とScreenFlip() ;はメインループに移動してください。
・WaitKey();の代わりにCheckHitKeyAll()を使ってください。
例えば、
 function_status = 1;
 WaitKey();
だと
if( CheckHitKeyAll() ) {
function_status = 1;
}
となります。

こうすることで常に処理が毎フレームメインループにもどることになり、適切にコードを直せばESCキーによる終了も何時でも出来るように修正できるはずです。
※ いまだと最初の説明が出ているときにESCキーで終了できませんよね?
また直したものを添付させていただきます。
関数を見直したので、Menue関数とMouseClick_Move関数はすっきりさせることが出来たのですが
End_NotEnd関数でWaitKey();を使わないと
プログラムを終了するかどうかの処理が一気に行われてしまいます。
色々試してみたのですが上手くいかなかったので助言を頂けると嬉しいです
添付ファイル
DrawPixel.cpp
(3.95 KiB) ダウンロード数: 143 回

アバター
h2so5
副管理人
記事: 2212
登録日時: 14年前
住所: 東京
連絡を取る:

Re: 画面に表示した点をクリックした座標まで移動させる

#7

投稿記事 by h2so5 » 14年前

ここが参考になると思います
http://dixq.net/g/41.html

コーヒー牛乳
記事: 9
登録日時: 14年前

Re: 画面に表示した点をクリックした座標まで移動させる

#8

投稿記事 by コーヒー牛乳 » 14年前

h2so5 さんが書きました:ここが参考になると思います
http://dixq.net/g/41.html
有難うございます
一度みたページだったのですが、そのときは良くわからずスルーしてました・・・
このページに載っている関数を使えば、キーを押したときの値と離したときの値が利用できるようになるんですね
書き直したのでファイルを添付させていただきます
添付ファイル
DrawPixel.cpp
(4.74 KiB) ダウンロード数: 136 回

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

Re: 画面に表示した点をクリックした座標まで移動させる

#9

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

大分スッキリしたんじゃないでしょうか?
あと気を付けたほうが良い点は、

・function_statusの値を即値ではenum定義したほうが分かりやすくなると思います。
例えば、

コード:

enum {
 STATUS_MENUE,
};
とすれば、
int function_status =  STATUS_MENUE;
と書いて
		case STATUS_MENUE:
			Menue();
			break;
と書けるのでどう動くのかすごく分かりやすくなると思います。
・あとwhile(1)
よりも後ろにある
if( ProcessMessage() == -1 )
をwhileに入れたほうが良いと思います。
while( ProcessMessage() != -1 )
これでよりすっきりします。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

コーヒー牛乳
記事: 9
登録日時: 14年前

Re: 画面に表示した点をクリックした座標まで移動させる

#10

投稿記事 by コーヒー牛乳 » 14年前

何度も有難うございます
列挙型というのは使ったことがなかったので上手くできてるかどうかはわかりませんが
直したのでまた貼っておきます
添付ファイル
DrawPixel.cpp
(4.82 KiB) ダウンロード数: 114 回

アバター
h2so5
副管理人
記事: 2212
登録日時: 14年前
住所: 東京
連絡を取る:

Re: 画面に表示した点をクリックした座標まで移動させる

#11

投稿記事 by h2so5 » 14年前

enumの使い方は大丈夫ですが、直し切れていない所がいくつか有りますね。

コード:

			//自機がクリック位置に到達したら
			if((int)BoxX == MouseX && (int)BoxY == MouseY)
			{
				//自機の移動が終わったら次の座標が送られてくるのを待つ為にClick = 0 をします
				Move_STATUS = 0;
				FUNCTION_STATUS = 1;
			}

コーヒー牛乳
記事: 9
登録日時: 14年前

Re: 画面に表示した点をクリックした座標まで移動させる

#12

投稿記事 by コーヒー牛乳 » 14年前

h2so5 さんが書きました:enumの使い方は大丈夫ですが、直し切れていない所がいくつか有りますね。

コード:

			//自機がクリック位置に到達したら
			if((int)BoxX == MouseX && (int)BoxY == MouseY)
			{
				//自機の移動が終わったら次の座標が送られてくるのを待つ為にClick = 0 をします
				Move_STATUS = 0;
				FUNCTION_STATUS = 1;
			}
ご指摘有難うございます
コードを直していると、見落としていてもエラーが出なくてそのまま気づかないことがあるんですね・・・
他のところも色々直してみました。何度も申し訳ありませんが、お付き合いくださると幸いです
添付ファイル
DrawPixel.cpp
(4.63 KiB) ダウンロード数: 153 回

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

Re: 画面に表示した点をクリックした座標まで移動させる

#13

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

大分良くなってきたと思いますよ。
で、もう幾つか直した方が良くなると思います。

・Move_TRUE, Move_FALSEは別のenumにしてください。
・変数Clickは使われていません。
・グローバルである必要の無い変数、Axなどはローカル変数にしてください。
・FUNCTION_STATUSを見なおしてみてください。即値がまだ残っています。
・End_NotEnd()とMenue()の方がほとんど同じなので共通化できませんか?
・Circle()とMouse_Move()は無理して分けなくても良いのでは?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

コーヒー牛乳
記事: 9
登録日時: 14年前

Re: 画面に表示した点をクリックした座標まで移動させる

#14

投稿記事 by コーヒー牛乳 » 14年前

softya(ソフト屋) さんが書きました:大分良くなってきたと思いますよ。
で、もう幾つか直した方が良くなると思います。

・Move_TRUE, Move_FALSEは別のenumにしてください。
・変数Clickは使われていません。
・グローバルである必要の無い変数、Axなどはローカル変数にしてください。
・FUNCTION_STATUSを見なおしてみてください。即値がまだ残っています。
・End_NotEnd()とMenue()の方がほとんど同じなので共通化できませんか?
・Circle()とMouse_Move()は無理して分けなくても良いのでは?
ご指摘有難うございます
色々見落としていたところを修正し、Circle()とMouse_Move()をまとめて、
画面内でクリックして画面外までドラッグすると自機が画面外まで行ってしまうことに気づいたので
マウスをクリックした座標が画面外に行かないように書き換えてみました。
(関係ないですが投稿禁止単語はマウスのX座標の変数名でした・・・・・・)

Menue()の見直しと、それにあたってEscapeKey()も少し書き換えてみたのですが
回りくどくなっていないか心配です。

修正していて思ったのですが
GetHitKeyStateAll_2(Key)をいくつかの関数で呼び出しているのを
一つにまとめることはできるのでしょうか?
単純にswitch構文の前に持ってくると、今度はEnd_NotEnd()を呼び出せなくなってしまいます
添付ファイル
DrawPixel.cpp
(4.4 KiB) ダウンロード数: 140 回

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

Re: 画面に表示した点をクリックした座標まで移動させる

#15

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

GetHitKeyStateAll_2(Key)は1つにできます。ClearDrawScreen() ;直後に一回で良いのでは無いでしょうか?
End_NotEnd()とEscapeKey()も引数で工夫すれば、1つの関数に出来ます。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

コーヒー牛乳
記事: 9
登録日時: 14年前

Re: 画面に表示した点をクリックした座標まで移動させる

#16

投稿記事 by コーヒー牛乳 » 14年前

softya(ソフト屋) さんが書きました:GetHitKeyStateAll_2(Key)は1つにできます。ClearDrawScreen() ;直後に一回で良いのでは無いでしょうか?
End_NotEnd()とEscapeKey()も引数で工夫すれば、1つの関数に出来ます。
End_NotEnd()とEscapeKey()をとりあえずまとめてみました
Escキーを押す → End_Menue()を呼び出す → Escキーが離されるのを待つ →再度Escキーが押されたら終了
という流れにしたいのですが、GetHitKeyStateAll_2(Key)をClearDrawScreen()の後に一回だけにすると
Escキーが離されるのを待つというのが上手く行かなくなり、結局Escape_STATUSという変数をはさんでいますが
これだと直す前とあまり変わっていないでしょうか・・・・・・?
添付ファイル
DrawPixel.cpp
(4.27 KiB) ダウンロード数: 111 回

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

Re: 画面に表示した点をクリックした座標まで移動させる

#17

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

まとめようとし過ぎて、かえってややこしくなっている気がしました。
なので、シンプルにしてみました。ご自分のコードと比べてみてください。
DrawPixel.cpp
(4.06 KiB) ダウンロード数: 209 回
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

コーヒー牛乳
記事: 9
登録日時: 14年前

Re: 画面に表示した点をクリックした座標まで移動させる

#18

投稿記事 by コーヒー牛乳 » 14年前

softya(ソフト屋) さんが書きました:まとめようとし過ぎて、かえってややこしくなっている気がしました。
なので、シンプルにしてみました。ご自分のコードと比べてみてください。
有難うございます、とても参考になりました
EscapeKey(FUNCTION_STATUS)と一つにまとめようとしていたのが問題だったのですね
直していただいたコードを参考に
End_Menue()からMove()へ戻るプログラムと
自機の速度を変化させるプログラムを追加してみました

あとは画像の表示など諸々の要素を追加して
何らかの形で発表できればと思っています
何度も回答を頂き、有難うございました
添付ファイル
DrawPixel.cpp
(4.68 KiB) ダウンロード数: 165 回

閉鎖

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