一、数字华容道
1.素材准备:
网上搜~,我这也是网上找的(免费资源找找就行)
2.目标实现
游戏规则就不说了,都玩过~,自己知道就好
(1)窗体的绘制
-
使用创建一个窗口类(Window)继承JFrame
-
在Window类中要调用两个方法
-
用于窗体的基本设置
-
设置窗体可见
-
-
在窗体的基本设置中要设置好以下内容
-
窗体大小
-
窗体标题
-
窗体居中
-
窗体关闭时退出应用程序
-
窗体位于其他窗口之上
-
取消窗体默认布局
-
window:
public class Window extends JFrame {
public Window(){//窗体设置windowSettings();//窗体可见this.setVisible(true);}
private void windowSettings() {//窗体大小,参数(宽,高)单位:像素this.setSize(960,565);//窗体标题this.setTitle("数字华容道");//窗体居中this.setLocationRelativeTo(null);//窗体关闭后退出程序this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//窗体位于其他窗口上this.setAlwaysOnTop(true);//取消窗体的默认布局this.setLayout(null);
}
}
RunClass:
public class RunClass {public static void main(String[] args) {Window window = new Window();
}
}
(2)窗体上组件的绘制
所有图片也是以左上角为主
window:
//构造里面添加
addComponents();
private void addComponents() {//添加标题addTitle();//添加游戏面板addGameBoard();//添加方向键addButtons();//添加背景addBackground();
}
private void addTitle() {//标题图片JLabel title = new JLabel(new ImageIcon("digital_huarong_road\\src\\images\\title.png"));//设置该组件的位置(x,y,宽,高)title.setBounds(960 - 232 - 125, 57, 232, 57);//将该组件添加进窗口this.add(title);
}
private void addGameBoard() {//游戏面板整体是个二维数组//先打乱一下数组disrupt(数组)disrupt(randomData);//记录空缺在数组中的位置recordPosition(randomData);
//检查for (int i = 0; i < randomData.length; i++) {System.out.println(Arrays.toString(randomData[i]));}
//创建面板gameBoard = new JPanel();gameBoard.setBounds(100, 75, 90 * 4, 90 * 4);gameBoard.setLayout(null);for (int i = 0; i < randomData.length; i++) {for (int j = 0; j < randomData[i].length; j++) {JLabel gameBoardBody = new JLabel(new ImageIcon("digital_huarong_road\\src\\images\\" + randomData[i][j] + ".png"));gameBoardBody.setBounds(j * 90, i * 90, 90, 90);gameBoard.add(gameBoardBody);}}this.add(gameBoard);
}
private void addButtons() {String[] fileNames = {"shang", "xia", "zuo", "you", "qiuzhu", "chongzhi"};
for (String fileName : fileNames) {if ("shang".equals(fileName)) {jButtonUp = new JButton(new ImageIcon("digital_huarong_road\\src\\images\\" + fileName + ".png"));jButtonUp.setBounds(732 - 40, 265 - 65, 57, 57);this.add(jButtonUp);}if ("xia".equals(fileName)) {jButtonDown = new JButton(new ImageIcon("digital_huarong_road\\src\\images\\" + fileName + ".png"));jButtonDown.setBounds(732 - 40, 347 - 65, 57, 57);this.add(jButtonDown);}if ("zuo".equals(fileName)) {jButtonLeft = new JButton(new ImageIcon("digital_huarong_road\\src\\images\\" + fileName + ".png"));jButtonLeft.setBounds(650 - 40, 347 - 65, 57, 57);this.add(jButtonLeft);}if ("you".equals(fileName)) {jButtonRight = new JButton(new ImageIcon("digital_huarong_road\\src\\images\\" + fileName + ".png"));jButtonRight.setBounds(813 - 40, 347 - 65, 57, 57);this.add(jButtonRight);}if ("chongzhi".equals(fileName)) {jButtonReset = new JButton(new ImageIcon("digital_huarong_road\\src\\images\\" + fileName + ".png"));jButtonReset.setBounds(786 - 40, 444 - 65, 108, 45);this.add(jButtonReset);}if ("qiuzhu".equals(fileName)) {jButtonHelp = new JButton(new ImageIcon("digital_huarong_road\\src\\images\\" + fileName + ".png"));jButtonHelp.setBounds(626 - 40, 444 - 65, 108, 45);this.add(jButtonHelp);}}
}
private void addBackground() {//标题图片JLabel background = new JLabel(new ImageIcon("digital_huarong_road\\src\\images\\background.png"));//设置该组件的位置(x,y,宽,高)background.setBounds(0, 0, 960, 565);//将该组件添加进窗口this.add(background);
}
private void disrupt(int[][] randomData) {
Random random = new Random();for (int i = 0; i < randomData.length; i++) {for (int j = 0; j < randomData[i].length; j++) {int x = random.nextInt(randomData.length);int y = random.nextInt(randomData[i].length);
int temp = randomData[i][j];randomData[i][j] = randomData[x][y];randomData[x][y] = temp;}}
}
效果如图:
(3)记录一下空缺图片在二维数组的位置
private void recordPosition(int[][] randomData) {
//拓展,循环可以起名//格式为:循环名:循环体//普通break只能退出单层循环//break 循环名; 意为退出该名称的循环outer:for (int i = 0; i < randomData.length; i++) {for (int j = 0; j < randomData[i].length; j++) {if (randomData[i][j] == 16) {x16 = i;y16 = j;break outer;}}}System.out.println("x:" + x16 + "\t" + "y:" + y16);
}
(4)给按钮添加事件()
//其他同理
private void addEventToButton() {jButtonUp.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("上");}}
}
(5)实现移动
主要解决:
-
数据交换
-
重绘
-
边界问题
window:其实是不推荐一个方法写这么多代码的~
private void addEventToButton() {jButtonUp.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("上");if (x16 == 3) {return;} else {randomData[x16][y16] = randomData[x16 + 1][y16];randomData[x16 + 1][y16] = 16;x16 = x16 + 1;
for (int i = 0; i < randomData.length; i++) {System.out.println(Arrays.toString(randomData[i]));}
//调用重绘方法redraw(randomData);
System.out.println("x:" + x16 + "\t" + "y:" + y16);
}
}});
jButtonDown.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("下");if (x16 == 0) {return;} else {randomData[x16][y16] = randomData[x16 - 1][y16];randomData[x16 - 1][y16] = 16;x16 = x16 - 1;
for (int i = 0; i < randomData.length; i++) {System.out.println(Arrays.toString(randomData[i]));}
//调用重绘方法redraw(randomData);
System.out.println("x:" + x16 + "\t" + "y:" + y16);
}
}});jButtonLeft.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("左");if (y16 == 3) {return;} else {randomData[x16][y16] = randomData[x16][y16 + 1];randomData[x16][y16 + 1] = 16;y16 = y16 + 1;
for (int i = 0; i < randomData.length; i++) {System.out.println(Arrays.toString(randomData[i]));}
//调用重绘方法redraw(randomData);System.out.println("x:" + x16 + "\t" + "y:" + y16);
}
}});jButtonRight.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("右");if (y16 == 0) {return;} else {randomData[x16][y16] = randomData[x16][y16 - 1];randomData[x16][y16 - 1] = 16;y16 = y16 - 1;
for (int i = 0; i < randomData.length; i++) {System.out.println(Arrays.toString(randomData[i]));}
//调用重绘方法redraw(randomData);System.out.println("x:" + x16 + "\t" + "y:" + y16);
}
}});jButtonReset.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("重置");
//重新打乱for (int i = 0; i < randomData.length; i++) {System.out.println(Arrays.toString(randomData[i]));}disrupt(randomData);recordPosition(randomData);redraw(randomData);//启用controlButtonEvent(true);
}});jButtonHelp.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("求助");success();
}});
}
重绘方法:
private void redraw(int[][] randomData) {gameBoard.removeAll();
for (int i = 0; i < randomData.length; i++) {for (int j = 0; j < randomData[i].length; j++) {JLabel gameBoardBody = new JLabel(new ImageIcon("digital_huarong_road\\src\\images\\" + randomData[i][j] + ".png"));gameBoardBody.setBounds(j * 90, i * 90, 90, 90);gameBoard.add(gameBoardBody);}}this.add(gameBoard);
gameBoard.repaint();
}
(6)求助与重置的实现
求助:一键成功
-
数组复位
-
重绘
-
清除对应按键的事件
private void success() {randomData = new int[][]{{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12},{13, 14, 15, 16},};for (int i = 0; i < randomData.length; i++) {System.out.println(Arrays.toString(randomData[i]));}
//一键完成redraw(randomData);//清除按钮事件controlButtonEvent(false);
}
重置:
-
打乱数组
-
重新定位
-
重绘
-
恢复对应按键的事件
disrupt(randomData);
recordPosition(randomData);
redraw(randomData);
//启用
controlButtonEvent(true);
redraw:
private void redraw(int[][] randomData) {//先清除所有内容gameBoard.removeAll();//重新添加for (int i = 0; i < randomData.length; i++) {for (int j = 0; j < randomData[i].length; j++) {JLabel gameBoardBody = new JLabel(new ImageIcon("digital_huarong_road\\src\\images\\" + randomData[i][j] + ".png"));gameBoardBody.setBounds(j * 90, i * 90, 90, 90);gameBoard.add(gameBoardBody);}}this.add(gameBoard);//重绘gameBoard.repaint();
}
数组复位:
randomData = new int[][]{{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12},{13, 14, 15, 16},
};
按键/钮事件控制
private void controlButtonEvent(boolean b) {jButtonUp.setEnabled(b);jButtonDown.setEnabled(b);jButtonLeft.setEnabled(b);jButtonRight.setEnabled(b);jButtonHelp.setEnabled(b);
}
(7)胜利规则
-
二维数组比较:Arrays类中有个深度比较的静态方法deepEquals!
-
弹窗
private void check(){//判断二维数组是否相同if (Arrays.deepEquals(randomData, DATA)){JOptionPane.showMessageDialog(this, "成功", "游戏结束", JOptionPane.PLAIN_MESSAGE);}
}
效果如图:
核心代码:
package production_stage04;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import java.util.Random;
public class Window extends JFrame {
private int[][] randomData = {{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12},{13, 14, 15, 16}};private static final int[][] DATA = {{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12},{13, 14, 15, 16}};
private int x16;private int y16;/*** 定义功能按钮*/private JButton jButtonUp = null;private JButton jButtonDown = null;private JButton jButtonLeft = null;private JButton jButtonRight = null;private JButton jButtonReset = null;private JButton jButtonHelp = null;private JPanel gameBoard = null;
public Window() {//窗体设置windowSettings();//窗体上添加组件addComponents();addEventToButton();
//窗体可见this.setVisible(true);}
private void check(){//判断二维数组是否相同if (Arrays.deepEquals(randomData, DATA)){JOptionPane.showMessageDialog(this, "成功", "游戏结束", JOptionPane.PLAIN_MESSAGE);}}
private void redraw(int[][] randomData) {gameBoard.removeAll();
for (int i = 0; i < randomData.length; i++) {for (int j = 0; j < randomData[i].length; j++) {JLabel gameBoardBody = new JLabel(new ImageIcon("digital_huarong_road\\src\\images\\" + randomData[i][j] + ".png"));gameBoardBody.setBounds(j * 90, i * 90, 90, 90);gameBoard.add(gameBoardBody);}}this.add(gameBoard);
gameBoard.repaint();}
private void addEventToButton() {jButtonUp.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("上");if (x16 == 3) {return;} else {randomData[x16][y16] = randomData[x16 + 1][y16];randomData[x16 + 1][y16] = 16;x16 = x16 + 1;
for (int i = 0; i < randomData.length; i++) {System.out.println(Arrays.toString(randomData[i]));}
//调用重绘方法redraw(randomData);check();
System.out.println("x:" + x16 + "\t" + "y:" + y16);
}
}});
jButtonDown.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("下");if (x16 == 0) {return;} else {randomData[x16][y16] = randomData[x16 - 1][y16];randomData[x16 - 1][y16] = 16;x16 = x16 - 1;
for (int i = 0; i < randomData.length; i++) {System.out.println(Arrays.toString(randomData[i]));}
//调用重绘方法redraw(randomData);check();System.out.println("x:" + x16 + "\t" + "y:" + y16);
}
}});jButtonLeft.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("左");if (y16 == 3) {return;} else {randomData[x16][y16] = randomData[x16][y16 + 1];randomData[x16][y16 + 1] = 16;y16 = y16 + 1;
for (int i = 0; i < randomData.length; i++) {System.out.println(Arrays.toString(randomData[i]));}
//调用重绘方法redraw(randomData);check();System.out.println("x:" + x16 + "\t" + "y:" + y16);
}
}});jButtonRight.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("右");if (y16 == 0) {return;} else {randomData[x16][y16] = randomData[x16][y16 - 1];randomData[x16][y16 - 1] = 16;y16 = y16 - 1;
for (int i = 0; i < randomData.length; i++) {System.out.println(Arrays.toString(randomData[i]));}
//调用重绘方法redraw(randomData);check();System.out.println("x:" + x16 + "\t" + "y:" + y16);
}
}});jButtonReset.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("重置");
//重新打乱for (int i = 0; i < randomData.length; i++) {System.out.println(Arrays.toString(randomData[i]));}disrupt(randomData);recordPosition(randomData);redraw(randomData);check();
//启用controlButtonEvent(true);
}});jButtonHelp.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("求助");success();check();}});
}
private void success() {randomData = new int[][]{{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12},{13, 14, 15, 16},};
for (int i = 0; i < randomData.length; i++) {System.out.println(Arrays.toString(randomData[i]));}
//一键完成redraw(randomData);//清除按钮事件controlButtonEvent(false);}
private void controlButtonEvent(boolean b) {jButtonUp.setEnabled(b);jButtonDown.setEnabled(b);jButtonLeft.setEnabled(b);jButtonRight.setEnabled(b);jButtonHelp.setEnabled(b);}
private void recordPosition(int[][] randomData) {
//拓展,循环可以起名//格式为:循环名:循环体//普通break只能退出单层循环//break 循环名; 意为退出该名称的循环outer:for (int i = 0; i < randomData.length; i++) {for (int j = 0; j < randomData[i].length; j++) {if (randomData[i][j] == 16) {x16 = i;y16 = j;break outer;}}}System.out.println("x:" + x16 + "\t" + "y:" + y16);
}
private void addComponents() {//添加标题addTitle();//添加游戏面板addGameBoard();//添加方向键addButtons();//添加背景addBackground();}
private void addBackground() {//标题图片JLabel background = new JLabel(new ImageIcon("digital_huarong_road\\src\\images\\background.png"));//设置该组件的位置(x,y,宽,高)background.setBounds(0, 0, 960, 565);//将该组件添加进窗口this.add(background);}
private void addButtons() {String[] fileNames = {"shang", "xia", "zuo", "you", "qiuzhu", "chongzhi"};
for (String fileName : fileNames) {if ("shang".equals(fileName)) {jButtonUp = new JButton(new ImageIcon("digital_huarong_road\\src\\images\\" + fileName + ".png"));jButtonUp.setBounds(732 - 40, 265 - 65, 57, 57);this.add(jButtonUp);}if ("xia".equals(fileName)) {jButtonDown = new JButton(new ImageIcon("digital_huarong_road\\src\\images\\" + fileName + ".png"));jButtonDown.setBounds(732 - 40, 347 - 65, 57, 57);this.add(jButtonDown);}if ("zuo".equals(fileName)) {jButtonLeft = new JButton(new ImageIcon("digital_huarong_road\\src\\images\\" + fileName + ".png"));jButtonLeft.setBounds(650 - 40, 347 - 65, 57, 57);this.add(jButtonLeft);}if ("you".equals(fileName)) {jButtonRight = new JButton(new ImageIcon("digital_huarong_road\\src\\images\\" + fileName + ".png"));jButtonRight.setBounds(813 - 40, 347 - 65, 57, 57);this.add(jButtonRight);}if ("chongzhi".equals(fileName)) {jButtonReset = new JButton(new ImageIcon("digital_huarong_road\\src\\images\\" + fileName + ".png"));jButtonReset.setBounds(786 - 40, 444 - 65, 108, 45);this.add(jButtonReset);}if ("qiuzhu".equals(fileName)) {jButtonHelp = new JButton(new ImageIcon("digital_huarong_road\\src\\images\\" + fileName + ".png"));jButtonHelp.setBounds(626 - 40, 444 - 65, 108, 45);this.add(jButtonHelp);}}
}
private void disrupt(int[][] randomData) {
Random random = new Random();for (int i = 0; i < randomData.length; i++) {for (int j = 0; j < randomData[i].length; j++) {int x = random.nextInt(randomData.length);int y = random.nextInt(randomData[i].length);
int temp = randomData[i][j];randomData[i][j] = randomData[x][y];randomData[x][y] = temp;}}
}
private void addGameBoard() {//游戏面板整体是个二维数组//先打乱一下数组disrupt(数组)disrupt(randomData);//记录空缺在数组中的位置recordPosition(randomData);
//检查for (int i = 0; i < randomData.length; i++) {System.out.println(Arrays.toString(randomData[i]));}
//创建面板gameBoard = new JPanel();gameBoard.setBounds(100, 75, 90 * 4, 90 * 4);gameBoard.setLayout(null);for (int i = 0; i < randomData.length; i++) {for (int j = 0; j < randomData[i].length; j++) {JLabel gameBoardBody = new JLabel(new ImageIcon("digital_huarong_road\\src\\images\\" + randomData[i][j] + ".png"));gameBoardBody.setBounds(j * 90, i * 90, 90, 90);gameBoard.add(gameBoardBody);}}this.add(gameBoard);}
private void addTitle() {//标题图片JLabel title = new JLabel(new ImageIcon("digital_huarong_road\\src\\images\\title.png"));//设置该组件的位置(x,y,宽,高)title.setBounds(960 - 232 - 125, 57, 232, 57);//将该组件添加进窗口this.add(title);}
private void windowSettings() {//窗体大小,参数(宽,高)单位:像素this.setSize(960, 565);//窗体标题this.setTitle("数字华容道");//窗体居中this.setLocationRelativeTo(null);//窗体关闭后退出程序this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);//窗体位于其他窗口上this.setAlwaysOnTop(true);//取消窗体的默认布局this.setLayout(null);
}
}
(8)后期优化/拓展
自己看着来,不写了