【JavaFx】使用JavaFx实现拼图游戏 实现键盘操作

本文介绍如何在基于JavaFx的拼图游戏中实现键盘操作功能。通过监听键盘方向键,利用GridPane计算相邻方块坐标,并通过扩展随机数组解决交换过程中出现的定位错误问题。详细介绍了解决方案及键盘操作的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 参考博客:https://blog.youkuaiyun.com/qq_42370146/article/details/84842168#commentBox
  • 在原博主的拼图游戏上添加了键盘控制系统,即通过方向键上下左右进行交换。
  • 思路很简单,就是通过GridPane获取坐标的功能计算出上下左右的坐标,然后通过已经实现的交换方法进行交换,但是交换方法必须获得两个源,而:
  • GridPane不支持通过坐标访问源,所以算出坐标后并不能直接访问来进行交换,所以如何通过坐标来联系上在那个位置的那张图片的源就是难点。
  • 解决方法:n[]这个随机数组中值虽然是随机的,但是n[1],n[2]却是依次排列的,比如imageview[n[5]]就代表第5张图,这样就可以通过以n[5]的值作为ImageView的索引来实现访问第几张图了。然后就可以进行交换了。
  • 但是交换过去后有一个很严重的问题,比如在向上交换后再向下交换,就是把第九张图和第六张图交换之后想再换回去时,现在空白方块在地址5,通过计算下面的方块地址为8,应该和n[8]交换,但是n[8]其实还是刚刚的第九张图,因此就会一直和自己交换,程序看上去就一动不动。
  • 其实我们交换的是图片的源,和n[]并没有关系,所以n[]还是原来的样子,并没有跟着一起交换,这样就导致算出来的新坐标对应的还是老的索引,因此我们应该把n[]也跟着一起交换,达到一致。而n[]中只有8个元素,我们要交换的话,需要九个元素都在,因此要创建一个新数组,前八个元素一样,把缺了的元素m补在最后。
  • 实现:使用一个int[] ncopy = new int[9]来拓展随机数组n[8]。通过遍历将前八个元素复制,并将m添加到ncopy最后。在源图片交换后,将数组里的元素也交换。

  • 键盘操作部分代码:
switch (arg0.getCode()) {
   
			case DOWN:
				// 计算出需要交换的对象图片的位置nindex
				int nrow = mrow + 1;
				int ncol = mcol;
				int nindex = nrow * 3 + ncol;
				if (nindex >= 0 && nindex <= 8) {
   
					// 由于n[]中的索引是和位置一一对应的,再将其值作为imageViews的索引
					// 只要算出nindex,就能对应上相应的图片。将其交换
					// ncopy拓展了n,将m作为第九个元素加入数组,否则就访问不到最后一张图片。
					myevent1.swapimg(imageViews[m], imageViews[ncopy[nindex]]);
					// 图片交换后,将数组值也交换,否则多次操作之后数据会混乱,导致胡乱交换。
					int temp2 = ncopy[mindex];
					ncopy[mindex] = ncopy[nindex];
					ncopy[nindex] = temp2;
				}
				break;

  • Game_1:
package application;

import java.util.Random;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.geometry.Rectangle2D;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.Alert.AlertType;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import java.util.Arrays;

public class Game_1 extends Application {
   
	public int m; // m是不在随机数组的那个数字
	ImageView[] imageViews = new ImageView[9];
	Image image2 = new Image("application/test.jpg", 800, 800, false, false);
	public int partImagewidth = (int) image2.getHeight() / 3;
	public int[] ncopy;

	@Override
	public void start(Stage primaryStage) {
   
		init(primaryStage);
	}

	// 绘制拼图界面和按钮
	public void init(Stage primaryStage) {
   
		// 父布局
		VBox vBox = new VBox();

		// 3*3九宫格布局,作为上方的选项嵌套入父布局
		GridPane gridPane = new GridPane();

		// 水平布局,作为下方的选项嵌套入父布局
		HBox hbox = new HBox();
		hbox.setPadding(new Insets(10)); // 填充
		hbox.setAlignment(Pos.CENTER); // 居中

		// 添加3个点击
		Button home = new Button("返回首页");
		home.setOnAction(e -> {
   
			Start start = new Start();
			start.start(new Stage());
			primaryStage.close();
		});

		Button again = new Button("重新游戏");
		again.setOnAction(e -> {
   
			Game_1 game = new Game_1();
			game.start(new Stage());
			primaryStage.close();
		});

		Button look = new Button("查看原图");
		look.setOnAction(e -> {
   
			OnImage_1 OnImage = new OnImage_1();
			OnImage.start(new Stage());
		});

		// 设置按钮大小并居中
		home.setPrefSize(200, 50);
		again.setPrefSize(200, 50);
		look.setPrefSize(200, 50);
		// 设置控件之间
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值