我很难让程序循环执行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);
});
但是我用红色圈出的球即使发生碰撞也不会改变颜色。
答案 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
的列表。