Im trying to create a scrolling background effect with two imageViews where one picture is on top of another picture and out of the window; then i try to scroll both down the window to create a scrolling effect by changing their y coordinates. I made a loop to do so and put a thread.sleep so it wouldnt do it too quickly. Then i reset the picutres positions and do the loop again. However, when i try to run the program, the window will never open. Taking out the loop obviously properly shows the window with the picutre.
public class TestBackground extends Application{
@Override
public void start(Stage stage) throws Exception {
stage.setTitle("DRIFT STAGE");
Pane game = new Pane();
Scene gameScene = new Scene(game, 956, 740);
ImageView background = new ImageView(getClass().getResource("bg.png").toExternalForm());
game.getChildren().add(background);
ImageView background2 = new ImageView(getClass().getResource("bg.png").toExternalForm());
game.getChildren().add(background2);
background2.setY(-740);
//loop to scroll background vertically
for (int j = 0; j < 20; j++) {
for (double i = 1.0; i < 741.0; i++) {
background.setY(background.getY() + i);
background2.setY(background2.getY() + i);
try {
Thread.sleep(250);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
background.setY(0.0);
background2.setY(-740.0);
}
stage.setScene(gameScene);
stage.show();
}
public static void main(String[] args) { launch(args); }
}
Advertisement
Answer
Your loop is not the right thing to do. Use a Transition Animation on each ImageView. You want a TranslateTransition.
Something like this:
// Animation to scroll background vertically
TranslateTransition trans1 = new TranslateTransition(Duration.minutes(1), background);
trans1.setFromY(0);
trans1.setToY(740);
trans1.setCycleCount(20);
TranslateTransition trans2 = new TranslateTransition(Duration.minutes(1), background2);
trans2.setFromY(-740);
trans2.setToY(0);
trans2.setCycleCount(20);
ParallelTransition parTrans = new ParallelTransition(trans1, trans2);
parTrans.play();
If your intention is to have these images as a parallax background that scrolls “forever”, set the transitions to cycle indefinitely
trans1.setCycleCount(Animation.INDEFINITE);
and use slightly different durations for each.
If you are using the same image, don’t load it twice:
Image bgImg = new Image(getClass().getResource("bg.png").toExternalForm());
ImageView background = new ImageView(bgImg);
game.getChildren().add(background);
ImageView background2 = new ImageView(bgImg);
game.getChildren().add(background2);
Here’s the whole start method with an added speed slider, just for fun:
@Override
public void start(Stage stage) {
stage.setTitle("DRIFT STAGE");
Pane game = new Pane();
Scene gameScene = new Scene(game, 956, 740);
Image bgImg = new Image(getClass().getResource("bg.png").toExternalForm());
ImageView background = new ImageView(bgImg);
ImageView background2 = new ImageView(bgImg);
Slider speedSlider = new Slider(0, 5, 1);
game.getChildren().addAll(background, background2, speedSlider);
// Animation to scroll background vertically
TranslateTransition trans1 = new TranslateTransition(Duration.seconds(10), background);
trans1.setFromY(0);
trans1.setToY(740);
trans1.setInterpolator(Interpolator.LINEAR);
trans1.setCycleCount(Animation.INDEFINITE);
TranslateTransition trans2 = new TranslateTransition(Duration.seconds(10), background2);
trans2.setFromY(-740);
trans2.setToY(0);
trans2.setCycleCount(Animation.INDEFINITE);
trans2.setInterpolator(Interpolator.LINEAR);
ParallelTransition parTrans = new ParallelTransition(trans1, trans2);
parTrans.rateProperty().bind(speedSlider.valueProperty());
parTrans.play();
stage.setScene(gameScene);
stage.show();
}