首页 > 解决方案 > 带有图像的记忆游戏 javafx 错误图像打开

问题描述

我一直在研究 javaFX 上的存储卡游戏,您单击一张卡并翻转,然后单击另一张卡,如果它们相同,它会翻转,如果它们关闭时不同,它会保持不变,我按照本教程进行操作,但我想将其从字母更改为图像,问题是当我单击一个图块时,会显示不同图块上的图像

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;


import java.util.*;

public class Main extends Application {
    private int num_of_pairs = 8;
    private int num_per_row = 4;


     Tile selected = null;
    private int clickCount=2;

    @Override
    public void start(Stage primaryStage) throws Exception {
//        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
        primaryStage.setTitle("Hello World");



        Pane root = new Pane();

        ArrayList<Tile> tiles = new ArrayList<>();
        ImageView[] puzz=new ImageView[num_of_pairs];

        for(int i=0;i< puzz.length;i++){
            puzz[i]= new ImageView("image.jpeg");
            puzz[i].setFitHeight(110);
            puzz[i].setFitWidth(110);
        }


        for (int i = 0; i < num_of_pairs; i++) {

            tiles.add(new Tile(puzz[i]));
            tiles.add(new Tile(puzz[i]));



        }

        Collections.shuffle(tiles);

        for (int i = 0; i < tiles.size(); i++) {

            Tile tile = tiles.get(i);

            tile.setTranslateX(120 * (i % num_per_row));
            tile.setTranslateY(120 * (i / num_per_row));

            System.out.println(120*(i%num_per_row));
            System.out.println(120*(i/num_per_row));


            root.getChildren().add(tile);


        }




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


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




    class Tile extends StackPane {




        ImageView image;




        Tile(ImageView image) {
            this.image=image;


            Rectangle border = new Rectangle(120, 120);

            border.setFill(null);

            border.setStroke(Color.BLACK);



            getChildren().addAll(this.image,border);

            setOnMouseClicked(this::handleMouseClick);


            close();
        }

        public void handleMouseClick(MouseEvent event){

                if (isOpen() || clickCount==0)
                    return;
                clickCount--;
                if (selected == null) {
                    selected = this;
                    open(() ->{});
                }else{
                    open(() -> {
                        if(!hasSameValue(selected)){
                            selected.close();
                            this.close();
                        }
                        selected=null;
                        clickCount=2;
                    });
                }

            }


        public boolean isOpen() {
            return image.getOpacity() == 1;
        }

        public void close() {
            FadeTransition ft = new FadeTransition(Duration.seconds(0.5), image);
            ft.setToValue(0);
            ft.play();
        }

        public void open(Runnable action) {
            FadeTransition ft = new FadeTransition(Duration.seconds(0.5), image);
            ft.setToValue(1);
            ft.setOnFinished(e -> action.run());
            ft.play();
        }

        public boolean hasSameValue(Tile other) {
            return image.getImage().equals(other.image.getImage());
        }


    }
}

标签: javajavafx

解决方案


节点(例如ImageViews)在任何场景图中只能出现一次。您试图ImageView在根窗格中使用每个两次;本质上,这里发生的情况是第二次将 添加ImageView到根(通过Tile)时,它会从第一个图块中删除并放置在第二个图块中。然后,如果您单击与Tile一次添加图像对应的位置,则图像会使用第二次添加时的坐标出现。

相反,您可以创建一个 s 数组,并在两个不同Image的 s 中使用每个数组Image两次。像这样的东西应该工作: ImageView

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;


import java.util.*;

public class Main extends Application {
    private int num_of_pairs = 8;
    private int num_per_row = 4;


    Tile selected = null;
    private int clickCount=2;

    @Override
    public void start(Stage primaryStage) throws Exception {

        primaryStage.setTitle("Hello World");



        Pane root = new Pane();

        ArrayList<Tile> tiles = new ArrayList<>();

        // Note array changed to Image:
        Image[] puzz=new Image[num_of_pairs];

        for(int i=0;i< puzz.length;i++){
            puzz[i]= new Image("image.jpeg");
        }


        for (int i = 0; i < num_of_pairs; i++) {

            // Create two *different* ImageViews for each Image:

            ImageView first = new ImageView(puzz[i]);
            first.setFitHeight(110);
            first.setFitWidth(110);

            ImageView second = new ImageView(puzz[i]);
            second.setFitHeight(110);
            second.setFitWidth(110);

            tiles.add(new Tile(first));
            tiles.add(new Tile(second));



        }

        Collections.shuffle(tiles);

        for (int i = 0; i < tiles.size(); i++) {

            Tile tile = tiles.get(i);

            tile.setTranslateX(120 * (i % num_per_row));
            tile.setTranslateY(120 * (i / num_per_row));

            System.out.println(120*(i%num_per_row));
            System.out.println(120*(i/num_per_row));


            root.getChildren().add(tile);


        }




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


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




    class Tile extends StackPane {




        ImageView image;




        Tile(ImageView image) {
            this.image=image;


            Rectangle border = new Rectangle(120, 120);

            border.setFill(null);

            border.setStroke(Color.BLACK);



            getChildren().addAll(this.image,border);

            setOnMouseClicked(this::handleMouseClick);


            close();
        }

        public void handleMouseClick(MouseEvent event){

                if (isOpen() || clickCount==0)
                    return;
                clickCount--;
                if (selected == null) {
                    selected = this;
                    open(() ->{});
                }else{
                    open(() -> {
                        if(!hasSameValue(selected)){
                            selected.close();
                            this.close();
                        }
                        selected=null;
                        clickCount=2;
                    });
                }

            }


        public boolean isOpen() {
            return image.getOpacity() == 1;
        }

        public void close() {
            FadeTransition ft = new FadeTransition(Duration.seconds(0.5), image);
            ft.setToValue(0);
            ft.play();
        }

        public void open(Runnable action) {
            FadeTransition ft = new FadeTransition(Duration.seconds(0.5), image);
            ft.setToValue(1);
            ft.setOnFinished(e -> action.run());
            ft.play();
        }

        public boolean hasSameValue(Tile other) {
            return image.getImage().equals(other.image.getImage());
        }


    }
}

推荐阅读