笔记四:Java基础阶段结束,用GUI实现的美女拼图游戏

> 此小项目中用到的图片还有源码有需要的朋友私信

项目演示

此小游戏可通过按钮来实现上下左右的拼图,还可以通过求助和重置按钮来复原和重新开始游戏。

在项目开始之前,希望大家多多支持,点个赞。谢谢!

思路分析:

  • - 绘制游戏界面
  • - 实现图片打乱
  • - 给按钮添加事件
  • - 移动空白图片按钮的实现
  • - 求助按钮的实现
  • - 重置按钮的实现

1、用GUI绘制游戏界面

思路分析:

  • - 新建一个类:PictureFrame,让这个类继承自JFrame。
  • - 在PictureFrame类中编写无参构造方法,在构造方法中调用两个方法;initFrame()方法,用于窗口的基本设置。setVisible(true)方法,用于设置窗口可见。
  • - 在initFrame()方法中设置窗口可见:
  • 1、窗口大小
  • 2、窗口标题
  • 3、窗口居中
  • 4、窗口关闭是退出程序
  • 5、窗口位于其他窗口之上
  • 6、取消窗口默认布局
  • - 定义方法用于窗口上组件的绘制:paintView();并在构造方法中调用。
  • - 把所有的按钮和面板定义为成员变量,写进PictureFrame类中。
  • - 定义测试类App;创建PictureFrame的对象进行测试。
public class PictureFrame extends JFrame {//定义按钮的成员变量private JButton shangButton;private JButton zuoButton;private JButton xiaButton;private JButton youButton;private JButton qiuZhuButton;private JButton chongZhiButton;//设置一个面板的成员变量private JPanel imagePanel;public PictureFrame() {//用于窗体的基本设置initFrame();//窗口上组件的绘制paintview();//设置窗体可见this.setVisible(true);}public void initFrame() {//设置窗口大小this.setSize(960, 565);//设置窗口关闭时默认操作(整数3表示:窗口关闭时退出应用程序)this.setDefaultCloseOperation(3);//设置位置,值为null,则窗口位置屏幕中央this.setLocationRelativeTo(null);//设置此窗口是否始终位于其他窗口之上this.setAlwaysOnTop(true);//设置窗口标题this.setTitle("动漫拼图");//取消JFrame的默认布局this.setLayout(null);}//窗体上组件的绘制public void paintview() {//标题图片JLabel titleLabel = new JLabel(new ImageIcon("day09\images\title.png"));titleLabel.setBounds(354, 27, 232, 57);this.add(titleLabel);//创建面板imagePanel = new JPanel();imagePanel.setBounds(150, 114, 360, 360);imagePanel.setLayout(null);//遍历二维数组,得到图片编号for (int i = 0; i < datas.length; i++) {for (int j = 0; j < datas[i].length; j++) {//创建JLabel对象,加载图片资源JLabel imagesJlabel = new JLabel(new ImageIcon("day09\images\" + datas[i][j] + ".png"));//调整照片位置imagesJlabel.setBounds(j * 90, i * 90, 90, 90);imagePanel.add(imagesJlabel);}}//把面板添加到窗体上this.add(imagePanel);//拼图参照图JLabel canZhaoTuLabel = new JLabel(new ImageIcon("day09\images\canzhaotu.png"));canZhaoTuLabel.setBounds(574, 114, 122, 121);this.add(canZhaoTuLabel);//上下左右、求助、重置按钮shangButton = new JButton(new ImageIcon("day09\images\shang.png"));shangButton.setBounds(732, 265, 57, 57);this.add(shangButton);zuoButton = new JButton(new ImageIcon("day09\images\zuo.png"));zuoButton.setBounds(650, 347, 57, 57);this.add(zuoButton);xiaButton = new JButton(new ImageIcon("day09\images\xia.png"));xiaButton.setBounds(732, 347, 57, 57);this.add(xiaButton);youButton = new JButton(new ImageIcon("day09\images\you.png"));youButton.setBounds(813, 347, 57, 57);this.add(youButton);qiuZhuButton = new JButton(new ImageIcon("day09\images\qiuzhu.png"));qiuZhuButton.setBounds(624, 444, 108, 45);this.add(qiuZhuButton);chongZhiButton = new JButton(new ImageIcon("day09\images\chongzhi.png"));chongZhiButton.setBounds(786, 444, 108, 45);this.add(chongZhiButton);//展示背景图JLabel backgroundLabel = new JLabel(new ImageIcon("day09\images\background.png"));backgroundLabel.setBounds(0, 0, 960, 530);this.add(backgroundLabel);}}

测试类:

public class App {public static void main(String[] args) {PictureFrame pictureFrame = new PictureFrame();}}

2、图片打乱并给按钮添加事件(用按钮移动空白图片)

思路分析

  • - 定义方法,用于打乱二维数组:initData()
  • - 创建Random对象,遍历存储的二维数字,得到每一个元素
  • - 产生两个随机索引,进行二维数组元素交换
  • - 定义之前现在类中定义一个二维数组
  • - 在构造方法中调用initData()方法
  • - 数组中的0是用来记录0号索引空白图片
  • - 给按钮添加事件,用来实现移动空白图片的位置,
  • 1、移动空白图片的位置就是和上下左右的图片进行交互,
  • 2、交换完成之后调用重回方法:rePainView(),
  • 3、处理边界问题。
  • - 在测试类App中测试

```java

public class PictureFrame extends JFrame {//定义一个二维数组,用来储存图片的编号private int[][] datas = {{1, 2, 3, 4},{5, 6, 7, 8,},{9, 10, 11, 12},{13, 14, 15, 0}};//定义按钮的成员变量private JButton shangButton;private JButton zuoButton;private JButton xiaButton;private JButton youButton;private JButton qiuZhuButton;private JButton chongZhiButton;//设置一个面板的成员变量private JPanel imagePanel;public PictureFrame() {//用于窗体的基本设置initFrame();//窗口上组件的绘制paintview();//设置窗体可见this.setVisible(true);}public void initFrame() {//设置窗口大小this.setSize(960, 565);//设置窗体关闭时默认操作(整数3表示:窗口关闭时退出应用程序)this.setDefaultCloseOperation(3);//设置位置,值为null,则窗口位置屏幕中央this.setLocationRelativeTo(null);//设置此窗口是否始终位于其他窗口之上this.setAlwaysOnTop(true);//设置窗口标题this.setTitle("动漫拼图");//取消JFrame的默认布局this.setLayout(null);}//窗体上组件的绘制public void paintview() {//标题图片JLabel titleLabel = new JLabel(new ImageIcon("day09\images\title.png"));titleLabel.setBounds(354, 27, 232, 57);this.add(titleLabel);//创建面板imagePanel = new JPanel();imagePanel.setBounds(150, 114, 360, 360);imagePanel.setLayout(null);//遍历二维数组,得到图片编号for (int i = 0; i < datas.length; i++) {for (int j = 0; j < datas[i].length; j++) {//创建JLabel对象,加载图片资源JLabel imagesJlabel = new JLabel(new ImageIcon("day09\images\" + datas[i][j] + ".png"));//调整照片位置imagesJlabel.setBounds(j * 90, i * 90, 90, 90);imagePanel.add(imagesJlabel);}}//把面板添加到窗体上this.add(imagePanel);//拼图参照图JLabel canZhaoTuLabel = new JLabel(new ImageIcon("day09\images\canzhaotu.png"));canZhaoTuLabel.setBounds(574, 114, 122, 121);this.add(canZhaoTuLabel);//上下左右、求助、重置按钮shangButton = new JButton(new ImageIcon("day09\images\shang.png"));shangButton.setBounds(732, 265, 57, 57);this.add(shangButton);zuoButton = new JButton(new ImageIcon("day09\images\zuo.png"));zuoButton.setBounds(650, 347, 57, 57);this.add(zuoButton);xiaButton = new JButton(new ImageIcon("day09\images\xia.png"));xiaButton.setBounds(732, 347, 57, 57);this.add(xiaButton);youButton = new JButton(new ImageIcon("day09\images\you.png"));youButton.setBounds(813, 347, 57, 57);this.add(youButton);qiuZhuButton = new JButton(new ImageIcon("day09\images\qiuzhu.png"));qiuZhuButton.setBounds(624, 444, 108, 45);this.add(qiuZhuButton);chongZhiButton = new JButton(new ImageIcon("day09\images\chongzhi.png"));chongZhiButton.setBounds(786, 444, 108, 45);this.add(chongZhiButton);//展示背景图JLabel backgroundLabel = new JLabel(new ImageIcon("day09\images\background.png"));backgroundLabel.setBounds(0, 0, 960, 530);this.add(backgroundLabel);//按钮添加事件shangButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {if (x0 == 3) {return;}datas[x0][y0] = datas[x0 + 1][y0];//这一步作用是啥,为什么要让datas[x0+1][y0]=0;//原理是交换,datas[x0][y0]=0是固定的,然后把datas[x0+1][y0]赋值给datas[x0][y0]//再把0给datas[x0+1][y0],datas[x0 + 1][y0] = 0;x0 = x0 + 1;//对图片进行重新遍历输出rePaintView();}});zuoButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {if (y0 == 3) {return;}datas[x0][y0] = datas[x0][y0 + 1];datas[x0][y0 + 1] = 0;y0 = y0 + 1;//对图片进行重新遍历输出rePaintView();}});xiaButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {if (x0 == 0) {return;}datas[x0][y0] = datas[x0 - 1][y0];datas[x0 - 1][y0] = 0;x0 = x0 - 1;//对图片进行重新遍历输出rePaintView();}});youButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {if (y0 == 0) {return;}datas[x0][y0] = datas[x0][y0 - 1];datas[x0][y0 - 1] = 0;y0 = y0 - 1;//对图片进行重新遍历输出rePaintView();}});}//定义两个int类型的变量,用于记录0号图片的位置//0号图片作用是啥,为什么要定义0号图片//0号图片作用是和数组里面的编号图片作一交换,用来完成拼图private int x0;private int y0;//打乱二维数组public void randomData() {Random random = new Random();for (int i = 0; i < datas.length; i++) {for (int j = 0; j < datas[i].length; j++) {int x = random.nextInt(datas.length);int y = random.nextInt(datas[i].length);int temp = datas[i][j];datas[i][j] = datas[x][y];datas[x][y] = temp;}}//记录0号图片的位置 wc作用是啥?wc作用是给最外层for循环起了一个名字,之后用break结束整体循环wc:for (int i = 0; i < datas.length; i++) {for (int j = 0; j < datas[i].length; j++) {if (datas[i][j] == 0) {x0 = i;y0 = j;break wc;}}}}//遍历移动后的图形,移动的图形重新绘制public void rePaintView() {//移除所有:移除的是JPanel标签上的全部组件,目的就是清空里面的数据imagePanel.removeAll();//遍历二维数组for (int i = 0; i < datas.length; i++) {for (int j = 0; j < datas[i].length; j++) {//创建JLabel对象,加载图片资源JLabel imagesJlabel1 = new JLabel(new ImageIcon("day09\images\" + datas[i][j] + ".png"));//调整照片位置imagesJlabel1.setBounds(j * 90, i * 90, 90, 90);imagePanel.add(imagesJlabel1);}}//对JPanel里面的组件进行从新打印imagePanel.repaint();}}

```

3、求助按钮和重置按钮、游戏成功后的实现

思路分析

  • - 定义移动成功分方法:success();
  • 1、在方法中实现成功之后按钮不可用,
  • - 在求助按钮中调用两个方式实现操作
  • 1、调用success();
  • 2、调用rePaintView();
  • - 当重置之后需要修个数组,使数组变为之前带有0号图片的数组
  • - 打乱数组
  • - 重绘面板
  • - 设置按钮可用
  • - 万一有人成功通过游戏怎么办
  • 先在PictureFrame类中定义新的成功的二维数组
  • 1、定义一个方法,用于比较两个数组(`新的数组和老的数组`)元素是否相同
  • 2、每次移动一个按钮调用这个方法,如果返回为true,则调用success()方法;
  • - 去测试类中测试代码的可行性就完成了
public class PictureFrame extends JFrame {//定义一个二维数组,用来储存图片的编号private int[][] datas = {{1, 2, 3, 4},{5, 6, 7, 8,},{9, 10, 11, 12},{13, 14, 15, 0}};//定义一个成功的二维数组private int[][] winDatas = {{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12},{13, 14, 15, 0}};//定义按钮的成员变量private JButton shangButton;private JButton zuoButton;private JButton xiaButton;private JButton youButton;private JButton qiuZhuButton;private JButton chongZhiButton;//设置一个面板的成员变量private JPanel imagePanel;public PictureFrame() {//用于窗体的基本设置initFrame();//窗口上组件的绘制paintview();//设置窗体可见this.setVisible(true);}public void initFrame() {//设置窗口大小this.setSize(960, 565);//设置窗体关闭时默认操作(整数3表示:窗口关闭时退出应用程序)this.setDefaultCloseOperation(3);//设置位置,值为null,则窗口位置屏幕中央this.setLocationRelativeTo(null);//设置此窗口是否始终位于其他窗口之上this.setAlwaysOnTop(true);//设置窗口标题this.setTitle("动漫拼图");//取消JFrame的默认布局this.setLayout(null);}//窗体上组件的绘制public void paintview() {//标题图片JLabel titleLabel = new JLabel(new ImageIcon("day09\images\title.png"));titleLabel.setBounds(354, 27, 232, 57);this.add(titleLabel);//创建面板imagePanel = new JPanel();imagePanel.setBounds(150, 114, 360, 360);imagePanel.setLayout(null);//遍历二维数组,得到图片编号for (int i = 0; i < datas.length; i++) {for (int j = 0; j < datas[i].length; j++) {//创建JLabel对象,加载图片资源JLabel imagesJlabel = new JLabel(new ImageIcon("day09\images\" + datas[i][j] + ".png"));//调整照片位置imagesJlabel.setBounds(j * 90, i * 90, 90, 90);imagePanel.add(imagesJlabel);}}//把面板添加到窗体上this.add(imagePanel);//拼图参照图JLabel canZhaoTuLabel = new JLabel(new ImageIcon("day09\images\canzhaotu.png"));canZhaoTuLabel.setBounds(574, 114, 122, 121);this.add(canZhaoTuLabel);//上下左右、求助、重置按钮shangButton = new JButton(new ImageIcon("day09\images\shang.png"));shangButton.setBounds(732, 265, 57, 57);this.add(shangButton);zuoButton = new JButton(new ImageIcon("day09\images\zuo.png"));zuoButton.setBounds(650, 347, 57, 57);this.add(zuoButton);xiaButton = new JButton(new ImageIcon("day09\images\xia.png"));xiaButton.setBounds(732, 347, 57, 57);this.add(xiaButton);youButton = new JButton(new ImageIcon("day09\images\you.png"));youButton.setBounds(813, 347, 57, 57);this.add(youButton);qiuZhuButton = new JButton(new ImageIcon("day09\images\qiuzhu.png"));qiuZhuButton.setBounds(624, 444, 108, 45);this.add(qiuZhuButton);chongZhiButton = new JButton(new ImageIcon("day09\images\chongzhi.png"));chongZhiButton.setBounds(786, 444, 108, 45);this.add(chongZhiButton);//展示背景图JLabel backgroundLabel = new JLabel(new ImageIcon("day09\images\background.png"));backgroundLabel.setBounds(0, 0, 960, 530);this.add(backgroundLabel);//按钮添加事件shangButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {if (x0 == 3) {return;}datas[x0][y0] = datas[x0 + 1][y0];//这一步作用是啥,为什么要让datas[x0+1][y0]=0;//原理是交换,datas[x0][y0]=0是固定的,然后把datas[x0+1][y0]赋值给datas[x0][y0]//再把0给datas[x0+1][y0],datas[x0 + 1][y0] = 0;x0 = x0 + 1;//调用判断方法,成功之后调用提示按钮的方法if (isSuccess()) {success();}//对图片进行重新遍历输出rePaintView();}});zuoButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {if (y0 == 3) {return;}datas[x0][y0] = datas[x0][y0 + 1];datas[x0][y0 + 1] = 0;y0 = y0 + 1;//调用判断方法,成功之后调用提示按钮的方法if (isSuccess()) {success();}//对图片进行重新遍历输出rePaintView();}});xiaButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {if (x0 == 0) {return;}datas[x0][y0] = datas[x0 - 1][y0];datas[x0 - 1][y0] = 0;x0 = x0 - 1;//调用判断方法,成功之后调用提示按钮的方法if (isSuccess()) {success();}//对图片进行重新遍历输出rePaintView();}});youButton.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {if (y0 == 0) {return;}datas[x0][y0] = datas[x0][y0 - 1];datas[x0][y0 - 1] = 0;y0 = y0 - 1;//调用判断方法,成功之后调用提示按钮的方法if (isSuccess()) {success();}//对图片进行重新遍历输出rePaintView();}});}//定义两个int类型的变量,用于记录0号图片的位置//0号图片作用是啥,为什么要定义0号图片//0号图片作用是和数组里面的编号图片作一交换,用来完成拼图private int x0;private int y0;//打乱二维数组public void randomData() {Random random = new Random();for (int i = 0; i < datas.length; i++) {for (int j = 0; j < datas[i].length; j++) {int x = random.nextInt(datas.length);int y = random.nextInt(datas[i].length);int temp = datas[i][j];datas[i][j] = datas[x][y];datas[x][y] = temp;}}//记录0号图片的位置 wc作用是啥?wc作用是给最外层for循环起了一个名字,之后用break结束整体循环wc:for (int i = 0; i < datas.length; i++) {for (int j = 0; j < datas[i].length; j++) {if (datas[i][j] == 0) {x0 = i;y0 = j;break wc;}}}}//遍历移动后的图形,移动的图形重新绘制public void rePaintView() {//移除所有:移除的是JPanel标签上的全部组件,目的就是清空里面的数据imagePanel.removeAll();//遍历二维数组for (int i = 0; i < datas.length; i++) {for (int j = 0; j < datas[i].length; j++) {//创建JLabel对象,加载图片资源JLabel imagesJlabel1 = new JLabel(new ImageIcon("day09\images\" + datas[i][j] + ".png"));//调整照片位置imagesJlabel1.setBounds(j * 90, i * 90, 90, 90);imagePanel.add(imagesJlabel1);}}//对JPanel里面的组件进行从新打印imagePanel.repaint();}//定义一个成功的操作,用提示来调用public void success() {datas = new int[][]{{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12},{13, 14, 15, 16}};shangButton.setEnabled(false);zuoButton.setEnabled(false);xiaButton.setEnabled(false);youButton.setEnabled(false);}//定义一个点击按钮判断是否成功的方法public boolean isSuccess() {for (int i = 0; i < datas.length; i++) {for (int j = 0; j < datas[i].length; j++) {if (datas[i][j] != winDatas[i][j]) {return false;}}}return true;}}
发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章