Kollision zwischen zwei ImageViews

  • Antworten:13
  • Bentwortet
Florian S.
  • Forum-Beiträge: 71

12.03.2014, 13:05:44 via Website

Hallo,
eigentlich recht simple Frage: wie erkenne ich eine Kollision zwischen zwei ImageViews?
Ich habe einen Spieler der auf einer Map entlang läuft und pro Map je zwei Objekte in Form von ImageViews die der Spieler einsammeln soll, und ich möchte also erkennen, ob er dieses Objekt berührt(egal von welcher Seite). Ich habe von Spieler eine x und y-Koordinate, gleiches gilt für die beiden Objekte, also jeweils die Koordinaten, von denen aus gezeichnet wird, hier noch die wichtigen Code-Teile:

1public Random rmd = new Random();
2 public int maxX=700,maxY=370,minX=0,minY=158;
3
4 ImageView stone1,stone2;
5
6 public int extraStones=0;
7
8 public int randomX1,randomX2,randomY1,randomY2;

1stone1 = new ImageView(GameActivity.this);
2 stone1.setImageResource(R.drawable.volcano_currency_small);
3 stone2 = new ImageView(GameActivity.this);
4 stone2.setImageResource(R.drawable.volcano_currency_small);
5
6 layout = (RelativeLayout) findViewById(R.id.RelativeLayout1);
7 layout.setOnClickListener(this);
8 RelativeLayout.LayoutParams lp =
9 new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
10 lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
11 layout.addView(stone1,lp);
12 layout.addView(stone2,lp);

1randomX1=rmd.nextInt((maxX-minX)+1)+minX;
2 randomX2=rmd.nextInt((maxX-minX)+1)+minX;
3 randomY1=rmd.nextInt((maxY-minY)+1)+minY;
4 randomY2=rmd.nextInt((maxY-minY)+1)+minY;
5 stone1.setX(randomX1);
6 stone1.setY(randomY1);
7 stone2.setX(randomX2);
8 stone2.setY(randomY2);

(für jede Map wird für jedes Objekt je eine zufällige x und y-Koordinate generiert)

Was ich schon getestet habe, war eine Idee von mir, nämlich:
1public void checkStoneContact()
2 {
3 if(xPos>randomX1&&xPos<randomX1+56&&yPos>randomY1&&yPos<randomY1+44)
4 {
5 stone1.setVisibility(ImageView.INVISIBLE);
6 extraStones+=3;
7 }
8
9 if(xPos>randomX2&&xPos<randomX2+56&&yPos>randomY2&&yPos<randomY2+44)
10 {
11 stone2.setVisibility(ImageView.INVISIBLE);
12 extraStones+=3;
13 }
14 }
Folgender Effekt: Prinzipiell nicht schlecht, aber es wird eben nur auf die eine x und y-Koordinate reagiert, das heißt es wird nur auf die Oberseite vom Spieler reagiert....
Was ich dann noch versuchen wollte, war ein Snippet aus dem Internet, bis ich dann festgestellt habe, dass es nicht Java sondern JavaFX ist...
Dieser Snippet sah so aus:
1private boolean checkCollision(ImageView one, ImageView two)
2 {
3 Bounds oneLb = one.getLayoutBounds();
4 Bounds twoLb = two.getLayoutBounds();
5
6 // Bild2 liegt rechts von Bild1
7 if( (oneLb.getMinX() + oneLb.getWidth()) <= twoLb.getMinX() )
8 {
9 return false;
10 }
11
12 // Bild2 liegt unter den Bild1
13 if( (oneLb.getMinY() + oneLb.getHeight()) <= twoLb.getMinY() )
14 {
15 return false;
16 }
17
18 // Bild2 liegt links von Bild1
19 if( (twoLb.getMinX() + twoLb.getWidth()) <= oneLb.getMinX() )
20 {
21 return false;
22 }
23
24 // Bild2 liegt über den Bild3
25 if( (twoLb.getMinY() + twoLb.getHeight()) <= oneLb.getMinY() )
26 {
27 return false;
28 }
29
30 // wenn man hier angekommen ist, dann kollidieren die BBoxen
31 return true;
32 }
Klar, bounds funktioniert nicht.. Hat es sowas ähnliches in Java?
Oder habt ihr andere Ideen?

LG
Florian S.

Antworten
Mac Systems
  • Forum-Beiträge: 1.727

12.03.2014, 13:22:54 via Website

Wieso malst du nicht mal auf was du machen willst und schreibst einen Simple Klasse die sowas als boolean ausgibt. Hierfür würde Ich einen einfachen Unit Test schreiben da es erstmal nichts mit einem ImageView zu tun hast. Bounding Boxen sind dafür geeignet, sind zwar nicht pixel perfekt aber es sollte anb Anfang reichen. Auch würde Ich mir mal die Klasse Rect anschauen da an sich alles drin ist was du brauchst

Windmate HD, See you @ IO 14 , Worked on Wundercar, Glass V3, LG G Watch, Moto 360, Android TV

Antworten
Florian S.
  • Forum-Beiträge: 71

12.03.2014, 13:57:19 via Website

Das habe ich auch schon gefunden mit Bounding Box aber wie mache ich das konkret? Also ich kann über das rectangle 3 rechtecke um meine Objekte erstellen soweit habe ich es verstanden. Nur wie weiß ich dann, wann die miteinander kollidieren, habe sowas noch nie gemacht...

LG

Antworten
Mac Systems
  • Forum-Beiträge: 1.727

12.03.2014, 14:15:24 via Website

Object A und B haben eine Bounding Box und du must ansich nur prüfen ob sich deren Koordinaten überscheiden, Rect kann das wie gesagt schon, mittels intersects. Ab einer gewissen anzahl mag das nicht mehr praktikabel sein da du im Prinzip jede Box überprüfen musst.

— geändert am 12.03.2014, 14:15:52

Windmate HD, See you @ IO 14 , Worked on Wundercar, Glass V3, LG G Watch, Moto 360, Android TV

Antworten
Florian S.
  • Forum-Beiträge: 71

12.03.2014, 14:18:08 via Website

Achso, also Pseudo-Code:
1if(rect1.instersect(rect2)
2{
3....
4}
und das gleiche dann mit dem anderen... geht das so?

LG

— geändert am 12.03.2014, 14:18:16

Antworten
Mac Systems
  • Forum-Beiträge: 1.727

12.03.2014, 14:24:58 via Website

Wie wäre es das Auszuprobieren, gib einen Toast.makeText(..) aus wenn es passt.

Windmate HD, See you @ IO 14 , Worked on Wundercar, Glass V3, LG G Watch, Moto 360, Android TV

Antworten
Florian S.
  • Forum-Beiträge: 71

12.03.2014, 14:36:30 via Website

Funktioniert so wohl nicht..
1public void checkStoneContact()
2 {
3 playerRect = new Rect(xPos,yPos,xPos+45,yPos-100);
4 stone1Rect = new Rect(randomX1,randomY1,randomX1+55,randomY1-40);
5 stone2Rect = new Rect(randomX2,randomY2,randomX2+55,randomY2-40);
6
7 if(playerRect.intersect(stone1Rect))
8 Toast.makeText(getApplicationContext(),"Funktioniert", Toast.LENGTH_SHORT).show();
9
10 if(playerRect.intersect(stone2Rect))
11 Toast.makeText(getApplicationContext(),"Funktioniert", Toast.LENGTH_SHORT).show();
12 }

Bekomme keinen Toast angezeigt...

— geändert am 12.03.2014, 14:42:39

Antworten
Mac Systems
  • Forum-Beiträge: 1.727

12.03.2014, 14:46:18 via Website

Schonmal den Debugger benutzt ? Würde das mach checken, immer nur geht nicht schreiben ist etwas wenig mühe

Irgendwelche Random werte da zu nutzen bei Testen ist auch nicht gerade hilfreich, papier und bleistift sind da mal hilfreicher

— geändert am 12.03.2014, 14:47:29

Windmate HD, See you @ IO 14 , Worked on Wundercar, Glass V3, LG G Watch, Moto 360, Android TV

Antworten
Florian S.
  • Forum-Beiträge: 71

12.03.2014, 15:24:22 via Website

Das sind keine Random-Werte, xPos ist eben die xPosition der linken Seite, YPos die y-Position der oberen Seite, xPos+45 die xPosition der rechten Seite (das Image ist 45Px breit) und unten eben YPos-100, weil es 100 px hoch ist. Gleiches gilt für die "stones" also die Kollisionsobjekte, falls du da meinst, dass da Random drin steht, das ist schon ok, die Objekte mit denen der Spieler kollidiert, werden ja Random erzeugt, deswegen brauche ich genau die Koordinaten...

Antworten
Mac Systems
  • Forum-Beiträge: 1.727

12.03.2014, 16:20:59 via Website

Das ist doch simpelste Mathe, also schon den Debugger befragt ?

Windmate HD, See you @ IO 14 , Worked on Wundercar, Glass V3, LG G Watch, Moto 360, Android TV

Antworten
Florian S.
  • Forum-Beiträge: 71

12.03.2014, 16:47:53 via Website

Nein, das funktioniert bei mir nie so wie es soll mit dem Debugger...
Weißt du denn woran's liegt?

— geändert am 12.03.2014, 17:54:16

Antworten
Mac Systems
  • Forum-Beiträge: 1.727

12.03.2014, 18:13:50 via Website

Nein weis ich nicht, aber wenn Ich die Boxen der Views habe kann Ich das ausrechnen, wieso kannst du nicht einfachste Mathematik ?
Dann lerne den debugger zu benutzen, gibt gefühl 1000 Quellen die das beschreiben.

Windmate HD, See you @ IO 14 , Worked on Wundercar, Glass V3, LG G Watch, Moto 360, Android TV

Antworten
Mac Systems
  • Forum-Beiträge: 1.727

12.03.2014, 18:27:35 via Website

Laut API Doc musst du intersects benutzen und nicht intersect, man beachte das s am ende. Da die andere methode das ursprungs Rect verändert laut Andoid Source

Windmate HD, See you @ IO 14 , Worked on Wundercar, Glass V3, LG G Watch, Moto 360, Android TV

Antworten
Florian S.
  • Forum-Beiträge: 71

12.03.2014, 18:31:09 via Website

Funktioniert jetzt, danke.

Antworten