当前位置: 首页 > 工具软件 > 拼图 > 使用案例 >

拼图小游戏

苏鸿羽
2023-12-01

一个简单的拼图小游戏
1.首先设计视图面板。
2.添加所需要的图片按钮。
3.最主要的是设计监听事件,添加图片的监听按钮,设定移动空白图片周围的按钮。
4.判断是否成功 。

package sxy;
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;
    }
}

二、效果图
![效果图](https://img-blog.csdnimg.cn/20200210154646314.PNG?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzcyMzY3Ng==,size_16,color_FFFFFF,t_70)
 类似资料: