用javafx写一个拼图游戏,要求鼠标点击移动,能实时显示所走步数和所用时间.

时间: 2024-02-13 19:03:40 浏览: 40
好的,下面我将根据您的要求,提供一个简单的 JavaFX 拼图游戏的实现方案。 首先,我们需要准备一张图片,用于拼图。假设我们选择了一张 640x640 的图片,将其分割成 16 个小块,每个小块大小为 160x160。 接下来,我们需要创建一个 UI 界面,用于显示拼图的图片和游戏信息。这个界面可以使用 VBox、HBox、ImageView、Label 等控件来实现。 代码示例: ```java public class PuzzleGame extends Application { private static final int NUM_ROWS = 4; private static final int NUM_COLS = 4; private static final int TILE_SIZE = 160; private static final int BOARD_SIZE = NUM_ROWS * NUM_COLS; private int moves; private long startTime; private boolean gameStarted; private Label movesLabel; private Label timeLabel; private Pane board; @Override public void start(Stage primaryStage) { // 加载拼图图片 Image image = new Image("puzzle.jpg"); // 创建 UI 界面 VBox root = new VBox(); root.setAlignment(Pos.CENTER); root.setSpacing(20); // 创建游戏信息区域 HBox infoBox = new HBox(); infoBox.setAlignment(Pos.CENTER); infoBox.setSpacing(40); // 创建步数信息 movesLabel = new Label("Moves: 0"); movesLabel.setFont(Font.font("Arial", FontWeight.BOLD, 24)); infoBox.getChildren().add(movesLabel); // 创建时间信息 timeLabel = new Label("Time: 0:00"); timeLabel.setFont(Font.font("Arial", FontWeight.BOLD, 24)); infoBox.getChildren().add(timeLabel); root.getChildren().add(infoBox); // 创建拼图板块 board = new Pane(); board.setPrefSize(NUM_COLS * TILE_SIZE, NUM_ROWS * TILE_SIZE); board.setStyle("-fx-background-color: #cccccc;"); // 将拼图块按序号添加到面板中 for (int i = 0; i < BOARD_SIZE; i++) { int row = i / NUM_COLS; int col = i % NUM_COLS; ImageView tile = new ImageView(); tile.setImage(image); tile.setViewport(new Rectangle2D(col * TILE_SIZE, row * TILE_SIZE, TILE_SIZE, TILE_SIZE)); tile.setLayoutX(col * TILE_SIZE); tile.setLayoutY(row * TILE_SIZE); tile.setUserData(i); // 存储拼图块编号 tile.setOnMouseClicked(this::handleTileClick); board.getChildren().add(tile); } root.getChildren().add(board); // 显示界面 Scene scene = new Scene(root, 640, 800); primaryStage.setScene(scene); primaryStage.show(); } // 处理拼图块点击事件 private void handleTileClick(MouseEvent event) { int index = (int) ((ImageView) event.getSource()).getUserData(); if (gameStarted) { // 计算所走步数和所用时间 moves++; long elapsedTime = System.currentTimeMillis() - startTime; String timeStr = String.format("%d:%02d", elapsedTime / 1000 / 60, elapsedTime / 1000 % 60); // 更新游戏信息 movesLabel.setText("Moves: " + moves); timeLabel.setText("Time: " + timeStr); } else { // 开始游戏 gameStarted = true; startTime = System.currentTimeMillis(); } // 移动拼图块 moveTile(index); } // 移动拼图块 private void moveTile(int index) { // 查找空白拼图块的位置 int blankIndex = -1; for (Node node : board.getChildren()) { if ((int) node.getUserData() == BOARD_SIZE - 1) { blankIndex = board.getChildren().indexOf(node); break; } } // 计算拼图块和空白块的行列差值 int rowDiff = index / NUM_COLS - blankIndex / NUM_COLS; int colDiff = index % NUM_COLS - blankIndex % NUM_COLS; // 如果拼图块和空白块不在同一行或同一列,则不能移动 if (rowDiff != 0 && colDiff != 0) { return; } // 如果拼图块和空白块在同一行或同一列,且中间没有其他拼图块,则可以移动 boolean canMove = true; if (rowDiff == 0) { int startCol = Math.min(index % NUM_COLS, blankIndex % NUM_COLS); int endCol = Math.max(index % NUM_COLS, blankIndex % NUM_COLS); for (int i = startCol + 1; i < endCol; i++) { Node node = board.getChildren().get(NUM_COLS * (index / NUM_COLS) + i); if ((int) node.getUserData() != BOARD_SIZE - 1) { canMove = false; break; } } } else { int startRow = Math.min(index / NUM_COLS, blankIndex / NUM_COLS); int endRow = Math.max(index / NUM_COLS, blankIndex / NUM_COLS); for (int i = startRow + 1; i < endRow; i++) { Node node = board.getChildren().get(NUM_COLS * i + (index % NUM_COLS)); if ((int) node.getUserData() != BOARD_SIZE - 1) { canMove = false; break; } } } if (canMove) { // 交换拼图块和空白块的位置 Node tile = board.getChildren().get(index); double oldX = tile.getLayoutX(); double oldY = tile.getLayoutY(); tile.setLayoutX(board.getChildren().get(blankIndex).getLayoutX()); tile.setLayoutY(board.getChildren().get(blankIndex).getLayoutY()); board.getChildren().get(blankIndex).setLayoutX(oldX); board.getChildren().get(blankIndex).setLayoutY(oldY); } // 判断游戏是否完成 if (isGameCompleted()) { // 停止计时器 gameStarted = false; // 显示完成提示 Alert alert = new Alert(Alert.AlertType.INFORMATION); alert.setTitle("Congratulations!"); alert.setHeaderText(null); alert.setContentText("You have completed the puzzle in " + moves + " moves and " + timeLabel.getText() + "!"); alert.showAndWait(); } } // 判断游戏是否完成 private boolean isGameCompleted() { for (Node node : board.getChildren()) { if ((int) node.getUserData() != board.getChildren().indexOf(node)) { return false; } } return true; } public static void main(String[] args) { launch(args); } } ``` 在上面的代码中,我们首先加载了拼图图片,然后创建了一个 VBox,包含了一个 HBox 和一个 Pane。HBox 用于显示游戏信息,比如所走步数和所用时间,Pane 用于显示拼图块。 在 Pane 中,我们按编号将 16 个拼图块添加到面板中,并为每个拼图块添加了鼠标点击事件监听器。当用户点击某个拼图块时,我们会计算该拼图块和空白块的位置关系,如果可以移动,就会交换两个块的位置。同时,我们会实时更新所走步数和所用时间,并判断游戏是否完成。 在拼图块移动时,我们还需要判断拼图块和空白块之间是否有其他拼图块,如果有,则不能移动。这个判断逻辑比较复杂,需要分别处理拼图块和空白块在同一行和同一列的情况。 最后,当游戏完成后,我们会弹出一个提示框,显示所走步数和所用时间。

相关推荐

最新推荐

recommend-type

javafx实现五子棋游戏

主要为大家详细介绍了javafx实现五子棋游戏,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
recommend-type

JavaFX 教程 (中文).docx

主要介绍Scene Builder 下使用一些组件以及应用程序打包、部署
recommend-type

钢桁架结构振动特性渐变分析工具

钢桁架结构振动特性渐变分析工具
recommend-type

zigbee-cluster-library-specification

最新的zigbee-cluster-library-specification说明文档。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

实现实时数据湖架构:Kafka与Hive集成

![实现实时数据湖架构:Kafka与Hive集成](https://img-blog.csdnimg.cn/img_convert/10eb2e6972b3b6086286fc64c0b3ee41.jpeg) # 1. 实时数据湖架构概述** 实时数据湖是一种现代数据管理架构,它允许企业以低延迟的方式收集、存储和处理大量数据。与传统数据仓库不同,实时数据湖不依赖于预先定义的模式,而是采用灵活的架构,可以处理各种数据类型和格式。这种架构为企业提供了以下优势: - **实时洞察:**实时数据湖允许企业访问最新的数据,从而做出更明智的决策。 - **数据民主化:**实时数据湖使各种利益相关者都可
recommend-type

可见光定位LED及其供电硬件具体型号,广角镜头和探测器,实验设计具体流程步骤,

1. 可见光定位LED型号:一般可使用5mm或3mm的普通白色LED,也可以选择专门用于定位的LED,例如OSRAM公司的SFH 4715AS或Vishay公司的VLMU3500-385-120。 2. 供电硬件型号:可以使用常见的直流电源供电,也可以选择专门的LED驱动器,例如Meanwell公司的ELG-75-C或ELG-150-C系列。 3. 广角镜头和探测器型号:一般可采用广角透镜和CMOS摄像头或光电二极管探测器,例如Omron公司的B5W-LA或Murata公司的IRS-B210ST01。 4. 实验设计流程步骤: 1)确定实验目的和研究对象,例如车辆或机器人的定位和导航。
recommend-type

JSBSim Reference Manual

JSBSim参考手册,其中包含JSBSim简介,JSBSim配置文件xml的编写语法,编程手册以及一些应用实例等。其中有部分内容还没有写完,估计有生之年很难看到完整版了,但是内容还是很有参考价值的。
recommend-type

"互动学习:行动中的多样性与论文攻读经历"

多样性她- 事实上SCI NCES你的时间表ECOLEDO C Tora SC和NCESPOUR l’Ingén学习互动,互动学习以行动为中心的强化学习学会互动,互动学习,以行动为中心的强化学习计算机科学博士论文于2021年9月28日在Villeneuve d'Asq公开支持马修·瑟林评审团主席法布里斯·勒菲弗尔阿维尼翁大学教授论文指导奥利维尔·皮耶昆谷歌研究教授:智囊团论文联合主任菲利普·普雷教授,大学。里尔/CRISTAL/因里亚报告员奥利维耶·西格德索邦大学报告员卢多维奇·德诺耶教授,Facebook /索邦大学审查员越南圣迈IMT Atlantic高级讲师邀请弗洛里安·斯特鲁布博士,Deepmind对于那些及时看到自己错误的人...3谢谢你首先,我要感谢我的两位博士生导师Olivier和Philippe。奥利维尔,"站在巨人的肩膀上"这句话对你来说完全有意义了。从科学上讲,你知道在这篇论文的(许多)错误中,你是我可以依
recommend-type

实现实时监控告警系统:Kafka与Grafana整合

![实现实时监控告警系统:Kafka与Grafana整合](https://imgconvert.csdnimg.cn/aHR0cHM6Ly9tbWJpei5xcGljLmNuL21tYml6X2pwZy9BVldpY3ladXVDbEZpY1pLWmw2bUVaWXFUcEdLT1VDdkxRSmQxZXB5R1lxaWNlUjA2c0hFek5Qc3FyRktudFF1VDMxQVl3QTRXV2lhSWFRMEFRc0I1cW1ZOGcvNjQw?x-oss-process=image/format,png) # 1.1 Kafka集群架构 Kafka集群由多个称为代理的服务器组成,这