gpt4 book ai didi

JavaFX(部分)在网格 Pane 外隐藏图像

转载 作者:行者123 更新时间:2023-12-01 14:28:30 25 4
gpt4 key购买 nike

基本上我有这个布局:Image of the GUI layout .
它是一个带菜单栏(红色)的 BorderPane(黑色),一个包含一些东西的 Container,在左侧边栏(绿色)和一个嵌套在中心(橙色)内的 GridPane(灰色)

GridPane 的单元格填充了可以消失的 ImageViews(蓝色),当重新填充时,它们可能会堆叠,通过平行过渡从顶部落入它们的位置。到目前为止一切顺利,但我想隐藏 GridPane 和菜单栏之间的图像部分,但无法让它工作。有人知道如何解决这个问题吗?我也不介意隐藏整个图片而只有一部分突出。

//编辑:

Image of the actual game
主布局是使用 fxml 文件创建的。启动后, ImageView 已添加到网格 Pane 中。

最佳答案

如果您检查 GridPane 的 JavaDoc,您将看到:

默认情况下,GridPane 不会裁剪其内容,因此如果子项的最小尺寸阻止其适应其空间,则子项的边界可能会扩展到其自身的边界之外。

对于类(class)的每个 child 也是如此Pane .所以你需要手动处理剪辑,为此有方法 setClip() .
实现它的一种简单方法是使用 Rectangle与用于剪辑的 Pane 的尺寸。下面有一个代码可以做到这一点:

public void clipChildren(Region region) {
final Rectangle clipPane = new Rectangle();
region.setClip(clipPane);

region.layoutBoundsProperty().addListener((ov, oldValue, newValue) -> {
clipPane.setWidth(newValue.getWidth());
clipPane.setHeight(newValue.getHeight());
});
}

老实说,我也没有意识到这一点。您可以阅读一篇很棒的文章,其中详细解释了所有内容: JavaFX Pane Clipping

在我给你一个完整的例子之前,我想建议你使用 Pane而不是 GridPane .主要原因是您可以更好地操作(单击、拖动等)您的控件。另外,一些免责声明,我不是游戏开发人员,所以下面的示例只是一个示例。

MainApp.java
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import javafx.stage.Stage;

public class MainApp extends Application {

@Override
public void start(Stage stage) throws Exception {
GameBoard gameBoard = new GameBoard();

BorderPane mainPane = new BorderPane();

Button restartButton = new Button("Restart");
restartButton.setOnAction(e -> {
gameBoard.restartGame();
});

FlowPane controlPane = new FlowPane();
controlPane.setAlignment(Pos.CENTER);
controlPane.getChildren().add(restartButton);

mainPane.setCenter(gameBoard);
mainPane.setBottom(controlPane);

stage.setScene(new Scene(mainPane, 600, 600));
stage.show();
}

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

}

游戏板.java
import java.util.ArrayList;
import java.util.Random;

import javafx.animation.ParallelTransition;
import javafx.animation.RotateTransition;
import javafx.animation.TranslateTransition;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Pane;
import javafx.scene.layout.Region;
import javafx.scene.layout.StackPane;
import javafx.scene.shape.Rectangle;
import javafx.util.Duration;

public class GameBoard extends StackPane {

private final int TILE_WIDTH = 60;
private final int TILE_HEIGHT = 60;

private final int WIDTH;
private final int HEIGHT;

private int rows;
private int columns;

private ArrayList<Image> tileImages = new ArrayList<Image>();

private final Pane gamePane = new Pane();

public GameBoard() {
this(9, 9);
}

public GameBoard(int rows, int columns) {

this.rows = rows;
this.columns = columns;

WIDTH = columns * TILE_WIDTH;
HEIGHT = rows * TILE_HEIGHT;

// set the Clipping
clipChildren(gamePane);

// set the background color and also fix the dimensions
gamePane.setStyle("-fx-background-color : #52033D");
gamePane.setMinSize(WIDTH, HEIGHT);
gamePane.setPrefSize(WIDTH, HEIGHT);
gamePane.setMaxSize(WIDTH, HEIGHT);
getChildren().add(gamePane);

initTilesImages();
fillTiles();
}

public void clipChildren(Region region) {
final Rectangle clipPane = new Rectangle();
region.setClip(clipPane);

// In case we want to make a resizable pane we need to update
// our clipPane dimensions
region.layoutBoundsProperty().addListener((ov, oldValue, newValue) -> {
clipPane.setWidth(newValue.getWidth());
clipPane.setHeight(newValue.getHeight());
});
}

public void restartGame() {
gamePane.getChildren().clear();
fillTiles();
}

private void initTilesImages() {
tileImages.add(new Image(this.getClass().getResource("/resources/redTile.png").toExternalForm()));
tileImages.add(new Image(this.getClass().getResource("/resources/greenTile.png").toExternalForm()));
tileImages.add(new Image(this.getClass().getResource("/resources/blueTile.png").toExternalForm()));
tileImages.add(new Image(this.getClass().getResource("/resources/purpleTile.png").toExternalForm()));
tileImages.add(new Image(this.getClass().getResource("/resources/whiteTile.png").toExternalForm()));
tileImages.add(new Image(this.getClass().getResource("/resources/yellowTile.png").toExternalForm()));
}

// Fill with random images
private void fillTiles() {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
ImageView tile = createTile(j, i);
gamePane.getChildren().add(tile);
}
}
}

// Create the ImageView which I call "tile"
private ImageView createTile(int x, int y) {
Random rand = new Random();

int index = rand.nextInt(tileImages.size());
ImageView img = new ImageView(tileImages.get(index));

img.setFitWidth(TILE_WIDTH);
img.setFitHeight(TILE_HEIGHT);

img.setTranslateX(x * TILE_WIDTH);

// set some rotation and transition

RotateTransition rt = new RotateTransition(Duration.millis(2000));
rt.setFromAngle(0);
rt.setToAngle(360);



TranslateTransition tt = new TranslateTransition(Duration.millis(2000));
tt.setFromY(TILE_HEIGHT * (y - rows));
tt.setToY(y * TILE_HEIGHT);
tt.play();

ParallelTransition pt = new ParallelTransition(img, tt, rt);
pt.play();

return img;
}

}

结果 :

enter image description here

关于JavaFX(部分)在网格 Pane 外隐藏图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51620537/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com