Jafafx: циклическое обнаружение столкновений и перемещение объектов - PullRequest
0 голосов
/ 15 октября 2018

Мне сложно сделать программный цикл moveBall и collisionDetection, чтобы программа всегда проверяла наличие столкновения и перемещала шары.

В данный момент программа просто проверяет наличие столкновенияво время первой итерации после этого он ничего не делает.

Идеальный сценарий - заставить шары всегда чувствовать, сталкиваются они или нет.

Я включил весь класс Ball и код для кнопки запуска.Я думал о том, чтобы сделать цикл while вокруг этой маленькой части кода, но мне так и не удалось заставить его работать.

            for (Ball b : balls) {
                    b.moveBall();
                    b.collisionDetection(balls);
                }

Помощь и предложения приветствуются!

Класс Ball

package fx;

import java.util.ArrayList;

import javax.print.attribute.standard.MediaSize.Other;

import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Shape;
import javafx.util.Duration;



public class Ball {

    public int id;
    public Circle circle;
    public int team;

    public Ball(int x, int y, int _id, int _team) {

        id = _id;

        Circle ball = new Circle(10, Color.BLACK);
        ball.relocate(x, y);
        circle = ball;

        team = _team;
    }

        public void moveBall() {
            System.out.println(this.team);
                //team blue
                if (this.team == 0) {
                    Timeline timeline = new Timeline(new KeyFrame(Duration.seconds(5),
                              new KeyValue(this.circle.layoutXProperty(), 
                                      980-((Circle)this.circle).getRadius())));

                    timeline.setAutoReverse(true);
                    timeline.setCycleCount(Timeline.INDEFINITE);
                    timeline.play();

                }//team orange
                else if (this.team == 1) {
                    Timeline timeline = new Timeline(new KeyFrame(Duration.seconds(5),
                              new KeyValue(this.circle.layoutXProperty(), 
                                      35-((Circle)this.circle).getRadius())));
                    timeline.setAutoReverse(true);
                    timeline.setCycleCount(Timeline.INDEFINITE);
                    timeline.play();
                }       
        }

    public Circle getCircle() {
        return this.circle;
    }

    //collision detection

    public void collisionDetection(ArrayList < Ball > balls) {
        boolean collisionDetected = false;
            for (Ball ball : balls) {
                System.out.println(ball.id + " vs " + this.id);
                if (ball.id == this.id) {
                    collisionDetected = false;
                    continue;
                } else if (ball.id != this.id) {
                    Shape intersect = Shape.intersect(this.circle, ball.circle);
                    if (intersect.getBoundsInLocal().getWidth() != -1) {
                        collisionDetected = true;
                    }
                }
            }
            if (collisionDetected == true) {
                circle.setFill(Color.BROWN);
                System.out.println("colided");
            } else {

                collisionDetected = false;
            }
    }
}

GUI Class

startBtn.setOnAction(e ->{
    startBtn.setDisable(true);


    // Get text
    // Do a check. Gör typkontroll
    int ballCount = Integer.parseInt(NrInput.getText());




        Random r = new Random();
        int Low = 20;
        int High = 420;
        int id = 0;
        //System.out.println(bounds.getMaxX());

        for (int i = 0; i < ballCount; i++) {
            Ball ball;

            // Randomize Y
            int y = r.nextInt(High-Low) + Low;

            //every other ball gets in different teams
            if (i % 2 == 0) {
                ball = new Ball(35, y, id, 0);

            } else {
                ball = new Ball(965, y, id, 1);

            }
            balls.add(ball);
            canvas.getChildren().add(ball.getCircle());
            id = id + 1;

        }

            for (Ball b : balls) {
                    b.moveBall();
                    b.collisionDetection(balls);
                }

    startBtn.setDisable(false);
});

Программа выглядит так

Но шары, которыея обведенный красным не изменит цвет, даже если они будут сталкиваться.

1 Ответ

0 голосов
/ 16 октября 2018

Но шары, которые я обвел красным, не изменят цвет, даже если они столкнутся.

Причина в том, что цвет не меняется, потому что Ball.collisionDetection()оценивается один раз и оценивается, когда столкновение еще не произошло.

Вам необходимо использовать привязку, чтобы убедиться, что она переоценивается всякий раз, когда шары перемещаются Timeline.

public Ball(int x, int y, int _id, int _team) {
    id = _id;

    Circle ball = new Circle(10, Color.BLACK);
    ball.relocate(x, y);
    circle = ball;

    team = _team;


    // New codes here
    ball.fillProperty().bind(Bindings.createObjectBinding(() -> {
        if (ball.checkCollision(balls)) {
            return Color.BROWN;
        }
        else {
            return Color.BLACK;
        }
    }, ball.layoutXProperty()));
}

// In Ball class
public boolean checkCollision(List<Ball> allBalls) {
    // Your collision logic
}

Вы можете перемещаться туда, куда вы хотите поместить привязку, поскольку ваша логика коллизий, вероятно, требует, чтобы вы передали список других Ball.

...