如何生成矩形并更新它们AnimationTimer?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何生成矩形并更新它们AnimationTimer?相关的知识,希望对你有一定的参考价值。
下面的代码绘制一个交叉路口并添加一辆汽车,汽车一直移动到其车道的末端(因为灯是红色的)。我在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;
}
}
红绿灯:
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;
}
}
答案
要将汽车动态添加到数组列表,可以将以下代码放在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();
以上是关于如何生成矩形并更新它们AnimationTimer?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 UIView 上绘制一个 NSString 数组,它们之间没有任何前导空格并占据整个矩形?