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

GridPane来将一个游戏名"JIGSAW PUZZLE"和三个难度选择按钮加入。点击三个按钮,都会关闭开始界面,并打开一个单独的游戏界面。
// 使用GridPane来安放按钮和欢迎文字GridPane gridPane = new GridPane();gridPane.setAlignment(Pos.CENTER);gridPane.setHgap(5.5);gridPane.setVgap(5.5);// 显示难度选择按钮Button start_1 = new Button("简单模式");start_1.setOnAction(e -> {Game_1 game_1 = new Game_1();game_1.start(new Stage());// 关闭开始界面primaryStage.close();});......// 设置按钮大小并调节位置start_1.setPrefSize(200, 100);start_2.setPrefSize(200, 100);start_3.setPrefSize(200, 100);Scene scene = new Scene(gridPane, 400, 400);// 添加css文件scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());primaryStage.setTitle("CLSCHEN作品");primaryStage.setScene(scene);primaryStage.setResizable(false);primaryStage.show();
// 通过ID(clschen)定位到Start里定义的标签,并修改字体等#clschen {-fx-font-size: 22.0px;-fx-font-family: "Arial Black";-fx-fill: #818181;-fx-effect: innershadow( three-pass-box , rgba(0.0,0.0,0.0,0.7) , 6.0, 0.0 , 0.0 , 2.0 );}// 修改Start里的按钮样式,并增加按下后会变化的动态效果.button {-fx-font-size:20.0px;-fx-text-fill: white;-fx-font-family: "Arial Narrow";-fx-font-weight: bold;-fx-background-color: linear-gradient(#61a2b1, #2A5058);-fx-effect: dropshadow( three-pass-box , rgba(0.0,0.0,0.0,0.6) , 5.0, 0.0 , 0.0 , 1.0 );}
imageView.setViewPort(new Rectangle2D(x,y,width,higth))方法 ImageView[]的数组,并通过循环存储每块图片。
// 切割图片分配给图片数组for (int i = 0, k = 0; i <= 2; i++) {for (int j = 0; j <= 2; j++, k++) {imageViews[k].setViewport(new Rectangle2D(partImagewidth * j, partImagewidth * i, partImagewidth, partImagewidth));}}
GridPane实现,以简单模式为例,就是在GridPane中按照位置和设计好的顺序加入九个ImageView。其中前八张图都是原图的一部分,第九张图是一张空白图。
// 生成8个不重复的逆序数为偶数的数字public int[] random() {}// 生成8个不重复数public int[] random_num() {}// 判断逆序数是否为偶数public boolean iso(int[] num) {}
n[]来存放前八个被打乱的逆序数为偶数的数,使用m来存放剩下的那一个数。ImageViews[m]就代表最后一张图。
// 定义逆序数为偶数的随机数组int[] n = random();// 找出那个不在随机数组里面的数字m = findnum(n);// 定义一个数组来存储所有随机数(包括m)ncopy = new int[9];for (int i = 0; i < 9; i++) {if (i == 8) {ncopy[8] = m;} else {ncopy[i] = n[i];}}// 按照产生的随机数将imageView数组加入面板gridPane.add(imageViews[n[0]], 0, 0);gridPane.add(imageViews[n[1]], 1, 0);gridPane.add(imageViews[n[2]], 2, 0);gridPane.add(imageViews[n[3]], 0, 1);gridPane.add(imageViews[n[4]], 1, 1);gridPane.add(imageViews[n[5]], 2, 1);gridPane.add(imageViews[n[6]], 0, 2);gridPane.add(imageViews[n[7]], 1, 2);// 设定空白区域// 3.png为一个透明图,放在空格子中image image1 = new Image("application\empty.png");imageViews[m].setImage(image1);
n[]和m合并到一个数组里,命名为ncopy[],这点在键盘操作说明中会有提及。imageViews[0]就代表第一块图片,imageViews[1]就代表第二块图片…在每一步移动的时候,都判断每块图片有没有在相应的位置上。index = 3 * row + colissucc方法:
// 判断是否拼图成功public boolean issucc(ImageView[] imageViews) {for (int i = 0; i <= 8; ++i) {if (i != 3 * GridPane.getRowIndex(imageViews[i]) + GridPane.getColumnIndex(imageViews[i])) {return false;}}return true;}
imageView[m]的坐标相比较,比如该图在m的左边,那么它的y坐标相同,x坐标比m小一个图片的像素大小。对上之后,就可以把两张图进行交换。
public void handle(MouseEvent arg0) {// 取得鼠标点击位置处图片的位置ImageView img = (ImageView) arg0.getSource();double sx = img.getLayoutX();double sy = img.getLayoutY();// 计算与空白图片位置的差值double dispx = sx - imageViews[m].getLayoutX();double dispy = sy - imageViews[m].getLayoutY();......
if ((dispx == -partImagewidth) && (dispy == 0)) { // 点击的空格左边的格子swapimg(img, imageViews[m]); // 交换imageViewif (issucc(imageViews)) { // 判断是否拼成功Alert alert = new Alert(AlertType.WARNING, "恭喜你,拼图成功!");alert.show();}} else if ((dispx == 0) && (dispy == -partImagewidth)) { // 上面的格子swapimg(img, imageViews[m]);if (issucc(imageViews)) {Alert alert = new Alert(AlertType.WARNING, "恭喜你,拼图成功!");alert.show();}} else if ((dispx == partImagewidth) && (dispy == 0)) { // 右边的格子swapimg(img, imageViews[m]);if (issucc(imageViews)) {Alert alert = new Alert(AlertType.WARNING, "恭喜你,拼图成功!");alert.show();}} else if ((dispx == 0) && (dispy == partImagewidth)) { // 下面的格子swapimg(img, imageViews[m]);if (issucc(imageViews)) {Alert alert = new Alert(AlertType.WARNING, "恭喜你,拼图成功!");alert.show();}
n[]这个随机数组中值虽然是随机的,但是n[1],n[2]却是依次排列的,比如imageviews[n[5]]就代表第5张图,这样就可以通过以n[5]的值作为imageView[]的索引来实现访问第几张图了。然后就可以进行交换了。 1 * 3 + 2 = 5)张图,但是第五张图对应的不是imageView[5],而是imageView[n[5]]。因此要和后者进行交换才能成功。
// 由于n[]中的索引是和位置一一对应的,再将其值作为imageViews的索引// 只要算出nindex,就能对应上相应的图片。将其交换// ncopy拓展了n,将m作为第九个元素加入数组,否则就访问不到最后一张图片。myevent1.swapimg(imageViews[m], imageViews[ncopy[nindex]]);
n[]并没有关系,所以n[]还是原来的样子,并没有跟着一起交换,这样就导致算出来的新坐标对应的还是老的索引,因此我们应该把n[]也跟着一起交换,达到一致。n[]中只有8个元素,我们要交换的话,需要九个元素都在,因此要创建一个新数组,前八个元素复制过来,把缺了的元素m补在最后。int[] ncopy = new int[9]来拓展随机数组n[8]。通过遍历将前八个元素复制,并将m添加到ncopy最后。在源图片交换后,将数组里的元素也交换。
// 键盘操作的实现class myKeyEvent implements EventHandler<KeyEvent> {@Overridepublic void handle(KeyEvent arg0) {myevent myevent1 = new myevent();int mrow = GridPane.getRowIndex(imageViews[m]);int mcol = GridPane.getColumnIndex(imageViews[m]);int mindex = mrow * 3 + mcol;// 针对不同的按键给出不同的反应switch (arg0.getCode()) {case DOWN:// 计算出需要交换的对象图片的位置nindexint 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;if (issucc(imageViews)) { // 判断是否拼成功Alert alert = new Alert(AlertType.WARNING, "恭喜你,拼图成功!");alert.setTitle("Congratulations!");alert.setHeaderText(null);alert.show();}}break;case UP:nrow = mrow - 1;ncol = mcol;nindex = nrow * 3 + ncol;if (nindex >= 0 && nindex <= 8) {myevent1.swapimg(imageViews[m], imageViews[ncopy[nindex]]);int temp2 = ncopy[mindex];ncopy[mindex] = ncopy[nindex];ncopy[nindex] = temp2;if (issucc(imageViews)) { // 判断是否拼成功Alert alert = new Alert(AlertType.WARNING, "恭喜你,拼图成功!");alert.setTitle("Congratulations!");alert.setHeaderText(null);alert.show();}}break;case LEFT:nrow = mrow;ncol = mcol - 1;nindex = nrow * 3 + ncol;if (nindex >= 0 && nindex <= 8 && nindex != 2 && nindex != 5) {myevent1.swapimg(imageViews[m], imageViews[ncopy[nindex]]);int temp2 = ncopy[mindex];ncopy[mindex] = ncopy[nindex];ncopy[nindex] = temp2;if (issucc(imageViews)) { // 判断是否拼成功Alert alert = new Alert(AlertType.WARNING, "恭喜你,拼图成功!");alert.setTitle("Congratulations!");alert.setHeaderText(null);alert.show();}}break;case RIGHT:nrow = mrow;ncol = mcol + 1;nindex = nrow * 3 + ncol;if (nindex >= 0 && nindex <= 8 && nindex != 3 && nindex != 6) {myevent1.swapimg(imageViews[m], imageViews[ncopy[nindex]]);int temp2 = ncopy[mindex];ncopy[mindex] = ncopy[nindex];ncopy[nindex] = temp2;if (issucc(imageViews)) { // 判断是否拼成功Alert alert = new Alert(AlertType.WARNING, "恭喜你,拼图成功!");alert.setTitle("Congratulations!");alert.setHeaderText(null);alert.show();}}break;default:break;}}}