Javafx动画使用循环



我正在尝试建立像游戏这样的太空入侵者。我已经绘制了一个正方形,我想使用循环和thread.sleep逐步向下移动它。但是,广场立即被绘制。我了解有些动画路径可以使用,但我想保持低级别并使用坐标系。

是否有使用这样的循环制作时间轴动画的方法?

package com.company;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.*;
import javafx.scene.layout.*;
import javafx.scene.shape.Rectangle;
public class Main extends  Application  {
    public static void main(String[] args)  {
        // write your code here
        launch(args);
    }
    public void start(Stage myStage) throws InterruptedException {
        myStage.setTitle("space invaders");
        Pane rootNode= new Pane();
        Scene myScene=new Scene(rootNode, 400, 800);
        myStage.setScene(myScene);
        Rectangle r = new Rectangle();
        myStage.show();
        rootNode.getChildren().add(r);
        r.setX(50);
        r.setY(50);
        r.setWidth(20);
        r.setHeight(20);
        for (int i = 0; i < 500; i++){
            Thread.sleep(2000);
            r.setTranslateY(i);
        }
    }
}

这是一个可怕的实现。我可能会使用AnimationTimer。这是用Timeline完成的。它基本上是向右或向左移动。如果击中右或左界,请掉落,然后向相反的方向移动。

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import javafx.animation.KeyFrame;
import javafx.animation.PauseTransition;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;
/**
 *
 * @author blj0011
 */
public class JavaFXApplication343 extends Application
{
    int invaderWidth = 30;
    int invaderHeight = 10;
    int gapBetweenInvaderX = 5;
    int gapBetweenInvaderY = 5;
    int locationTrackerX;
    int locationTrackerY;
    int screenWidth = 300;
    int screenHeight = 400;
    double timeBetweenFrames = .25;
    boolean direction = true;
    Timeline timeline;
    @Override
    public void start(Stage primaryStage)
    {
        Pane pane = new Pane();
        locationTrackerX = (screenWidth - (invaderWidth * 6 + gapBetweenInvaderX * 5)) / 2;
        locationTrackerY = (screenHeight - (invaderHeight * 6 + gapBetweenInvaderY * 5)) / 7;
        List<Rectangle> invaders = new ArrayList();
        for (int i = 0; i < 36; i++) {
            Rectangle rectangle = new Rectangle(locationTrackerX, locationTrackerY, invaderWidth, invaderHeight);
            rectangle.setFill(Color.YELLOW);
            invaders.add(rectangle);
            System.out.println(locationTrackerX);
            locationTrackerX += invaderWidth + gapBetweenInvaderX;
            if ((i + 1) % 6 == 0) {
                locationTrackerX = (screenWidth / 2) - ((invaderWidth * 6 + gapBetweenInvaderX * 5) / 2);
                locationTrackerY += invaderHeight + gapBetweenInvaderY;
            }
        }
        timeline = new Timeline(new KeyFrame(Duration.seconds(timeBetweenFrames), (event) -> {
            //Check to see if invader hits bounds
            Optional<Rectangle> hitRightOptional = invaders.stream().filter(invader -> invader.getBoundsInLocal().getMaxX() >= pane.getWidth()).findFirst();
            Optional<Rectangle> hitLeftOptional = invaders.stream().filter(invader -> invader.getBoundsInLocal().getMinX() <= 0).findFirst();
            //Move invaders
            if (hitRightOptional.isPresent()) {
                invaders.forEach((tempInvader) -> tempInvader.setY(tempInvader.getY() + 10));
                timeline.stop();
                PauseTransition pause = new PauseTransition(Duration.seconds(timeBetweenFrames));
                pause.setOnFinished((pauseEvent) -> {
                    invaders.forEach(invader -> invader.setX(invader.getX() - 10));
                    timeline.play();
                });
                pause.play();
                direction = false;
            }
            else if (hitLeftOptional.isPresent()) {
                invaders.forEach((tempInvader) -> tempInvader.setY(tempInvader.getY() + 10));
                timeline.stop();
                PauseTransition pause = new PauseTransition(Duration.seconds(timeBetweenFrames));
                pause.setOnFinished((pauseEvent) -> {
                    invaders.forEach(invader -> invader.setX(invader.getX() + 10));
                    timeline.play();
                });
                pause.play();
                direction = true;
            }
            else {
                if (direction) {
                    invaders.forEach(invader -> invader.setX(invader.getX() + 10));
                }
                else {
                    invaders.forEach(invader -> invader.setX(invader.getX() - 10));
                }
            }
        }));
        timeline.setCycleCount(Timeline.INDEFINITE);
        Button btn = new Button();
        btn.setText("Start Game");
        btn.setOnAction((ActionEvent event) -> {
            timeline.play();
            btn.setDisable(true);
        });
        pane.getChildren().addAll(invaders);
        pane.setPrefSize(screenWidth, screenHeight);
        VBox root = new VBox(pane, new StackPane(btn));
        Scene scene = new Scene(root, screenWidth, screenHeight);
        primaryStage.setTitle("Hello World!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args)
    {
        launch(args);
    }
}

已解决:

       Task task = new Task<Void>() {
        @Override public Void call() throws InterruptedException {
            for (int i = 1; i <= 800; i=i+10) {
                Thread.sleep(25);
                //updateProgress(i, max);
                r.setTranslateY(i);
            }
            return null;
        }
    };
    new Thread(task).start();            

最新更新