学习如何使用javafx,我遇到了节点或“目标”从边缘到边缘反弹的问题。在第一次穿越窗格后,他们停下来。我到目前为止的这段代码......
public class game extends Application implements EventHandler<ActionEvent>{
target1 target1 = new target1();
target2 target2 = new target2();
shooter shooter = new shooter();
Button fireButton = new Button("Fire!");
Pane pane = new Pane();
/**
*
* @param primaryStage
*/
@Override
public void start(Stage primaryStage) {
Scene scene = new Scene(pane, 800, 600);
primaryStage.setTitle("GAME");
primaryStage.setScene(scene);
pane.getChildren().add(fireButton);
fireButton.setLayoutX(700);
fireButton.setLayoutY(500);
pane.getChildren().add(shooter);
shooter.setX(380);
shooter.setY(540);
shooter.setWidth(40);
shooter.setHeight(20);
shooter.setArcWidth(20);
shooter.setArcHeight(20);
pane.getChildren().add(target1);
target1.setX(0);
target1.setY(250);
target1.setWidth(30);
target1.setHeight(20);
target1.setArcWidth(20);
target1.setArcHeight(20);
pane.getChildren().add(target2);
target2.setX(0);
target2.setY(150);
target2.setWidth(15);
target2.setHeight(10);
target2.setArcWidth(20);
target2.setArcHeight(20);
primaryStage.show();
ShooterButtonPressHandler shooterButton = new ShooterButtonPressHandler();
fireButton.setOnAction(shooterButton);
KeyFrame keyFrame = new KeyFrame(Duration.millis(1), this);
Timeline animation = new Timeline(keyFrame);
animation.setCycleCount(Timeline.INDEFINITE);
animation.play();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
@Override
public void handle(ActionEvent event) {
if (target1.isColliding(pane) ) {
target1.processCollision();
}
target1.animate(pane);
if (target2.isColliding(pane) ) {
target2.processCollision();
}
target2.animate(pane);
}
/**
*
*/
public class ShooterButtonPressHandler implements EventHandler<ActionEvent>{
@Override
public void handle(ActionEvent event) {
if (target1.getX() >= 370 && target1.getX()<= 400){
System.out.println("hit");
}
if (target2.getX() >= 370 && target2.getX()<= 400){
System.out.println("hit");
}
else {
System.out.println("miss");
}
}
}
这是目标1的类......目标2完全相同。
public class target1 extends Rectangle{
int velocity = 1;
public void animate (Pane pane) {
Double x = this.getX();
x = velocity + x;
setX(x);
} // end method animate
public Boolean isColliding (Pane pane) {
Double side = pane.getWidth();
Boolean collision = (this.getX() + this.getWidth() >= side);
if (collision) {
this.setX(side);
}
return collision;
} // end method isColliding
public void processCollision () {
if(velocity == 1){
this.velocity = -1;
}
else{
this.velocity = 1;
}
} // end method processCollision
答案 0 :(得分:1)
<强>问题强>
您面临的问题是由于声明
this.setX(side);
让我们考虑一下你的目标到达边界的情景。在这个阶段,对于target1:
X = 790
width = 30
side = 800
X + width = 790 + 30 = 820, which is greater than 800
所以,
collision = true
X = side = 800
现在我们有,
X = 800
width = 30
side = 800
X + width = 800 + 30 = 830, which is greater than 800
同样,我们有collision = true
,这将永远持续下去。
<强>解决方案强>
您可以将 X 设置为小于side+width
的值。有多种方法可以实现这一目标,其中之一是
this.setX(this.getX() - this.getWidth());
但是,这会破坏两个目标之间的同步,因为它们的宽度不相等。 找到更好的解决方案留给读者
还有一个问题我想指出,碰撞会处理右端而不是左端的碰撞。要处理两个目的,您可以编辑代码
public Boolean isColliding(Pane pane) {
Double side = pane.getWidth();
Boolean collision = false;
if(this.getX() + this.getWidth() >= side) {
this.setX(this.getX() - this.getWidth());
collision = true;
} else if (this.getX() - this.getWidth() <= 0) {
this.setX(this.getX() + this.getWidth());
collision = true;
}
return collision;
}