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(); }