[关闭]
@CLSChen 2019-10-06T14:49:50.000000Z 字数 7516 阅读 1062

JIGSAW PUZZLE难点总结


实现功能


项目构成


所做的工作

游戏界面 测试结果

151141.png-2488.7kB
1.png-2938.1kB


具体实现

开始界面的实现

  1. // 使用GridPane来安放按钮和欢迎文字
  2. GridPane gridPane = new GridPane();
  3. gridPane.setAlignment(Pos.CENTER);
  4. gridPane.setHgap(5.5);
  5. gridPane.setVgap(5.5);
  6. // 显示难度选择按钮
  7. Button start_1 = new Button("简单模式");
  8. start_1.setOnAction(e -> {
  9. Game_1 game_1 = new Game_1();
  10. game_1.start(new Stage());
  11. // 关闭开始界面
  12. primaryStage.close();
  13. });
  14. ......
  15. // 设置按钮大小并调节位置
  16. start_1.setPrefSize(200, 100);
  17. start_2.setPrefSize(200, 100);
  18. start_3.setPrefSize(200, 100);
  19. Scene scene = new Scene(gridPane, 400, 400);
  20. // 添加css文件
  21. scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
  22. primaryStage.setTitle("CLSCHEN作品");
  23. primaryStage.setScene(scene);
  24. primaryStage.setResizable(false);
  25. primaryStage.show();
  1. // 通过ID(clschen)定位到Start里定义的标签,并修改字体等
  2. #clschen {
  3. -fx-font-size: 22.0px;
  4. -fx-font-family: "Arial Black";
  5. -fx-fill: #818181;
  6. -fx-effect: innershadow( three-pass-box , rgba(0.0,0.0,0.0,0.7) , 6.0, 0.0 , 0.0 , 2.0 );
  7. }
  8. // 修改Start里的按钮样式,并增加按下后会变化的动态效果
  9. .button {
  10. -fx-font-size:20.0px;
  11. -fx-text-fill: white;
  12. -fx-font-family: "Arial Narrow";
  13. -fx-font-weight: bold;
  14. -fx-background-color: linear-gradient(#61a2b1, #2A5058);
  15. -fx-effect: dropshadow( three-pass-box , rgba(0.0,0.0,0.0,0.6) , 5.0, 0.0 , 0.0 , 1.0 );
  16. }

图片截取和存储的实现

  1. // 切割图片分配给图片数组
  2. for (int i = 0, k = 0; i <= 2; i++) {
  3. for (int j = 0; j <= 2; j++, k++) {
  4. imageViews[k].setViewport(
  5. new Rectangle2D(partImagewidth * j, partImagewidth * i, partImagewidth, partImagewidth));
  6. }
  7. }

图片在九宫格中的摆放以及排列顺序

  1. // 生成8个不重复的逆序数为偶数的数字
  2. public int[] random() {}
  3. // 生成8个不重复数
  4. public int[] random_num() {}
  5. // 判断逆序数是否为偶数
  6. public boolean iso(int[] num) {}
  1. // 定义逆序数为偶数的随机数组
  2. int[] n = random();
  3. // 找出那个不在随机数组里面的数字
  4. m = findnum(n);
  5. // 定义一个数组来存储所有随机数(包括m)
  6. ncopy = new int[9];
  7. for (int i = 0; i < 9; i++) {
  8. if (i == 8) {
  9. ncopy[8] = m;
  10. } else {
  11. ncopy[i] = n[i];
  12. }
  13. }
  14. // 按照产生的随机数将imageView数组加入面板
  15. gridPane.add(imageViews[n[0]], 0, 0);
  16. gridPane.add(imageViews[n[1]], 1, 0);
  17. gridPane.add(imageViews[n[2]], 2, 0);
  18. gridPane.add(imageViews[n[3]], 0, 1);
  19. gridPane.add(imageViews[n[4]], 1, 1);
  20. gridPane.add(imageViews[n[5]], 2, 1);
  21. gridPane.add(imageViews[n[6]], 0, 2);
  22. gridPane.add(imageViews[n[7]], 1, 2);
  23. // 设定空白区域
  24. // 3.png为一个透明图,放在空格子中
  25. image image1 = new Image("application\empty.png");
  26. imageViews[m].setImage(image1);

拼图成功的判断

  1. // 判断是否拼图成功
  2. public boolean issucc(ImageView[] imageViews) {
  3. for (int i = 0; i <= 8; ++i) {
  4. if (i != 3 * GridPane.getRowIndex(imageViews[i]) + GridPane.getColumnIndex(imageViews[i])) {
  5. return false;
  6. }
  7. }
  8. return true;
  9. }

鼠标移动的实现

  1. public void handle(MouseEvent arg0) {
  2. // 取得鼠标点击位置处图片的位置
  3. ImageView img = (ImageView) arg0.getSource();
  4. double sx = img.getLayoutX();
  5. double sy = img.getLayoutY();
  6. // 计算与空白图片位置的差值
  7. double dispx = sx - imageViews[m].getLayoutX();
  8. double dispy = sy - imageViews[m].getLayoutY();
  9. ......
  1. if ((dispx == -partImagewidth) && (dispy == 0)) { // 点击的空格左边的格子
  2. swapimg(img, imageViews[m]); // 交换imageView
  3. if (issucc(imageViews)) { // 判断是否拼成功
  4. Alert alert = new Alert(AlertType.WARNING, "恭喜你,拼图成功!");
  5. alert.show();
  6. }
  7. } else if ((dispx == 0) && (dispy == -partImagewidth)) { // 上面的格子
  8. swapimg(img, imageViews[m]);
  9. if (issucc(imageViews)) {
  10. Alert alert = new Alert(AlertType.WARNING, "恭喜你,拼图成功!");
  11. alert.show();
  12. }
  13. } else if ((dispx == partImagewidth) && (dispy == 0)) { // 右边的格子
  14. swapimg(img, imageViews[m]);
  15. if (issucc(imageViews)) {
  16. Alert alert = new Alert(AlertType.WARNING, "恭喜你,拼图成功!");
  17. alert.show();
  18. }
  19. } else if ((dispx == 0) && (dispy == partImagewidth)) { // 下面的格子
  20. swapimg(img, imageViews[m]);
  21. if (issucc(imageViews)) {
  22. Alert alert = new Alert(AlertType.WARNING, "恭喜你,拼图成功!");
  23. alert.show();
  24. }

键盘移动的实现(难点)

  1. // 由于n[]中的索引是和位置一一对应的,再将其值作为imageViews的索引
  2. // 只要算出nindex,就能对应上相应的图片。将其交换
  3. // ncopy拓展了n,将m作为第九个元素加入数组,否则就访问不到最后一张图片。
  4. myevent1.swapimg(imageViews[m], imageViews[ncopy[nindex]]);
  1. // 键盘操作的实现
  2. class myKeyEvent implements EventHandler<KeyEvent> {
  3. @Override
  4. public void handle(KeyEvent arg0) {
  5. myevent myevent1 = new myevent();
  6. int mrow = GridPane.getRowIndex(imageViews[m]);
  7. int mcol = GridPane.getColumnIndex(imageViews[m]);
  8. int mindex = mrow * 3 + mcol;
  9. // 针对不同的按键给出不同的反应
  10. switch (arg0.getCode()) {
  11. case DOWN:
  12. // 计算出需要交换的对象图片的位置nindex
  13. int nrow = mrow + 1;
  14. int ncol = mcol;
  15. int nindex = nrow * 3 + ncol;
  16. if (nindex >= 0 && nindex <= 8) {
  17. // 由于n[]中的索引是和位置一一对应的,再将其值作为imageViews的索引
  18. // 只要算出nindex,就能对应上相应的图片。将其交换
  19. // ncopy拓展了n,将m作为第九个元素加入数组,否则就访问不到最后一张图片。
  20. myevent1.swapimg(imageViews[m], imageViews[ncopy[nindex]]);
  21. // 图片交换后,将数组值也交换,否则多次操作之后数据会混乱,导致胡乱交换。
  22. int temp2 = ncopy[mindex];
  23. ncopy[mindex] = ncopy[nindex];
  24. ncopy[nindex] = temp2;
  25. if (issucc(imageViews)) { // 判断是否拼成功
  26. Alert alert = new Alert(AlertType.WARNING, "恭喜你,拼图成功!");
  27. alert.setTitle("Congratulations!");
  28. alert.setHeaderText(null);
  29. alert.show();
  30. }
  31. }
  32. break;
  33. case UP:
  34. nrow = mrow - 1;
  35. ncol = mcol;
  36. nindex = nrow * 3 + ncol;
  37. if (nindex >= 0 && nindex <= 8) {
  38. myevent1.swapimg(imageViews[m], imageViews[ncopy[nindex]]);
  39. int temp2 = ncopy[mindex];
  40. ncopy[mindex] = ncopy[nindex];
  41. ncopy[nindex] = temp2;
  42. if (issucc(imageViews)) { // 判断是否拼成功
  43. Alert alert = new Alert(AlertType.WARNING, "恭喜你,拼图成功!");
  44. alert.setTitle("Congratulations!");
  45. alert.setHeaderText(null);
  46. alert.show();
  47. }
  48. }
  49. break;
  50. case LEFT:
  51. nrow = mrow;
  52. ncol = mcol - 1;
  53. nindex = nrow * 3 + ncol;
  54. if (nindex >= 0 && nindex <= 8 && nindex != 2 && nindex != 5) {
  55. myevent1.swapimg(imageViews[m], imageViews[ncopy[nindex]]);
  56. int temp2 = ncopy[mindex];
  57. ncopy[mindex] = ncopy[nindex];
  58. ncopy[nindex] = temp2;
  59. if (issucc(imageViews)) { // 判断是否拼成功
  60. Alert alert = new Alert(AlertType.WARNING, "恭喜你,拼图成功!");
  61. alert.setTitle("Congratulations!");
  62. alert.setHeaderText(null);
  63. alert.show();
  64. }
  65. }
  66. break;
  67. case RIGHT:
  68. nrow = mrow;
  69. ncol = mcol + 1;
  70. nindex = nrow * 3 + ncol;
  71. if (nindex >= 0 && nindex <= 8 && nindex != 3 && nindex != 6) {
  72. myevent1.swapimg(imageViews[m], imageViews[ncopy[nindex]]);
  73. int temp2 = ncopy[mindex];
  74. ncopy[mindex] = ncopy[nindex];
  75. ncopy[nindex] = temp2;
  76. if (issucc(imageViews)) { // 判断是否拼成功
  77. Alert alert = new Alert(AlertType.WARNING, "恭喜你,拼图成功!");
  78. alert.setTitle("Congratulations!");
  79. alert.setHeaderText(null);
  80. alert.show();
  81. }
  82. }
  83. break;
  84. default:
  85. break;
  86. }
  87. }
  88. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注