java入门拼图小游戏_【java】JavaFX从零开始实现拼图小游戏

最近java课老师布置了一个作业:制作一个拼图小游戏,关键老师自己说javaGUI编程没用,讲课的时候好像跳过了(没去上课不过我猜应该没讲吧),现在又叫我们做这些,实在是哭笑不得。

得了吧,老师的任务只能老老实实完成对吧,但是我又想到像Swing这些工具包已经基本上被淘汰了,做出来的页面有点老土,要学就学点好的,于是我选择用JavaFX来完成这次作业。

JavaFX的发展也不容乐观,一直不温不火的,但是本着对桌面应用有着一定的兴趣,就学一学吧,于是学了半天后开始上手做出来这个极其简陋的拼图游戏,希望随之以后的深入学习,能够做出更精美的应用。

(一)首页界面

6f9c17b767083e62343819daceef75ce.png

首页就很简单,一个VBox作为父布局,嵌套一个HBox子布局,HBox子布局里写三个Button事件,点击后打开指定难度的窗体,并关闭首页窗体,下面的文本是放在父布局VBox里的Label的文本内容,至于背景和按钮颜色则是用css来指定,整个过程唯一要关注的就是各个按钮大小间距位置等等。

(二)游戏界面

在游戏中我设置了三种难度,分别是3*3,4*4,5*5,实现上基本一样,所以只讲第一个简单难度九宫格的实现即可。

点击简单按钮后,关闭首页窗口,打开游戏窗口:

bb9ebeddb63020b022715193b92f739f.png

讲这个页面的难点(其实也很简单):

(1) 图片的截取:我当然不是PS去把一张图片截成一块块图片啦,这里我用imageview.setViewPort(new Rectangle2D (x,y,width,higth))的方法进行切割,可以指定图片从哪儿开始切,以及需要的图片大小

(2)图片的存储:利用图片数组ImageView[ ]存储切割好的图片即可,每一个数组元素里就是完整图片的一个子图片

(3)图片在九宫格中的摆放:利用GridPane布局,可以指定在布局里图片的位置,达到九宫格的效果

(4)图片摆放后必须有解:学名叫N数码问题,看了一些大神的博客以下结论:

当列数为奇数时,一切操作不影响奇偶性,当前状态逆序数为偶数等价于拼图有解

当列数为偶数时,上下交换影响奇偶性,只要当前状态逆序数奇偶性^当前空格状态的奇偶性=偶数等价于拼图有解

(5)实现拼图有解:由上面的结论我们可以这样,从[0-8]中随机取8个不重复的数字,保证这串数字的逆序数为偶数,例如:[2 0 1 3 4 5 6 7],没有获得的数字为[8],首先令索引为8图片数组存储一个空白图片,然后我们把这串数字作为图片数组i的下标,分别把图片放在对应九宫格的位置,如:

i[2]  i[0]  i[1]

i[3]  i[4]  i[5]

i[6]  i[7]  i[8]----->存储空白图片

(6)图片的移动:点击空白格子周围的格子,实现图片在布局中的位置交换即可,如点击i[7]实现交换:

i[2]  i[0]  i[1]

i[3]  i[4]  i[5]

i[6]  i[8]i[7]

(7)如何算作拼图成功:每一次图片交换,就检查是否拼图成功,至于是否拼图成功想必可以很直观的看出来,我们是顺序切割图片再顺序存储,因此像这样就能判定成功:

i[0]  i[1]  i[2]

i[3]  i[4]  i[5]

i[6]  i[7]  i[8]

(8)判定拼图成功:我们需要判定数组下标是不是在它需要对应的位置,数学化后的公式为:n = 3 * r + c,n为数组下标,r为行的索引,c为列的索引,如i[4]下标为4,行索引为1,列索引为1,可得:4=n=1*3+1=4,显然可证该图片所处的位置是正确的

(9)下方按钮事件:返回首页即关闭当前窗口再打开首页窗口,重新游戏即关闭当前窗口再打开游戏窗口,显示原图相当于提示功能,在不关闭当前窗口的前提下,打开另一个显示完整图片的窗口

(三)游戏成功界面

9b80b135d93b1b520a429d7e7a8bd568.png

没什么难度,当检测拼图成功时弹出一个文本框即可。

(四)源码部分

(1)首页界面

import javafx.application.Application;

import javafx.event.ActionEvent;

import javafx.event.EventHandler;

import javafx.geometry.Insets;

import javafx.stage.Stage;

import javafx.scene.Scene;

import javafx.scene.control.Button;

import javafx.scene.control.Label;

import javafx.scene.image.Image;

import javafx.scene.layout.HBox;

import javafx.scene.layout.VBox;

import javafx.scene.paint.Color;

import javafx.scene.text.Font;

/**

*开始菜单主界面

*作者:Mr. Yu

*2018年12月5日,下午5:40:51

*/

public class Start extends Application {

@Override

public void start(Stage primaryStage) {

try {

// 父容器

VBox vBox = new VBox();

// 子容器,分别是按钮和输出文本

HBox hBox_1 = new HBox();

HBox hBox_2 = new HBox();

// 显示难度选择按钮

Button start_1 = new Button("简单");

start_1.setOnAction(new EventHandler() {

@Override

public void handle(ActionEvent arg0) {

// 打开另一个窗口,即游戏窗口

Game_1 game_1 = new Game_1();

game_1.start(new Stage());

// 关闭开始界面

primaryStage.close();

}

});

Button start_2 = new Button("困难");

start_2.setOnAction(new EventHandler() {

@Override

public void handle(ActionEvent arg0) {

// 打开另一个窗口,即游戏窗口

Game_2 game_2 = new Game_2();

game_2.start(new Stage());

// 关闭开始界面

primaryStage.close();

}

});

Button start_3 = new Button("地狱");

start_3.setOnAction(new EventHandler() {

@Override

public void handle(ActionEvent arg0) {

// 打开另一个窗口,即游戏窗口

Game_3 game_3 = new Game_3();

game_3.start(new Stage());

// 关闭开始界面

primaryStage.close();

}

});

Label label = new Label("@余氏出品,必属渣品");

//设置文本样式大小和颜色

label.setFont(new Font("Arial", 30));

label.setTextFill(Color.web("black"));

hBox_1.getChildren().addAll(start_1, start_2, start_3);

hBox_2.getChildren().add(label);

vBox.getChildren().addAll(hBox_1, hBox_2);

// 设置按钮大小并调节位置

start_1.setPrefSize(100, 60);

start_2.setPrefSize(100, 60);

start_3.setPrefSize(100, 60);

hBox_1.setPadding(new Insets(650, 100, 0, 175));

hBox_2.setPadding(new Insets(50, 50, 500, 260));

// 设置控件之间的距离

hBox_1.setSpacing(100);

// 标题栏图标

Image image = new Image("application/4.jpg");

Scene scene = new Scene(vBox, 800, 800);

scene.getStylesheets().add(getClass().getResource("Start.css").toExternalForm());

primaryStage.getIcons().add(image);

primaryStage.setTitle("智障拼图");

primaryStage.setScene(scene);

primaryStage.setResizable(false);

primaryStage.show();

} catch (Exception e) {

e.printStackTrace();

}

}

public static void main(String[] args) {

launch(args);

}

}

(2)简单难度的游戏界面

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.layout.GridPane;

import javafx.scene.layout.HBox;

import javafx.scene.layout.VBox;

/**

*游戏界面----简单

*作者:Mr. Yu

*2018年12月5日,下午5:40:51

*/

public class Game_1 extends Application {

public int m; // m是不在随机数组的那个数字

ImageView[] imageViews = new ImageView[9];

@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

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值