ImageView在JavaFX中的相互作用

时间:2015-01-10 16:28:05

标签: java javafx javafx-8

为什么这些陈述不起作用?

if (iv_ship.intersects(iv_plane.getBoundsInLocal())) System.out.println("xxxxxxxxx");
if (iv_plane.intersects(iv_ship.getBoundsInLocal())) System.out.println("zzzz");
if (iv_plane.getBoundsInLocal().intersects(iv_ship.getBoundsInLocal())) System.out.println("dupa");

我很确定这两个物体相交。也许这是TranslateTransition的错误? 但我也试图在海岸交叉矩形,而不是TT。 最好的问候。

以下是所有代码:

package riverpuff.v3;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import javafx.animation.AnimationTimer;
import javafx.animation.Timeline;
import javafx.animation.TranslateTransition;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.util.Duration;

/**
 *
 * @author Marek
 */
public class RiverPuffV3 extends Application {

    public String name = "";
    public Rectangle shot = new Rectangle();

    @Override
    public void start(Stage primaryStage) {

        createMenu(primaryStage);

        primaryStage.show();
        primaryStage.setResizable(false);
        primaryStage.getIcons().
                add(new Image(getClass().getResourceAsStream("Icon.png")));
    }

    private void createMenu(Stage primaryStage) {

        primaryStage.setScene(null);

        GridPane pane_menu = new GridPane();

        Button button_name = new Button("Name");
        button_name.setMaxHeight(Double.MAX_VALUE);
        button_name.setMaxWidth(Double.MAX_VALUE);
        button_name.setOnAction(e -> {
            createName(primaryStage);
            /*try{        
                OutputStreamWriter writer = new OutputStreamWriter( new FileOutputStream("log.txt", true), "UTF-8");
                BufferedWriter fbw = new BufferedWriter(writer);
                fbw.newLine();
                fbw.write("append txt...");
                fbw.newLine();
                fbw.close();
            }
            catch (Exception v) {
            System.out.println("Error: " + v.getMessage());
            }*/
        });

        Button button_start = new Button("Start");
        button_start.setMaxHeight(Double.MAX_VALUE);
        button_start.setMaxWidth(Double.MAX_VALUE);
        button_start.setOnAction(e -> {
            drawGame(primaryStage);
        });

        pane_menu.setHgap(10);
        pane_menu.setVgap(10);
        pane_menu.add(button_name,0,10,10,10);
        pane_menu.add(button_start,15,10,10,10);

                                                                                //reading name from a file
        try {
            String read_file = null;
            BufferedReader in = new BufferedReader(new FileReader("log.txt"));
            read_file = in.readLine();
            Text text_name = new Text("Hello " + read_file);
            pane_menu.add(text_name,5,5,10,5);
        } catch (FileNotFoundException e) {
            System.out.println("File not found!");
            //throw new RuntimeException("File not found");
        } catch (IOException e) {
            System.out.println("IO Error occured");
            //throw new RuntimeException("IO Error occured");
        } 

        Scene scene_menu = new Scene(pane_menu, 300, 500);

        primaryStage.setTitle("River Puff");
        primaryStage.setScene(scene_menu);

    }

                                                                                //save name to a file
    private void createName (Stage primaryStage) {

        primaryStage.setScene(null);

        GridPane pane_name = new GridPane();

        TextField tf_name = new TextField();
        tf_name.setMaxHeight(50);
        tf_name.setMaxWidth(240);
        tf_name.setAlignment(Pos.CENTER);
        tf_name.setFont(Font.font("Verdana",25));
        tf_name.setOnKeyPressed(ke -> {
            if (ke.getCode() == KeyCode.ENTER) {
                name = tf_name.getText();
                if (!name.isEmpty()){
                    MyFile myFile = new MyFile();
                    myFile.writeTextFile("log.txt", name);
                }
                createMenu(primaryStage);
            }
        });
        Button button_ok = new Button("OK");        
        button_ok.setMaxHeight(30);
        button_ok.setMaxWidth(80);
        button_ok.setOnAction(e -> {
            name = tf_name.getText();
            if (!name.isEmpty()){
                MyFile myFile = new MyFile();
                myFile.writeTextFile("log.txt", name);
            }
            createMenu(primaryStage);
        });

        Text text_name = new Text("What is your name?");
        text_name.setFont(Font.font("Verdana",15));

        pane_name.setHgap(10);
        pane_name.setVgap(10);

        pane_name.add(text_name,8,9,5,5);
        pane_name.add(button_ok,11,22,8,3);
        pane_name.add(tf_name,3,15,24,5);

        Scene scene_name = new Scene(pane_name, 300, 500);

        primaryStage.setTitle("River Puff - Name");
        primaryStage.setScene(scene_name);

    }

    private void drawGame (Stage primaryStage) {

        primaryStage.setScene(null);

        final int H = 700;
        final int W = 1000;

        Group root = new Group();
        Scene scene_game = new Scene(root, W, H, Color.LIGHTBLUE);

        Button button_menu = new Button("Menu");
        button_menu.setOnAction(e ->{
            createMenu(primaryStage);
        });

        Image ship = new Image((getClass().getResourceAsStream("ship.png")));   //loading images
        Image plane = new Image((getClass().getResourceAsStream("Icon.png")));

        /**********************************************************************/

        Rectangle[] coastL = {
            new Rectangle(), new Rectangle(),
            new Rectangle(), new Rectangle(), 
            new Rectangle(), new Rectangle(), 
            new Rectangle(), new Rectangle()
        }; 
        Rectangle[] coastR = {            
            new Rectangle(), new Rectangle(),
            new Rectangle(), new Rectangle(), 
            new Rectangle(), new Rectangle(), 
            new Rectangle(), new Rectangle()
        };


        for (int i=0; i<8; i++) {
            coastL[i].setFill(Color.FORESTGREEN);
            coastL[i].setHeight(100);
            coastR[i].setFill(Color.FORESTGREEN);
            coastR[i].setHeight(100);
        }


        AnimationTimer timer = new AnimationTimer() {
            int[] j = {0,0,0,0,0,0,0,0};

            @Override
            public void handle(long now) {

                for (int i=0; i<8; i++) if (j[i]==(i*100+800)) j[i]=i*100;

                for (int i=1;i<9;i++) {                                         //creating coast
                    coastL[i-1].setX(0);
                    coastL[i-1].setY(j[i-1]-(i*100));
                    coastL[i-1].setWidth(250+i*(i%3));

                    coastR[i-1].setX(W-(250+i*(i%4)));
                    coastR[i-1].setY(j[i-1]-(i*100));
                    coastR[i-1].setWidth(250+i*(i%4));
                } 
                for (int i=0;i<8;i++) j[i]++;
            }
        };
        timer.start();

        ImageView iv_ship = new ImageView();
        iv_ship.setImage(ship);
        iv_ship.setFitWidth(150);
        iv_ship.setFitHeight(45);
        iv_ship.setX(300);
        iv_ship.setY(0);

        TranslateTransition tt_shipX = 
                new TranslateTransition(Duration.millis(2000), iv_ship);        //moving enemies
        tt_shipX.setAutoReverse(true);
        tt_shipX.setCycleCount(Timeline.INDEFINITE);        
        tt_shipX.setByX(200f);
        tt_shipX.play();    

        TranslateTransition tt_shipY = 
                new TranslateTransition(Duration.millis(13000), iv_ship);
        tt_shipY.setAutoReverse(false);
        tt_shipY.setCycleCount(Timeline.INDEFINITE);
        tt_shipY.setByY(800);
        tt_shipY.play();        

        ImageView iv_plane = new ImageView();
        iv_plane.setImage(plane);
        iv_plane.setFitWidth(50);
        iv_plane.setFitHeight(50);
        iv_plane.setX(475);
        iv_plane.setY(600);

        TranslateTransition tt_plane = 
                new TranslateTransition(Duration.millis(1), iv_plane);          

        TranslateTransition tt_shot = 
                new TranslateTransition(Duration.millis(4000), shot);
        tt_shot.setAutoReverse(false);
        tt_shot.setCycleCount(1);
        TranslateTransition tt_shotB =
                new TranslateTransition(Duration.millis(0.5f), shot);
        tt_shotB.setAutoReverse(false);
        tt_shotB.setCycleCount(1);

        root.setOnKeyPressed((KeyEvent ke) -> {                                 //steering a plane            }
            if (ke.getCode() == KeyCode.LEFT && 
                    tt_plane.getNode().getTranslateX() > -475) {
                tt_plane.setByX(-5f);
                tt_plane.play();
                System.out.println(tt_plane.getNode().getTranslateX());
            }
            else if (ke.getCode() == KeyCode.RIGHT && 
                    tt_plane.getNode().getTranslateX() < 475) {
                tt_plane.setByX(5f);
                tt_plane.play();
                System.out.println(tt_plane.getNode().getTranslateX());
            }
            else if (ke.getCode() == KeyCode.A) {
                shot.setFill(Color.BLACK);
                shot.setX(tt_plane.getNode().getTranslateX()+495);
                shot.setY(580);
                shot.setWidth(10);
                shot.setHeight(20);

                tt_shot.setByY(-600);
                tt_shot.play();
                tt_shot.setOnFinished((ActionEvent arg0) -> {
                    shot.setDisable(true);
                    tt_shotB.setByY(600);
                    tt_shotB.play();
                });
            }
        });

        if (iv_ship.intersects(iv_plane.getBoundsInLocal())) System.out.println("xxxxxxxxx");
        if (iv_plane.intersects(iv_ship.getBoundsInLocal())) System.out.println("zzzz");
        if (iv_plane.getBoundsInLocal().intersects(iv_ship.getBoundsInLocal())) System.out.println("dupa");

        root.getChildren().add(button_menu);
        for (int i=0; i<8; i++) {
            root.getChildren().add(coastL[i]);
            root.getChildren().add(coastR[i]);
        }
        root.getChildren().add(iv_plane);
        root.getChildren().add(iv_ship);
        root.getChildren().add(shot);
        primaryStage.setScene(scene_game);
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

}

1 个答案:

答案 0 :(得分:1)

首先,您需要考虑可以转换节点(使用翻译),因此您需要getBoundsInLocal()代替getBoundsInParent()

根据javadocs:

  

getBoundsInParent()获取属性boundsInParent的值。此Node的矩形边界,包括其变换。 boundsInParent通过获取局部边界(由boundsInLocal定义)并应用创建的变换来计算。

这将在两个节点的任何给定位置都有效:

if(iv_plane.getBoundsInParent().intersects(iv_ship.getBoundsInParent())){
    System.out.println("Intersection detected");
}

您必须解决的下一个问题是何时检查可能的交叉路口。根据您的代码,您只检查过一次,甚至没有添加到根/场景/阶段的节点。那不行。

为了实现这一目标,您必须在每次移动其中一个时进行检查,使用一些监听器来更改translateXProperty()translateYProperty()中的更改,如下所示:

private final ChangeListener<Number> checkIntersection = (ob,n,n1)->{
    if (iv_plane.getBoundsInParent().intersects(iv_ship.getBoundsInParent())){
        System.out.println("Intersection detected");
    }
};

private ImageView iv_ship, iv_plane;

private void drawGame (Stage primaryStage) {
    iv_ship = new ImageView();
    iv_plane = new ImageView();
    ...
    iv_ship.translateXProperty().addListener(checkIntersection);
    iv_ship.translateYProperty().addListener(checkIntersection);
    ...
    root.getChildren().addAll(iv_plane,iv_ship);
    primaryStage.setScene(scene_game);
}