# Rectangle Runde Hitbox



## RegenSonne (6. Aug 2017)

Hallo, ich habe ein kleines Spiel gemacht.. nur die Hitbox ist ein Quadrat.. obwohl mein Bild n kreis ist... Vermutlich wird auch der Alpha Kanal als bild gewertet? wie kann ich das umgehen.. dass eben nur der kreis als hitbox dient.

Ausschnitt:


```
r1 = new Rectangle(Draw.ballx, Draw.bally, Draw.rectbs, Draw.rectbs);
  for (int i = 0; i < 25; i++) {
   r2 = new Rectangle(CreateGegner.gx[i], CreateGegner.gy[i], 10, 10);
   if (r1.intersects(r2)) {
    col[i] = true;
   } else {
    col[i] = false;
   }
  }
```

Die Gegner passen so perfekt..


Lg und danke für eure Hilfe!


----------



## thecain (6. Aug 2017)

Du hast ja hier nur rechtecke... Wo soll da plötzlich ein Kreis her kommen?


----------



## RegenSonne (6. Aug 2017)

Und wir mache ich ein kreis?


----------



## Flown (7. Aug 2017)

RegenSonne hat gesagt.:


> Und wir mache ich ein kreis?


Graphics Doku sagt dir mehr dazu: HIER. Auch Google hilft dir: HIER


----------



## RegenSonne (7. Aug 2017)

Vielen dank ^^ @Flown


----------



## RegenSonne (7. Aug 2017)

Ich habe pngs als kreis aber ich meinte wie ich die hitbox als kreis mache..

Ich schau mir den beitrag von graphics aber mal an ^^

Lg


----------



## Harry Kane (7. Aug 2017)

RegenSonne hat gesagt.:


> Ich habe pngs als kreis


Hier liegt offenbar ein grundsätzliches Missverständnis vor.
Ein Kreis, der in einem PNG gezeichnet wird, ist etwas vollkommen anderes als ein "kreisförmiges PNG". Letzteres gibt es nicht. Ein PNG (oder allgemein, ein Image) ist etwas rechteckiges. Wenn von dem Rechteck nur bestimmte Pixel zählen sollen, musst du wohl die dafür notwendige Kollionsabfrage unter Berücksichtigung der Pixeleigenschaften selber programmieren.


----------



## Blender3D (9. Aug 2017)

Wenn du berechnen willst ob zwei Kreise sich berühren. Berechne einfach den Abstand der Mittelpunkte.
distance = distancePoints( M1, M2 );
sumRadius = R1+R2;
distance > sumRadius -> keine Kollision
distance = sumRadius -> Berührung
distance < sumRadius -> Kollision

```
// Calculates distance between 2 points.
double distancePoints( Point p1, Point p2 ){
    return Math.sqrt(Math.pow( p2.x - p1.x ) + Math.pow(p2.y - p1.y ));
}
```


----------



## Thallius (9. Aug 2017)

Naja einfacher ist es das Bild als Maske zu benutzen und die Hitbox durch eine Pixelfarbe zu definieren. Damit kann man mit ganz wenig Aufwand beliebig komplexe Hitboxen erstellen indem man sie einfach malt.

Gruß

Claus


----------



## RegenSonne (11. Aug 2017)

Wie benutzt man ein Bild als Maske? Hast du da ein beispielbeitrag? @Thallius 

lg


----------



## RegenSonne (11. Aug 2017)

Ich habe mit nem Robot die pixelfarbe geholt aber wie mache ich das.. etwas genauer bitte..?

lg


----------



## Thallius (12. Aug 2017)

Auch mal nach bufferedImage


----------



## JuKu (15. Aug 2017)

@Thallius Das was du meinst ist leider recht ineffizient, da du kaum erkennen kannst, dass es sich auf dem Bild um einen Kreis handelt (es sei denn, dein Programm ist echt so intelligent), stattdessen müsstest du dann mit vielen kleinen Polygnen arbeiten. Und das wiederum benötigt sehr viel Performance.


----------



## RegenSonne (15. Aug 2017)

Und was wäre die effizienteste lösung? @JuKu


----------



## Thallius (16. Aug 2017)

JuKu hat gesagt.:


> @Thallius Das was du meinst ist leider recht ineffizient, da du kaum erkennen kannst, dass es sich auf dem Bild um einen Kreis handelt (es sei denn, dein Programm ist echt so intelligent), stattdessen müsstest du dann mit vielen kleinen Polygnen arbeiten. Und das wiederum benötigt sehr viel Performance.



Wie kommst du denn auf das schmale Brett. Mal einen schwarzen Kreis auf weißen Grund und dann mach daraus ein Image. Nun kann ich für jede Koordinate mit einer Abfrage feststellen ob diese im Kreis liegt oder nicht. Schneller geht es überhaupt nicht.


----------



## mrBrown (16. Aug 2017)

Thallius hat gesagt.:


> Wie kommst du denn auf das schmale Brett. Mal einen schwarzen Kreis auf weißen Grund und dann mach daraus ein Image. Nun kann ich für jede Koordinate mit einer Abfrage feststellen ob diese im Kreis liegt oder nicht. Schneller geht es überhaupt nicht.


Du musst dann Pixelweise prüfen, fällt dir etwa noch was ineffizienteres ein?


----------



## JuKu (16. Aug 2017)

mrBrown hat gesagt.:


> Du musst dann Pixelweise prüfen, fällt dir etwa noch was ineffizienteres ein?



Dem ist ja eig. schon nichts mehr hinzuzufügen.

@Thallius Diese Behauptung ist leider Quatsch, da du zwar eine Hülle um das komplexe Polygon ziehen kannst (und somit nicht jedes mal alles berechnen musst), aber sobald das Objekt die Hülle durchschreitet, musst du, wie @mrBrown es bereits gesagt hat, Pixelweise prüfen.

@RegenSonne
Die effizienteste Lösung wäre es, einen Kreis zu nehmen und diesen gar nicht erst aus dem Bild zu generieren, sondern lediglich den Radius in irgendeine Datei zu schreiben und dann den Kreis mittig auf das Bild zu zentrieren.


----------



## Thallius (17. Aug 2017)

Sorry erklärt mir einer eure Denkweise? Wenn ich das Bild als bifferdImage habe, dann mache ich eine einzige Abfrage auf den Pixelwert der Koordinate von der ich wissen will ob sie im Kreis liegt oder nicht. Das ein einziger Speicherzugriff auf einen Speicherblock im Heap. Das Schaft jeder Prozessor in einem Taktzyklus. Wie willst du das mit irgendwelchen polygonberechnungen schneller hinbekommen?


----------



## mrBrown (17. Aug 2017)

In den meisten Fälle reicht dir nicht zu wissen, ob irgendein Pixel mit der Hitbox kollidiert, sondern ob zwei Hitboxen miteinander kollidieren.


----------



## JuKu (17. Aug 2017)

Thallius hat gesagt.:


> Wenn ich das Bild als bifferdImage habe, dann mache ich eine einzige Abfrage auf den Pixelwert der Koordinate von der ich wissen will ob sie im Kreis liegt oder nicht.



Angenommen die Texture sieht so aus (gelb):



Du kannst aber eben nicht (es sei denn, dein Programm ist super intelligent, wovon ich nicht ausgehe!) erkennen, dass es sich bei dieser Grafik (gelb) um einen Kreis handelt! Für den Computer kannst du das nur durch einzelne Linien / Polygone (rote Linien) approximieren. Und dann prüfst du ja auch *nicht nur einen Pixel* deines Charakters, sondern du willst ja wissen, *ob irgendein Pixel* deines Charakters im Kreis liegt!
D.h. du müsstest nach deiner Methode alle Pixel des Charakters mit der Hitbox des Kreises abgleichen. Und das ist eben ineffizient.

*Fakt ist: Du hast diesen Kreis nicht, von dem du die ganze Zeit ausgehst!*
Wenn du nicht gerade ein neuronales Netz hast, welches diesen erkennt, dann ist es dir nahezu unmöglich (es sei denn, er ist irgendwie zentriert, aber das ist ein anderes Thema), zu erkennen, dass es sich um einen Kreis in der Grafik handelt! Und das ist nicht mal gegeben, der Thread Ersteller hat "Runde Hitbox" und nicht Kreis geschrieben, d.h. es kann sich auch um ein Ei handeln o.ä.
Er hat lediglich eine Grafik und will daraus eine Hitbox generieren. Und da kommst du höchstens auf Polygone.


----------



## Blender3D (17. Aug 2017)

JuKu hat gesagt.:


> Er hat lediglich eine Grafik und will daraus eine Hitbox generieren. Und da kommst du höchstens auf Polygone.


Das ist eine Variante die sehr gut funktioniert.
Bau Dir eine Klasse z.B. Sprite. die beinhaltete ein Image, Koordinaten usw. und ein Polygon als Hitbox.
Default = Rechteck. für genauere Kollisionsabfrage gib ein Polygon an. ( Mittels Grafikprogramm kannst Du die Koordinaten des Polygons ermitteln.) --> sehr genaue Kollision.
Ich habe das bereits für einige Spiele verwendet. funktioniert sehr effizient.

Wenn Du nur Kreise hast dann verwende meinen Vorschlag wie oben beschrieben.


----------



## Thallius (17. Aug 2017)

Ich bin jetzt hier raus. Ihr konstruiert gerade irgendwas um eure Meinung zu rechtfertigen ohne auch nur ansatzweise auf die Aufgabenstellung des TO einzugehen...


----------



## mrBrown (17. Aug 2017)

Thallius hat gesagt.:


> Ich bin jetzt hier raus. Ihr konstruiert gerade irgendwas um eure Meinung zu rechtfertigen ohne auch nur ansatzweise auf die Aufgabenstellung des TO einzugehen...


Wir konstruieren genau den Anwendungsfall, den der TO hat - nämlich zwei Hitboxen kollidieren lassen, nicht Pixel mit Hitbox


----------



## InfectedBytes (18. Aug 2017)

Aus dem Anfangspost geht hervor das er einen "ball" mit "gegnern" kollidieren lassen möchte. Der Ball wird garantiert ein Kreis sein und die Gegner höchstwahrscheinlich Rechtecke und/oder Kreise. Falls sie doch komplizierte Figuren darstellen, ist es vermutlich mehr als ausreichend diese per Rechteck zu approximieren, falls sie dennoch genauer kollidieren sollen -> Polygone.

Falls die Gegner Kreise sind:
Distanz der Kreiszentren vergleichen, falls diese kleiner als die Summe der Radien ist -> Kollision

Falls die Gegner Rechtecke sind:
Am besten zwei schrittig vorgehen. Erstmal so tun als wäre der Kreis ein Rechteck, falls sich diese Rechtecke nicht berühren, ist man fertig (fail-fast). Falls sich diese jedoch berühren, musst du etwas aufwendiger die Kreis-Rechteck Kollision prüfen: Am "einfachsten" indem du jeweils auf Kollision mit den einzelnen Kanten des Rechtecks prüfst.

Eine Pixelgenaue Überprüfung sollte definitiv vermieden werden, da dass ewig langsam ist, denn dann müsste man die "Kollisionsbilder" (schwarz=nichts, weiß=Objekt) entsprechend ihrer positiv quasi übereinander legen und per &-Operation "zeichnen", in dem resultierenden Bild würde jeder weiße Pixel eine überlappung darstellen. => Pixel für Pixel durchgehen und prüfen ist nunmal etwas das sehr lange dauert, insbesondere bei großen Bilder. Um es zumindest etwas schneller zu machen, sollte man definitiv vorher auf Rechteck Kollision prüfen (fail-fast) und nur das überlappende Rechteck Pixelgenau prüfen.


----------



## Blender3D (18. Aug 2017)

InfectedBytes hat gesagt.:


> Falls die Gegner Rechtecke sind:
> Am besten zwei schrittig vorgehen. Erstmal so tun als wäre der Kreis ein Rechteck, falls sich diese Rechtecke nicht berühren, ist man fertig (fail-fast). Falls sich diese jedoch berühren, musst du etwas aufwendiger die Kreis-Rechteck Kollision prüfen: Am "einfachsten" indem du jeweils auf Kollision mit den einzelnen Kanten des Rechtecks prüfst.


Ich verwende Rechtecke ob zu testen, ob eine Kollision infrage kommt. Falls ja genauerer Check, wenn gewünscht.


----------



## RegenSonne (27. Aug 2017)

Ja es sind alles Kreise. Ich probiereal das was @InfectedBytes gesagt hat... 

Wo ich gerade im Chat bin, kennt jemand ein gutes Tutorial für OpenGL? Wollte das Mal ausprobieren ^^ LG und danke an alle Antworter ^^


----------



## JuKu (30. Aug 2017)

Ein OpenGL Tutorial gibt es z.B. hier:
http://www.opengl-tutorial.org/


----------



## RegenSonne (30. Aug 2017)

Vielen Dank <3


----------



## lant (30. Aug 2017)

oder hier :3
http://www.youtube.com/playlist?list=PLRIWtICgwaX0u7Rf9zkZhLoLuZVfUksDP


----------



## RegenSonne (30. Aug 2017)

Jo damit habe ich angefangen.. hab allerdings was auf deutsch gesucht.. trzdm vielen dank ^^


----------

