# pixelgenaue Kollision



## baddestpoet (11. Mai 2010)

Ich versuche die pixelgenaue Kollision aus Quaxlis Tutorial in meinen Spielprototypen zu implementieren, aber bekomme immer folgende Fehlermeldung wenn mal eine Kollision auftritt:

Exception in thread "Thread-2" java.awt.image.RasterFormatException: (x + width) is outside of Raster
	at sun.awt.image.BytePackedRaster.createWritableChild(BytePackedRaster.java:1306)
	at java.awt.image.BufferedImage.getSubimage(BufferedImage.java:1173)
	at Sprite.checkCollision(Sprite.java:78)
	at GamePanel.doLogic(GamePanel.java:158)
	at GamePanel.run(GamePanel.java:92)
	at java.lang.Thread.run(Thread.java:636)


Hat jemand ne Ahnung, woher das kommt? Hier meine Kollisionsmethode und deren Aufruf im GamePanel (da wird für abgegebene Schüsse gecheckt, ob sie mit einem Gegner kollidieren):


```
public boolean checkCollision(Sprite s) { //pixelgenaue Kollision
    	Rectangle2D.Double cut = (Double) this.createIntersection(s); //Schnittmenge der Sprites
    	
    	if(cut.width<1 || cut.height<1)
    		return false; //Prüfung ob wirklich verwertbare Menge kollidiert
    	
    	//Rechteck in Bezug auf die jeweiligen Images
    	Rectangle2D.Double sub_me = getSubRec(this,cut);
    	Rectangle2D.Double sub_him = getSubRec(s,cut);
    	
    	//geschnittene Bestandteile der Sprites
    	BufferedImage img_me = pics[currentpic].getSubimage((int) sub_me.x, (int) sub_me.y, (int) sub_me.width, (int) sub_me.height);
    	BufferedImage img_him = pics[currentpic].getSubimage((int) sub_him.x, (int) sub_him.y, (int) sub_him.width, (int) sub_him.height);
    	
    	for(int i=0;i<img_me.getWidth();i++) {
    		for (int j=0;j<img_him.getHeight();j++) {
    			int rgb1 = img_me.getRGB(i,j);
    			int rgb2 = img_him.getRGB(i,j);
    			
    			if(!isOpaque(rgb1) && !isOpaque(rgb2))
    				return true; //wenn ein Pixel gefunden wurde, der auf beiden Teilbildern nicht transparent ist
    		}
    	}
    	return false;
    }
```


```
for(Sprite token:shots) {
        	token.doLogic(delta);
        	for (Sprite sprite:enemies) {
        		if(sprite.checkCollision(token)) {
        			token.setRemove();
        			sprite.setRemove();
        		}
        	}
        }
```


----------



## Hansdampf (11. Mai 2010)

Du musst über min(img_me.width,img_him.width) und min(img_me.height,img_him.height) loopen.
Oder so ähnlich, auf jeden Fall liegt hier der Fehler.

edit: Ich glaube, ich habe teilweise Blödsinn geschrieben.


----------



## Quaxli (11. Mai 2010)

Das kann man an der Ecke nicht genau sagen, da wirst Du wohl ein bißchen debuggen müssen.
Was mir aber aufgefallen ist:


```
BufferedImage img_me = pics[currentpic].getSubimage((int) sub_me.x, (int) sub_me.y, (int) sub_me.width, (int) sub_me.height);
        BufferedImage img_him = pics[currentpic].getSubimage((int) sub_him.x, (int) sub_him.y, (int) sub_him.width, (int) sub_him.height);
```

Du liest für das aktuelle Sprite und den "Kollisions-Gegner" beides mal das Bild des aktuellen Sprites aus. Solange das bei beiden gleich ist, hast Du an der Ecke vielleicht kein Problem, grundsätzlich ist das aber falsch.
Ich könnte mir aber vorstellen, daß das sogar die Ursache für Deinen Fehler ist?


----------



## baddestpoet (12. Mai 2010)

Oh ja, das hab ich übersehen. Aber ich bekomm immer noch die gleiche Fehlermeldung.

@Hansdampf: die Dimensionen der Schnittmenge müssten doch von beiden Teilbildern gleich sein, da macht es glaub ich keinen Unterschied ob ich img_me oder img_him nehme.

Der Fehler tritt übrigens schon in der Zeile

```
BufferedImage img_me = pics[currentpic].getSubimage((int) sub_me.x, (int) sub_me.y, (int) sub_me.width, (int) sub_me.height);
```
 auf, da kommt die Schleife ja noch gar nicht zum Tragen...


----------



## Steev (12. Mai 2010)

Normalerweise müsste einer der Sub-Image-Werte auserhalb des Rasters des Bildes sein, von dem du das Sub-Image erzeugen willst.
Lass dir doch mal die Bounds von dem pics[currntpic] sowie sub_me.x, y, width und height ausgeben. Irgendwas stimmt da nicht...

Gruß
Steev


----------

