内存游戏与图像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());
}

}
}

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

相反,您可以创建一个Images的数组,并在两个不同的ImageViews中使用每个Image两次。类似的方法应该有效:

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());
}

}
}

最新更新