質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

3回答

4787閲覧

四角形の衝突判定がうまくできません(重なります)。

退会済みユーザー

退会済みユーザー

総合スコア0

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2018/10/18 07:53

前提・実現したいこと

X,Y座標をテキストフィールドに入力しボタンを押すと、縦横50の塗りつぶされた正方形を描くものです。
ただし正方形の始点の座標は、2次元配列を用いることと、既に存在する正方形と衝突する場合は、「衝突します」と表示させたいです。

java

import java.applet.Applet;
import java.awt.Button;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Label;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Prog2Lec10Subject02 extends Applet implements ActionListener{
TextField tf1,tf2;
Button additionButton;

int i,j; int x,y; int[][] zahyo; String str = ""; public void init(){ i=j=0; zahyo = new int[10][2]; add(new Label("x座標")); tf1 = new TextField("",5); tf1.addActionListener(this); add(tf1); add(new Label("y座標")); tf2 = new TextField("",5); tf2.addActionListener(this); add(tf2); additionButton = new Button("追加"); additionButton.addActionListener(this); add(additionButton); } public void actionPerformed(ActionEvent e){ if(e.getSource() == additionButton) { x = Integer.parseInt(tf1.getText()); y = Integer.parseInt(tf2.getText()); zahyo[i][0] =x; zahyo[i][1] =y; } repaint(); } public void update(Graphics g){ paint(g); g.drawString(str, 100, 50); if(isCollision() == false){ g.setColor(Color.RED); g.fillRect(x,y, 50, 50); str = ""; i++; } else if(isCollision() == true){ str = "追加しようとする正方形は、他の正方形と衝突します"; } } public boolean isCollision(){ for(int j=0; i>j; j++);{ if(zahyo[0][j]+50 > zahyo[i][0]&& zahyo[1][j]+50 > zahyo[i][1]&& zahyo[i][0]+50 > zahyo[0][j]&& zahyo[i][1]+50 > zahyo[1][j]) return true; } return false; }

}

### 試したこと 最初にx=50,y=50を入れ、次にx=75,y=75を入力すると、重なるため衝突しますと出ました。 しかしx=200,y=100を入れ、次にx=230,y=100を入力すると、重なってしまいます。 恐らく最初のzahyo[i][0],[i][1]にx・yは代入されているので、「i++」の位置か、boolean isCollisionの中身がおかしいような気がするのですが、うまく動かないので、ご教示願います。 ### 補足情報(FW/ツールのバージョンなど) ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

四角形の交差の判定は、
(以下、青の正方形がある状態で赤の正方形を加えようとする状況とみてください)

イメージ説明

このいずれかに当てはまれば交差せず、いずれにも当てはまらなかったとき交差すると判定できます。
こう考えると、正方形でない長方形にも応用が利きます。

java

1public boolean isCollision(){ 2 3 int[] source = zahyo[i]; //衝突判定を行う四角形の左上のXY座標 4 int sourceX = source[0]; 5 int sourceY = source[1]; 6 7 for(int j = 0; i > j; j++){ 8 int[] target = zahyo[j]; //比較対象の四角形の左上のXY座標 9 int targetX = target[0]; 10 int targetY = target[1]; 11 12 if (!(sourceX + 50 < targetX || targetX + 50 < sourceX 13 || sourceY + 50 < targetY || targetY + 50 < sourceY)) { 14 return true; 15 } 16 } 17 return false; 18}

二次元配列について

Javaの二次元配列は、実は「配列の配列」、つまり「配列を要素に持つ配列」なのです。
int[]intを要素に持つ配列であるように、int[][]int[]を要素に持つ配列なのです。

投稿2018/10/18 18:41

編集2018/10/19 16:21
swordone

総合スコア20651

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/10/19 03:39

ありがとうございました。 コードを入れるとうまくできました。 私の理解不足ですが、単純に[]が一次元、[][]が二次元配列と言うわけではないのでしょうか? 最初に青の四角形(source)のxは[0][0]で、yが[0][1]で、比較対象の赤の四角形(target)のxは[1][0]、yが[1][1]で、[][]同士を比較するのではないのでしょうか? やっているうちに「iとj」、「xとy」の関係が分からなくなってしまいました。 あと衝突した場合のコメントが、次に衝突しない場合でも残ってしまうことと、「追加」を押して衝突する場合、「追加」をもう一度押さないと、コメントがでません。 お手数ですが、御教授願います。
swordone

2018/10/19 03:50

逆ですね。targetが青で、sourceが赤です。
退会済みユーザー

退会済みユーザー

2018/10/19 07:35

青の四角形(比較対象)に赤の四角形(衝突判定を行う)が当たるので、逆でした。 何とか課題はできたのですが、二次元配列についてほとんど理解できていなかったと思うので、再度、勉強しなおします。 ありがとうございました。
guest

0

おそらく、isCollision()を以下のようにすれば、正しく判定できると思います。

Java

1public boolean isCollision(){ 2 3 for(int j = 0; i > j; j++){ 4 5 //[1] 6 int[] source = zahyo[i]; //衝突判定を行う四角形の左上のXY座標 7 int sourceX = source[0]; 8 int sourceY = source[1]; 9 10 int[] target = zahyo[j]; //比較対象の四角形の左上のXY座標 11 int targetX = target[0]; 12 int targetY = target[1]; 13 14 //[2] 15 //左上の点が四角形内部にあるか確認する 16 if(targetX <= sourceX && sourceX <= targetX + 50 17 && targetY <= sourceY && sourceY <= targetY + 50){ 18 return true; 19 } 20 21 //右上の点が四角形内部にあるか確認する 22 if(targetX <= sourceX + 50 && sourceX + 50 <= targetX + 50 23 && targetY <= sourceY && sourceY <= targetY + 50){ 24 return true; 25 } 26 27 //左下の点が四角形内部にあるか確認する 28 if(targetX <= sourceX && sourceX <= targetX + 50 29 && targetY <= sourceY + 50 && sourceY + 50 <= targetY + 50){ 30 return true; 31 } 32 33 //右下の点が四角形内部にあるか確認する 34 if(targetX <= sourceX + 50 && sourceX + 50 <= targetX + 50 35 && targetY <= sourceY + 50 && sourceY + 50 <= targetY + 50){ 36 return true; 37 } 38 39 } 40 41 return false; 42}

コードを読む限り、zahyo[x][y]のzahyo[x]は、入力した四角形のXY座標が代入されています。

Java

1System.out.print(zahyo[0][0]) //1回目に入力した四角形のX座標 2System.out.print(zahyo[1][0]) //2回目に入力した四角形のX座標 3System.out.print(zahyo[2][0]) //3回目に入力した四角形のX座標 4System.out.print(zahyo[2][1]) //3回目に入力した四角形のY座標

ですので、isCollision()内で、zahyo[i]とすると、衝突判定を行う四角形のXY座標を、長さ2のint配列で取得できます。(上記コードの[1])

次に衝突判定についてですが、今回、四角形は回転しないので、衝突判定を行う四角形の4つの頂点が、いずれも他の四角形内に存在しないことを確かめれば、正しく衝突判定が行えます。(上記コードの[2])

投稿2018/10/18 12:08

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/10/19 07:30

ありがとうございました。 まだ二次元の配列が理解できていないようです。 もう一度、よく考えてみます。
guest

0

とりあえずヒントだけ。

zahyo[A][B]のAとBが何を意味しているか考えましょう。
isCollision()を見ると使い方が定まっていません。

見るところはisCollision()の関数の中のzahyo[][]の箇所です。


iの取りうる範囲は0 ≦ i < 9ですね。
jの取りうる範囲は0 ≦ j < iですね。

isCollision()内で使われているzahyo[][]は以下の種類です。

  • zahyo[0][j]
  • zahyo[i][0]
  • zahyo[1][j]
  • zahyo[i][1]
  • zahyo[i][0]
  • zahyo[0][j]
  • zahyo[i][1]
  • zahyo[1][j]

zahyo[A][B]で、ABの範囲はぞれぞれどうなっているでしょうか?

投稿2018/10/18 08:20

編集2018/10/18 15:01
dice142

総合スコア5158

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/10/18 08:47

最初に入力したx,yはzahyo[0][0]と[0][1]に入っています。次のx,yは[1][0]と[1][1]で、[i][0]と[i][1]になります。 jはxの場合は[0]で、yは[1]です。 問題を見ると、『Boolean isCoolision(int,int){・・・}、戻り値:Boolean(衝突はtrue、しない場合はfalse)、第一引数:整数型(x座標)、第二引数:整数型(y座標)』を衝突判定のメソッドとして用いることとなっています。 たぶん(int,int)に何かを入れるか、{・・・}の中にzahyo[][]を入れるような気がするのですが、いまいち理解できません。 もう少し、ヒントをいただけるとありがたいのですが、何卒よろしくお願いいたします。
dice142

2018/10/18 15:03

回答に追記しました。
退会済みユーザー

退会済みユーザー

2018/10/19 03:00

zahyo[A][B]で、Aは0~9、Bは0か1だと思います。 例えば1回目のx,yが100,100だと[0][0]が100、[0][1]が100。 2回目のx,yが200,100だと[1][0]が200、[1][1]が100。 3回目のx,yが250,100だと[2][0]が200、[2][1]が100(衝突)。 i回目のXは[i][0]、yは[i][1]になります。 なので、 for(int i=0; i<10; i++);{  if(zahyo[i+1][0]+50 > zahyo[i][0]&&   zahyo[i][0]+50 > zahyo[i+1][0]&& zahyo[i+1][0]+50 > zahyo[i][1]&& zahyo[i][1]+50 > zahyo[i+1][1]) return true; } return false; としてみたのですが、うまくいきません。 swordone様コードを入れるとうまく動いたのですが、正方形の始点を二次元配列を用いる必要があるので、違うような気もします。 xを[i][0]に入れることが間違っているのでしょうか? あと衝突した場合のコメントが、次に衝突しない場合でも残ってしまうことと、「追加」を押して衝突する場合、「追加」をもう一度押さないと、コメントがでません。 これも関係するのでしょうか? よろしくお願いいたします。
dice142

2018/10/19 03:20

> i回目のXは[i][0]、yは[i][1]になります。 ここまでは合ってるのですが、なぜ修正したコードは i をループ変数としているのでしょうか? i は次の正方形のindex、jはそれまでの正方形と比較するためのループ変数でしたよね? また、ミスが一つとは限りません。 > swordone様コードを入れるとうまく動いたのですが、... swordone様のコードに関してはswordone様の回答のコメントで質問されるべきかと思いますが、 swordone様も2次元配列を使っていらっしゃいますよ。 > 衝突した場合のコメントが、次に衝突しない場合でも残ってしまうことと、... 衝突判定が上手くできていない状態で衝突のコメントが正しく出る保証はないです。 ひとつずつ解決するのが良いです。
退会済みユーザー

退会済みユーザー

2018/10/19 07:31

ありがとうございました。 もう一度、二次元配列について勉強しなおします。 インターネットで調べただけで、何とかしようとしていたので、書籍を購入してから再チャレンジします。
dice142

2018/10/19 07:36

いやまあネット上でも有用な記事がたくさんあるので、ネットのみで調べるのは問題ないと思いますが。 書籍を購入されるならものによって内容の濃さや読みやすさがぜんぜん違うので その辺を調べてから購入されることをおすすめします。
退会済みユーザー

退会済みユーザー

2018/10/19 07:47

色々ありがとうございました。 とりあえず初心者用とされる「スッキリわかるjava入門」を買ってみようと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問