• 拼图小游戏Java简易版


    技术需求

    Java基础封装、继承、多态。

    代码实现

    创建一个子类继承自父类JFrame,好处是继承到父类的所有方法,直接使用,更为方便。

    public class MyFrame{}
    
    • 1

    创建方法用于设置窗口参数

    public void window(){
            // 设置窗口大小
            setSize(514,594);
            // 设置窗口标题
            setTitle("单机游戏v1.0");
            // 设置窗口居中显示
            setLocationRelativeTo(null);
            // 设置窗口置顶
            setAlwaysOnTop(true);
            // 设置程序关闭模式为窗口关闭
            setDefaultCloseOperation(MyFrameDemo.EXIT_ON_CLOSE);
            // 取消默认布局
            setLayout(null);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    图片本身不能移动,将图片映射为二维数组下标,数组下标的改变实际上就模拟了图片的移动。
    程序每次运行都需要打乱图片的摆放顺序,这里采取的办法是:将图片编号,然后把图片的序号存到一维数组中,打乱一维数组中的数据,然后把一维数组的数据再赋值给二维数组。

    // 创建成员变量二维数组,用来存放随机生成的图片
    int[][] arr = new int[4][4];
    // 创建顺序正确的二维数组,用于校验游戏是否成功
    int[][] win = {
                {0,1,2,3},
                {4,5,6,7},
                {8,9,10,11},
                {12,13,14,15}
        };
    
    // 创建成员变量行、列(用于记录空白图片的位置)、步数(用来统计步数)
    int row;
    int column;
    int count = 0;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    创建方法将二维数组随机化,以模拟图片打乱

    public void initData(){
            Random random = new Random();
            // 用来保存图片的正确顺序
            int[] a = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
            // 打乱顺序
            for (int i = 0; i < a.length; i++) {
                int index = random.nextInt(a.length);
                int temp = a[i];
                a[i] = a[index];
                a[index] = temp;
            }
            // 一位数组下标计数器
            int index = 0;
            // 将打乱好的数据存入二位数组中
            for (int i = 0; i < arr.length; i++) {
                for (int j = 0; j < arr[i].length; j++) {
                    arr[i][j] = a[index];
                    // 定位空白图片位置
                    if (arr[i][j] == 0){
                        row = i;
                        column = j;
                    }
                    // 更新一维数组小标
                    index++;
                }
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    接下来完成图片的加载,上面我们已经将图片的名字编号,然后将打乱顺序的编号存入了二维数组中,接下来利用这些编号,将图片加载进容器内并显示出来。

    // 加载图片
        public void view(){
            // 清除容器内的所有组件,后面图片移动时我们要刷新页面,
            // 如果页面中存在有组件的话,后加载的组件会被先加载的组件覆盖
            // JFrame中的重合问题采用的是先来先显示
            getContentPane().removeAll();
    
            // 创建标签用来显示移动的步数
            JLabel countLabel = new JLabel("一共走了" + count + "步");
            // 设置标签大小
            countLabel.setBounds(50,20,100,20);
            // 将标签加载到容器中(因为取消了默认布局,必须手动加载)
            getContentPane().add(countLabel);
    
            // 加载图片
            for (int i = 0; i < arr.length; i++) {
                for (int j = 0; j < arr[i].length; j++) {
                    // 创建图片对象用于存放图片,注意图片的路径的\要写\\,避免转义
                    // 注意:图片的名字已映射为二位数组中的数据,所以图片的名字要
                    //      用二维数组替换
                    //      如:E:\\image\\" + arr[i][j] + ".png
                    ImageIcon imageIcon = new ImageIcon("图片的全路径");
                    // 创建标签,将图片对象添加进去
                    JLabel imageLabel = new JLabel(imageIcon);
                    // 设置标签大小
                    // 将每个图片的显示位置动态设置,体现出我们设置二维数组的便捷性
                    imageLabel.setBounds(50 + j*100, 90 + i*100, 100, 100);
                    // 将标签添加进容器
                    getContentPane().add(imageLabel);
                }
            }
    
            // 添加背景图片(为啥要将背景图片放到下面?知道的可以在评论区留言哦)
            ImageIcon imageIcon = new ImageIcon("背景图片全路径");
            JLabel backgroundLabel = new JLabel(imageIcon);
            getContentPane().add(backgroundLabel);
    
            // 获取当前容器对象,重新编辑组件(这行代码的作用?)
            getContentPane().repaint();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    到这完成了游戏界面的加载工作,我们希望创建对象时能自动加载界面,所以需要再空参构造器中进行初始化工作。

    // 构造方法完成初始化
        public MyFrame(){
            // 初始化窗口
            showView();
            // 数据初始化
            initData();
            // 初始化图片
            printView();
            // 注册键盘监听器(这里用的this就体现出继承的好处了)
            this.addKeyListener(this);
            // 设置窗口可见
            setVisible(true);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    本质上图片是不能发生移动的,我们将图片映射到了二位数组中,就可以通过改变二维数组的下边来模拟移动操作,比如往左移,那么只需要将两个数组的数据互换就行。而每次移动都要去判断是否游戏胜利。

    // 完成状态
        public boolean check(){
            for (int i = 0; i < arr.length; i++) {
                for (int j = 0; j < arr[i].length; j++) {
                // 对比当前二位数组和预设二位数组中的数据是否相同
                    if (arr[i][j] != win[i][j]){
                        return false;
                    }
                }
            }
            return true;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    通过键盘移动图片,需要对键盘设置监听器,需要实现键盘监听器接口

     // 键盘监听
        @Override
        public void keyReleased(KeyEvent e) {
            move(e.getKeyCode());
            // 刷新页面
            printView();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    // 键盘监听
        public void move(int key){
            // 胜利
            if (check()){
                return;
            }
            // 左
            if (key == 37){
                if (column != 3){
                    arr[row][column] = arr[row][column + 1];
                    arr[row][column + 1] = 0;
                    column++;
                    count++;
                }
                // 上
            } else if (key == 38) {
                if (row != 3){
                    arr[row][column] = arr[row + 1][column];
                    arr[row + 1][column] = 0;
                    row++;
                    count++;
                }
                // 右
            } else if (key == 39) {
                if (column != 0){
                    arr[row][column] = arr[row][column - 1];
                    arr[row][column - 1] = 0;
                    column--;
                    count++;
                }
                // 下
            } else if (key == 40) {
                if (row != 0) {
                    arr[row][column] = arr[row - 1][column];
                    arr[row - 1][column] = 0;
                    row--;
                    count++;
                }
            } else if (key == 90){
                arr = new int[][]{
                            {0, 1, 2, 3},
                            {4, 5, 6, 7},
                            {8, 9, 10, 11},
                            {12, 13, 14, 15}
                };
            }
        }
        // 下面方法用不到就不管
        @Override
        public void keyTyped(KeyEvent e) {
        }
        @Override
        public void keyPressed(KeyEvent e) {
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    完整代码

    MyFrame类

    import javax.swing.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    import java.util.Random;
    
    public class MyFrame extends JFrame implements KeyListener, ActionListener {
    
        // 二维数组控制图片编号
        int[][] arr = new int[4][4];
        int[][] win = {
                {0,1,2,3},
                {4,5,6,7},
                {8,9,10,11},
                {12,13,14,15}
        };
        // 行
        int row;
        // 列
        int column;
        // 步数
        int count = 0;
    
        // 构造方法完成初始化
        public MyFrame(){
            // 初始化窗口
            showView();
            // 数据初始化
            initData();
            // 初始化图片
            printView();
            // 初始化菜单
            Menu();
            // 注册键盘监听器
            this.addKeyListener(this);
            // 设置窗口可见
            setVisible(true);
        }
    
        // 菜单
        public void Menu(){
            // 创建菜单对象
           JMenuBar jMenuBar = new JMenuBar();
            // 创建栏目对象
            JMenu jMenu1 = new JMenu("功能");
            JMenu jMenu2 = new JMenu("关于");
            // 创建条目对象
            JMenuItem jMenuItem = new JMenuItem("Replay");
    
            // 条目添加进栏目
            jMenu1.add(jMenuItem);
            // 栏目添加进菜单
            jMenuBar.add(jMenu1);
            jMenuBar.add(jMenu2);
            // 菜单添加进窗口
            this.setJMenuBar(jMenuBar);
    
            // 给条目添加监听
            jMenuItem.addActionListener(this);
        }
    
        // 二位数组随机化
        public void initData() {
            Random random = new Random();
            int[] arr1 = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
            for (int i = 0; i < arr.length; i++) {
                int index = random.nextInt(arr1.length);
                int temp = arr1[i];
                arr1[i] = arr1[index];
                arr1[index] = temp;
            }
            int index = 0;
            for (int i = 0; i < arr.length; i++) {
                for (int j = 0; j < arr[i].length; j++) {
                    arr[i][j] = arr1[index];
                    if (arr[i][j] == 0){
                        row = i;
                        column = j;
                    }
                    index++;
                }
            }
        }
    
        // 窗口设置
        public void showView(){
            // 设置窗口大小
            setSize(514,594);
            // 设置关闭模式
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            // 设置置顶显示
            setAlwaysOnTop(true);
            // 设置居中显示
            setLocationRelativeTo(null);
            // 设置窗口标题
            setTitle("石头迷阵v1.0单机版");
            // 取消默认布局
            setLayout(null);
        }
    
        // 界面加载
        public void printView(){
            // 清除界面
            getContentPane().removeAll();
            // 胜利,输出图片
            if (check()){
                JLabel winLabel = new JLabel(new ImageIcon("E:\\黑马程序员\\image\\image\\win.png"));
                winLabel.setBounds(124,230,266,88);
                getContentPane().add(winLabel);
            }
            // 步数加载
            JLabel jLabel = new JLabel("步数:" + count);
            jLabel.setBounds(50,20,100,20);
            getContentPane().add(jLabel);
    
            // 添加图片
            for (int i = 0; i < 4; i++) {
                for (int j = 0; j < 4; j++) {
                											//这个地址要根据你自己的地址来写
                    JLabel image = new JLabel(new ImageIcon("E:\\image\\"+arr[i][j]+".png"));
                    image.setBounds(50 + j*100, 90 + i*100, 100 ,100);
                    getContentPane().add(image);
                }
            }
            // 背景图片
            JLabel backgroung = new JLabel(new ImageIcon("E:\\image\\background.png"));
            backgroung.setBounds(26,30,450,484);
            getContentPane().add(backgroung);
    
            // 获取当前容器对象,重新编辑组件
            getContentPane().repaint();
        }
    
        // 键盘监听
        @Override
        public void keyReleased(KeyEvent e) {
            move(e.getKeyCode());
            // 刷新页面
            printView();
        }
    
        // 完成状态
        public boolean check(){
            for (int i = 0; i < arr.length; i++) {
                for (int j = 0; j < arr[i].length; j++) {
                    if (arr[i][j] != win[i][j]){
                        return false;
                    }
                }
            }
            return true;
        }
        // 键盘监听
        public void move(int key){
            // 胜利
            if (check()){
                return;
            }
            // 左
            if (key == 37){
                if (column != 3){
                    arr[row][column] = arr[row][column + 1];
                    arr[row][column + 1] = 0;
                    column++;
                    count++;
                }
                // 上
            } else if (key == 38) {
                if (row != 3){
                    arr[row][column] = arr[row + 1][column];
                    arr[row + 1][column] = 0;
                    row++;
                    count++;
                }
                // 右
            } else if (key == 39) {
                if (column != 0){
                    arr[row][column] = arr[row][column - 1];
                    arr[row][column - 1] = 0;
                    column--;
                    count++;
                }
                // 下
            } else if (key == 40) {
                if (row != 0) {
                    arr[row][column] = arr[row - 1][column];
                    arr[row - 1][column] = 0;
                    row--;
                    count++;
                }
            } else if (key == 90){
                arr = new int[][]{
                            {0, 1, 2, 3},
                            {4, 5, 6, 7},
                            {8, 9, 10, 11},
                            {12, 13, 14, 15}
                };
            }
        }
    
        //
        @Override
        public void keyTyped(KeyEvent e) {
    
        }
    
        //
        @Override
        public void keyPressed(KeyEvent e) {
    
        }
    
        @Override
        public void actionPerformed(ActionEvent e) {
            // 初始化数据
            initData();
            // 步数初始化
            count = 0;
            // 初始化图片图片
            printView();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224

    测试类

    public class Test {
        public static void main(String[] args) {
            new MyFrame();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    相关图片

    可以做任何自己想做的拼图游戏,根据大小自己切割。
    上述代码用到的图片:
    百度网盘
    链接:https://pan.baidu.com/s/1FCoXXOm6spF9qsdfjTWYug
    提取码:785g
    (上述代码为简易版,供学习参考,如有不足欢迎及时指正)

  • 相关阅读:
    MySQL 相关英文单词
    使用speedtest-cli进行服务器上传和下载速度测试
    flutter系列之:flutter架构什么的,看完这篇文章就全懂了
    Code For Better 谷歌开发者之声——开发者必备神器
    K8S容忍toleration的声明语法、配置项含义及和污点的配合使用
    Meta首份元宇宙白皮书9大看点,瞄准80万亿美元市场
    百度之星(夏日漫步)
    构建镜像开源工具 buildah
    传输层协议—TCP协议
    python毕业设计项目源码选题(7)校园排课选课系统毕业设计毕设作品开题报告开题答辩PPT
  • 原文地址:https://blog.csdn.net/qq_44256227/article/details/125485348