RECT型を使ってのめり込み防止の実装について。

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

RECT型を使ってのめり込み防止の実装について。

#1

投稿記事 by keito94 » 6年前

C++初心者です。
http://dixq.net/forum/viewtopic.php?f=3 ... 1の言うことに従って
RECT型で当たり判定を実装していますが、当たり判定の部分は実装できました。
めり込み防止の部分となるとどうも考えがつきません。
今現在僕が考えているルーチンは、
①プレイヤーが衝突したら、地面の座標を返す。
②地面の座標とプレイヤーの座標を比較する。
③めり込んでいたら、プレイヤーをずらして当たる前にまで戻す。
なのですが…。
RECT型の当たり判定で、地面の座標を新しく作る予定の当たり判定プログラムに教える方法がわかりません。
どうすればいいのでしょうか?
それを教える方法が完成すれば後は楽にできるんです。
添付してあるコードは一部のみなので、単体では動きません。
添付ファイル
RectCollision.zip
(6.09 KiB) ダウンロード数: 301 回
デバッグは投げ捨てるものではない。
今までの質問でこれは学んだこと。
質問する時は、必ずちゃんと調べた上に問題をもとにした仕様書を作ってから質問すること。
仕様書の大切さを改めて思い知った…。

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

Re: RECT型を使ってのめり込み防止の実装について。

#2

投稿記事 by ISLe » 6年前

keito94 さんが書きました:RECT型で当たり判定を実装していますが、当たり判定の部分は実装できました。
ここは、敵キャラとの当たり判定だけにRECT使っています。
いまやろうとしているのは、ブロックとの当たり判定にRECTを導入しようということではないのでしょうかね。

そのまんま引っ張ってきて、無意味だ無駄だってやりとりを何度も繰り返すばかり。
コード理解しようとしてくださいよ。
オフトピック
そもそもネットに転がってるサンプルコードがなあ。

アバター
keito94
記事: 264
登録日時: 7年前
連絡を取る:

Re: RECT型を使ってのめり込み防止の実装について。

#3

投稿記事 by keito94 » 6年前

ごめんなさい…。
RECTは敵キャラとの当たり判定でしたか…。
でも、ルーチンはそのままなんですが、効率が良くて汎用性のあるブロック当たり判定がどうしても思いつかないんです…。
衝突したブロックの座標を返すサンプルコードをくれませんか…。
ISLe さんが書きました: コード理解しようとしてくださいよ。
わかりました…。
デバッグは投げ捨てるものではない。
今までの質問でこれは学んだこと。
質問する時は、必ずちゃんと調べた上に問題をもとにした仕様書を作ってから質問すること。
仕様書の大切さを改めて思い知った…。

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

Re: RECT型を使ってのめり込み防止の実装について。

#4

投稿記事 by ISLe » 6年前

keito94 さんが書きました:効率が良くて汎用性のあるブロック当たり判定がどうしても思いつかないんです…。
衝突したブロックの座標を返すサンプルコードをくれませんか…。
いますぐやるべきは、CCollision::CheckMap関数にある、キャラとブロックの当たり判定をRECT構造体を使うように書き換えること。
いまは動作そのものは変えなくていい。むしろ変えてはいけない。
衝突したブロックの座標云々はRECT構造体使って衝突したブロックが分かるようにできてから。

言っちゃあなんですが、効率が良いとか汎用性があるとか、keito94さんに判断できるんですか?

アバター
keito94
記事: 264
登録日時: 7年前
連絡を取る:

Re: RECT型を使ってのめり込み防止の実装について。

#5

投稿記事 by keito94 » 6年前

ISLeさんに言われてRECT構造体に書き換えてみたのですがバグだらけです。
なにか、アドバイスはないのでしょうか?
添付ファイル
Collision.zip
(6.71 KiB) ダウンロード数: 336 回
デバッグは投げ捨てるものではない。
今までの質問でこれは学んだこと。
質問する時は、必ずちゃんと調べた上に問題をもとにした仕様書を作ってから質問すること。
仕様書の大切さを改めて思い知った…。

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

Re: RECT型を使ってのめり込み防止の実装について。

#6

投稿記事 by ISLe » 6年前

keito94 さんが書きました:ISLeさんに言われてRECT構造体に書き換えてみたのですがバグだらけです。
なにか、アドバイスはないのでしょうか?
バグだらけなのはわたしの責任なんですか?

何か書いても、書いた内容を理解する気はないように見えるし、無関係なところも含めてあちこちテキトーにいじくり回して問題を増やすし、さらにはその責任を押し付けられるのでは、何も書きたくないすなあ。

No.1に添付してるRectCollision.cppとか、大元からめちゃくちゃいじくり回してるけど、No.5ではわざわざIntersectRect関数とは別に関数作ってたりするし、ほんとにコードいじくり回すだけで理解してないんだなって思います。
#もちろん理解した上で使わないという選択肢はある。
コードいじくり回す時間を、コードを理解する時間に回して欲しい。

CCollision::CheckMap関数には、もうひとつ別の大きな問題があるんだけど、keito94さんが自力でそれに気付くのは無理かな。
RECT構造体使って、点でなく形での当たり判定を想像したら、それに気付くと期待するのだけど、想像しないから。


それと、いま気づいたんですが…
keito94 さんが書きました:③めり込んでいたら、プレイヤーをずらして当たる前にまで戻す。
「当たる前にまで戻す」?
また方針転換ですか?
あるいは、そもそもRECT構造体を使う理由を理解してないってことでしょうか。

アバター
keito94
記事: 264
登録日時: 7年前
連絡を取る:

Re: RECT型を使ってのめり込み防止の実装について。

#7

投稿記事 by keito94 » 6年前

ISLe さんが書きました: また方針転換ですか?
ごめんなさい…。
ブロックに当たったら当たる前の座標に戻すでしたね…。
頭のなかで勘違いしてしまいました…。
後、添付しているソースコードでは、左の当たり判定の部分は実装されたのですが、右の当たり判定の部分がバグっているようです。
添付ファイル
Collision.zip
(6.7 KiB) ダウンロード数: 293 回
デバッグは投げ捨てるものではない。
今までの質問でこれは学んだこと。
質問する時は、必ずちゃんと調べた上に問題をもとにした仕様書を作ってから質問すること。
仕様書の大切さを改めて思い知った…。

アバター
keito94
記事: 264
登録日時: 7年前
連絡を取る:

Re: RECT型を使ってのめり込み防止の実装について。

#8

投稿記事 by keito94 » 6年前

http://dixq.net/forum/blog.php?u=2409&b=6635
これを読んで下さい。
今のコードはどうせバグバグ祭りだと思いますので…。
理由はそこに書かれてあると思います。
デバッグは投げ捨てるものではない。
今までの質問でこれは学んだこと。
質問する時は、必ずちゃんと調べた上に問題をもとにした仕様書を作ってから質問すること。
仕様書の大切さを改めて思い知った…。

たいちう
記事: 418
登録日時: 13年前

Re: RECT型を使ってのめり込み防止の実装について。

#9

投稿記事 by たいちう » 6年前

プログラムを書けないのは仕方ないが、
せめて最後にISLeさんにお詫びやお礼は書けないのだろうか。

アバター
usao
記事: 1887
登録日時: 11年前

Re: RECT型を使ってのめり込み防止の実装について。

#10

投稿記事 by usao » 6年前

オフトピック
問題点は プログラミング言語の種類 とは違うところにあると思うのですが…

理解して → 書く

言語の種類が問題になるのは後者の側の作業.
問題点が前者側にあるのなら,言語を変えても改善しないのではないかと危惧します.
最後に編集したユーザー usao on 2017年6月27日(火) 19:14 [ 編集 1 回目 ]

アバター
keito94
記事: 264
登録日時: 7年前
連絡を取る:

Re: RECT型を使ってのめり込み防止の実装について。

#11

投稿記事 by keito94 » 6年前

ISLeさん、今まで色々ご迷惑をかけてごめんなさい…。
でも、C言語の素質がないことをようやく知りました…。
では、ありがとうございました!!
デバッグは投げ捨てるものではない。
今までの質問でこれは学んだこと。
質問する時は、必ずちゃんと調べた上に問題をもとにした仕様書を作ってから質問すること。
仕様書の大切さを改めて思い知った…。

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

Re: RECT型を使ってのめり込み防止の実装について。

#12

投稿記事 by ISLe » 6年前

keito94 さんが書きました:ブロックに当たったら当たる前の座標に戻すでしたね…。
頭のなかで勘違いしてしまいました…。
いやいや、さらに酷くなってますよ。

A.「当たったら」とは
当たっていない状態から当たっている状態への『変化』
B.「当たっている」とは
その時点で当たっているという『状態』

AとBの違いが分からないですかねえ。

状態×変化のAは、状態だけのBより複雑になるのは明らか。

わたしはずっと「めり込みの補正」と表現してますよ。

Pythonを学んでこのような日本語のニュアンスの違いが分かるようになるといいですね。

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

Re: RECT型を使ってのめり込み防止の実装について。

#13

投稿記事 by ISLe » 6年前

オフトピック
やたらサンプルコードよこせ言ってたけど、うちのブログは参考にならんかったかな。
まあ、2010年の記事だしJavaだし。
実験要素山盛りなのでそのままコピペはよろしくないから、せめて自力で見付けられるくらい意欲ある人でないとな。

NNN

Re: RECT型を使ってのめり込み防止の実装について。

#14

投稿記事 by NNN » 6年前

やや雑談な書き込みです

前の方の質問でことごとくズレた受け取り方をするので
デバッグ頑張れという形の認識になっただけマシかなと思っていましたが
最近のスレの流れを見ると残念な形になってますね

感覚的にはアクションゲームを作るには圧倒的に技術不足で
オセロや五目並べレベルの簡易ゲームを作るべきなのでは?という感じ。
下積みって大事だな〜と思いました

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

Re: RECT型を使ってのめり込み防止の実装について。

#15

投稿記事 by ISLe » 6年前

CCollision::CheckMapを改造。
戻り値のRECTは、矩形ではなく、各方向に何ピクセルめり込んでいるかを表す。

rcMoverは、CMoverクラスから直接持ってきたいところだが、引数周りを変えると変更点が多くなりすぎるので先送りとする。

コード:

RECT CCollision::CheckMap(int x, int y) {
	RECT rcMover = {
		x + mPt[0].x,
		y + mPt[0].y,
		x + mPt[7].x + 1,
		y + mPt[7].y + 1,
	};
	RECT rc, rcResult;
	CopyRect(&rcResult, &rcMover);
	DWORD w_map = Game->MapData().GetMapWidth();
	DWORD h_map = Game->MapData().GetMapHeight();
	DWORD w_chip = Game->MapData().GetChipWidth();
	DWORD h_chip = Game->MapData().GetChipHeight();
	//レイヤー1が四角形床。
	for (DWORD y_map = 0; y_map < h_map; y_map++) {
		for (DWORD x_map = 0; x_map < w_map; x_map++) {
			int index = Game->MapData().GetValue(1, x_map, y_map);
#if 0
			//斜め床の判定。
			int indexslope = GetChipLayerNum(x, y);
			int src_x = (index % Game->GetBitCount()) * cwidth;
			int src_y = (index / Game->GetBitCount()) * cheight;
			//坂道の当たり判定があるのなら、-2を返す。
			if (indexslope != 0) {
				//res.x = -2;
				//res.y = -2;
				return res;
			}
#endif
			if (index == 0) {
				// 四角いブロック
				RECT rcBlock = { x_map*w_chip, y_map*h_chip, (x_map + 1)*w_chip, (y_map + 1)*h_chip };
				if (IntersectRect(&rc, &rcMover, &rcBlock)) {
					// めり込んでいる分だけ領域を削る
					if (rc.left == rcMover.left) { // 左寄り
						if (rc.right > rcResult.left) rcResult.left = rc.right;
					}
					if (rc.top == rcMover.top) { // 上寄り
						if (rc.bottom > rcResult.top) rcResult.top = rc.bottom;
					}
					if (rc.right == rcMover.right) { // 右寄り
						if (rc.left < rcResult.right) rcResult.right = rc.left;
					}
					if (rc.bottom == rcMover.bottom) { // 下寄り
						if (rc.top < rcResult.bottom) rcResult.bottom = rc.top;
					}
				}
			}
		}
	}
	// めり込んでいる量に変換
	rcResult.left -= rcMover.left;
	rcResult.top -= rcMover.top;
	rcResult.right = rcMover.right - rcResult.right;
	rcResult.bottom = rcMover.bottom - rcResult.bottom;
	return rcResult;
}

返信

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