方法无法识别 JavaFX 应用程序中的调用
Method not recognizing the call this in JavaFX application
我正在开发一个程序,显示圆圈与墙壁和自身发生碰撞。
我在使用补偿碰撞的方法时遇到了问题。
public class bouncyFX extends Application {
public ArrayList<Ball> arr = new ArrayList<Ball>();
public static void main(String[] args) {
launch(args);
}
static Pane pane;
@Override
public void start(final Stage primaryStage) {
pane = new Pane();
final Scene scene = new Scene(pane, 800, 600);
primaryStage.setScene(scene);
primaryStage.show();
pane.setOnMouseClicked(new EventHandler<MouseEvent>() {
public void handle(final MouseEvent event) {
final Ball ball = new Ball(event.getX(), event.getY(), 40, Color.AQUA);
ball.circle.relocate(event.getX(), event.getY());
pane.getChildren().addAll(ball.circle);
arr.add(ball);
final Bounds bounds = pane.getBoundsInLocal();
final Timeline loop = new Timeline(new KeyFrame(Duration.millis(10), new EventHandler<ActionEvent>() {
double deltaX = ball.ballDeltaX;
double deltaY = ball.ballDeltaY;
public void handle(final ActionEvent event) {
ball.circle.setLayoutX(ball.circle.getLayoutX() + deltaX);
ball.circle.setLayoutY(ball.circle.getLayoutY() + deltaY);
final boolean atRightBorder = ball.circle.getLayoutX() >= (bounds.getMaxX()-ball.circle.getRadius());
final boolean atLeftBorder = ball.circle.getLayoutX() <= (bounds.getMinX()+ball.circle.getRadius());
final boolean atBottomBorder = ball.circle.getLayoutY() >= (bounds.getMaxY()-ball.circle.getRadius());
final boolean atTopBorder = ball.circle.getLayoutY() <= (bounds.getMinY()+ball.circle.getRadius());
if(atRightBorder || atLeftBorder)
deltaX *= -1;
if(atBottomBorder || atTopBorder)
deltaY *= -1;
for(int i = 0; i<arr.size(); i++){
for(int j = i+1; j<arr.size()-1; j++){
arr.get(i).collisionMagnitued(arr.get(j));
}
}
}
}));
loop.setCycleCount(Timeline.INDEFINITE);
loop.play();
}
});
}
class Ball{
public Circle circle;
public double ballDeltaX = 3;
public double ballDeltaY = 3;
public void AddBall(Ball b){
arr.add(b);
}
public Ball(double X, double Y, double Rad, Color color) {
circle = new Circle(X, Y, Rad);
circle.setFill(color);
}
private boolean defineCollision(Ball b){
double xd = this.circle.getLayoutX() - b.circle.getLayoutX();
double yd = this.circle.getLayoutY() - b.circle.getLayoutY();
double sumRad = this.circle.getRadius() + b.circle.getRadius();
double squareRad = Math.pow(sumRad, 2);
double distSquare = Math.pow(xd, 2) + Math.pow(yd, 2);
if(distSquare <= squareRad){
return true;
}return false;
}
public void collisionMagnitued(Ball b){
if(this.defineCollision(b)){
double tempDeltaX = ballDeltaX;
double tempDeltaY = ballDeltaY;
if((this.ballDeltaX < 0 && b.ballDeltaX > 0) || (this.ballDeltaX >0 && b.ballDeltaX <0)){
this.ballDeltaX *= -this.ballDeltaX;
b.ballDeltaX *= -b.ballDeltaX;
System.out.println("tredje");
}
if((this.ballDeltaY < 0 && b.ballDeltaY > 0) || (this.ballDeltaY > 0 && b.ballDeltaY < 0)){
this.ballDeltaY *= -this.ballDeltaY;
b.ballDeltaY *= -b.ballDeltaY;
System.out.println("fjärde");
}
else{
System.out.println("Knull");
this.ballDeltaX *= -1;
b.ballDeltaX *= -1;
}
}
}
}
}
球(或圆圈)已创建并按预期在边界上弹跳。
当我在最后一个方法中获取打印语句时,碰撞检测方法起作用了。但是,似乎我的 ArrayList 没有填充对象或尝试比较参数 Ball 和调用该方法的 Ball 的方法有问题。
我离题了吗?不确定我应该如何从这里出发。
我发现你的逻辑有几个问题:
第一个问题是,当球 "bounce" 超出窗格的边界时,您不会更改它们的 ballDeltaX
或 ballDeltaY
值(您只需更改本地值在动画循环中并使用本地值更新位置)。所以两个球第一次碰撞时,它们的 ballDeltaX
和 ballDeltaY
值都等于 +3(初始值),这可能并不代表动画循环将它们移动的实际方向。在事实上,您实际上从未使用 ballDeltaX
或 ballDeltaY
的任何更新值来计算新位置;您获得这些变量的初始值,将它们复制到 deltaX
和 deltaY
,然后使用 deltaX
和 deltaY
计算新位置。因此,如果您更改 ballDeltaX
和 ballDeltaY
,动画循环永远不会看到更改。
for
循环在我看来是错误的;我认为他们不会比较列表的最后两个元素。 (当 i = arr.size()-2
在外循环的倒数第二次迭代中,你的内循环是 for (int j = arr.size() - 1; j < arr.size() -1; j++) {...}
当然永远不会迭代。)我认为你希望边界条件是 i < arr.size() - 1
和 j < arr.size()
,即反过来。
然后您在 collisionMagnitued(...)
中的 if
/else
结构可能不是您想要的。我不确定你想在那里实现什么,但是 else
子句只有在第二个 if
是 false
时才会启动,而不管第一个 [=] 中发生什么27=].
最后,您将在每次单击鼠标时启动一个新动画。因此,举例来说,如果您有三个球在周围弹跳,则您有三个动画循环 运行,每个循环都在球碰撞时更新值。您只需要开始一个循环;如果它引用一个空列表,它应该不会造成任何伤害。
我正在开发一个程序,显示圆圈与墙壁和自身发生碰撞。
我在使用补偿碰撞的方法时遇到了问题。
public class bouncyFX extends Application {
public ArrayList<Ball> arr = new ArrayList<Ball>();
public static void main(String[] args) {
launch(args);
}
static Pane pane;
@Override
public void start(final Stage primaryStage) {
pane = new Pane();
final Scene scene = new Scene(pane, 800, 600);
primaryStage.setScene(scene);
primaryStage.show();
pane.setOnMouseClicked(new EventHandler<MouseEvent>() {
public void handle(final MouseEvent event) {
final Ball ball = new Ball(event.getX(), event.getY(), 40, Color.AQUA);
ball.circle.relocate(event.getX(), event.getY());
pane.getChildren().addAll(ball.circle);
arr.add(ball);
final Bounds bounds = pane.getBoundsInLocal();
final Timeline loop = new Timeline(new KeyFrame(Duration.millis(10), new EventHandler<ActionEvent>() {
double deltaX = ball.ballDeltaX;
double deltaY = ball.ballDeltaY;
public void handle(final ActionEvent event) {
ball.circle.setLayoutX(ball.circle.getLayoutX() + deltaX);
ball.circle.setLayoutY(ball.circle.getLayoutY() + deltaY);
final boolean atRightBorder = ball.circle.getLayoutX() >= (bounds.getMaxX()-ball.circle.getRadius());
final boolean atLeftBorder = ball.circle.getLayoutX() <= (bounds.getMinX()+ball.circle.getRadius());
final boolean atBottomBorder = ball.circle.getLayoutY() >= (bounds.getMaxY()-ball.circle.getRadius());
final boolean atTopBorder = ball.circle.getLayoutY() <= (bounds.getMinY()+ball.circle.getRadius());
if(atRightBorder || atLeftBorder)
deltaX *= -1;
if(atBottomBorder || atTopBorder)
deltaY *= -1;
for(int i = 0; i<arr.size(); i++){
for(int j = i+1; j<arr.size()-1; j++){
arr.get(i).collisionMagnitued(arr.get(j));
}
}
}
}));
loop.setCycleCount(Timeline.INDEFINITE);
loop.play();
}
});
}
class Ball{
public Circle circle;
public double ballDeltaX = 3;
public double ballDeltaY = 3;
public void AddBall(Ball b){
arr.add(b);
}
public Ball(double X, double Y, double Rad, Color color) {
circle = new Circle(X, Y, Rad);
circle.setFill(color);
}
private boolean defineCollision(Ball b){
double xd = this.circle.getLayoutX() - b.circle.getLayoutX();
double yd = this.circle.getLayoutY() - b.circle.getLayoutY();
double sumRad = this.circle.getRadius() + b.circle.getRadius();
double squareRad = Math.pow(sumRad, 2);
double distSquare = Math.pow(xd, 2) + Math.pow(yd, 2);
if(distSquare <= squareRad){
return true;
}return false;
}
public void collisionMagnitued(Ball b){
if(this.defineCollision(b)){
double tempDeltaX = ballDeltaX;
double tempDeltaY = ballDeltaY;
if((this.ballDeltaX < 0 && b.ballDeltaX > 0) || (this.ballDeltaX >0 && b.ballDeltaX <0)){
this.ballDeltaX *= -this.ballDeltaX;
b.ballDeltaX *= -b.ballDeltaX;
System.out.println("tredje");
}
if((this.ballDeltaY < 0 && b.ballDeltaY > 0) || (this.ballDeltaY > 0 && b.ballDeltaY < 0)){
this.ballDeltaY *= -this.ballDeltaY;
b.ballDeltaY *= -b.ballDeltaY;
System.out.println("fjärde");
}
else{
System.out.println("Knull");
this.ballDeltaX *= -1;
b.ballDeltaX *= -1;
}
}
}
}
}
球(或圆圈)已创建并按预期在边界上弹跳。
当我在最后一个方法中获取打印语句时,碰撞检测方法起作用了。但是,似乎我的 ArrayList 没有填充对象或尝试比较参数 Ball 和调用该方法的 Ball 的方法有问题。
我离题了吗?不确定我应该如何从这里出发。
我发现你的逻辑有几个问题:
第一个问题是,当球 "bounce" 超出窗格的边界时,您不会更改它们的 ballDeltaX
或 ballDeltaY
值(您只需更改本地值在动画循环中并使用本地值更新位置)。所以两个球第一次碰撞时,它们的 ballDeltaX
和 ballDeltaY
值都等于 +3(初始值),这可能并不代表动画循环将它们移动的实际方向。在事实上,您实际上从未使用 ballDeltaX
或 ballDeltaY
的任何更新值来计算新位置;您获得这些变量的初始值,将它们复制到 deltaX
和 deltaY
,然后使用 deltaX
和 deltaY
计算新位置。因此,如果您更改 ballDeltaX
和 ballDeltaY
,动画循环永远不会看到更改。
for
循环在我看来是错误的;我认为他们不会比较列表的最后两个元素。 (当 i = arr.size()-2
在外循环的倒数第二次迭代中,你的内循环是 for (int j = arr.size() - 1; j < arr.size() -1; j++) {...}
当然永远不会迭代。)我认为你希望边界条件是 i < arr.size() - 1
和 j < arr.size()
,即反过来。
然后您在 collisionMagnitued(...)
中的 if
/else
结构可能不是您想要的。我不确定你想在那里实现什么,但是 else
子句只有在第二个 if
是 false
时才会启动,而不管第一个 [=] 中发生什么27=].
最后,您将在每次单击鼠标时启动一个新动画。因此,举例来说,如果您有三个球在周围弹跳,则您有三个动画循环 运行,每个循环都在球碰撞时更新值。您只需要开始一个循环;如果它引用一个空列表,它应该不会造成任何伤害。