Genauer Intersection Check

Hey!

Ich arbeite wieder an einem neuen Spiel (ManaWarII) :slight_smile:

Hier ein paar Screenshots der neuen Figuren:

Diesesmal versuche ich mich an JavaFX (Wieso JavaFX? Ganz einfach: Da JavaFX eine aktuellere Audio API und viele hilfreiche Funktionen enthält).
Ich bin gerade bei der Erstellung der ersten Entities aber bin auf ein kleines Problem gestoßen.
Also: Ich möchte verschiedene Spieler und Feinde Objekte erstellen, die jeweils eine bestimmte Animation/ein bestimmtes Bild anzeigen.

Im Moment erweitert meine Entity Klasse „Rectangle“:




import javafx.scene.shape.Rectangle;

import org.black_ixx.manawar.MWApplication;

public class IEntity extends Rectangle{
	
	public static int ID = 0;
	
	private final int id;
	private final MWApplication app;
	
	
	private boolean remove = false;
	
	public IEntity(MWApplication app){
		IEntity.ID++;
		this.id=IEntity.ID;
		this.app=app;
	}
	
	
	public void setRemove(boolean b){
		this.remove=b;
	}
	
	
	public int getID(){
		return id;
	}
	
	public MWApplication getApp(){
		return app;
	}
	
	public boolean isRemove(){
		return remove;
	}
	
	

}

package org.black_ixx.manawar.entities;

import java.awt.image.BufferedImage;

public class IEntityDrawable extends IEntity{
	
	
	private BufferedImage[] pics;	
	
	private int currentpic = 0;
	
	
	public IEntityDrawable(BufferedImage[] pics){
		super();
		this.pics=pics;
		
		setWidth(pics[0].getWidth());
		setHeight(pics[0].getHeight());
		
		
		
	}
	
	
	
	
	
	

	public boolean checkOpaqueColorCollisions(IEntityDrawable s){
		
		if(!s.isVisible()||!this.isVisible() || this == s){
			return false;
		}
		
		if(!s.intersects(this.getBoundsInLocal())){
			return false;
		}//TODO: Vlt bald nur noch cut benutzen und direkt checken ob valid

		
		
		return false;

	}


}



Ich kann zwar schon prüfen ob sich zwei Rectangles überlappen, aber ich möchte eine genauere Prüfung: Ich möchte jeden Pixel der Objekte prüfen und nur Kollisionen zählen, bei denen sich farbige Pixel überlappen.
Dafür fehlen mir aber noch die JavaFX Basics…

Ich habe eine halbe Stunde lang überlegt, was ich hier in diesem Beitrag für Versuche hereinschreiben könnte aber da keiner meiner Tests geklappt hat lasse ich es lieber.

  1. Frage:
    Kann das Ganze mit einer Erweiterung der „Rectangle“ Klasse überhaupt funktionieren? (Ich habe sie mir ausgesucht da 1. Bilder auch Quader sind und 2. Die Rectangle Klasse mehrere Methoden wie zb. r.setX(x) bereitstellt)

  2. Frage:
    Habt ihr irgendwelchen Ideen oder Erfahrungen bezogen auf den Pixelcheck?

  3. Frage:
    Wie kann ich am besten die Game-Objekte zeichnen? Gibt es irgendwelchen Paint Methoden die ich überschreiben kann, oder muss ich ständig manuell alle Bilder zeichnen?

Danke! :slight_smile:

Ich würde die Hitbox einfach aus mehreren Rectangles zusammenfügen, z.B. 1 für den Körper, 2 für die Arme, 2 für die Beine, 1 für den Kopf. Aber warum brauchst du es denn überhaupt so genau?
Ich finde deine Figuren passen auch alle ganz gut in ein Rectangle. Und zur Not machst du die Hitbox eher etwas kleiner, das fällt einem weniger auf als wenn sie zu groß ist.^^

Mit JavaFX hab ich zwar selbst keine Erfahrung (die TODO Liste, jaja …), aber Quaxli beschreibt in seinem Tutorial ( http://forum.byte-welt.net/threads/5049-Quaxli-s-Spiele-Tutorial ) Pixelgenaue Kollision - dort für Swing mit BufferedImage, aber mit einem JavaFX-Image und seinem PixelReader sollte man an die relevanten Infos drankommen.

Trotzdem ist Benes Einwand gerechtfertigt: So ein Pixelgenauer Test kann (wenn man “naiv” drangeht) recht aufwändig sein. Natürlich würde man den Bounding-Rectangle-Test erstmal vorher machen, um schnell die meisten Kollisionen auszuschließen. Aber je nachdem, wie das Bild aufgebaut ist (speziell Größe, und natürlich die Form des Kollisionsrelevanten Bereiches) könnte es sinnvoll sein, dort nochmal eine zweite Ebene an Rechtecks-Abfragen einzuziehen.

[QUOTE=Bene]Ich würde die Hitbox einfach aus mehreren Rectangles zusammenfügen, z.B. 1 für den Körper, 2 für die Arme, 2 für die Beine, 1 für den Kopf. Aber warum brauchst du es denn überhaupt so genau?
Ich finde deine Figuren passen auch alle ganz gut in ein Rectangle. Und zur Not machst du die Hitbox eher etwas kleiner, das fällt einem weniger auf als wenn sie zu groß ist.^^[/QUOTE]

Danke für die Antwort :slight_smile:

Ich finde Hitboxen klingen doch schon ganz gut, aber ich sehe zwei kleine Probleme…

  1. Bewegen die Figuren ihre Arme (Teilweise sehr extrem zb. wenn sie gerade jemanden angreifen) dh. ich müsste die Hitboxen jedesmal an die Armbewegung anpassen
  2. Werde ich auch verschiedene Skills einbauen wie zb. eine Axt die herumfliegt und sich dreht. Da kann es schon mal öfters vorkommen, dass die Axt einen nicht erwischt weil sie sich im richtigen Moment „wegdreht“. Bei der alten Version des hatte ich auch Quaxlis Pixel Methode angewandt und es hat sehr gut funktioniert. Davor, ohne den genauen Check, hat das Spiel ziemlich verbuggt gewirkt :confused:

[QUOTE=Marco13;86451]Mit JavaFX hab ich zwar selbst keine Erfahrung (die TODO Liste, jaja …), aber Quaxli beschreibt in seinem Tutorial ( http://forum.byte-welt.net/threads/5049-Quaxli-s-Spiele-Tutorial ) Pixelgenaue Kollision - dort für Swing mit BufferedImage, aber mit einem JavaFX-Image und seinem PixelReader sollte man an die relevanten Infos drankommen.

Trotzdem ist Benes Einwand gerechtfertigt: So ein Pixelgenauer Test kann (wenn man „naiv“ drangeht) recht aufwändig sein. Natürlich würde man den Bounding-Rectangle-Test erstmal vorher machen, um schnell die meisten Kollisionen auszuschließen. Aber je nachdem, wie das Bild aufgebaut ist (speziell Größe, und natürlich die Form des Kollisionsrelevanten Bereiches) könnte es sinnvoll sein, dort nochmal eine zweite Ebene an Rechtecks-Abfragen einzuziehen.[/QUOTE]

Quaxlis Tutorial habe ich auch schon hinter mir aber ich komme einfach nicht darauf, wie ich herausfinden kann, an welchen Stellen sich zwei Objekte überlappen…

Mit „Shape i = Shape.intersect(s, this);“ bekomme ich zwar eine neue Form bestehend aus den Punkten der alten Formen die sich überschneiden, aber das Ganze ist (soweit ich weiß) nicht auf die aktuellen Koordinaten der Flächen bezogen.
Was ich damit meine:

(Korrigiert mich bitte wenn ich falsch liege ;-))

Eine Klasse „Rectangle2D“ würde es auch geben, aber diese Klasse bietet noch weniger Funktionen an (Sie lässt sich nichtmal an bestimmte Koordinaten setzen).

Gibt es vielleicht irgendeinen anderen Weg zu den Pixel zu kommen, die sich überschneiden, damit man diese dann prüfen kann?

verwirrt inwieweit hängen denn der Shape#intersects-Test und der Pixeltest zusammen? Den Shape-Test würde man ja so nicht machen - nur erstmal einen Rectangle-Test, und nur FALLS sich die Rectangles überschneiden, macht man den Pixel-Test.

Meine Idee war folgende:

Zuerst wird geprüft ob sich die zwei Rectangles überlappen.
Ist das der Fall wird der Code fortgesetzt.
Nun möchte ich prüfen, welche Pixel der beiden Objekte sich überlappen, und diese Pixel will ich dann nach Transparenz überprüfen.

Also:


methode(IEntity s){    //Findet in der iEntity Klasse statt. Dh. this = iEntity

if(!Rectangles überschneiden sich){
return false;
}

//Hier möchte ich nun herausfinden welche Pixel der Objekte sich überschneiden
//Bei Quaxli mit AWT sieht das so aus:
//	Rectangle2D.Double cut = (Double) this.createIntersection(s);
//		Rectangle2D.Double sub_me = getSubRec(this, cut);
//		Rectangle2D.Double sub_him = getSubRec(s, cut);
//Und anschließend möchte ich die einzelnen Pixel der Bilder vergleichen



}```


Ich kann zwar ganz einfach jeden Pixel der Bilder überprüfen, aber das Problem ist, dass nur ein paar Pixel sich überschneiden. Und genau was DIESE PIXEL sind möchte ich irgendwie herausfinden.


Wegen dem "Shape-test":

Das war ein Versuch, mit dem ich herausfinden wollte, welche Pixel sich momentan überschneiden.

Hmja, nochmal: Im Moment rede ich ein bißchen in den Luftleeren Raum, aber: Soweit ich das gesehen habe, kann man sich vom Image ja diesen PixelReader abholen, und bei dem einzelne Pixel überprüfen. Oder geht es jetzt gerade darum, wie man den Bereich ausrechnet, WO sie sich überschneiden?

Es geht darum, wie man herausfindet, WO sich die Pixel überschneiden. Genau :slight_smile:

Also, dann mal mangels JavaFX munter aus dem Bauch raus geraten - alles unter dem starken (!) vorbehalt, dass ich nicht sicher bin, wie die Tatsache, dass dort alles “Nodes” eines Szenegraphen sind, diesen Test beeinflusst: Die Objekte haben jeweils “Bounds” - also ein Rechteck, das ihre Position und Größe beschreibt. Vermutlich muss man sich die “local bounds” beider Objekte abholen und sie mit Node#localToScene in ein gemeinsames Koordinatensystem transformieren. Dort kann man testen, ob sie sich überschneiden mit boundsA.intersects(boundsB). FALLS sie sich überschneiden, muss man den Überschneidungsbereich bestimmten. Auf die Schnelle hab’ ich da keine Methode dafür gesehen, gibt’s aber vermutlich (wenn nicht, ist es auch nicht so schwer, die selbst zu schreiben). Dieser Überschneidungsbereich (wieder ein Bounds) muss dann vermutlich mit Node#sceneToLocal wieder zurück ins lokale Koordinatensystem geholt werden - jeweils für jeden der beiden Knoten. Dann sollte dieser (ins lokale Koordinatensystem der Knoten transformierte) Überschneidungsbereich jeweils genau dem Bereich des “Images” entsprechen, das im jeweiligen Knoten das Image des jeweils anderen Knotens schneidet. Und die Pixel, die in diesem Bildbereich liegen, kann man dann überprüfen, so wie es bei Quaxli auch gemacht wird.
Alles ohne Gewähr. Aber vielleicht teste ich es bei Gelegenheit mal. Wollte schon ewig mal "irgend"was mit JavaFX machen. Aber man kommt ja zu nix…

Das folgende Beispiel ist zwar weit weg vom Optimum verdeutlicht aber die Vorgehensweise:

  • Intersection-Test zwischen den beiden Raumschiffen
  • Wenn erfolgreich: überlappender Bereich berechnen
  • jeweils Snapshots der Nodes im überlappender Bereich erstellen
  • Pixel für Pixel auf Transperenz testen

Ich hab im Beispiel mit den BoundsInParent gearbeitet um relativ simple den Scale-Effekt einzubauen.

Pfeiltasten zum bewegen, NUM+/- zum vergrößern des Raumschiffs
Der Code läuft mit Java 8.

import javafx.geometry.Bounds;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.SnapshotParameters;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Border;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.BorderStroke;
import javafx.scene.layout.BorderStrokeStyle;
import javafx.scene.layout.BorderWidths;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.Pane;
import javafx.scene.layout.TilePane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

/**
 *
 * @author Melfis
 */
public class Collosion extends Application {

    @Override
    public void start(Stage primaryStage) {
        Image img_spaceship = new Image("http://staff.unak.is/andy/gameprogramming0910/bitMapGame/spaceship.png");
        ImageView imgView_1 = new ImageView(img_spaceship);
        ImageView imgView_2 = new ImageView(img_spaceship);
        imgView_2.setX(50);
        imgView_2.setY(100);

        ImageView imgV_intersect_1 = new ImageView();
        ImageView imgV_intersect_2 = new ImageView();     
        
        Circle int_point = new Circle(3, Color.TRANSPARENT);
        int_point.setStroke(Color.RED);
        int_point.setVisible(false);

        BorderPane root = new BorderPane();
        
        Pane pane = new Pane();
        pane.setBorder(new Border(new BorderStroke(Color.GREEN, BorderStrokeStyle.SOLID, new CornerRadii(1), new BorderWidths(2))));
        pane.setPrefSize(200, 200);
        pane.setOnMouseClicked((MouseEvent me) -> {
            pane.requestFocus();
        });
        Rectangle clip=new Rectangle();
        clip.heightProperty().bind(pane.heightProperty());
        clip.widthProperty().bind(pane.widthProperty());
        pane.setClip(clip);
        pane.getChildren().addAll(imgView_1, imgView_2, int_point);
        pane.focusTraversableProperty().set(true);
        
        VBox vb = new VBox();
        
        Label lb_irec = new Label("Intersect Rec:");
        Label lb_irec_result = new Label("-");
        Label lb_ipx = new Label("Intersect Pixel:");
        Label lb_ipx_result = new Label("-");
        
        TilePane tp=new TilePane();
        tp.setPrefTileHeight(40);
        tp.setPrefTileWidth(40);
        tp.getChildren().addAll(imgV_intersect_1, imgV_intersect_2);
        
        vb.getChildren().addAll(lb_irec, lb_irec_result, lb_ipx, lb_ipx_result, tp);

        pane.addEventHandler(KeyEvent.KEY_PRESSED, (KeyEvent ke) -> {
            double speed = 5.0;
            double scalerate = 1.1;
            double scale = imgView_1.getScaleX();
            double x = imgView_1.getX();
            double y = imgView_1.getY();
            if (ke.getCode() == KeyCode.UP) y -= speed;
            if (ke.getCode() == KeyCode.DOWN) y += speed;
            if (ke.getCode() == KeyCode.LEFT) x -= speed;
            if (ke.getCode() == KeyCode.RIGHT) x += speed;
            if (ke.getCode() == KeyCode.ADD) scale *= scalerate;
            if (ke.getCode() == KeyCode.SUBTRACT) scale /= scalerate;

            imgView_1.setX(x);
            imgView_1.setY(y);
            imgView_1.setScaleX(scale);
            imgView_1.setScaleY(scale);
            imgView_1.setScaleZ(scale);
            Bounds b1 = imgView_1.getBoundsInParent();
            Bounds b2 = imgView_2.getBoundsInParent();

            boolean px_intersection = false;
            boolean rec_intersection = b1.intersects(b2);
            WritableImage intersect_img1 = null;
            WritableImage intersect_img2 = null;

            if (rec_intersection) {
                //Überlappender Bereich
                double min_x = b1.getMinX() > b2.getMinX() ? b1.getMinX() : b2.getMinX();
                double max_x = b1.getMaxX() < b2.getMaxX() ? b1.getMaxX() : b2.getMaxX();
                double min_y = b1.getMinY() > b2.getMinY() ? b1.getMinY() : b2.getMinY();
                double max_y = b1.getMaxY() < b2.getMaxY() ? b1.getMaxY() : b2.getMaxY();
                
                //Snapshot der beiden Nodes
                SnapshotParameters ssp = new SnapshotParameters();
                ssp.setFill(Color.TRANSPARENT);
                Rectangle2D rec_clip=new Rectangle2D(min_x, min_y, max_x - min_x, max_y - min_y);
                ssp.setViewport(rec_clip);
                intersect_img1 = imgView_1.snapshot(ssp, null);
                intersect_img2 = imgView_2.snapshot(ssp, null);
                

                //Test der Transperenz
                for (int j = 0; j < intersect_img1.getHeight(); j++) {
                    for (int i = 0; i < intersect_img1.getWidth(); i++) {
                        Color col_1 = intersect_img1.getPixelReader().getColor(i, j);
                        Color col_2 = intersect_img2.getPixelReader().getColor(i, j);
                        if (col_1.getOpacity() > 0.1 && col_2.getOpacity() > 0.1) {
                            px_intersection = true;
                            int_point.setCenterX(min_x + i);
                            int_point.setCenterY(min_y + j);
                            break;
                        }
                    }
                    if(px_intersection)break;
                }
            }
            int_point.setVisible(px_intersection);
            lb_irec_result.setText("" + rec_intersection);
            lb_ipx_result.setText("" + px_intersection);
            imgV_intersect_1.setImage(intersect_img1);
            imgV_intersect_2.setImage(intersect_img2);
        });

        root.setBottom(vb);
        root.setCenter(pane);
        Scene scene = new Scene(root, 300, 300);

        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }


    public static void main(String[] args) {
        launch(args);
    }

}

[QUOTE=Marco13]Also, dann mal mangels JavaFX munter aus dem Bauch raus geraten - alles unter dem starken (!) vorbehalt, dass ich nicht sicher bin, wie die Tatsache, dass dort alles „Nodes“ eines Szenegraphen sind, diesen Test beeinflusst: Die Objekte haben jeweils „Bounds“ - also ein Rechteck, das ihre Position und Größe beschreibt. Vermutlich muss man sich die „local bounds“ beider Objekte abholen und sie mit Node#localToScene in ein gemeinsames Koordinatensystem transformieren. Dort kann man testen, ob sie sich überschneiden mit boundsA.intersects(boundsB). FALLS sie sich überschneiden, muss man den Überschneidungsbereich bestimmten. Auf die Schnelle hab’ ich da keine Methode dafür gesehen, gibt’s aber vermutlich (wenn nicht, ist es auch nicht so schwer, die selbst zu schreiben). Dieser Überschneidungsbereich (wieder ein Bounds) muss dann vermutlich mit Node#sceneToLocal wieder zurück ins lokale Koordinatensystem geholt werden - jeweils für jeden der beiden Knoten. Dann sollte dieser (ins lokale Koordinatensystem der Knoten transformierte) Überschneidungsbereich jeweils genau dem Bereich des „Images“ entsprechen, das im jeweiligen Knoten das Image des jeweils anderen Knotens schneidet. Und die Pixel, die in diesem Bildbereich liegen, kann man dann überprüfen, so wie es bei Quaxli auch gemacht wird.
Alles ohne Gewähr. Aber vielleicht teste ich es bei Gelegenheit mal. Wollte schon ewig mal "irgend"was mit JavaFX machen. Aber man kommt ja zu nix…[/QUOTE]

Klingt ziemlich rechenintensiv… Wenn ich sonst keine bessere Lösung finde werde ich das mal ausprobieren! Danke :slight_smile:

[QUOTE=Melfis;86693]Das folgende Beispiel ist zwar weit weg vom Optimum verdeutlicht aber die Vorgehensweise:

  • Intersection-Test zwischen den beiden Raumschiffen
  • Wenn erfolgreich: überlappender Bereich berechnen
  • jeweils Snapshots der Nodes im überlappender Bereich erstellen
  • Pixel für Pixel auf Transperenz testen

Ich hab im Beispiel mit den BoundsInParent gearbeitet um relativ simple den Scale-Effekt einzubauen.

Pfeiltasten zum bewegen, NUM+/- zum vergrößern des Raumschiffs
Der Code läuft mit Java 8.

import javafx.geometry.Bounds;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.SnapshotParameters;
import javafx.scene.control.Label;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Border;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.BorderStroke;
import javafx.scene.layout.BorderStrokeStyle;
import javafx.scene.layout.BorderWidths;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.Pane;
import javafx.scene.layout.TilePane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

/**
 *
 * @author Melfis
 */
public class Collosion extends Application {

    @Override
    public void start(Stage primaryStage) {
        Image img_spaceship = new Image("http://staff.unak.is/andy/gameprogramming0910/bitMapGame/spaceship.png");
        ImageView imgView_1 = new ImageView(img_spaceship);
        ImageView imgView_2 = new ImageView(img_spaceship);
        imgView_2.setX(50);
        imgView_2.setY(100);

        ImageView imgV_intersect_1 = new ImageView();
        ImageView imgV_intersect_2 = new ImageView();     
        
        Circle int_point = new Circle(3, Color.TRANSPARENT);
        int_point.setStroke(Color.RED);
        int_point.setVisible(false);

        BorderPane root = new BorderPane();
        
        Pane pane = new Pane();
        pane.setBorder(new Border(new BorderStroke(Color.GREEN, BorderStrokeStyle.SOLID, new CornerRadii(1), new BorderWidths(2))));
        pane.setPrefSize(200, 200);
        pane.setOnMouseClicked((MouseEvent me) -> {
            pane.requestFocus();
        });
        Rectangle clip=new Rectangle();
        clip.heightProperty().bind(pane.heightProperty());
        clip.widthProperty().bind(pane.widthProperty());
        pane.setClip(clip);
        pane.getChildren().addAll(imgView_1, imgView_2, int_point);
        pane.focusTraversableProperty().set(true);
        
        VBox vb = new VBox();
        
        Label lb_irec = new Label("Intersect Rec:");
        Label lb_irec_result = new Label("-");
        Label lb_ipx = new Label("Intersect Pixel:");
        Label lb_ipx_result = new Label("-");
        
        TilePane tp=new TilePane();
        tp.setPrefTileHeight(40);
        tp.setPrefTileWidth(40);
        tp.getChildren().addAll(imgV_intersect_1, imgV_intersect_2);
        
        vb.getChildren().addAll(lb_irec, lb_irec_result, lb_ipx, lb_ipx_result, tp);

        pane.addEventHandler(KeyEvent.KEY_PRESSED, (KeyEvent ke) -> {
            double speed = 5.0;
            double scalerate = 1.1;
            double scale = imgView_1.getScaleX();
            double x = imgView_1.getX();
            double y = imgView_1.getY();
            if (ke.getCode() == KeyCode.UP) y -= speed;
            if (ke.getCode() == KeyCode.DOWN) y += speed;
            if (ke.getCode() == KeyCode.LEFT) x -= speed;
            if (ke.getCode() == KeyCode.RIGHT) x += speed;
            if (ke.getCode() == KeyCode.ADD) scale *= scalerate;
            if (ke.getCode() == KeyCode.SUBTRACT) scale /= scalerate;

            imgView_1.setX(x);
            imgView_1.setY(y);
            imgView_1.setScaleX(scale);
            imgView_1.setScaleY(scale);
            imgView_1.setScaleZ(scale);
            Bounds b1 = imgView_1.getBoundsInParent();
            Bounds b2 = imgView_2.getBoundsInParent();

            boolean px_intersection = false;
            boolean rec_intersection = b1.intersects(b2);
            WritableImage intersect_img1 = null;
            WritableImage intersect_img2 = null;

            if (rec_intersection) {
                //Überlappender Bereich
                double min_x = b1.getMinX() > b2.getMinX() ? b1.getMinX() : b2.getMinX();
                double max_x = b1.getMaxX() < b2.getMaxX() ? b1.getMaxX() : b2.getMaxX();
                double min_y = b1.getMinY() > b2.getMinY() ? b1.getMinY() : b2.getMinY();
                double max_y = b1.getMaxY() < b2.getMaxY() ? b1.getMaxY() : b2.getMaxY();
                
                //Snapshot der beiden Nodes
                SnapshotParameters ssp = new SnapshotParameters();
                ssp.setFill(Color.TRANSPARENT);
                Rectangle2D rec_clip=new Rectangle2D(min_x, min_y, max_x - min_x, max_y - min_y);
                ssp.setViewport(rec_clip);
                intersect_img1 = imgView_1.snapshot(ssp, null);
                intersect_img2 = imgView_2.snapshot(ssp, null);
                

                //Test der Transperenz
                for (int j = 0; j < intersect_img1.getHeight(); j++) {
                    for (int i = 0; i < intersect_img1.getWidth(); i++) {
                        Color col_1 = intersect_img1.getPixelReader().getColor(i, j);
                        Color col_2 = intersect_img2.getPixelReader().getColor(i, j);
                        if (col_1.getOpacity() > 0.1 && col_2.getOpacity() > 0.1) {
                            px_intersection = true;
                            int_point.setCenterX(min_x + i);
                            int_point.setCenterY(min_y + j);
                            break;
                        }
                    }
                    if(px_intersection)break;
                }
            }
            int_point.setVisible(px_intersection);
            lb_irec_result.setText("" + rec_intersection);
            lb_ipx_result.setText("" + px_intersection);
            imgV_intersect_1.setImage(intersect_img1);
            imgV_intersect_2.setImage(intersect_img2);
        });

        root.setBottom(vb);
        root.setCenter(pane);
        Scene scene = new Scene(root, 300, 300);

        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }


    public static void main(String[] args) {
        launch(args);
    }

}
```[/QUOTE]



Sieht sehr hilfreich aus :) Vielen vielen Dank! 
Habe nach deinem Vorbild eine Kollisionscheck Methode erstellt, aber noch nicht getestet. Nochmals: Vielen Dank :D





Im Moment bin ich wirklich am Zweifeln... bringt es JavaFX wirklich?
Eine Menge der wichtigen Methoden von AWT/SWING fehlen einfach... Das meiste konnte ich zwar - wenn auch mit viel Arbeit - ersetzen aber ich frage mich ernsthaft ob sich das Ganze überhaupt lohnt...
Was mir zum Beispiel gerade Schwierigkeiten bereitet: Die Erstellung von "Subimages" aus einem Bild. Dafür gibt es (Zumindest habe ich noch keine entdeckt) einfach keine einfachen direkten Methoden!
Ich glaube ich höre wieder mit JavaFX auf... dafür aber noch eine Frage: Lassen sich JavaFX Elemente in ein Projekt mit AWT/Swing einbauen ohne große Performance Probleme zu bereiten?
Ich hatte hauptsächlich aufgrund der modernen Audio API mit JavaFX angefangen, und die würde ich gerne weiterhin irgendwie benutzen.

booohk-bok-bok-bok-boooohk-bok (Das soll das gackernde Geräusch eines „feigen Huhns“ sein :smiley: ). Warum denn gleich aufgeben?

Wofür brauchst du denn das Subimage? Beim BufferedImage war die „getSubImage“-Methode zumindest immer eine gute Möglichkeit, sich die Zeichenperformance kaputt zu machen. Für den Pixeltest braucht man ja … ja, nur eine Menge von Pixeln, und die sind ja in bezug auf das Gesamtbild nur ein Stück verschoben, und man kann sich den benötigten Bereich ja mit dem PixelReader direkt in einen Buffer schieben lassen.

Unabhängig davon: Den Audio-Teil sollte man ja eigentlich komplett unabhängig vom Grafik-Teil nutzen können. Aber jetzt hast du mich doch neugierig gemacht. Das, was mit http://docs.oracle.com/javafx/2/api/javafx/scene/effect/Effect.html alles möglich ist, mit Swing nachzubauen wäre doch ein Krampf (und ich glaube, dass man mit einigem davon so ein Spiel schon gewaltig aufpeppen könnte …)

[QUOTE=Marco13]booohk-bok-bok-bok-boooohk-bok (Das soll das gackernde Geräusch eines „feigen Huhns“ sein :smiley: ). Warum denn gleich aufgeben?

Wofür brauchst du denn das Subimage? Beim BufferedImage war die „getSubImage“-Methode zumindest immer eine gute Möglichkeit, sich die Zeichenperformance kaputt zu machen. Für den Pixeltest braucht man ja … ja, nur eine Menge von Pixeln, und die sind ja in bezug auf das Gesamtbild nur ein Stück verschoben, und man kann sich den benötigten Bereich ja mit dem PixelReader direkt in einen Buffer schieben lassen.

Unabhängig davon: Den Audio-Teil sollte man ja eigentlich komplett unabhängig vom Grafik-Teil nutzen können. Aber jetzt hast du mich doch neugierig gemacht. Das, was mit http://docs.oracle.com/javafx/2/api/javafx/scene/effect/Effect.html alles möglich ist, mit Swing nachzubauen wäre doch ein Krampf (und ich glaube, dass man mit einigem davon so ein Spiel schon gewaltig aufpeppen könnte …)[/QUOTE]

Mein Kampfgeist sagt mir eigentlich auch dass ich es noch weiter versuchen sollte…

Ich brauche Subimages, um aus Skins die Sprites zu generieren (Macht mein Programm im Moment mit AWT. Wird immer nur am Anfang vom Spiel/Nach der Erstellung eines neuen Charakters ausgeführt). Dafür gibt es sicherlich auch einen (wahrscheinlich aufwendigen) Weg mit JavaFX, aber ich befürchte, dass ich ständig an so kleinen „fehlenden Methoden“ hängen werde und dadurch die ganze Entwicklung extrem langsamer wird.
Wenn ich mal bei AWT/Swing ein paar kleine Probleme habe google ich und finde nach wenigen Sekunden eine Lösung. Wenn ich bei JavaFX ein Problem habe dauert es teilweise ewig bis ich eine Lösung finde.

Entweder gibt es einen Weg die Audio-API von JavaFX unabhänging vom Rest zu nutzen, oder ich suche vielleicht einfach nochmal nach einer guten Audio Libary.
Klar: JavaFX bietet mehrere ziemlich hilfreiche Methoden an und hat einen guten (meiner Meinung nach) Grundgedanken. Den Aufbau von Scenes und Stages zum Beispiel finde ich genial. Leider ruiniert die Tatsache, dass wichtige Methoden fehlen, das Ganze (wieder meine persönliche Meinung :P).

Die beste Libary nützt nichts wenn man die Api nicht aufmerksam liest :stuck_out_tongue_winking_eye:

http://docs.oracle.com/javafx/2/api/javafx/scene/image/ImageView.html

// displays it rotated
ImageView iv3 = new ImageView();
iv3.setImage(image);
Rectangle2D viewportRect = new Rectangle2D(40, 35, 110, 110);
iv3.setViewport(viewportRect);
iv3.setRotate(90);```

Was fehlt dir den?

Ich glaube, dieser “Viewport” ist nur auf das Rendering (d.h. das Anzeigen) der Bilder bezogen. Für diese Kollisionserkennung war wohl etwas gesucht, was einem Zugriff auf die Pixel (!) in einem bestimmten Bereich des Bildes erlaubt - also sowas wie http://docs.oracle.com/javase/7/docs/api/java/awt/image/BufferedImage.html#getSubimage(int,%20int,%20int,%20int) . Aber wie schon gesagt: Da rechnet man einfach einen X/Y-offset auf die Koordinaten, und dann sollte das ja schon reichen…