# Kollisionserkennung



## Paladin (17. Jan 2007)

Hi Leute,

für ein Spiel in welchem der Spieler ein Fahrzeug durch eine Vertikal und Horizontal Scrollende Landschaft bewegt (Sicht: Vogelperspektive) versuche ich gerade eine möglichst genaue Kollisionserkennung umzusetzen. Auf dem
Spielfeld befinden sich mehrere Objekte wie zum Beispiel Häuser, Felsen und ähnliches welche dafür relevant sein
sollen.

Um eine Kollision zu erkennen hole ich mir von jedem Objekt (was auf dem Bildschirm ist) mit getBounds die Umrisse und überprüfe ob das Fahrzeug des Spielers sich mit einem dieser Objekte überschneidet.

Mein Problem ist jetzt aber folgendes: 
Das Fahrzeug des Spielers kann sich drehen. Dies geschieht mit AffineTransform und Rotate. 
Da AffineTransform und Rotate ja aber nur das Koordinatensystem drehen (glaube ich) bekomme ich bei getBounds
auf den gedrehten Körper (das Fahrzeug des Spielers) ein normales Rechteck zurück (welches nicht um x Grad gedreht ist wie das Fahrzeug).

Dies führt bei der Kollisionserkennung natürlich dazu, dass ich teilweise auch schon eine Kollision erkenne wenn das Fahrzeug nur nah an einem Gebäude vorbeifährt.

Was kann ich tun um dieses Problem zu lösen?

Ich habe mal gelesen, dass man auch eine Pixelgenaue Kollisionserkennung machen kann. Wie funktioniert sowas?

Vielen Dank im voraus.

Gruß

Paladin


----------



## Marco13 (17. Jan 2007)

Die Kollisionserkennung pixelgenau zu machen wäre evtl. möglich, wenn man selbst zeichnet (d.h. jeden Pixel selbst per Hand setzt). Vermutlich ist es aber auch garnicht notwendig. 

Es gäbe da unterschiedliche Möglichkeiten, die unterschiedlich aufwändig, unterschiedlich genau und unterschiedlich flexibel sind. Eine Möglichkeit, die ausreichend genau sein dürfte: Du könntest bei getBounds nicht ein ungedrehtes Rectangle zurückgeben, sondern ein Polygon, das den Umriß des (gedrehten) Objektes beschreibt. (Sind deine Objekte Images, mit transparenten Bereichen, oder malst du die selbst (d.h. SIND deine Objekte vielleicht schon Shapes?)

Je nachdem, wie viele Objekte du hast, und wie kompliziert die sind, und wie viele davon bewegt werden können, würde es dann evtl. schon reichen, zu überprüfen, ob sich eine Kante eines Bounding-Polygons mit einer Kante eines anderen schneidet, oder sie sich gegenseitig enthalten. Wenn es zu langsam wird, kann man auch mit einer Bounding Volume Hierarchie drangehen.

Die Frage nach einer vernünftigen Kollisionsantwort bleibt aber in allen Fällen erstmal offen.


----------



## Paladin (18. Jan 2007)

> Eine Möglichkeit, die ausreichend genau sein dürfte: Du könntest bei getBounds nicht ein ungedrehtes Rectangle zurückgeben, sondern ein Polygon, das den Umriß des (gedrehten) Objektes beschreibt. (Sind deine Objekte Images, mit transparenten Bereichen, oder malst du die selbst (d.h. SIND deine Objekte vielleicht schon Shapes?)



Alle Grafikobjekte sind vom Typ BufferedImage. Manche Objekte (wie zum Beispiel auch das Fahrzeug des Spielers) sind png Dateien weil ich dort Transparenz & Schatteneffekte benötige. Andere Bilder wie zum Beispiel Häuser, Steine und ähnliches sind gif's.

Wie bekomme ich das hin, dass ich von meinem BufferedImage ein Polygon zurückbekomme welches den Umriss des gedrehten Objekts beschreibt?


----------



## Marco13 (18. Jan 2007)

Man könnte die tranparenten Bereiche der Images automatisch raussuchen und daraus ein Polygon erstellen lassen - das wäre aber ziemlich schwierig zu programmieren. Die einfache Alternative wäre, die Bilder in einem Grafikprogramm zu öffnen, und sich von Hand ein Polygon zu erstellen, das das Objekt hinreichend genau einschließt. 

Das Polygon kann man dann rotieren und verschieben, genau so, wie jetzt das Bild verschoben wird: Du hast ja vmtl. ein Graphics2D, dem du eine AffineTransform setzt. Und genau mit dieser AffineTransform könntest du alle Punkte der Polygone transformieren, bevor du auf Kollisionen testest.


----------

