2014-11-12 2 views
1

Я пишу игру с шашками, которая, как следует из названия, находится между человеком и персонажем. Каждая контрольная панель для человека имеет установленное определение перетаскивания. OnDragDetected собирает координаты текущего местоположения проверяющего. OnDragDropped собирает координаты, где игрок хочет сбросить шашку. Как только это действие будет завершено, существует множество других функций, чтобы гарантировать, что это действие действительно. Если ход действителен, то это ход ИИ. После того, как ИИ делает свой ход, это черед игрока и т. Д.JavaFX8 Человек против игры AI. Разрешение задержки для действия человека

Проблема, с которой я сталкиваюсь, заключается в том, что я должен как-то задержать все функции, которые происходят после того, как игрок перетащит и сбросит шашку, поскольку мне сначала нужно собрать информацию о координатах.

Я пробовал много вещей, но безуспешно. Я бы очень признателен за любые указатели, поскольку это моя первая программа, в которой я использую JavaFX.

спасибо.

+1

Вы должны ссылаться на проверку достоверности на ход игрока в обработчик событий, который захватывает игрока ход. Возможно, посмотрите на мою версию [Tic Tac Toe (Noughts and Crosses)] (https://github.com/james-d/TicTacToe) в качестве примера. –

ответ

0

Я не уверен, что знаю, что вы подразумеваете под «задержкой» здесь. Вам просто нужно управлять всем с помощью обработчиков событий и следить за тем, куда кусок перемещается и перемещается. Затем проверьте правильность, когда пользователь попытается выполнить переход (как правило, высвободив перетаскивание).

Вот очень простой план (один игрок просто двигается). В реальной жизни, конечно, квадратное состояние (occupied) было бы более сложным (два игрока и т. Д.), Равно как и проверка валидации. Но это должно дать вам представление.

import javafx.application.Application; 
import javafx.beans.property.BooleanProperty; 
import javafx.beans.property.ObjectProperty; 
import javafx.beans.property.SimpleBooleanProperty; 
import javafx.beans.property.SimpleObjectProperty; 
import javafx.css.PseudoClass; 
import javafx.scene.Node; 
import javafx.scene.Scene; 
import javafx.scene.layout.BorderPane; 
import javafx.scene.layout.GridPane; 
import javafx.scene.layout.StackPane; 
import javafx.scene.shape.Circle; 
import javafx.stage.Stage; 

public class CheckersExample extends Application { 

    private static final int BOARD_SIZE = 10 ; 

    private static final int SQUARE_SIZE = 60 ; 
    private static final int PIECE_RADIUS = 25 ; 

    @Override 
    public void start(Stage primaryStage) { 

     // Use a GridPane for the board: 
     GridPane board = new GridPane(); 

     // track where move is made from and to 
     ObjectProperty<Square> moveFrom = new SimpleObjectProperty<>(); 
     ObjectProperty<Square> moveTo = new SimpleObjectProperty<>(); 

     // Create the squares and add views of them to the grid pane: 
     for (int y=0; y<BOARD_SIZE; y++) { 
      for (int x=0; x<BOARD_SIZE; x++) { 
       Square square = new Square(x, y); 
       board.add(square.getView(), x, y); 

       // alternate squares in last 3 rows are occupied: 

       if (y >= BOARD_SIZE-3 && (x + y) % 2 == 1) { 
        square.setOccupied(true); 
       } 

       // add event handlers for dragging to enable moving pieces: 

       setUpDraggingForMove(square, moveFrom, moveTo); 
      } 
     } 

     BorderPane root = new BorderPane(board); 
     Scene scene = new Scene(root); 
     scene.getStylesheets().add("checkers.css"); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    private void setUpDraggingForMove(Square square, ObjectProperty<Square> moveFrom, 
      ObjectProperty<Square> moveTo) { 

     // CSS pseudoclass for highlighting squares before moving to them: 
     PseudoClass highlight = PseudoClass.getPseudoClass("highlight"); 

     // when starting drag, if square has a piece, set the moveFrom: 

     square.getView().setOnDragDetected(event -> { 
      if (square.isOccupied()) { 
       moveFrom.set(square) ; 

       // this enables drag events to other nodes (squares): 
       square.getView().startFullDrag(); 
      } 
     }); 

     // if dragging onto a square that's a valid move, highlight it and set the moveTo: 

     square.getView().setOnMouseDragEntered(event -> { 
      if (moveValid(moveFrom.get(), square)) { 
       square.getView().pseudoClassStateChanged(highlight, true); 
       moveTo.set(square); 
      } 
     }); 

     // when dragging off a square, un-highlight it and unset the moveTo: 

     square.getView().setOnMouseDragExited(event -> { 
      square.getView().pseudoClassStateChanged(highlight, false); 
      moveTo.set(null); 
     }); 

     // when releasing, if the move is valid, set the moveFrom to be unoccupied and the 
     // moveTo to be occupied: 

     square.getView().setOnMouseReleased(event -> { 
      if (moveValid(moveFrom.get(), moveTo.get())) { 
       moveFrom.get().setOccupied(false); 
       moveTo.get().setOccupied(true); 
      } 
      moveFrom.set(null); 
      moveTo.set(null); 
     }); 
    } 

    // check validity of move: 

    private boolean moveValid(Square from, Square to) { 
     if (from == null ||       // no from 
      to == null ||       // no to 
      !from.isOccupied() ||     // from occupied 
      to.isOccupied() ||      // to occupied 
      from.getY() - to.getY() != 1 ||   // not moving forward 
      Math.abs(from.getX() - to.getX()) != 1) // not moving sideways 
     { 
      return false ; 
     } else { 
      return true ; 
     } 

    } 


    // represents a square on the board. Encapsulates its position (x and y), 
    // whether or not it contains a piece (occupied) 
    // and exposes a UI component representing it (view): 

    private static class Square { 
     private final int x ; 
     private final int y ; 
     private final BooleanProperty occupied ; 

     private final StackPane view ; 

     public Square(int x, int y) { 
      this.x = x ; 
      this.y = y ; 
      this.occupied = new SimpleBooleanProperty(this, "occupied", false); 

      this.view = createView(); 
     } 

     private StackPane createView() { 

      // use a StackPane as the base view: 

      StackPane view = new StackPane(); 
      view.getStyleClass().add("square"); 

      // pseudoclass to enable alternate color on alternate squares: 

      PseudoClass oddClass = PseudoClass.getPseudoClass("odd"); 

      // fill GridPane cell: 

      GridPane.setFillHeight(view, true); 
      GridPane.setFillWidth(view, true); 

      // fix size: 

      view.setMinSize(SQUARE_SIZE, SQUARE_SIZE); 
      view.setMaxSize(SQUARE_SIZE, SQUARE_SIZE); 

      // set pseudoclass state for "odd" squares: 

      if ((x + y) % 2 == 0) { 
       view.pseudoClassStateChanged(oddClass, true); 
      } 

      // add piece to stack pane... 

      Circle piece = new Circle(SQUARE_SIZE/2, SQUARE_SIZE/2, PIECE_RADIUS); 
      piece.getStyleClass().add("piece"); 
      view.getChildren().add(piece); 

      // .. but only actually display it if the square is occupied: 

      piece.visibleProperty().bind(occupied); 

      return view ; 
     } 

     public Node getView() { 
      return view ; 
     } 

     public int getX() { 
      return x ; 
     } 

     public int getY() { 
      return y ; 
     } 

     public final BooleanProperty occupiedProperty() { 
      return this.occupied; 
     } 

     public final boolean isOccupied() { 
      return this.occupiedProperty().get(); 
     } 

     public final void setOccupied(final boolean occupied) { 
      this.occupiedProperty().set(occupied); 
     }  

    } 

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

checkers.css:

.root { 

    /* and.. breathe... */ 

    -fx-padding: 40px ; 
} 

.square { 

    /* use a looked-up color for the main background of a square, 
     so it's easy to change */ 

    -square-background: antiquewhite ; 

    /* nest some backgrounds to give the effect of a raised border: */ 
    -fx-background-color: white, lightgray, darkgray, black, -square-background ; 
    -fx-background-insets: 0px, 1px 1px 0px 0px, 2px 2px 1px 1px, 4px 4px 2px 2px, 5px 5px 3px 3px ; 
} 
.square:odd { 
    /* change the main background on "odd" squares: */ 
    -square-background: cornflowerblue ; 
} 

.square:highlight { 
    /* and change it again for highlighted squares: */ 
    -square-background: lightgoldenrodyellow ; 
} 

.piece { 
    /* color for pieces: */ 
    -fx-fill: steelblue ; 
} 
Смежные вопросы