在动画制作时,节点只向一个方向而不是来回移动

时间:2014-12-04 23:46:53

标签: animation javafx

学习如何使用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

1 个答案:

答案 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;
}