2016-11-04 32 views
0

我有一个国际象棋棋盘,我正在尝试添加棋子到棋盘上。棋盘上的每个点都是矩形,所以我认为添加棋子的最佳方式是将ImagePattern添加到每个获得棋子的矩形。我遇到的问题是当我添加一个ImagePattern到一个Rectangle时,它会使该矩形的背景变白,尽管在添加ImagePattern之前颜色是什么。所以我的问题是,有没有办法让我在添加ImagePattern后保留Rectangle的背景颜色? 为了演示的目的,我的代码只添加了一块板。如何添加一个ImagePattern矩形,同时仍然保持Rectangles背景颜色

public class ChessBoard extends Application { 
    GridPane root = new GridPane(); 
    final int size = 8; 

    public void start(Stage primaryStage) { 
    for (int row = 0; row < size; row++) { 
     for (int col = 0; col < size; col++) { 
      Rectangle square = new Rectangle(); 
      Color color; 

      if ((row + col) % 2 == 0) 
       color = Color.WHITE; 
      else 
       color = Color.BLACK; 

      square.setFill(color); 
      root.add(square, col, row); 
      if(row == 4 && col == 3){ 
       Image p = new Image("Peices/Black/0.png"); 
       ImagePattern pat = new ImagePattern(p); 
       square.setFill(pat); 
      } 



      square.widthProperty().bind(root.widthProperty().divide(size)); 
      square.heightProperty().bind(root.heightProperty().divide(size)); 
      square.setOnMouseClicked(e->{ 
       square.setFill(Color.BLUE); 
      }); 
     } 
    } 
    primaryStage.setScene(new Scene(root, 400, 400)); 
    primaryStage.show(); 
} 

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

回答

0

我想你正在寻找与BlendMode完成的混合。例如:

Image p = new Image("Peices/Black/0.png"); 
ImagePattern pat = new ImagePattern(p); 
Rectangle r1 = new Rectangle(); 
r1.setX(50); 
r1.setY(50); 
r1.setWidth(50); 
r1.setHeight(50); 
r1.setFill(pat); 

Rectangle r = new Rectangle(); 
r.setX(50); 
r.setY(50); 
r.setWidth(50); 
r.setHeight(50); 
r.setFill(Color.BLUE); 
r.setBlendMode(BlendMode.ADD); 

据我所知,没有直接的方法来实现这一点。
来源:https://docs.oracle.com/javase/8/javafx/api/javafx/scene/effect/BlendMode.html

0

不,您不能使用多于一个填充Rectangle。理论上你可以使用具有多种背景的Region,但这可能是一个坏主意。最有可能你会想至少有一些为片以下的功能,这是行不通的,如果你不做出个自己的节点:

  • 拖动一块从一个领域到另一个
  • 动画移动

我建议使用StackPane,并把董事会在后台把Pane在它上面放置件。只需使用ImageView即可。

实施例:

@Override 
public void start(Stage primaryStage) { 
    GridPane board = new GridPane(); 
    Region[][] fields = new Region[8][8]; 
    for (int i = 0; i < fields.length; i++) { 
     Region[] flds = fields[i]; 
     for (int j = 0; j < flds.length; j++) { 
      Region field = new Region(); 
      flds[j] = field; 
      field.setBackground(new Background(new BackgroundFill((i + j) % 2 == 0 ? Color.WHITE : Color.BLACK, CornerRadii.EMPTY, Insets.EMPTY))); 
     } 
     board.addRow(i, flds); 
    } 

    // use 1/8 of the size of the Grid for each field 
    RowConstraints rowConstraints = new RowConstraints(); 
    rowConstraints.setPercentHeight(100d/8); 
    ColumnConstraints columnConstraints = new ColumnConstraints(); 
    columnConstraints.setPercentWidth(100d/8); 

    for (int i = 0; i < 8; i++) { 
     board.getColumnConstraints().add(columnConstraints); 
     board.getRowConstraints().add(rowConstraints); 
    } 

    Pane piecePane = new Pane(); 
    StackPane root = new StackPane(board, piecePane); 

    NumberBinding boardSize = Bindings.min(root.widthProperty(), root.heightProperty()); 

    ImageView queen = new ImageView("https://upload.wikimedia.org/wikipedia/commons/thumb/4/47/Chess_qdt45.svg/480px-Chess_qdt45.svg.png"); 
    DropShadow shadow = new DropShadow(BlurType.GAUSSIAN, Color.WHITE, 2, 1, 0, 0); 

    // drop shadow for black piece on black field 
    queen.setEffect(shadow); 

    // trigger move to topleft field on mouse click 
    queen.setOnMouseClicked(evt -> { 
     Node source = (Node) evt.getSource(); 
     TranslateTransition animation = new TranslateTransition(Duration.seconds(0.5), source); 
     Region targetRegion = fields[0][0]; 
     final PositionChangeListener listener = (PositionChangeListener) source.getUserData(); 
     listener.setField(null); 
     animation.setByX(targetRegion.getLayoutX() - source.getLayoutX()); 
     animation.setByY(targetRegion.getLayoutY() - source.getLayoutY()); 
     animation.setOnFinished(e -> { 
      source.setTranslateX(0); 
      source.setTranslateY(0); 
      listener.setField(targetRegion); 
     }); 
     animation.play(); 
    }); 

    PositionChangeListener changeListener = new PositionChangeListener(queen); 
    queen.setUserData(changeListener); 
    changeListener.setField(fields[4][3]); 

    // board size should be as large as possible but at most the min of the parent sizes 
    board.setPrefSize(Double.MAX_VALUE, Double.MAX_VALUE); 
    board.maxWidthProperty().bind(boardSize); 
    board.maxHeightProperty().bind(boardSize); 

    // same size for piecePane 
    piecePane.setPrefSize(Double.MAX_VALUE, Double.MAX_VALUE); 
    piecePane.maxWidthProperty().bind(boardSize); 
    piecePane.maxHeightProperty().bind(boardSize); 

    // add piece to piecePane 
    piecePane.getChildren().add(queen); 

    Scene scene = new Scene(root, 400, 400); 

    primaryStage.setScene(scene); 
    primaryStage.show(); 
} 

private static class PositionChangeListener implements ChangeListener<Bounds> { 

    private final ImageView piece; 

    public PositionChangeListener(ImageView piece) { 
     this.piece = piece; 
    } 

    private Region currentField; 

    public void setField(Region newRegion) { 
     // register/unregister listeners to bounds changes of associated field 
     if (currentField != null) { 
      currentField.boundsInParentProperty().removeListener(this); 
     } 
     currentField = newRegion; 
     if (newRegion != null) { 
      newRegion.boundsInParentProperty().addListener(this); 
      changed(null, null, newRegion.getBoundsInParent()); 
     } 
    } 

    @Override 
    public void changed(ObservableValue<? extends Bounds> observable, Bounds oldValue, Bounds newValue) { 
     // align piece with field 
     piece.setLayoutX(newValue.getMinX()); 
     piece.setLayoutY(newValue.getMinY()); 
     piece.setFitHeight(newValue.getHeight()); 
     piece.setFitWidth(newValue.getWidth()); 
    } 

} 
+0

感谢您的回答。我一直在为此进行研究,但我不认为自己能够做到,但我只是想确保。我真的很喜欢你使用StackPane的建议,我会尝试一下。 – theAnon

+0

fabian,我一直没有搞乱这段代码一段时间,我只是有一个快速的问题,如果我想添加一个MouseListener到每个单独的广场,并看看如果该广场是一个合法的举动某一块,成为添加监听器的最佳地点?我一直在努力想象它在过去的几天里,没有任何我已经尝试似乎工作。顺便谢谢你的这个例子,我已经从中学到了很多东西! – theAnon

相关问题