Javaに関する様々な情報をご紹介します。

Javaに関する様々な情報をご紹介します。
評価

0

円同士の衝突判定がうまくいきません。

直径20pxの円2つの移動と衝突判定を行っています。
初期位置はどちらもランダムで、x・yの移動はどちらも+1ずつ移動させています。
壁(画面の端)との判定はうまくいっている(ようにみえる)のですが、円同士がぶつかったかどうかの判定が思うように行きません。
2つの円の中心の距離を測り、2つの円の半径の合計より短ければ衝突しているはずなので、互いの移動の向きを反転させています。
2つの円の中心の距離は三平方の定理を用いて計算しているつもりです。
壁との判定もそうですが、現状の移動速度ではそこまで問題にならないでしょうけれど、移動の向きを反転させた後に衝突判定に引っかからなくなるまで連続して移動させるようにしています。
円同士の判定のところでその移動をさせようとすると、プログラムが固まってしまいます。
その移動の部分をコメントアウトすれば固まることはないのですが、そもそも見た目が円同士ぶつかったから移動の向きが反転したというように見えません。
プログラムが固まってしまうときの画面を見てみると、明らかに円同士がぶつかっていませんでした。
これら衝突判定は他の言語で私が実際に使ったことのある方法で、その言語では問題はありませんでした。
何が原因なのでしょうか?
移動と判定の部分のソースを提示します。
以下の部分は1ループごとに実行されます。
    for(int n=0;n<num+1;n++){
        pos_x[n]+=speed_x[n];
        pos_y[n]+=speed_y[n];
        if(wall[n]==true){
            if(pos_x[n]<10 || pos_x[n]>490){
                speed_x[n]*=-1;
                while(pos_x[n]<10 || pos_x[n]>490){
                    pos_x[n]+=speed_x[n];
                }
            }
            if(pos_y[n]<10 || pos_y[n]>490){
                speed_y[n]*=-1;
                while(pos_y[n]<10 || pos_y[n]>490){
                    pos_y[n]+=speed_y[n];
                }
            }
        }
        else{
        }
        if(collision[n]==true){
            for(int m=0;m<num+1;m++){
                if(m!=n){
                    if(Math.sqrt(Math.pow((pos_x[n]-pos_x[m]),2)+Math.pow((pos_x[n]-pos_x[m]),2))<(size[n]+size[m])){
                        speed_x[n]*=-1;
                        speed_y[n]*=-1;
                        while(Math.sqrt(Math.pow((pos_x[n]-pos_x[m]),2)+Math.pow((pos_x[n]-pos_x[m]),2))<(size[n]+size[m])){
                            pos_x[n]+=speed_x[n];
                            pos_y[n]+=speed_y[n];
                            pos_x[m]+=speed_x[m];
                            pos_y[m]+=speed_y[m];
                        }
                    }
                }
            }
        }
    }

8

回答

7905

閲覧

8件の回答

評価

0

なんか勘違いか打ち間違いでしょか?
三平方の定理は縦横 (xy) でないと。。。

評価

0

式を見直していたらx^2+y^2とすべきところがx^2+x^2となっていました。
コピペした後修正するのを忘れていたようです。
すいませんでした。
修正したら円が2つのときはうまくいくようになりました。

ですが、円を3つ以上して見てみると、うまくいくときもあればなぜか衝突した途端プログラムが応答しなくなってしまうことがあります。
今度は何が原因なのでしょうか?

評価

0

円が3つある状況をいろいろと観察してみました。
円1と円2が衝突するときは何も問題ないのですが、円3がどちらかと衝突した後でプログラムが応答しなくなるようです。
ボタンで円を追加したり削除したりできる仕様なのですが、それが影響しているのでしょうか?
円を2つ追加し、衝突しなさそうなら2つ目を削除して追加しなおし。
衝突するようならそのまま3つ目を追加。
これも衝突しなさそうなら3つ目を削除して追加しなおし。
というようにして3つの円がそれぞれ何かしらの円と衝突しそうな状況を作って観察しています。

評価

0

3つ目が1つ目または2つ目と衝突してもうまくいくときもありました。
一体何なんでしょう。

評価

0

無応答になるのにはいくつか原因があるが、大抵はコーディングミスまたは見込み違いで永遠にループ条件が成立してしまうパターン(いわゆる無限ループ)だな。

評価

0

衝突したら互いの移動の向きを反転させて、衝突している状態じゃなくなるまで移動させてるつもりなんです。
プログラムが応答しなくなる=無限ループにでもなっているんじゃないか
ってのはわかってます。
でも、なんで無限ループになているのかが分からないんです。

もう一度円同士の衝突処理部分のみ載せてみます。
//n=0〜(ボールの数-1)=(num)
if(collision[n]==true){
    for(int m=0;m<num+1;m++){
        if(m!=n){
            if(Math.sqrt(Math.pow((pos_x[n]-pos_x[m]),2)+Math.pow((pos_y[n]-pos_y[m]),2))<(size[n]+size[m])){
                speed_x[n]*=-1;
                speed_y[n]*=-1;
                while(Math.sqrt(Math.pow((pos_x[n]-pos_x[m]),2)+Math.pow((pos_y[n]-pos_y[m]),2))<(size[n]+size[m])){
                    pos_x[n]+=speed_x[n];
                    pos_y[n]+=speed_y[n];
                    pos_x[m]+=speed_x[m];
                    pos_y[m]+=speed_y[m];
                }
            }
        }
    }
}

評価

0


今日は超嬉しかった!!通信販売で素敵な名ブランドバックを購入した。価額は1万円ぐらいしか使っていなかった。代金を支払って、5日後商品が着きました。
鞄の質がとてもいいですね。私は大変好きです。
この店にの商品は市場のと比べると、価格が安いですよ。
では、この店のウェブサイトを皆に教えます。
www.roiexjp.biz皆速く買いに行ってくださいね。

評価

0

あ。
n番目の円は移動の向きをきちんと反転させていましたが、m番目の円はさせていませんでした。
だから判定後の移動でずっと追いかけっこになってしまってプログラムが応答しなくなるんですね。
2つのときにうまくいっていたのが不思議な気もしなくないですけど。
これで円をいくつ増やしても応答しなくならなくなりました。
ありがとうございました。

質問から6ヶ月以上経過しているので、回答を書き込むことはできません。