前言

利用按钮组件以及图片的嵌入完成基本游戏的搭建,其中按钮事件监听是本代码的难点。以及事先要规划好基本模块,包括游戏的UI窗口、操作模块以及代码逻辑设计。


启动代码:

package API_UI_拼图游戏2;

public class start {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new UI_Bulid();
    }

}


窗口容器代码:

package API_UI_拼图游戏2;

import java.awt.GridLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.Random;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPanel;

class Mid_Panel extends JPanel{ //中部容器
    Button_remote[] btn = new Button_remote[25]; //按钮控件 以下默认最大只有5X5规模
    ImageIcon[] image = new ImageIcon[25];  //图片库
    int cutSize; //行or列规模
    int total; //图片总数
    int[] squence = new int[25];  //随机顺序 
    int tag;  //空白位置
    int Now_Size;

    Mid_Panel(String Image_Path,int cutSize) {
        Now_Size = 0;
        this.setRandomPanel(Image_Path,cutSize);
    }

    public void setRandomPanel(String Image_Path,int cutSize) {
        this.cutSize = cutSize;
        this.total = cutSize * cutSize;
        this.tag = total-1;

        this.removeAll();
        this.updateUI();
        this.setLayout(new GridLayout(cutSize,cutSize));
        this.setRandom();
        for(int i=0;i<total;i++) {
            btn[i] = new Button_remote();
            btn[i].setRow(i / cutSize);
            btn[i].setRank(i % cutSize);
            btn[i].addMouseListener(new MouseAdapter() {
                public void mousePressed(MouseEvent e) {
                    Button_remote button = (Button_remote) e.getSource();
                    Mid_Panel.this.change(button);
                }
            });
            this.add(btn[i]);           
        }

        for(int i=0;i<total-1;i++) {
            image[i] = new ImageIcon(Image_Path+"\\"+(squence[i]+1)+".jpg");
            btn[i].setIcon(image[i]);
        }
    }

    public void setRandom() {
        Random random = new Random();
        boolean[] mark = new boolean[total];
        Arrays.fill(mark, true);

        for(int i=0,num;i<total-2;i++) {
            num = random.nextInt(total-1);  //[0,total-1)
            if(mark[num]) {
                mark[num] = false;
                squence[i] = num;
            } else {
                i--;
            }
        }

        for(int i=0;i<total-1;i++) {  //避免最后一个随机很久都没找到
            if(mark[i]) {
                squence[total-2] = i;
                break;
            }
        }
        squence[total-1] = total-1;
    }

    private boolean Judge(int x,int y,int ax,int ay) {      
        if(ax == x && Math.abs(ay - y)==1 || ay == y && Math.abs(ax - x)==1) {
            return true;
        }else {
            return false;
        }
    }

    private boolean isWin() {
        for(int i=0;i<total-1;i++) {
            if(squence[i] != i) {
                return false;
            }
        }
        return true;
    }

    public void change(Button_remote button) {
        int x = button.getRow();
        int y= button.getRank();
        int ax = btn[tag].getRow();
        int ay = btn[tag].getRank();
        if(Judge(x, y, ax, ay)) {
            ImageIcon img = (ImageIcon)button.getIcon();
            button.setIcon(null);
            btn[tag].setIcon(img);

            int temp = x*cutSize+y;
            squence[tag]^=squence[temp];
            squence[temp]^=squence[tag];
            squence[tag]^=squence[temp];
            this.tag = temp;

            this.Now_Size++;

            if(isWin()) {

            }
        }
    }

}

/* * squence[position]:在position位置对应的图片名称 * */

操作界面代码:

package API_UI_拼图游戏2;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JRadioButtonMenuItem;

class UI_Bulid extends JFrame {
    Mid_Panel panel;
    String Image_Path; //图片路径
    int cutSize; //图片切割的数量
    JMenuBar bar; //菜单的顶层容器
    JMenu MenuMain,MenuOther,MenuChange;
    JMenuItem ItemRecord,ItemStart,ItemExit,ItemView,ItemBook;
    JRadioButtonMenuItem[] Game_Difficult = new JRadioButtonMenuItem[3];

    public UI_Bulid() {
        this.setTitle("Game");
        this.setSize(580,571);      
        this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        this.setResizable(false);
        this.setLocationRelativeTo(null);
        this.addWindowListener(new Exit_Query());

        this.setMenu();

        this.setDifficult();

        this.setMenuControl();

        panel = new Mid_Panel(Image_Path, cutSize);

        this.add(panel);

        this.setVisible(true);

    }

    class Exit_Query extends WindowAdapter {
        private UI_Bulid illustrate;
        @Override
        public void windowClosing(WindowEvent e) {  //注意!!这里是要重写windowClosing而不是windowClosed!!一个是点击关闭的事情一个是关闭后的事情 - -
            // TODO Auto-generated method stub
            super.windowClosed(e);
            int chose = JOptionPane.showConfirmDialog(illustrate, "你真的要退出吗?");
            if(chose == JOptionPane.YES_OPTION) {
                System.exit(0);
            }
        }       
    }

    public void setPath(String Image_Path) {
        this.Image_Path = Image_Path;
    }

    public void setcutSize(int cutSize) {
        this.cutSize = cutSize;
    }

    public void setDifficult() {
        this.Image_Path = "ImageElem\\Elem_1";
        this.cutSize = 3;
        for(int i=0;i<Game_Difficult.length;i++) {
            if(Game_Difficult[i].isSelected()) {
                this.Image_Path = "ImageElem\\Elem_"+(i+1);
                this.cutSize = i+3;
                break;
            }
        }
    }

    public void setMenu() {
        bar = new JMenuBar();
        MenuMain = new JMenu("菜单");
        MenuOther = new JMenu("其他");
        MenuChange = new JMenu("难度");

        ItemRecord = new JMenuItem("纪录");
        ItemStart = new JMenuItem("开始");
        ItemExit = new JMenuItem("退出");
        ItemView = new JMenuItem("答案");
        ItemBook = new JMenuItem("关于");



        this.setJMenuBar(bar);
        bar.add(MenuMain);
        bar.add(MenuOther);

        MenuMain.add(ItemStart);
        MenuMain.add(ItemView);
        MenuMain.add(MenuChange);
        MenuMain.add(ItemExit);

        MenuOther.add(ItemRecord);
        MenuOther.add(ItemBook);

        ButtonGroup Size_1 = new ButtonGroup(); //添加一组单选关系组
        String str;
        for (int i = 0; i < Game_Difficult.length; i++) {
            switch(i) {
            case 0:
                str = "Simple";
                break;
            case 1:
                str = "Ordinary";
                break;
            default:
                str = "Hard";
                break;
            }           
            Game_Difficult[i] = new JRadioButtonMenuItem(str);
            Size_1.add(Game_Difficult[i]);
            MenuChange.add(Game_Difficult[i]);
        }
        Game_Difficult[0].setSelected(true); //默认简单选项
    }

    public void setMenuControl() {
        this.ItemStart.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
            // System.out.println("Restart!");
                UI_Bulid.this.setDifficult();
// System.out.println(Image_Path+"\n"+cutSize);
                panel.setRandomPanel(Image_Path, cutSize);
            }
        });

        this.ItemExit.addActionListener(new ActionListener() {
            private UI_Bulid illustrate;
            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                int chose = JOptionPane.showConfirmDialog(illustrate, "你真的要退出吗?");
                if(chose == JOptionPane.YES_OPTION) {
                    System.exit(0);
                }
            }
        });

        this.ItemView.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                // TODO Auto-generated method stub
                JFrame findMechine = new JFrame("完成图案");
                JButton btn = new JButton(new ImageIcon("ImageElem\\Index_01.jpg"));
                findMechine.add(btn);
                findMechine.setSize(580,571);
                findMechine.setResizable(false);
                findMechine.setLocationRelativeTo(null);
                findMechine.setVisible(true);
            }
        });
    }
}

拼图按钮类:

package API_UI_拼图游戏2;

import javax.swing.JButton;

class Button_remote extends JButton{
    private int row; //行
    private int rank; //列
    /** * @return the row */
    public int getRow() {
        return row;
    }
    /** * @param row the row to set */
    public void setRow(int row) {
        this.row = row;
    }
    /** * @return the rank */
    public int getRank() {
        return rank;
    }
    /** * @param rank the rank to set */
    public void setRank(int rank) {
        this.rank = rank;
    }


}

总结

类梳理

  1. JFrame用来创建application
  2. JApplet用来创建applet
  3. JDialog用来创建对话框
  4. JPanel提供一个面板
  5. JScrollPane是具有滚动条的窗格
  6. JSplitPane是具有拆分功能的窗格
  7. JTabbedPane是带有若干标签的分类窗格
  8. JInternalFrame用于创建内嵌于JFrame中的内部框架
  9. Box提供创建横向/纵向盒子容器的功能

基本组件总结


改进:

  1. 游戏没有加入多线程部分
  2. 部分菜单模块的功能还未实现
  3. 游戏随机生成的拼图模块顺序可能本身存在BUG(永远Accept不了):当出现12345687这种映射状况或者其再组合的情况是无解的,所以随机的同时应该将出现能够重组合得到该情况的序列剪枝