Jafafx:循环碰撞检测和移动物体

时间:2018-10-15 17:13:48

标签: javafx collision-detection

我很难让程序循环执行moveBall和crashDetection,以便程序始终检查是否有碰撞并移动球。

此刻,程序仅在第一次迭代期间检查碰撞,此后,它什么也不做。

理想的情况是,无论球是否发生碰撞,都必须始终保持球的状态。

我已经包括了整个Ball类和开始按钮的代码。我曾考虑过围绕这小部分代码进行一次while循环,但我从未设法使其正常工作。

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

感谢帮助和建议!

球类

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类

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);
});

The program looks like this

但是我用红色圈出的球即使发生碰撞也不会改变颜色。

1 个答案:

答案 0 :(得分:1)

  

但是我用红色圈出的球即使发生碰撞也不会改变颜色。

原因是颜色没有改变是因为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的列表。