Kollisionsermittlung

Letavino

Aktives Mitglied
Guten Tag,

ich übe mich gerade in der 2D Programmierung in Java.
Bei einem kleinen Testprogramm soll im Moment ein Viereck von oben nach unten fallen.
Der Hintergrund der Anwendung wird durch ein Bild dargestellt, welches komplett transparent ist, nur ganz unten einen schwarzen Balken hat. Wenn sich das Viereck auf dem transparenten Hintergrund bewegt, soll keine Kollision auslösen, bei dem schwarzen Balken am unteren Ende jedoch schon.

Doch leider kommt er nicht so weit, denn es fliegt eine "outside of Raster" Exception.

Hier der Code:

(Fehler liegt bei der Erzeugung des Subimiges: BufferedImage srcSub = srcImg.getSubimage[...])

Java:
public void move()
{
	boolean[] collision = Tools.collision((int)this.x,(int)this.y,this.img,0,0,backgroundImg);

	if(!collision[2])
	{
		inAir = true; 
		timeInAir += Main.sleep;
	}
	else
	{
		inAir = false; 
		timeInAir = 0;
	}
	if(collision[0])
		speedY = 0;			
	
	if(collision[1])
		speedX = 0;
			
	if(collision[3])
		speedX = 0;

	if(collision[4])
		System.out.println("Inner Collision");
		
	//v	   += g * t
	speedY = Main.forceOfGravity * timeInAir /1000;
		
	//s = v	* t
	this.x 	  += speedX * Main.sleep/1000;
	this.y 	  += speedY * Main.sleep/1000;	
}

Java:
public static boolean[] collision(int srcX, int srcY, BufferedImage srcImg, int refX, int refY, BufferedImage refImg)
{
	boolean[] b = new boolean[5];
		
	Rectangle srcRect = new Rectangle(srcX,srcY,srcImg.getWidth(),srcImg.getHeight());
	Rectangle refRect = new Rectangle(refX,refY,refImg.getWidth(),refImg.getHeight());
		
	Rectangle intRect = new Rectangle();;
				
	intRect = srcRect.intersection(refRect);
		
	System.out.println(
			srcX+","+srcY+","+srcImg.getWidth()+","+srcImg.getHeight()+"     "+
		(int)intRect.getX()+","+(int)intRect.getY()+","+(int)intRect.getWidth()+","+ (int)intRect.getHeight());
		
		BufferedImage srcSub = srcImg.getSubimage((int)intRect.getX(), (int)intRect.getY(), (int)intRect.getWidth(), (int)intRect.getHeight());
		BufferedImage refSub = srcImg.getSubimage((int)intRect.getX(), (int)intRect.getY(), (int)intRect.getWidth(), (int)intRect.getHeight());
		
		
	for(int i=0;i<intRect.getWidth()-1;i++)
		for(int j=0;j<intRect.getHeight()-1;j++)
			if(!isTransparent(i,j,srcSub)&&!isTransparent(i,j,refSub))
			{	
				if(intRect.getY()+j==srcY)
					b[0] = true; //oben
				if(intRect.getX()+i==srcX+srcImg.getWidth()-1)
					b[1] = true; //rechts
				if(intRect.getY()+j==srcY+srcImg.getHeight()-1)
					b[2] = true; //unten
				if(intRect.getX()+i==srcX)
					b[3] = true; //links
					
				if(!(b[0]||b[1]||b[2]||b[3])) // mitte
					b[4] = true;
			}
	return b;
}
Die Ausgabe inklusive Exception:
Java:
0,0,10,30     0,0,10,30
0,0,10,30     0,0,10,30
0,0,10,30     0,0,10,30
0,0,10,30     0,0,10,30
0,0,10,30     0,0,10,30
0,0,10,30     0,0,10,30
0,0,10,30     0,0,10,30
0,0,10,30     0,0,10,30
Exception in thread "Thread-4" java.awt.image.RasterFormatException: (y + height) is outside of Raster
	at sun.awt.image.ByteInterleavedRaster.createWritableChild(Unknown Source)
	at java.awt.image.BufferedImage.getSubimage(Unknown Source)
	at Tools.collision(Tools.java:48)
	at Sprite.move(Sprite.java:73)
	at Main.moveObjects(Main.java:107)
	at Main.run(Main.java:54)
	at java.lang.Thread.run(Unknown Source)
0,1,10,30     0,1,10,30

Es scheint mit der Veränderung des Y-Wertes des Vierecks zutun zu haben. Aber wo genau liegt der Fehler?

Wenn der Code nicht auf Anhieb verständlich ist, einfach nachfragen und ich werde ihn genauer erläutern!
Wenn sonst noch Fragen sind, bitte einfach melden.

Mit freundlichem Gruß,
Letavino
 
S

SlaterB

Gast
was hat es mit srcX,srcY und all den Koordinaten auf sich, wann sind die 0 und wann nicht?

anscheinend liegt ein Bild mit Höhe 30 vor, von y = 0 kann man mit der normalen Höhe 30 ein subImage() machen,
aber bei y=1 wird immer noch Höhe 30 geschnitten, das haut offensichtlich nicht hin

> intRect = srcRect.intersection(refRect);
kann man vielleicht beschuldigen, sollte dort Höhe 29 rauskommen?

schau dir dazu nochmal genau die beiden Rechtecke an und das Ergebnis,
kopiere diese Berechnung in eine neue main-Methode,
wenn sie fachlich nicht hinkommt, dann evtl. selber anders nachbauen
 
Zuletzt bearbeitet von einem Moderator:

Letavino

Aktives Mitglied
Danke schonmal für deine Antwort!

was hat es mit srcX,srcY und all den Koordinaten auf sich, wann sind die 0 und wann nicht?

srcX und srcY stehen für die Ursprungskoordinaten des Vierecks (src steht für Source).
refX und refY stehen für die Ursprungskoordinaten des des Hintergrundes (ref soll für Referenz stehen).

anscheinend liegt ein Bild mit Höhe 30 vor, von y = 0 kann man mit der normalen Höhe 30 ein subImage() machen,
aber bei y=1 wird immer noch Höhe 30 geschnitten, das haut offensichtlich nicht hin

Da scheinst du recht zu haben. Aber alle Rechtecke und Bilder werden doch ohne Bezug zum vorherigen Durchlauf neu erstellt, oder sehe ich das falsch?

€dit:
Ich habe deinen Edit gerade gesehen und werde es mal testen. Danke nochmal! :)

€dit2:
Die Ausgabe
Java:
System.out.println(intRect.getHeight());
bringt als Ergebnis die 30, daran scheint es also leider auch nicht zu liegen.
 
Zuletzt bearbeitet:

Letavino

Aktives Mitglied
Ich habe jetzt testweise einige Ausgaben eingebaut, einige Daten von Hand eingetragen und alles wieder zurück geändert und seltsamerweise funktioniert es nun wie gewünscht.
Wie gesagt, bewusst könnte ich nicht sagen, dass sich irgendetwas am Code verändert hätte.
Es funktioniert auch, wenn man das Viereck auf der Y-Achse verschiebt. Verschiebt man es aber beim Konstruieren auf der X Achse, so erscheint die gleiche Exception, wie vorher, nur auf die X Achse bezogen: "(x + width) is outside of Raster"

Vorheriger Ursprungsort des Vierecks: (0|0)
Was auch geht: zb.: (0|5)
Was aber eine Exception wirft: (5|0)

Ich werde natürlich auch für mich weiter testen, aber vielleicht kennt ja jemand ein ähnliches Phänomen.

Ich aktualisiere hier, wenn ich etwas neues herausgefunden habe.

Gruß!

€dit:
Jetzt habe ich meinen Fehler wsl gefunden:
Java:
BufferedImage srcSub = srcImg.getSubimage((int)intRect.getX(), (int)intRect.getY(), (int)intRect.getWidth(), (int)intRect.getHeight());
Die X und Y Variablen, die ich über intRect hole, beziehen sich auf den allgemeinen Null Punkt.
Die erwarteten Variablen müssen sich aber auf das Quellbild beziehen.

Ich hoffe mal, damit sollte es sich schnell lösen lassen. :)

Ich lass es noch kurz offen, falls noch jmd etwas anmerken möchte, oder ich doch noch einen Fehler finde.
 
Zuletzt bearbeitet:

Neue Themen


Oben