首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JavaFX8人对AI游戏玩。允许人为行动的拖延

JavaFX8人对AI游戏玩。允许人为行动的拖延
EN

Stack Overflow用户
提问于 2014-11-12 00:44:39
回答 1查看 506关注 0票数 1

我正在写的跳棋游戏,如标题所示,是介于人类玩家和人工智能之间。为人类玩家设置的每个检查器都设置了拖动检测。OnDragDetected收集检查程序当前位置的坐标。OnDragDropped收集玩家想要放下棋盘的位置的坐标。完成此操作后,还会发生一系列其他函数,以确保移动是有效的。如果移动是有效的,那就轮到AI了。在AI完成移动之后,这是人类玩家的轮回,等等。

我的问题是,我必须以某种方式延迟在玩家拖放检查器之后发生的所有功能,因为我需要首先收集有关坐标的信息。

我试过很多次,但都没有成功。我非常感谢任何指针,因为这是我第一个使用JavaFX的程序。

谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-11-12 03:03:52

我不太清楚你所说的“延迟”是什么意思。您只需要使用事件处理程序来管理所有东西,并跟踪该片段从何处移动到哪里。然后,当用户试图完成移动时(通常通过释放拖动)检查有效性。

这是一个非常基本的轮廓(一个玩家只是移动碎片)。当然,在现实生活中,平方状态(occupied)将更加复杂(两个玩家,等等),移动验证也是如此。但它应该给你一个主意。

代码语言:javascript
复制
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:

代码语言:javascript
复制
.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 ;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26877315

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档