2

I am trying to check collision detection on the nodes which are inside StackPane. Below is my code:

public void start(Stage primaryStage) throws Exception {
    StackPane pane = new StackPane();
    Scene scene = new Scene(pane,300,300,Color.GREEN);
    primaryStage.setScene(scene);       
    primaryStage.show();

    Rectangle  rect1 = new Rectangle(50, 50);
    rect1.setFill(Color.BLUE);
    Rectangle rect2 = new Rectangle(50, 50);         

    pane.getChildren().add(rect1);
    pane.getChildren().add(rect2);

    TranslateTransition translateTransitionEnemyCar = new TranslateTransition();
    translateTransitionEnemyCar.setDuration(Duration.millis(2000));
    translateTransitionEnemyCar.setNode(rect2);
    translateTransitionEnemyCar.setFromY(-150);
    translateTransitionEnemyCar.setToY(150);
    translateTransitionEnemyCar.setAutoReverse(true);
    translateTransitionEnemyCar.setCycleCount(Timeline.INDEFINITE);
    translateTransitionEnemyCar.play();             
    checkCollision(pane,rect1,rect2);       
}

//Collision Detection
 void checkCollision(StackPane pane, final Rectangle rect1, Rectangle rect2){   

     rect2.boundsInParentProperty().addListener(new ChangeListener<Bounds>() {
        @Override
        public void changed(ObservableValue<? extends Bounds> arg0,Bounds oldValue, Bounds newValue) {
            if(rect1.intersects(newValue)){
                System.out.println("Collide ============= Collide");
            }
        }
    });
 }
}

Here the collision detection is working if I use AnchorPane. But with StackPane I am not able to achieve it. I guess it is because of the co-ordinate system of the stack pane (Correct me if I am wrong).

So please help me out to achieve collision detection of the above two rectangles. Also please provide some suggestion (if you know) to implement such collision detection on nodes inside StackPane if I want to change the the co-ordinate of the nodes.

Angom
  • 721
  • 1
  • 11
  • 27
  • possible duplicate of [Checking Collision of Shapes with JavaFX](http://stackoverflow.com/questions/15013913/checking-collision-of-shapes-with-javafx) – jewelsea Jan 29 '14 at 07:16
  • A StackPane is not an appropriate parent node to use for such tasks as its layout centers everything, instead place everything in a Group or a Pane and use the techniques in the linked possible duplicate answer. – jewelsea Jan 29 '14 at 07:19
  • I have already check that but I just want to try if this also can be implemented or not. :) – Angom Jan 29 '14 at 07:26

2 Answers2

6

In your test condition you compare the local bounds of one rectangle with the bounds in parent of the other rectangle. You want to compare the same bounds types.

So change:

rect1.intersects(newValue)

To:

rect1.getBoundsInParent().intersects(newValue)

To understand bounds types better, you might want to play with this intersection demo application.

jewelsea
  • 150,031
  • 14
  • 366
  • 406
  • One clarification, my code was working when I use AnchrPane. So it means bound in local and bound in parent of the rect1 was same in AnchorPane but they are different in StackPane. Am I right? – Angom Jan 29 '14 at 11:19
  • Ask a new question as a new question please Angom. – jewelsea Jan 29 '14 at 11:48
  • Asked a new question: http://stackoverflow.com/questions/21430787/how-does-bound-in-local-and-bound-in-parent-works-in-anchorpane-and-stackpane – Angom Jan 29 '14 at 12:13
1

Well in My experience, if creating an environment (collision space) a group should be used as opposed to a container..

I think in your situation the stackPane is the culprit.

plus I think your collision check should be more along the lines of this:

public void checkCollisions(){
    if(rect1.getBoundsInParent().intersects(rect2.getBoundsInParent)){
        Shape intersect = Shape.intersect(rect1, rect2);
        if(intersect.getBoundsInLocal().getWidth() != -1){
            // Collision handling here
            System.out.println("Collision occured");
        }
    }
}

Or you could do something more along these lines: in a class that extends "Node"

public boolean collided(Node other) {
    if(this.getBoundsInParent().intersects(other.getBoundsInParent())){
        Shape intersect = Shape.intersect(this.getShape(), other.getShape());
        if(intersect.getBoundsInLocal().getWidth() != -1){                
            System.out.println(this.getId() + " : " + other.getId());                 
            return true;
        }
    }        
    return false;        
}
public void checkCollisions(){
    for(Node n : root.getChildren().filtered(new Predicate(){
        @Override
        public boolean test(Object t) {
            //makes sure object does not collide with itself
            return !t.equals(this);
            // for shapes
            // return t instanceof Shape;  
        }
    }){
        if(collided(n)){
            // handle code here
        }
    }
}

well thats my 2 cents...

Another thing i just noticed is you are registering a new changeListener each time your check collision method is called without un-registering it.. that could lead to problems later imo...

jdub1581
  • 659
  • 5
  • 10