如何保持生成矩形并更新它们的AnimationTimer?

时间:2018-09-25 01:37:30

标签: java javafx arraylist

以下代码绘制了一个十字路口并添加了一辆汽车,该汽车一直行驶直到其车道尽头(因为指示灯为红色)。我将汽车添加到ArrayList中,以便继续生成汽车并对其进行更新(移动)。如果我在动画计时器内执行 cars.add(new Car()); ,则它不起作用。汽车代码会在随机一侧(N,S,E,W)生成具有随机大小的汽车。我的问题是,我该怎么写才能让代码继续在arraylist中生成汽车并对其进行更新?

模拟器:

import java.util.ArrayList;

import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.stage.Stage;

public class Simulator extends Application {
    ArrayList<Car> cars;
    TrafficLight[] trafficLights;
    TrafficLight northTrafficLight, westTrafficLight, eastTrafficLight, southTrafficLight;

    Group root;
    Canvas canvas;

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Simulator");

        root = new Group();
        cars = new ArrayList<Car>();
        cars.add(new Car());
        canvas = new Canvas(800, 800);
        trafficLights = new TrafficLight[4];

        // TrafficLights
        trafficLights[0] = new TrafficLight(185, 135, 100, 200, true, "N");
        trafficLights[1] = new TrafficLight(135, 565, 200, 100, true, "W");
        trafficLights[2] = new TrafficLight(565, 185, 200, 100, false, "E");
        trafficLights[3] = new TrafficLight(565, 565, 100, 200, false, "S");

        GraphicsContext gc = canvas.getGraphicsContext2D();
        drawShapes(gc);
        update();
        root.getChildren().add(canvas);

        Scene scene = new Scene(root, 800, 800);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private void drawShapes(GraphicsContext gc) {

        // Draw Intersection
        gc.setLineWidth(10.0);

        gc.strokeLine(250, 0, 250, 250);
        gc.strokeLine(0, 250, 250, 250);

        gc.strokeLine(550, 0, 550, 250);
        gc.strokeLine(550, 250, 800, 250);

        gc.strokeLine(250, 550, 250, 800);
        gc.strokeLine(250, 550, 0, 550);

        gc.strokeLine(550, 550, 550, 800);
        gc.strokeLine(550, 550, 800, 550);

        // Draw Cars
        for (int i = 0; i < cars.size(); i++) {
            root.getChildren().add(cars.get(i).drawCar());
        }

        // Draw Traffic light
        for (int i = 0; i < trafficLights.length; i++) {
            root.getChildren().add(trafficLights[i].drawTL());
            root.getChildren().add(trafficLights[i].drawRedCircle());
            root.getChildren().add(trafficLights[i].drawGreenCircle());
        }

    }

    private void update() {

        AnimationTimer timer = new AnimationTimer() {
            @Override
            public void handle(long arg0) {
                // TODO Auto-generated method stub
                for (int i = 0; i < cars.size(); i++) {
                    String side = cars.get(i).getSide();
                    if (side == "N") {
                        if (cars.get(i).getYPosition() > 224) {
                            cars.get(i).stopCar();
                        } else {
                            // car = new Car(trafficLights[0]);
                            cars.get(i).incrementYPosition();
                            cars.get(i).drawCar();
                        }
                    } else if (side == "S") {
                        if (cars.get(i).getYPosition() < 550) {
                            cars.get(i).stopCar();
                        } else {
                            // car = new Car(trafficLights[0]);
                            cars.get(i).decrementYPosition();
                            cars.get(i).drawCar();
                            // System.out.println(car.getYPosition());
                        }
                    } else if (side == "W") {
                        if (cars.get(i).getXPosition() > 224) {
                            cars.get(i).stopCar();
                        } else {
                            // car = new Car(trafficLights[0]);
                            cars.get(i).incrementXPosition();
                            cars.get(i).drawCar();
                        }
                    } else {
                        if (cars.get(i).getXPosition() < 555) {
                            cars.get(i).stopCar();
                        } else {
                            // car = new Car(trafficLights[0]);
                            cars.get(i).decrementXPosition();
                            cars.get(i).drawCar();
                            // System.out.println(car.getXPosition());
                        }
                    }
                }
                System.out.println(cars.size());
            }
        };
        timer.start();
    }
}

汽车:

import java.util.concurrent.ThreadLocalRandom;
import javafx.scene.shape.Rectangle;


public class Car {
    int size;
    int xposition;
    int yposition;
    int position;
    TrafficLight TrfcLight;
    String side;
    Rectangle car;

    public Car() {
        car = new Rectangle();
        size = ThreadLocalRandom.current().nextInt(25, 75 + 1);
        position = ThreadLocalRandom.current().nextInt(0, 3 + 1);
        switch(position) {

        case 0: side = "N";
                break;
        case 1: side = "S";
                break;
        case 2: side = "W";
                break;
        case 3: side = "E";
                break;
        default: side = "N";
                break;
        }
        if(side =="N") {
            xposition = ThreadLocalRandom.current().nextInt(250-size, 550 -size + 1);
            yposition = 0;
        }else if(side =="S"){
            xposition = ThreadLocalRandom.current().nextInt(250-size, 550 -size + 1);
            yposition = 800-size/2;
        }else if(side == "W") {
            xposition = 0;
            yposition = ThreadLocalRandom.current().nextInt(250-size, 550 -size + 1);
        }else {
            xposition = 800-size/2;
            yposition = ThreadLocalRandom.current().nextInt(250-size, 550 -size + 1);
        }
    }


    public Rectangle drawCar() {
        car.setX(xposition);
        car.setY(yposition);
        car.setWidth(size/2);
        car.setHeight(size/2);
        return car;
    }

    public void stopCar() {
        car.setX(xposition);
        car.setY(yposition);
    }

    public int getXPosition() {
        return xposition;
    }

    public int getYPosition() {
        return yposition;
    }

    public int getSize() {
        return size;
    }

    public String getSide() {
        return side;
    }

    public void incrementXPosition() {
        xposition+=2;
    }

    public void incrementYPosition() {
        yposition+=2;
    }

    public void decrementXPosition() {
        xposition-=2;
    }

    public void decrementYPosition() {
        yposition-=2;
    }
}

TrafficLight:

import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;

public class TrafficLight {

    int x, y, width, height;
    Rectangle trafficLight;
    Circle red, green;
    Color color;
    boolean solution;
    String side;

    public TrafficLight() {
        trafficLight = new Rectangle(); 
        red = new Circle();
        green = new Circle();
    }

    public TrafficLight(int x, int y, int width, int height, boolean solution, String side) {
        this.x = x;
        this.y = y;
        this.width = width;
        this.height = height;
        this.solution = solution;
        this.side = side;

        trafficLight = new Rectangle(); 
        red = new Circle();
        green = new Circle();
    }

    public Rectangle drawTL() {
        trafficLight.setX(x);
        trafficLight.setY(y);
        trafficLight.setWidth(width/2);
        trafficLight.setHeight(height/2);
        trafficLight.setFill(Color.TRANSPARENT);
        trafficLight.setStroke(Color.BLACK);
        trafficLight.setStrokeWidth(5);

        return trafficLight;
    }

    public Circle drawRedCircle() {
        if(width < height) {
            red.setCenterX(trafficLight.getX()+(trafficLight.getHeight()/4));
            red.setCenterY(trafficLight.getY()+(trafficLight.getHeight()/4));
            red.setRadius(trafficLight.getHeight()/7);
            if(solution) {
                red.setFill(Color.TRANSPARENT);
                red.setStroke(Color.BLACK);
                red.setStrokeWidth(2);
                side = "N";
                color = Color.TRANSPARENT;
            }else {         
                red.setFill(Color.RED);
                red.setStroke(Color.BLACK);
                red.setStrokeWidth(2);
                side ="S";
                color = Color.RED;
            }
        }else{
            red.setCenterX(trafficLight.getX()+(trafficLight.getHeight()/2));
            red.setCenterY(trafficLight.getY()+(trafficLight.getHeight()/2));
            red.setRadius(trafficLight.getWidth()/7);
            if(solution) {
                red.setFill(Color.TRANSPARENT);
                red.setStroke(Color.BLACK);
                red.setStrokeWidth(2);
                side = "W";
                color = Color.TRANSPARENT;
            }else {         
                red.setFill(Color.RED);
                red.setStroke(Color.BLACK);
                red.setStrokeWidth(2);
                side = "E";
                color = Color.RED;
            }
        }
        return red;     
    }

    public Circle drawGreenCircle() {
        if(width < height) {
            green.setCenterX(red.getCenterX());
            green.setCenterY(red.getCenterY()+50);
            green.setRadius(trafficLight.getHeight()/7);
            if(solution) {
                green.setFill(Color.RED);
                green.setStroke(Color.BLACK);
                green.setStrokeWidth(2);
                color = Color.RED;
            }else {         
                green.setFill(Color.TRANSPARENT);
                green.setStroke(Color.BLACK);
                green.setStrokeWidth(2);
                color = Color.TRANSPARENT;
            }       
        }else {
            green.setCenterX(red.getCenterX()+50);
            green.setCenterY(red.getCenterY());
            green.setRadius(trafficLight.getWidth()/7);
            if(solution) {
                green.setFill(Color.RED);
                green.setStroke(Color.BLACK);
                green.setStrokeWidth(2);
                color = Color.RED;
            }else {         
                green.setFill(Color.TRANSPARENT);
                green.setStroke(Color.BLACK);
                green.setStrokeWidth(2);
                color = Color.TRANSPARENT;
            }
        }
        return green;       
    }

    public String getSide() {
        return side;
    }

    public Color getColor() {
        return color;
    }
}

1 个答案:

答案 0 :(得分:1)

要将汽车动态添加到数组列表中,可以将以下代码放在start()方法的末尾。以下代码每3秒添加一辆新车(10次)。我已经验证了您的演示,并且可以正常工作。

Timeline tl = new Timeline(new KeyFrame(Duration.millis(3000), ae -> {
     Car car=new Car();
     cars.add(car);
     root.getChildren().add(car.drawCar());
 }));
 tl.setCycleCount(10);
 tl.play();