Java 拼图游戏

2014-07-01· 9711 次浏览
## 效果图 ![pintu.png](https://image.xsoftlab.net/baike/articleImages/9b0d694c18bc0af15f2f7909f78a83b4.jpg) ## 准备工作 准备2张500X500像素的图片,命名分别为0.jpg与1.jpg,放在代码根目录 ## 代码 ```java import java.awt.Choice; import java.awt.Image; import java.awt.Toolkit; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.image.CropImageFilter; import java.awt.image.FilteredImageSource; import java.awt.image.ImageFilter; import java.util.Random; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; public class PintuGame { public static void main(String args[]) { new PintuFrame().StartFrame(); } } class PintuFrame extends JFrame { private static final long serialVersionUID = 1L; // 等级设置 private static int level = 3; // 图片索引 private static int index = 0; // 图片数量 private static int picCount = 2; // 开始时间 private long startTime; // 初始化小方块 private JButton[] buttons; // 初始化空方块 private JPanel emptyPanel = new JPanel(); // 初始化监听类 private PintuListener listener = new PintuListener(); // 初始化Panel private JPanel panel = new JPanel(null); // 图片预览 private JLabel label; private String[] imgpath = new String[picCount]; // 选图时的图片路径 String path; public PintuFrame() { for (int i = 0; i < picCount; i++) { imgpath[i] = i + ".jpg"; System.out.println(imgpath[i]); } path = imgpath[index]; } /** * 开始窗体加载 */ public void StartFrame() { panel.removeAll(); JButton start = new JButton("开始");// 开始按钮 JButton left = new JButton("<"); JButton right = new JButton(">"); JLabel selLevel = new JLabel("LV:"); label = new JLabel(getIcon());// 根据图标设置标签 final Choice choice = new Choice();// 创建选择器 choice.add("--初级--");// 添加列表项 choice.add("--中级--"); choice.add("--高级--"); selLevel.setBounds(5, 0, 20, 20);// 设置坐标 choice.setBounds(28, 0, 65, 20); start.setBounds(93, 0, 85, 20); left.setBounds(178, 0, 61, 20); right.setBounds(239, 0, 61, 20); label.setBounds(0, 22, 300, 300);// 设置标签的方位 panel.add(selLevel); panel.add(choice); panel.add(start); panel.add(left); panel.add(right); panel.add(label); panel.repaint(); add(panel); setTitle("拼图游戏"); setBounds(450, 130, 300, 322); setResizable(false); // 添加关闭按钮 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setVisible(true); // 监听等级选择 start.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { level = choice.getSelectedIndex() + 3; launchFrame(); } }); // 监听选图按钮 <- left.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { if (index == 0) { index = picCount - 1; path = imgpath[index]; } else { path = imgpath[--index]; } panel.remove(label); label = new JLabel(getIcon()); label.setBounds(0, 22, 300, 300); panel.add(label); panel.repaint(); } }); // 监听选图按钮 -> right.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { if (index == picCount - 1) { index = 0; path = imgpath[index]; } else { path = imgpath[++index]; } panel.remove(label); label = new JLabel(getIcon()); label.setBounds(0, 22, 300, 300); panel.add(label); panel.repaint(); } }); } /** * 拼图窗体加载 */ public void launchFrame() { startTime = System.currentTimeMillis(); panel.removeAll(); buttons = new JButton[level * level]; // 设置图标组 Icon[] icon = new PintuFrame().creatIcon(path); // 小方块索引 int index = 0; // 小方块坐标 int x = 0, y = 0; // 设置小方块位置,图标,监听 for (int i = 0; i < level; i++) { for (int j = 0; j < level; j++) { // 添加图标 buttons[index] = new JButton(icon[index]); // 添加监听 buttons[index].addMouseListener(listener); // 设置位置 buttons[index].setBounds(x, y, 100, 100); // 添加到panel panel.add(buttons[index++]); x += 100; } y += 100; x = 0; } // 移除最后一个小方块 panel.remove(buttons[(level * level) - 1]); // 设置空方块位置 emptyPanel.setBounds((level - 1) * 100, (level - 1) * 100, 100, 100); // 添加空方块 panel.add(emptyPanel); panel.repaint(); add(panel); setResizable(false); setTitle("拼图游戏"); // 设置大小 setBounds(450, 130, level * 100, level * 100 + 30); // 打乱方格顺序 breakRank(); // 添加关闭按钮 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } // 选图界面图像 public Icon getIcon() { ImageIcon bi = new ImageIcon(getClass().getClassLoader().getResource(path)); // 缩放大小并显示到窗体 Image image = bi.getImage().getScaledInstance(300, 300, Image.SCALE_REPLICATE); return new ImageIcon(image); } // 打乱方格 public void breakRank() { Random r = new Random(); int x = 0, y = 0, emptyDir_X = 0, emptyDir_Y = 0; // 模拟随即点击1000次,打乱方格 for (int i = 0; i < 1000; i++) { int rid = r.nextInt(level * level - 1); // 获得该方格按钮的横坐标 x = buttons[rid].getBounds().x; // 获得该方格按钮的纵坐标 y = buttons[rid].getBounds().y; // 得到空方格的横坐标 emptyDir_X = emptyPanel.getBounds().x; // 得到空方格的纵坐标 emptyDir_Y = emptyPanel.getBounds().y; move(x, y, emptyDir_X, emptyDir_Y, buttons[rid]); } } // 移动方格 public void move(int x, int y, int emptyDir_X, int emptyDir_Y, JButton button) { // 进行比较果满足条件则交换 if (x == emptyDir_X && y - emptyDir_Y == 100) { button.setLocation(button.getBounds().x, button.getBounds().y - 100); } else if (x == emptyDir_X && y - emptyDir_Y == -100) { button.setLocation(button.getBounds().x, button.getBounds().y + 100); } else if (x - emptyDir_X == 100 & y == emptyDir_Y) { button.setLocation(button.getBounds().x - 100, button.getBounds().y); } else if (x - emptyDir_X == -100 && y == emptyDir_Y) { button.setLocation(button.getBounds().x + 100, button.getBounds().y); } else return; // 重新设置空方格的位置 emptyPanel.setLocation(x, y); } // 判断是否拼凑成功 public boolean isFinish() { for (int i = 0; i < (level * level) - 1; i++) { int x = buttons[i].getBounds().x; int y = buttons[i].getBounds().y; // 根据坐标位置判断是否拼凑成功 0+0 0+1 .. if (y / 100 * level + x / 100 != i) return false; } return true; } // 事件监听类 public class PintuListener extends MouseAdapter { @Override public void mousePressed(MouseEvent e) { JButton button = (JButton) e.getSource();// 获得鼠标按的方格按钮 int x = button.getBounds().x;// 获得该方格按钮的横坐标 int y = button.getBounds().y;// 获得该方格按钮的纵坐标 int nullDir_X = emptyPanel.getBounds().x;// 得到空方格的横坐标 int nullDir_Y = emptyPanel.getBounds().y;// 得到空方格的纵坐标 move(x, y, nullDir_X, nullDir_Y, button); if (isFinish()) {// 进行是否完成的判断 panel.remove(emptyPanel);// 移除最后一个小方块 panel.add(buttons[(level * level) - 1]);// 移除最后一个小方块 JOptionPane.showMessageDialog(null, "恭喜你,完成拼图\r\n用时为:" + (System.currentTimeMillis() - startTime) / 1000 + "S"); for (int i = 0; i < picCount; i++) {// 循环撤消鼠标事件 buttons[i].removeMouseListener(listener); } StartFrame(); } repaint(); } } // 创建方格图标组 public Icon[] creatIcon(String srcImageFile) { ImageIcon bi = new ImageIcon(this.getClass().getClassLoader().getResource(srcImageFile)); // 读取源图像 Image image = bi.getImage(); int index = 0; int x = 0, y = 0; Icon[] icon = new Icon[level * level];// 根据窗体大小创建图标数量 for (int i = 0; i < level; i++) { for (int j = 0; j < level; j++) { // 从原图像上获取一个方形位置 ImageFilter cropFilter = new CropImageFilter(x, y, 100, 100); // 截取方形图像 Image img = Toolkit.getDefaultToolkit() .createImage(new FilteredImageSource(image.getSource(), cropFilter)); icon[index++] = new ImageIcon(img); x += 100; } y += 100; x = 0; } return icon; } } ```