英文:
How to avoid collision with the border or with each other by changing the heading i.e. rotate the object
问题
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Bounds;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.Duration;
public class Car extends Application {
public static Pane canvas;
@Override
public void start(final Stage primaryStage) throws FileNotFoundException {
canvas = new Pane();
final Scene scene = new Scene(canvas, 800, 600);
scene.setFill(Color.LIGHTGREEN);
primaryStage.setTitle("Car");
primaryStage.setScene(scene);
primaryStage.show();
Image car1 = new Image(new FileInputStream("src/car2.png"));
Image car2 = new Image(new FileInputStream("src/car1.png"));
ImageView c1 = new ImageView(car1);
ImageView c2 = new ImageView(car2);
c1.setFitHeight(100);
c1.setFitWidth(100);
c1.relocate(100, 100);
c2.setFitHeight(100);
c2.setFitWidth(100);
c2.relocate(600, 100);
c2.setImage(car2);
c2.setVisible(true);
canvas.getChildren().add(c1);
canvas.getChildren().add(c2);
final Timeline loop = new Timeline(new KeyFrame(Duration.millis(10), new EventHandler<ActionEvent>() {
double deltaX = 3;
double deltaY = 3;
@Override
public void handle(final ActionEvent t) {
c1.setLayoutX(c1.getLayoutX() + deltaX);
c1.setLayoutY(c1.getLayoutY() + deltaY);
c2.setLayoutX(c2.getLayoutX() + deltaX);
c2.setLayoutY(c2.getLayoutY() + deltaY);
final Bounds bounds = canvas.getBoundsInLocal();
final boolean atRightBorder = c1.getLayoutX() >= (bounds.getMaxX() - c1.getRadius());
final boolean atLeftBorder = c1.getLayoutX() <= (bounds.getMinX() + c1.getRadius());
final boolean atBottomBorder = c1.getLayoutY() >= (bounds.getMaxY() - c1.getRadius());
final boolean atTopBorder = c1.getLayoutY() <= (bounds.getMinY() + c1.getRadius());
if (atRightBorder || atLeftBorder) {
deltaX *= -1;
}
if (atBottomBorder || atTopBorder) {
deltaY *= -1;
}
}
}));
loop.setCycleCount(Timeline.INDEFINITE);
loop.play();
}
public static void main(String[] args) {
launch(args);
}
}
英文:
-
The task is actually, two cars moving, the cars must be able to avoid
collision with the border or with each other by changing the heading
for example: rotate the object. **
>I got an error for this
> getRadius()import java.io.FileInputStream; import java.io.FileNotFoundException; import javafx.animation.KeyFrame; import javafx.animation.Timeline; import javafx.application.Application; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.geometry.Bounds; import javafx.scene.Scene; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.layout.Pane; import javafx.scene.paint.Color; //import javafx.scene.shape.Circle; import javafx.stage.Stage; import javafx.util.Duration; public class Car extends Application { //public static Image car; public static Pane canvas; @Override public void start(final Stage primaryStage) throws FileNotFoundException { canvas = new Pane(); final Scene scene = new Scene(canvas, 800, 600); scene.setFill(Color.LIGHTGREEN); primaryStage.setTitle("Car"); primaryStage.setScene(scene); primaryStage.show(); //export image Image car1 = new Image(new FileInputStream("src/car2.png")); Image car2 = new Image(new FileInputStream("src/car1.png")); ImageView c1 = new ImageView(car1); ImageView c2 = new ImageView(car2); c1.setFitHeight(100);//Resize image c1.setFitWidth(100); c1.relocate(100,100); c2.setFitHeight(100);//Resize image c2.setFitWidth(100); c2.relocate(600,100); c2.setImage(car2); c2.setVisible(true); //add to stage canvas.getChildren().add(c1); canvas.getChildren().add(c2); final Timeline loop = new Timeline(new KeyFrame(Duration.millis(10), new EventHandler<ActionEvent>() { double deltaX = 3; double deltaY = 3; @Override public void handle(final ActionEvent t) { c1.setLayoutX(c1.getLayoutX() + deltaX); c1.setLayoutY(c1.getLayoutY() + deltaY); c2.setLayoutX(c2.getLayoutX() + deltaX); c2.setLayoutY(c2.getLayoutY() + deltaY); final Bounds bounds = canvas.getBoundsInLocal(); final boolean atRightBorder = c1.getLayoutX() >= (bounds.getMaxX() - c1.getRadius()); final boolean atLeftBorder = c1.getLayoutX() <= (bounds.getMinX() + c1.getRadius()); final boolean atBottomBorder = c1.getLayoutY() >= (bounds.getMaxY() - c1.getRadius()); final boolean atTopBorder = c1.getLayoutY() <= (bounds.getMinY() + c1.getRadius()); if (atRightBorder || atLeftBorder) { deltaX *= -1; } if (atBottomBorder || atTopBorder) { deltaY *= -1; } } })); loop.setCycleCount(Timeline.INDEFINITE); loop.play(); } /** * @param args the command line arguments */ public static void main(String[] args) { launch(args); } }
答案1
得分: 2
import java.io.FileNotFoundException;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Bounds;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.Duration;
public class Car extends Application {
private Pane canvas;
private static final String[] CIRCLES_128 = {
"https://cdn3.iconfinder.com/data/icons/softwaredemo/PNG/128x128/Circle_Green.png",
"https://cdn3.iconfinder.com/data/icons/softwaredemo/PNG/128x128/Circle_Red.png",
};
private double car1DeltaX = 3, car2DeltaX = 3;
private double car1DeltaY = 3, car2DeltaY = 3;
@Override
public void start(final Stage primaryStage) throws FileNotFoundException {
canvas = new Pane();
final Scene scene = new Scene(canvas, 800, 600);
scene.setFill(Color.LIGHTGREEN);
primaryStage.setTitle("Car");
primaryStage.setScene(scene);
Image car1Image = new Image(CIRCLES_128[0]);
Image car2Image = new Image(CIRCLES_128[1]);
ImageView car1 = new ImageView(car1Image);
ImageView car2 = new ImageView(car2Image);
car1.setFitHeight(100);
car1.setFitWidth(100);
car1.relocate(100,100);
car2.setFitHeight(100);
car2.setFitWidth(100);
car2.relocate(600,100);
canvas.getChildren().addAll(car1, car2);
final Timeline loop = new Timeline(new KeyFrame(Duration.millis(10), t -> {
positionNode(car1, car1DeltaX, car1DeltaY);
positionNode(car2, car2DeltaX, car2DeltaY);
final Bounds canvasBounds = canvas.getBoundsInLocal();
final Bounds car1Bounds = car1.getBoundsInParent();
final Bounds car2Bounds = car2.getBoundsInParent();
if(collisionDetected(car1Bounds, car2Bounds)){
handleCollision();
}
if(atHorizontalEdge(canvasBounds,car1Bounds)){
car1DeltaX *= -1;
}
if(atVerticalEdge(canvasBounds,car1Bounds)){
car1DeltaY *= -1;
}
if(atHorizontalEdge(canvasBounds,car2Bounds)){
car2DeltaX *= -1;
}
if(atVerticalEdge(canvasBounds,car2Bounds)){
car2DeltaY *= -1;
}
}));
primaryStage.show();
loop.setCycleCount(Timeline.INDEFINITE);
loop.play();
}
private void positionNode(Node node, double deltaX, double deltaY) {
node.setLayoutX(node.getLayoutX() + deltaX);
node.setLayoutY(node.getLayoutY() + deltaY);
}
private boolean collisionDetected(Bounds b1, Bounds b2) {
return b1.intersects(b2);
}
private boolean atHorizontalEdge(Bounds enclosing, Bounds enclosed) {
return enclosed.getMaxX() >= enclosing.getMaxX() || enclosed.getMinX() <= enclosing.getMinX() ;
}
private boolean atVerticalEdge(Bounds enclosing, Bounds enclosed) {
return enclosed.getMaxY() >= enclosing.getMaxY() || enclosed.getMinY() <= enclosing.getMinY() ;
}
private void handleCollision() {
car1DeltaX *= -1; car1DeltaY *= -1;
car2DeltaX *= -1; car2DeltaY *= -1;
}
public static void main(String[] args) {
launch(args);
}
}
英文:
First thing, get the movement of the two cars fixed, so they stay withing canvas bounds. <br/>
import java.io.FileNotFoundException;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Bounds;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.Duration;
public class Car extends Application {
private Pane canvas;
private static final String[] CIRCLES_128 = {
"https://cdn3.iconfinder.com/data/icons/softwaredemo/PNG/128x128/Circle_Green.png",
"https://cdn3.iconfinder.com/data/icons/softwaredemo/PNG/128x128/Circle_Red.png",
};
@Override
public void start(final Stage primaryStage) throws FileNotFoundException {
canvas = new Pane();
final Scene scene = new Scene(canvas, 800, 600);
scene.setFill(Color.LIGHTGREEN);
primaryStage.setTitle("Car");
primaryStage.setScene(scene);
Image car1Image = new Image(CIRCLES_128[0]);
Image car2Image = new Image(CIRCLES_128[1]);
ImageView car1 = new ImageView(car1Image);
ImageView car2 = new ImageView(car2Image);
car1.setFitHeight(100);//Resize image
car1.setFitWidth(100);
car1.relocate(100,100);
car2.setFitHeight(100);//Resize image
car2.setFitWidth(100);
car2.relocate(600,100);
//add to stage
canvas.getChildren().addAll(car1, car2);
final Timeline loop = new Timeline(new KeyFrame(Duration.millis(10), new EventHandler<ActionEvent>() {
double car1DeltaX = 3, car2DeltaX = 3; //each car must have its own deltaX and Y because
double car1DeltaY = 3, car2DeltaY = 3; //only one car has to change direction when hitting the edge
@Override
public void handle(final ActionEvent t) {
car1.setLayoutX(car1.getLayoutX() + car1DeltaX);
car1.setLayoutY(car1.getLayoutY() + car1DeltaY);
car2.setLayoutX(car2.getLayoutX() + car2DeltaX);
car2.setLayoutY(car2.getLayoutY() + car2DeltaY);
final Bounds bounds = canvas.getBoundsInLocal();
final Bounds car1Bounds = car1.getBoundsInParent();
final Bounds car2Bounds = car2.getBoundsInParent();
//check car1
final boolean car1AtRightBorder = car1Bounds.getMaxX() >= bounds.getMaxX() ;//- bounds.getRadius();
final boolean car1AtLeftBorder = car1Bounds.getMinX()<= bounds.getMinX() ;//+ car1.getRadius();
final boolean car1AtBottomBorder = car1Bounds.getMaxY() >= bounds.getMaxY() ;//- car1.getRadius();
final boolean car1AtTopBorder = car1Bounds.getMinY() <= bounds.getMinY() ;//+ car1.getRadius();
if (car1AtRightBorder || car1AtLeftBorder) {
car1DeltaX *= -1;
}
if (car1AtBottomBorder || car1AtTopBorder) {
car1DeltaY *= -1;
}
//check car2
final boolean car2AtRightBorder = car2Bounds.getMaxX() >= bounds.getMaxX() ;
final boolean car2AtLeftBorder = car2Bounds.getMinX()<= bounds.getMinX() ;
final boolean car2AtBottomBorder = car2Bounds.getMaxY() >= bounds.getMaxY() ;
final boolean car2AtTopBorder = car2Bounds.getMinY() <= bounds.getMinY() ;
if (car2AtRightBorder || car2AtLeftBorder) {
car2DeltaX *= -1;
}
if (car2AtBottomBorder || car2AtTopBorder) {
car2DeltaY *= -1;
}
}
}));
primaryStage.show();
loop.setCycleCount(Timeline.INDEFINITE);
loop.play();
}
static void main(String[] args) {
launch(args);
}
}
Then you can add a simple method to determine if two bounds intersect :
private boolean collisionDetected(Bounds b1, Bounds b2) {
return b1.intersects(b2);
}
and use it in the loop:
public void handle(final ActionEvent t) {
car1.setLayoutX(car1.getLayoutX() + car1DeltaX);
car1.setLayoutY(car1.getLayoutY() + car1DeltaY);
car2.setLayoutX(car2.getLayoutX() + car2DeltaX);
car2.setLayoutY(car2.getLayoutY() + car2DeltaY);
final Bounds bounds = canvas.getBoundsInLocal();
final Bounds car1Bounds = car1.getBoundsInParent();
final Bounds car2Bounds = car2.getBoundsInParent();
if(collisionDetected(car1Bounds, car2Bounds)){
car1DeltaX *= -1; car1DeltaY *= -1;
car2DeltaX *= -1; car2DeltaY *= -1;
}
//check car1
final boolean car1AtRightBorder = car1Bounds.getMaxX() >= bounds.getMaxX() ;
final boolean car1AtLeftBorder = car1Bounds.getMinX()<= bounds.getMinX() ;
final boolean car1AtBottomBorder = car1Bounds.getMaxY() >= bounds.getMaxY() ;
final boolean car1AtTopBorder = car1Bounds.getMinY() <= bounds.getMinY() ;
if (car1AtRightBorder || car1AtLeftBorder) {
car1DeltaX *= -1;
}
if (car1AtBottomBorder || car1AtTopBorder) {
car1DeltaY *= -1;
}
//check car2
final boolean car2AtRightBorder = car2Bounds.getMaxX() >= bounds.getMaxX() ;
final boolean car2AtLeftBorder = car2Bounds.getMinX()<= bounds.getMinX() ;
final boolean car2AtBottomBorder = car2Bounds.getMaxY() >= bounds.getMaxY() ;
final boolean car2AtTopBorder = car2Bounds.getMinY() <= bounds.getMinY() ;
if (car2AtRightBorder || car2AtLeftBorder) {
car2DeltaX *= -1;
}
if (car2AtBottomBorder || car2AtTopBorder) {
car2DeltaY *= -1;
}
}
}));
<hr>
<hr>
The following is a refactored cleaner version:
public class Car extends Application {
private Pane canvas;
private static final String[] CIRCLES_128 = {
"https://cdn3.iconfinder.com/data/icons/softwaredemo/PNG/128x128/Circle_Green.png",
"https://cdn3.iconfinder.com/data/icons/softwaredemo/PNG/128x128/Circle_Red.png",
};
private double car1DeltaX = 3, car2DeltaX = 3; //each car must have its own deltaX and Y because
private double car1DeltaY = 3, car2DeltaY = 3; //only one car has to change direction when hitting the edge
@Override
public void start(final Stage primaryStage) throws FileNotFoundException {
canvas = new Pane();
final Scene scene = new Scene(canvas, 800, 600);
scene.setFill(Color.LIGHTGREEN);
primaryStage.setTitle("Car");
primaryStage.setScene(scene);
Image car1Image = new Image(CIRCLES_128[0]);
Image car2Image = new Image(CIRCLES_128[1]);
ImageView car1 = new ImageView(car1Image);
ImageView car2 = new ImageView(car2Image);
car1.setFitHeight(100);//Resize image
car1.setFitWidth(100);
car1.relocate(100,100);
car2.setFitHeight(100);//Resize image
car2.setFitWidth(100);
car2.relocate(600,100);
//add to stage
canvas.getChildren().addAll(car1, car2);
final Timeline loop = new Timeline(new KeyFrame(Duration.millis(10), t -> {
//move 2 cars to new position
positionNode(car1, car1DeltaX, car1DeltaY);
positionNode(car2, car2DeltaX, car2DeltaY);
final Bounds canvasBounds = canvas.getBoundsInLocal();
final Bounds car1Bounds = car1.getBoundsInParent();
final Bounds car2Bounds = car2.getBoundsInParent();
if(collisionDetected(car1Bounds, car2Bounds)){
handleCollision();
}
//check car1 within canvas bounds
if(atHorizontalEdge(canvasBounds,car1Bounds)){
car1DeltaX *= -1;
}
if(atVerticalEdge(canvasBounds,car1Bounds)){
car1DeltaY *= -1;
}
//check car2 within canvas bounds
if(atHorizontalEdge(canvasBounds,car2Bounds)){
car2DeltaX *= -1;
}
if(atVerticalEdge(canvasBounds,car2Bounds)){
car2DeltaY *= -1;
}
}));
primaryStage.show();
loop.setCycleCount(Timeline.INDEFINITE);
loop.play();
}
private void positionNode(Node node, double deltaX, double deltaY) {
node.setLayoutX(node.getLayoutX() + deltaX);
node.setLayoutY(node.getLayoutY() + deltaY);
}
private boolean collisionDetected(Bounds b1, Bounds b2) {
return b1.intersects(b2);
}
private boolean atHorizontalEdge(Bounds enclosing, Bounds enclosed) {
return enclosed.getMaxX() >= enclosing.getMaxX() || enclosed.getMinX()<= enclosing.getMinX() ;
}
private boolean atVerticalEdge(Bounds enclosing, Bounds enclosed) {
return enclosed.getMaxY() >= enclosing.getMaxY() || enclosed.getMinY()<= enclosing.getMinY() ;
}
private void handleCollision() {
//change cars directions
car1DeltaX *= -1; car1DeltaY *= -1;
car2DeltaX *= -1; car2DeltaY *= -1;
}
public static void main(String[] args) {
launch(args);
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论