第一步是创建项目 项目名自拟
第二部创建个包名 来规范class
然后是创建类 创建一个代码类 和一个运行类
代码如下:
- package heima;
-
- import java.awt.event.ActionEvent;
- import java.awt.event.ActionListener;
- import java.awt.event.KeyEvent;
- import java.awt.event.KeyListener;
- import java.util.Random;
-
- import javax.swing.ImageIcon;
- import javax.swing.JDialog;
- import javax.swing.JFrame;
- import javax.swing.JLabel;
- import javax.swing.JMenu;
- import javax.swing.JMenuBar;
- import javax.swing.JMenuItem;
- import javax.swing.border.BevelBorder;
-
- public class GameJFrame extends JFrame implements KeyListener,ActionListener{
- //GameJFrame这个界面表示的就是 游戏的主界面
- //以后跟游戏相关的所有逻辑都写在这个类中
-
- //创建一个二维数组
- //目的:用来管理数据
- //加载图片的时候,会根据二维数组中的数据来进行加载
- int[][] data =new int[4][4];
- //记录空白方块在二维数组中的位置
- int x=0;
- int y=0;
- //定义一个变量,记录当前展示图片的路径
- String path = "D:\\学习资料\\Java\\拼图小游戏\\image\\animal\\animal1\\";
- //定义一个二维数组 存储一个正确的数据
- int[][] win= {
- {1,2,3,4},
- {5,6,7,8},
- {9,10,11,12},
- {13,14,15,16},
- };
- //定义变量来统计部署
- int step = 0 ;
-
- //创建项目下面的条目对象
- JMenuItem replayItem =new JMenuItem("重新游戏");
- JMenuItem reLoginItem =new JMenuItem("重新登录");
- JMenuItem closeItem =new JMenuItem("关闭游戏");
-
- JMenuItem accountItem =new JMenuItem("丁国俊的微信");
-
- public GameJFrame () {
- //初始化界面
- intiJFrame();
-
- //初始化菜单
- initJMenuBar();
-
- //初始化数据
- initData();
-
- //初始化图片(根据打乱之后的结果去加载图片)
- initImage();
-
-
-
- //设置窗体可见 放到最后
- this.setVisible(true);
- }
-
- //初始化数据
- private void initData() {
- //1.定义一个一维数组
- int[] tempArr= {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
- //2.打乱数组中的数据顺序
- //遍历数组中得到的每一个元素,拿到每一个元素跟随索引上的数据进行交换
- Random r = new Random();
- for(int i =0 ;i<tempArr.length;i++) {
- //获取随机索引
- int index = r.nextInt(tempArr.length);
- //拿到遍历到每一个数据,跟随机索引上的数据进行交换
- int temp =tempArr[index];
- tempArr[i] = tempArr[index];
- tempArr[index] =temp;
- }
-
- //4.给二维数组添加数据
- //遍历一维数组tempArr得到每一个元素, 把每一个元素依次添加到二维数组当中
- for(int i=0;i<tempArr.length;i++) {
- if(tempArr[i]==0) {
- x=i/4;
- y=i%4;
- }else {
- data[i/4][i%4]=tempArr[i];
- }
- }
- }
- //初始化图片
- //添加图片的时候,就需要按照二维数组中管理的数据添加图片
- private void initImage() {
- //清空原本已经出现的所有图片
- this.getContentPane().removeAll();
-
- if(victory()) {
- //显示胜利图标
- JLabel winJLabel = new JLabel(new ImageIcon("D:\\学习资料\\Java\\拼图小游戏\\image\\win.png"));
- winJLabel.setBounds(203,283,197,73);
- this.getContentPane().add(winJLabel);
- }
-
-
-
- JLabel stepCount = new JLabel ("步数"+step);
- stepCount.setBounds(50,30,100,20);
- this.getContentPane().add(stepCount);
-
-
-
- //先加载的图片在上方 后加载的图片在下方
- //外循环---把内循环重复执行了4次
- for (int i = 0; i<4;i++) {
- //内循环---表示一行添加了4张图片
- for (int j = 0; j<4;j++) {
- //获取当前要加载图片的序号
- int num = data[i][j];
- //创建一个JLabel的对象(管理容器)
- JLabel jLabel =new JLabel(new ImageIcon(path+ num + ".jpg"));
- //指定图片位置
- jLabel.setBounds(105*j+83,105*i+134,105,105);
- //给图片添加边框
- jLabel.setBorder(new BevelBorder(BevelBorder.LOWERED));//设置边框凹下来
-
- //把管理容器添加到界面中
- this.getContentPane().add(jLabel);//取消默认的居中放置
- }
- }
- JLabel background =new JLabel(new ImageIcon("D:\\学习资料\\Java\\拼图小游戏\\image\\background.png"));
- background.setBounds(40,40,508,560);
- //将背景图片添加到界面中
- this.getContentPane().add(background);
-
- //刷新一下界面
- this.getContentPane().repaint();
-
- }
- public void intiJFrame() {
-
- //GameJFrame这个界面表示的就是 游戏的主界面
- //以后跟游戏相关的所有逻辑都写在这个类
- //设置界面的宽高
- this.setSize(603,680);
- //设置界面的标题
- this.setTitle("拼图单机版v1.8");
- //设置界面置顶
- this.setAlwaysOnTop(true);
- //设置页面居中
- this.setLocationRelativeTo(null);
- //设置关闭模式
- this.setDefaultCloseOperation(3);
-
- //取消默认的居中放置 只有取消了才会按照xy的形式来添加组件
- this.setLayout(null);
- //给整个界面添加键盘监听事件
- this.addKeyListener(this );
-
- }
- public void initJMenuBar(){
- //初始化菜单
- JMenuBar jMenuBar =new JMenuBar();
-
- //常见菜单上的两个选项的对象(功能 关于我们 )
- JMenu functionJMenu = new JMenu("功能");
- JMenu aboutJMenu = new JMenu("关于我们");
-
- //将每一个选项下面的条目放在选项当中
- functionJMenu.add(replayItem);
- functionJMenu.add(reLoginItem);
- functionJMenu.add(closeItem);
-
- aboutJMenu.add(accountItem);
-
- //给条目绑定时间
- replayItem.addActionListener(this);
- reLoginItem.addActionListener(this);
- closeItem.addActionListener(this);
- accountItem.addActionListener(this);
-
- //将菜单里的两个选项添加到菜单当中去
- jMenuBar.add(functionJMenu);
- jMenuBar.add(aboutJMenu);
-
- //给整个界面设置菜单
- this.setJMenuBar(jMenuBar);
-
-
-
- }
-
- @Override
- public void keyTyped(KeyEvent e) {
- // TODO Auto-generated method stub
-
- }
-
- @Override
- //按下不松时会调用这个方法
- public void keyPressed(KeyEvent e) {
- // TODO Auto-generated method stub
- int code = e.getKeyCode();
- if(code==65) {
- //把界面所有的图片删除
- this.getContentPane().removeAll();
- //加载第一张完整的图片
- JLabel all =new JLabel(new ImageIcon(path +"all.jpg"));
- all.setBounds(83,134,420,420);
- this.getContentPane().add(all);
- //加载背景图片
- //添加背景图片
- JLabel background =new JLabel(new ImageIcon("D:\\学习资料\\Java\\拼图小游戏\\image\\background.png"));
- background.setBounds(40,40,508,560);
- //将背景图片添加到界面中
- //把背景图片添加到界面中
- this.getContentPane().add(background);
- //刷新界面
- this.getContentPane().repaint();
- }
- }
-
- @Override
- public void keyReleased(KeyEvent e) {
-
- // TODO Auto-generated method stub
- //对 上,下,左,右进行判断
- //左37 上38 右39 下40
- int code =e.getKeyCode();
- if(code ==37) {
- System.out.println("向左移动");
- if(y==3){
- return;
- }
- data[x][y] =data[x][y+1];
- data[x][y+1]=0;
- y++;
- //有一次移动,计步器自增一次
- step++;
- //调用方法按照最新的数字加载图片
- initImage();
- }else if(code ==38) {
- System.out.println("向上移动");
- //逻辑
- //空白方框下方的数字往上移动
- //x,y表示空白方块
- //x+1,y表示空白方块下方的数字
-
- //把空白方块下方的数字赋值给空白方块
- if(x==3){
- return;
- }
- data[x][y] =data[x+1][y];
- data[x+1][y]=0;
- x++;
- //有一次移动,计步器自增一次
- step++;
- //调用方法按照最新的数字加载图片
- initImage();
- }else if(code ==39) {
- System.out.println("向右移动");
- if(y==0){
- return;
- }
- data[x][y] =data[x][y-1];
- data[x][y-1]=0;
- y--;
- //有一次移动,计步器自增一次
- step++;
- }else if(code ==40) {
- System.out.println("向下移动");
- if(x==0){
- return;
- }
- data[x][y] =data[x-1][y];
- data[x-1][y]=0;
- x--;
- //有一次移动,计步器自增一次
- step++;
- //调用方法按照最新的数字加载图片
- initImage();
- }else if(code ==65){
- initImage();
- }else if(code ==87) {
- data =new int[][] {
- {1,2,3,4},
- {5,6,7,8},
- {9,10,11,12},
- {13,14,15,16}
- };
- initImage();
- }
- }
- //判断data数组中的数据是否跟win数组中的i昂同
- //如果全部相同返回true,否则返false
- public boolean victory() {
- for( int i=0;i<data.length;i++) {
- //i:依次表示二维数组中的data里面的索引
- //data[i]:依次表示每一个一维数组
- for(int j=0;j<data[i].length;j++) {
- if(data[i][j] !=win[i][j]) {
- //只要有一个数据不一样则返回false
- return false;
- }
- }
- }
- //循环结束表示数组遍历比较完毕 ,全部一样的话返回true
- return false;
-
- }
- public void actionPerformed(ActionEvent e) {
- //获取当前被点击的条目对象
- Object obj =e.getSource();
- //判断
- if(obj ==replayItem) {
- System.out.println("重新游戏");
-
- //计步器清零
- step = 0;
-
- //再次打乱二维数组
- initData();
-
- //重新加载图片
- initImage();
- }else if(obj == reLoginItem) {
- System.out.println("重新登录");
- this.setVisible(false);
- //打开登入界面
- new LoginJFrame();
- }else if(obj == closeItem) {
- System.out.println("关闭游戏");
- //直接关闭游戏
- System.exit(0);
- }else if(obj == accountItem) {
- System.out.println("丁国俊的微信");
- JDialog jDialog=new JDialog();
- //创建一个管理图片的容器对象jDialog
- JLabel jLabel = new JLabel(new ImageIcon("D:\\学习资料\\Java\\拼图小游戏\\image\\微信图片_20231119183326.jpg")) ;
- //设置位置和宽高
- jLabel.setBounds(0,0,258,258);
- //把图片添加到弹框中
- jDialog.getContentPane().add(jLabel);
- //设置弹框大小
- jDialog.setSize(344,344);
- //让弹框置顶
- jDialog.setAlwaysOnTop(true);
- //让弹框剧中
- jDialog.setLocationRelativeTo(null);
- //弹框不关闭则无法操作下面的界面
- jDialog.setModal(true);
- //让弹框显示出来
- jDialog.setVisible(true);
- }
- }
- }
测试类如下:
- package heima;
-
- public class App {
- public static void main(String[]args) {
- //表示程序的启动入口
- //如果我们想要开启一个界面,就创建谁的对象就可以了
- new GameJFrame();//调用游戏主界面窗体
- //new RegisterJFrame();//注册界面
- //new LoginJFrame();//登入界面
- }
- }
运行结果如下: