Kollision Polygon und Rechteck

Oliundmarlo

Neues Mitglied
Hallo liebe User,
da ich gerade Semesterferien habe arbeite ich an einem kleinen Spielchen.
In der Mitte des Spielfeldes befindet sich ein Panzer. Mit den Tasten A und D lässt er sich rotieren. Mit W und S fährt er in Richtung des Vektors. Genau genommen verschiebt sich der Hintergrund. Der Panzer ist also immer im Zentrum.

Um Kollisionen zu erkennen habe ich ein Polygon um den Panzer gelegt. Über die Rotationsmatrix dreht sich das Polygon entsprechend um den Mittelpunkt des Panzers. Das klappt alles einwandfrei. 😀

panzer1.png

Ich habe nun Hindernisse(Häuser), als Rectangle in die Spielwelt eingefügt. Fährt der Panzer beispielsweise von unten auf ein Haus zu soll das drücken der W-Taste keine Verschiebung mehr in
(-y)-Richtung zulassen. Fährt er Rückwärts mit der S-Taste gegen das Haus soll natürlich auch die
(-y)-Verschiebung blockiert werden. Dieses Problem habe ich über den aktuellen Winkel des Panzers gelöst.
Mein Problem jedoch ist, dass sich der Panzer oft verhängt. Beispielsweise an den Ecken eines Hauses. Hat jemand eine Idee wie ich dieses Problem lösen kann? ;(

Hier mal ein bisschen Quellcode:

Java:
if(kol != null){
				
				if(maxY > kol.getMinY() && minY < kol.getMinY() && maxX > kol.getMinX() && minX < kol.getMaxX()){
					if(tankRotation >= 181 && tankRotation <= 359){
						System.out.println("W");
						wBlocked = true;
					}else if(tankRotation >= 1 && tankRotation <= 179){
						System.out.println("S");
						sBlocked = true;
					}else{
						//Keine Blockade
					}
					
				}else if(minY < kol.getMaxY() && maxY > kol.getMaxY() && minX < kol.getMaxX() && maxX > kol.getMinX()){
					if(tankRotation >= 1 && tankRotation <= 179){
						System.out.println("W");
						wBlocked = true;
					}else if(tankRotation >= 181 && tankRotation <= 359){
						System.out.println("S");
						sBlocked = true;
					}else{
						//Kein Block
					}
				}else if(minX < kol.getMaxX() && maxX > kol.getMaxX() && maxY > kol.getMinY() && minY < kol.getMaxY()){
					if(tankRotation >= 91 && tankRotation <= 269){
						System.out.println("W");
						wBlocked = true;
					}
					else if(tankRotation >= 271 && tankRotation <= 359 || tankRotation >= 1 && tankRotation <= 89){
						System.out.println("S");
						sBlocked = true;
					}else{
						//Kein Block
					}
				}else if(maxX > kol.getMinX() && minX < kol.getMinX() && maxY > kol.getMinY() && minY < kol.getMaxY()){
					if(tankRotation >= 271 && tankRotation <= 359 || tankRotation >= 1 && tankRotation <= 89){
						System.out.println("W");
						wBlocked = true;
					}
					else if(tankRotation >= 91 && tankRotation <= 269){
						System.out.println("S");
						sBlocked = true;
					}else{
						//Kein Block
						wBlocked = false;
						sBlocked = false;
					}
				}
				
			}
			else{
				//Kein Block
				wBlocked = false;
				sBlocked = false;
			}

Bei "Kol" handelt es sich um das Kollidierte Rectangle Haus.
minX, maxX, minY und maxY sind die Extremwerte des Polygons vom Panzer!
 
Zuletzt bearbeitet:
Ich denke mal, dass du eine Geschwindigkeit größer 1 verwendest. Dann liegt es daran, dass du durch das Haus hindurch glitchst und dann dein Programm erst merkt, dass da etwas nicht stimmt.

Dazu gibt es zwei Möglichkeiten:
  1. Du zerlegst die Bewegung in kleine Bewegungen und testest immer vor einer Bewegung, ob sich das Polygon und der Rectangle überschneiden (Polygon#intersect(Rectangle2D)).
  2. Du testest vor der Bewegung um z.B. 7 Längeneinheiten, ob du kollidieren würdest und dann ziehst du eine Linie von dem Panzer in Richtung des Vektors und tastest dich an das Haus heran (du springst die Hälfte des Weges, wenn du kollidierst, springst du die Hälfte der Hälfte zurück und testest erneut. Wenn du nicht kollidierst, andersrum)

Welche du verwendest, bleibt dir überlassen. Die erste ist einfacher zu implementieren und die Zweite ist performanter.
 
Ok hab das Problem jetzt doch selbsständig gelöst. Hat mich nen ganzen Tag gekostet aber es hat sich gelohnt. Funktioniert jetzt wunderbar. Trotzdem danke für den Ratschlag. Werde ich beim nächsten mal vielleicht so umsetzen.
😉 😉😉
 

Zurück
Oben