矩形の当たり判定処理

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

矩形の当たり判定処理

#1

投稿記事 by パインアップル » 14年前

前に質問させてもらったのですがまた詰まってしまったので教えてください

矩形の当たり判定です

コード:

#include "DxLib.h"
 
void sentouki();
void yomikomi();
void hanntei();
// WinMain関数
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
                     LPSTR lpCmdLine, int nCmdShow )
{
    
   ChangeWindowMode( TRUE ) ;
 
 
   DxLib_Init();   
 
    yomikomi();
 
while(!ProcessMessage() && !ClearDrawScreen()){
     sentouki();
     hanntei();
       
    
    WaitTimer( 20 ) ;
 
 }     
 
    // DXライブラリ使用の終了処理
    DxLib_End() ;
 
    // ソフトの終了
    return 0 ;
}


コード:


#include "DxLib.h"

static int handoru;
static int handoru2;
static int x1=200;
static int y1=200;
static int x2=x1+258;
static int y2=y1+258;
static int x3=250;
static int y3=100;   
static int x4=x3+32;
static int y4=y3+32;
static int flag=1;


void yomikomi(){
   handoru = LoadGraph("EDGE1.png");
   handoru2 = LoadGraph("EDGE2.bmp");
}   

void sentouki(){  
  DrawGraph(x1,y1,handoru,TRUE);
  DrawGraph(x3,y3,handoru2,TRUE);
}

void hanntei(){
   if( CheckHitKey( KEY_INPUT_UP ) == 1 ) y3 += 8 ;
   if( x1<x4 && y1<y4 && x2>x3 && y2>y3) y3 -= 8;
}
他サイトを参考にしたのですがどこが悪いかわかりません
移動キャンセルをしたいつもりです

自分で考えれば良いと思われるかもしれませんが課題的なもので・・・
いやはや、すみません 教えていただけると光栄です

non
記事: 1097
登録日時: 14年前

Re: 矩形の当たり判定処理

#2

投稿記事 by non » 14年前

パインアップル さんが書きました:移動キャンセルをしたいつもりです
どういう条件の時に、キャンセルしたいのでしょうか?
自分の考えは、他人に説明しないと、あなたの頭の中を想像してもわかりません。
どっちにしても、移動してから、移動分をもとに戻すより、移動させない方が自然ですよ。
パインアップル さんが書きました: 自分で考えれば良いと思われるかもしれませんが課題的なもので・・・
意味がわかりません。「課題的」って何?課題なら自分で考えた方が良いし、課題でなくたって自分で考えた方が良い。
自分で考えない方が良い場合があるなんて思えませんが。
non

パイン

Re: 矩形の当たり判定処理

#3

投稿記事 by パイン » 14年前

申し訳ありません

あるエリアに入ったら、移動分を戻したいと思っていたのですがやはり不自然ですね
とにもかくにも矩形の当たり判定ができない状況なのです
プログラミングの館にも書いてありませんでしたし、調べてみて書いたつもりがうまくいきません
移動処理を行った後、すぐに当たり判定を行わなければいけないと聞いたことがあるのですが
その意味もあまりわかりません

それと課題的なものではなくて課題でした ごめんなさい
もう少しで課題の期限が終わってしまうのです  だから、この掲示板で質問させていただきました

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 矩形の当たり判定処理

#4

投稿記事 by みけCAT » 14年前

y3だけでなくy4も足し引きしないといけないのではないでしょうか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 矩形の当たり判定処理

#5

投稿記事 by みけCAT » 14年前

こんな感じです。

コード:

void hanntei(){
   if( CheckHitKey( KEY_INPUT_UP ) == 1 ) { y3 += 8 ; y4 += 8; }
   if( x1<x4 && y1<y4 && x2>x3 && y2>y3) { y3 -= 8; y4 -= 8; }
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

パイン

Re: 矩形の当たり判定処理

#6

投稿記事 by パイン » 14年前

みけさん、本当にありがとうございます

右も左も分からない自分が言ってはいけないと思いますが
x4とy4はそれぞれx3,y3の増加に伴って変化するので
触らなくてもよいと思いました すいません
そもそも私の説明が下手で何を言っているか分からないと思いますが

肝心の当たり判定のほうはDrawBoxで解決できました
当たり判定を目で見るということができていなかったです


もうひとつ疑問がわいたのですがお願いします
あるエリアに入ったら「歩けないフラグに1を渡す」といったことがしたいのですが
そのエリアからはみ出たら、またフラグを0に戻すといった処理がしたいのです
簡単にelseを使うと他の部分の当たり判定に対応できなくなってしまいます 
解決策を教えてくださいませんか

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

Re: 矩形の当たり判定処理

#7

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

ここのルールですので、名前は統一してくださいね。
http://dixq.net/board/board.html
パイン さんが書きました:もうひとつ疑問がわいたのですがお願いします
あるエリアに入ったら「歩けないフラグに1を渡す」といったことがしたいのですが
そのエリアからはみ出たら、またフラグを0に戻すといった処理がしたいのです
簡単にelseを使うと他の部分の当たり判定に対応できなくなってしまいます 
解決策を教えてくださいませんか
具体的に行いたい事がよく分からないので、そのダメなコードを書いてみてもらえませんか。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

パイン

Re: 矩形の当たり判定処理

#8

投稿記事 by パイン » 14年前

すいません 名前統一します
前に提示したコードを少し変えたほどですが

コード:

#include "DxLib.h"
 
void sentouki();
void yomikomi();
void hanntei();
// WinMain関数
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
                     LPSTR lpCmdLine, int nCmdShow )
{
    
   ChangeWindowMode( TRUE ) ;
 
 
   DxLib_Init();   
 
    yomikomi();
 
while(!ProcessMessage() && !ClearDrawScreen()){
     sentouki();
     hanntei();
       
    
    WaitTimer( 20 ) ;
 
 }     
 
    // DXライブラリ使用の終了処理
    DxLib_End() ;
 
    // ソフトの終了
    return 0 ;
}

コード:

#include "DxLib.h"

static int handoru;
static int handoru2;
static int x1=0;
static int y1=0;
static int x2=x1+252;
static int y2=y1+258;
static int x3=200;
static int y3=200;   
static int x4=x3+32;
static int y4=y3+32;
static int flag=1;
int cr=(0,0,252);

void yomikomi(){
   handoru = LoadGraph("EDGE1.png");
   handoru2 = LoadGraph("EDGE2.bmp");
}   

void sentouki(){  
  DrawGraph(x1,y1,handoru,TRUE);
  DrawGraph(x3,y3,handoru2,TRUE);
  DrawBox(x1,y1,x2,y2,cr,FALSE);
}

void hanntei(){
   if( CheckHitKey( KEY_INPUT_UP ) == 1 && flag==1 ) y3 -= 8 ;
   if( CheckHitKey( KEY_INPUT_DOWN) == 1 && flag==1) y3 += 8 ;
   if( CheckHitKey( KEY_INPUT_RIGHT ) == 1 && flag==1) x3 += 8 ;
   if( CheckHitKey( KEY_INPUT_LEFT ) == 1 && flag==1) x3 -= 8 ;
      
   if( x1<x4 && y1<y4 && x2>x3 && y2>y3) flag=1;
   
}

こんな感じですかね
フラグ変数を渡して移動できなくするというところまではいいんですが
どのようにフラグ変数を1に戻そうかというところで詰まっています

やりたい処理はこんな感じです
(上のことを書いているうちに思いついたのですが間違っていたら御指摘願います)
フラグ変数に代入される数字は1,2,3,4のうちの一つです それぞれ上下右左に対応しています
当たり判定エリアにぶつかったときぶつかったフラグを代入します
そのときに押されていたキーに対応した数字を歩けないフラグに代入します

(例)
if( CheckHitKey( KEY_INPUT_UP) == 1 && !arukenai==1) y3 -= 8 ;
if( CheckHitKey( KEY_INPUT_DOWN) == 1 && !arukenai==2) y3 += 8 ;
if( CheckHitKey( KEY_INPUT_RIGHT ) == 1 && !arukenai==3) x3 += 8 ;
if( CheckHitKey( KEY_INPUT_LEFT ) == 1 && !arukenai ==4) x3 -= 8 ;

上に移動した→当たり判定にぶつかったので「butukatta=1」このように代入→
上に移動したときに当たり判定にぶつかったのでarukenai=1このように代入→
上キー以外のキーを使って当たり判定エリアから抜ける→butukatta=0,arukenai=0を実行




説明が下手で申し訳ありません
何卒、お願いします

box
記事: 2002
登録日時: 14年前

Re: 矩形の当たり判定処理

#9

投稿記事 by box » 14年前

パイン さんが書きました:

コード:

int cr=(0,0,252);
この文の意味がわからないので、教えてください。

# 知ってるんなら書いてやれよ、という横からのツッコミはナシで。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

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

Re: 矩形の当たり判定処理

#10

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

勝手に補足すると

コード:

int cr=(0,0,252);
はC言語の文法としては問題ありませんが、プログラムコードとして見た場合に意味のあるコードとして成立していません。
たんなるカッコつきのカンマ演算子を使った式です。たまたま使えているようですが。

で、本編ですがやることを整理してみましょう。
やりたい事は衝突したら移動をキャンセルすることなんですよね。
今の考え方で未完成部分も含めて書いてみると
(1)移動キーの方向に移動する。ただし、その方向に移動できないフラグ(butukatta)が有効な場合は移動しない。(3)で使うので移動方向はフラグとして残す。
(2)衝突しているか判定。結果はarukenaiに残す。衝突していなければ0
(3)衝突(arukenai==1)していたら移動方向に合わせてフラグ(butukatta)を設定する。衝突していなければ(butukatta)に0を入れる。
と言うことで良いですか?
あとこの方式だと一度障害物に刺さったままになるのですが、それは狙い通りですか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

non
記事: 1097
登録日時: 14年前

Re: 矩形の当たり判定処理

#11

投稿記事 by non » 14年前

パイン さんが書きました: x4とy4はそれぞれx3,y3の増加に伴って変化するので
触らなくてもよいと思いました 
どこで、x4,y4の値は変化するのでしょうか?
パイン さんが書きました:
肝心の当たり判定のほうはDrawBoxで解決できました
当たり判定を目で見るということができていなかったです
どうやって、DrawBoxで当たり判定が解決するのでしょう?
パイン さんが書きました: あるエリアに入ったら「歩けないフラグに1を渡す」といったことがしたいのですが
そのエリアからはみ出たら、またフラグを0に戻すといった処理がしたいのです
簡単にelseを使うと他の部分の当たり判定に対応できなくなってしまいます 
解決策を教えてくださいませんか
何をしたいのか、やっぱりわかりません。
現在のプログラムは、私が思っているのは、
EDGE1.pngの画像が(0,0)-(251,257)にあり、EDGE2.bmpの画像が(200,200)-(231,231)にある。
上下左右の矢印キーを押すと、EDGE2.bmpが上下左右に8ピクセル移動する。
間違ってますか?
もし、あっていたら、このあとどういう動きをさせたいのでしょうか?
EDGE1の範囲は、動ける範囲なのですか、それともEDGE1の外周に接触したら動けないのですか?
8の倍数で移動したら、当然外周でピッタリ位置にはなりませんが、それはどうするのですか?

また、これは課題であり、期限が迫っているとの事。最終の状態ではどのような課題なのですか?
non

パイン

Re: 矩形の当たり判定処理

#12

投稿記事 by パイン » 14年前

non さんが書きました:どこで、x4,y4の値は変化するのでしょうか?
whileの中に入れることを忘れていました
non さんが書きました:どうやって、DrawBoxで当たり判定が解決するのでしょう?
DrawBoxで四角形を描き当たり判定を見た結果、範囲を間違えていたようです
non さんが書きました:もし、あっていたら、このあとどういう動きをさせたいのでしょうか?
EDGE1の範囲は、動ける範囲なのですか、それともEDGE1の外周に接触したら動けないのですか?
8の倍数で移動したら、当然外周でピッタリ位置にはなりませんが、それはどうするのですか?
外周に接触したらではなくて範囲に入ったら当たり判定が反応します
8の倍数のことは考えていませんでした・・・ やっぱり素直に移動した後、移動した分を引くという
やり方のほうがいいのでしょうかね・・・
non さんが書きました:また、これは課題であり、期限が迫っているとの事。最終の状態ではどのような課題なのですか?
いえ、これは課題ではなく私のただの疑問です 課題自体は先ほど解決しました
すみません


>>ソフト屋さん、boxさん
crのことなのですが 初心者なのでよくわかりません ごめんなさい
そして移動のことなのですが、おそらくソフト屋さんの仰っていることでだいたい良いと思っております

(3)衝突(arukenai==1)していたら移動方向に合わせてフラグ(butukatta)を設定する。衝突していなければ(butukatta)に0を入れる。
というところですが
(3)衝突(butukatta==1)していたら移動方向に合わせてフラグ(arukenai)を設定する。衝突していなければ(butukatta)(arukenai)に0を入れる。
こうなると思います   移動方向ごとのキー入力許可はarukenai変数に管理させています

刺さったままになるということは理解できていません

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

Re: 矩形の当たり判定処理

#13

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

パイン さんが書きました:crのことなのですが 初心者なのでよくわかりません ごめんなさい
「ロベールのC++教室 - 第6章 コンマ演算子 -」
http://www7b.biglobe.ne.jp/~robe/cpphtm ... 03006.html
C++の解説ですがC言語でも同じなので読んでみてください。
これを理解すれば、int cr=(0,0,252);の結果は自ずと分かると思います。
で問題は、これはカラーコードを設定する代入文だと思いますが、DXライブラリのカラーコードは関数を使って求める必要がありその関数名が抜けています。
パイン さんが書きました: (3)衝突(arukenai==1)していたら移動方向に合わせてフラグ(butukatta)を設定する。衝突していなければ(butukatta)に0を入れる。
というところですが
(3)衝突(butukatta==1)していたら移動方向に合わせてフラグ(arukenai)を設定する。衝突していなければ(butukatta)(arukenai)に0を入れる。
こうなると思います   移動方向ごとのキー入力許可はarukenai変数に管理させています

あっ、ごめんなさい。butukattaとarukenaiが逆でしたね。
名前がややこしいで変更と整理させてください。
butukattaは0で未衝突。1で衝突。
arukenai_houkouが歩けない方向で1から4が入る。0ならどの方向にも歩ける。
idou_houkouは移動する場合に移動方向に合わせて1から4が代入される。

もう一度、書きなおします。
(1)移動キーの方向に移動する。ただし、その方向に移動できない(arukenai_houkou)場合は移動しない。(3)で使うので移動方向はidou_houkouとして残す。
(2)衝突しているか判定。結果はbutukattaに残す。衝突していなければ0。衝突なら1。
(3)衝突(butukatta==1)していたら移動方向(idou_houkou)を(arukenai_houkou)に代入する。衝突していなければ(arukenai_houkou)に0を入れる。
これでお望みの動作になったはずです。(3)でbutukattaに0を入れなくても(2)で入れているので問題ないですよ。
パイン さんが書きました:刺さったままになるということは理解できていません
これの問題は(3)の時点ではbutukatta==1なら障害物に刺さった状態であることです。衝突しているんだから刺さってますよね。
もし違う方向にキーを入れ無い限り刺さったままですよってことです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

パイン

Re: 矩形の当たり判定処理

#14

投稿記事 by パイン » 14年前

ありがとうございます

私の猿頭では理解するのに難しかったですが 2回読んだところやっと理解できました
刺さるということも納得できたのですが、解決法はあんまり考えなくても
当たり判定を少しでかくするだとかでいいと考えています 少しぐらい重なっていても分からないと思いますし

コンマ演算子ももう少し調べたいと思います

ありがとうございました

閉鎖

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