Typo boy
Typo boy

Reputation: 85

JavaFX - Interaction between circle and rectangle

I want to know how I can make an interaction when rectangle collapses with a circle . Like some kind of action that happens when circle and rectangle collapses. There is also a problem that circle can go out of frame, which I don't know how to limit it's movement. I'm not even sure if it's possible to do what I want this way.This is supposed to be a game where I need to dodge all rectangles and this is best I could do. Thanks it advance :)

       public class Java2 extends Application {

       public static final int KRUG_WIDTH = 10; 
       public static final int PANEL_WIDTH = 600;
       public static final int PANEL_HEIGHT = 600;

       private int mX = (PANEL_WIDTH - KRUG_WIDTH) / 2;
       private int mY = (PANEL_HEIGHT - KRUG_WIDTH) / 2;
       Random ran = new Random();

        @Override
        public void start(Stage primaryStage) {




            Rectangle rekt = new Rectangle(20, 20);
            Rectangle rekt1 = new Rectangle(20, 20);


            Circle r1 = new Circle(mX,mY,KRUG_WIDTH);  

            Pane root = new Pane(); //PANE

            r1.setFill(Color.WHITE);
            r1.setStroke(Color.BLACK);

            root.getChildren().add(r1);
            root.getChildren().add(rekt);
            root.getChildren().add(rekt1);

            Scene scene = new Scene(root, PANEL_WIDTH, PANEL_HEIGHT);





    PathTransition pathTransition = new PathTransition();
    Path path = new Path();



    //REKT-PATH
    pathTransition.setDuration(javafx.util.Duration.millis(600));
    pathTransition.setPath(path);
    pathTransition.setNode(rekt);
    pathTransition.setOrientation(PathTransition.OrientationType.ORTHOGONAL_TO_TANGENT);
    pathTransition.setCycleCount(2);
    pathTransition.setAutoReverse(true);
            pathTransition.setOnFinished(e -> {

                pathTransition.setPath(createPath());
                pathTransition.play();

            });
    pathTransition.play();




    PathTransition pathTransition1 = new PathTransition();
    Path path1 = new Path();



    //REKT1-PATH
    pathTransition1.setDuration(javafx.util.Duration.millis(550));
    pathTransition1.setPath(path1);
    pathTransition1.setNode(rekt1);
    pathTransition1.setOrientation(
PathTransition.OrientationType.ORTHOGONAL_TO_TANGENT);
    pathTransition1.setCycleCount(Timeline.INDEFINITE);
    pathTransition1.setAutoReverse(true);
            pathTransition1.setOnFinished(e -> {

                pathTransition1.setPath(createPath());
                pathTransition1.play();

            });
    pathTransition1.play();





    r1.setOnKeyPressed(e -> {
               switch (e.getCode()) {
                     case DOWN: r1.setCenterY(r1.getCenterY()+ 10);
                            break;
                     case UP: r1.setCenterY(r1.getCenterY()- 10);
                            break;
                     case LEFT: r1.setCenterX(r1.getCenterX() - 10);
                            break;
                     case RIGHT: r1.setCenterX(r1.getCenterX() + 10);
                            break;
                     case SPACE: 
                         break;

                     default:

               }
             });




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


    private Path createPath() {
            int loc2 = ran.nextInt(600 - 300 + 1) + 300;
            int loc = ran.nextInt(600 - 20 + 1) + 20; 

            Path path = new Path();

            path.getElements().add(new MoveTo(20, 20));
            path.getElements().add(new LineTo(loc, loc2));

            return path;

        }
        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) {
            launch(args);
        }

    }

Upvotes: 1

Views: 1335

Answers (1)

Roland
Roland

Reputation: 18415

Your approach isn't one I would take. Usually you have a timer as a game loop in which all the magic is happening, i. e. move sprites, check collision, update sprites in the UI. In JavaFX this would be an AnimationTimer.

In your code you miss several important things, among them the keyboard or mouse input. Or how you check the collision. There is e. g. an intersects method for the nodes, but that checks only the rectangular bounds of a node. You however have a circle, which makes matters more complex. However, if performance isn't an issue for your game, you could use the Shape's intersect method to create a new shape out of Rectangle and Circle and depending on the result decide whether you have a collision or not.

Some time ago I created example code about how to move sprites on the screen and check if they collide with others.

Regarding bouncing off the scene bounds in that code you simply check the scene bounds and change the movement delta to a bouncing value, i. e. if the sprite moves from left to right (dx is positive) and is at the right side, you set the delta dx to a negative value so that it moves in the opposite direction.

You can also take a look at a simple Pong game which uses a slightly modified version of that engine.


Example for shape intersection with your code:

Shape shape = Shape.intersect(rekt, r1);
boolean intersects = shape.getBoundsInLocal().getWidth() != -1; 
if( intersects) {
  System.out.println( "Collision");
}   

That alone raises the question where you'd put the check. Normally you'd have to perform it when anything moves, i. e. in both path transitions like this

pathTransition.currentTimeProperty().addListener( e -> {
...
});

and in the circle transition. That would be 2 checks too many.

Upvotes: 2

Related Questions