Day04-Java进阶-石头迷阵游戏 (游戏演示&绘制界面&重构代码&打乱方块&移动业务&判断胜利&重新开始)

1. 游戏演示及构建游戏窗体

package com.itheima.stonepuzzle;

import javax.swing.*;

public class Test {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        // 设置窗体的大小
        frame.setSize(514, 595);
        // 设置窗体的关闭模式
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        // 设置窗体的标题
        frame.setTitle("石头迷阵单机版V1.0");
        // 设置窗体居中
        frame.setLocationRelativeTo(null);
        // 设置窗体可见
        frame.setVisible(true);
    }
}

2. 绘制界面

2.1 恶心的写法

package com.itheima.stonepuzzle;

import javax.swing.*;

public class Test {
    public static void main(String[] args) {
        JFrame frame = new JFrame();
        // 设置窗体的大小
        frame.setSize(514, 595);
        // 设置窗体的关闭模式
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        // 设置窗体的标题
        frame.setTitle("石头迷阵单机版V1.0");
        // 设置窗体居中
        frame.setLocationRelativeTo(null);

        // 取消默认布局
        frame.setLayout(null);

        // 创建JLabel对象, 加载图片资源(构造方法中new ImageIcon())
        JLabel jl1 = new JLabel(new ImageIcon("D:\\image\\8.png"));
        // 设置摆放位置
        jl1.setBounds(50, 90, 100, 100);
        // 窗体对象调用getContentPane方法拿到面板对象,再调用add方法把JLabel对象jl1塞进去
        frame.getContentPane().add(jl1);

        JLabel jl2 = new JLabel(new ImageIcon("D:\\image\\8.png"));
        jl2.setBounds(150, 90, 100, 100);
        frame.getContentPane().add(jl2);

        JLabel jl3 = new JLabel(new ImageIcon("D:\\image\\8.png"));
        jl3.setBounds(250, 90, 100, 100);
        frame.getContentPane().add(jl3);

        JLabel jl4 = new JLabel(new ImageIcon("D:\\image\\8.png"));
        jl4.setBounds(350, 90, 100, 100);
        frame.getContentPane().add(jl4);

        JLabel jl5 = new JLabel(new ImageIcon("D:\\image\\8.png"));
        jl5.setBounds(50, 190, 100, 100);
        frame.getContentPane().add(jl5);

        JLabel jl6 = new JLabel(new ImageIcon("D:\\image\\8.png"));
        jl6.setBounds(150, 190, 100, 100);
        frame.getContentPane().add(jl6);

        JLabel jl7 = new JLabel(new ImageIcon("D:\\image\\8.png"));
        jl7.setBounds(250, 190, 100, 100);
        frame.getContentPane().add(jl7);

        JLabel jl8 = new JLabel(new ImageIcon("D:\\image\\8.png"));
        jl8.setBounds(350, 190, 100, 100);
        frame.getContentPane().add(jl8);

        JLabel jl9 = new JLabel(new ImageIcon("D:\\image\\8.png"));
        jl9.setBounds(50, 290, 100, 100);
        frame.getContentPane().add(jl9);

        JLabel jl10 = new JLabel(new ImageIcon("D:\\image\\8.png"));
        jl10.setBounds(150, 290, 100, 100);
        frame.getContentPane().add(jl10);

        JLabel jl11 = new JLabel(new ImageIcon("D:\\image\\8.png"));
        jl11.setBounds(250, 290, 100, 100);
        frame.getContentPane().add(jl11);

        JLabel jl12 = new JLabel(new ImageIcon("D:\\image\\8.png"));
        jl12.setBounds(350, 290, 100, 100);
        frame.getContentPane().add(jl12);

        JLabel jl13 = new JLabel(new ImageIcon("D:\\image\\8.png"));
        jl13.setBounds(50, 390, 100, 100);
        frame.getContentPane().add(jl13);

        JLabel jl14 = new JLabel(new ImageIcon("D:\\image\\8.png"));
        jl14.setBounds(150, 390, 100, 100);
        frame.getContentPane().add(jl14);

        JLabel jl15 = new JLabel(new ImageIcon("D:\\image\\8.png"));
        jl15.setBounds(250, 390, 100, 100);
        frame.getContentPane().add(jl15);

        JLabel jl16 = new JLabel(new ImageIcon("D:\\image\\8.png"));
        jl16.setBounds(350, 390, 100, 100);
        frame.getContentPane().add(jl16);

        JLabel background = new JLabel(new ImageIcon("D:\\image\\background.png"));
        background.setBounds(26, 30, 450, 484);
        frame.getContentPane().add(background);

        // 设置窗体可见
        frame.setVisible(true);
    }
}

2.2 使用循环和二维数组优化

2.2.1 使用循环

for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                JLabel imageLabel = new JLabel(new ImageIcon("D:\\image\\"+data[i][j]+".png"));
                imageLabel.setBounds(50 + 100 * j, 90 + 100 * i, 100, 100);
                frame.getContentPane().add(imageLabel);
            }
        }

2.2.2 二维数组优化

package com.itheima.stonepuzzle;

import javax.swing.*;

public class Test {
    public static void main(String[] args) {

        int[][] data = {
                {1, 2, 3, 4},
                {5, 6, 7, 8},
                {9, 10, 11, 12},
                {13, 14, 15, 0}
        };

        JFrame frame = new JFrame();
        // 设置窗体的大小
        frame.setSize(514, 595);
        // 设置窗体的关闭模式
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        // 设置窗体的标题
        frame.setTitle("石头迷阵单机版V1.0");
        // 设置窗体居中
        frame.setLocationRelativeTo(null);

        // 取消默认布局
        frame.setLayout(null);

        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                JLabel imageLabel = new JLabel(new ImageIcon("D:\\image\\"+data[i][j]+".png"));
                imageLabel.setBounds(50 + 100 * j, 90 + 100 * i, 100, 100);
                frame.getContentPane().add(imageLabel);
            }
        }

        JLabel background = new JLabel(new ImageIcon("D:\\image\\background.png"));
        background.setBounds(26, 30, 450, 484);
        frame.getContentPane().add(background);

        // 设置窗体可见
        frame.setVisible(true);
    }
}

3. 使用继承重构代码

package com.itheima.stonepuzzle;

import javax.swing.*;

public class MainFrame extends JFrame {

    int[][] data = {
            {1, 2, 3, 4},
            {5, 6, 7, 8},
            {9, 10, 11, 12},
            {13, 14, 15, 0}
    };

    public MainFrame(){
        initFrame();
        paintView();
        // 设置窗体可见
        setVisible(true);
    }

    /**
     * 此方法用于初始化窗口
     */
    public void initFrame() {
        // 设置窗体的大小
        setSize(514, 595);
        // 设置窗体的关闭模式
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        // 设置窗体的标题
        setTitle("石头迷阵单机版V1.0");
        // 设置窗体居中
        setLocationRelativeTo(null);
        // 取消默认布局
        setLayout(null);
    }

    /**
     * 此方法用户绘制窗口
     */
    public void paintView() {
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                JLabel imageLabel = new JLabel(new ImageIcon("D:\\image\\" + data[i][j] + ".png"));
                imageLabel.setBounds(50 + 100 * j, 90 + 100 * i, 100, 100);
                getContentPane().add(imageLabel);
            }
        }

        JLabel background = new JLabel(new ImageIcon("D:\\image\\background.png"));
        background.setBounds(26, 30, 450, 484);
        getContentPane().add(background);
    }
}
package com.itheima.stonepuzzle;

import javax.swing.*;

public class Test {
    public static void main(String[] args) {

        new MainFrame();

    }
}

4. 打乱石头方块

package com.itheima.stonepuzzle;

import javax.swing.*;
import java.util.Random;

public class MainFrame extends JFrame {

    int[][] data = {
            {1, 2, 3, 4},
            {5, 6, 7, 8},
            {9, 10, 11, 12},
            {13, 14, 15, 0}
    };

    public MainFrame() {
        initFrame();
        initData();
        paintView();
        // 设置窗体可见
        setVisible(true);
    }

    /**
     * 初始化数据(打乱绘图)
     */
    public void initData() {
        // 产生随机数
        Random r = new Random();
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                int RandomX = r.nextInt(4);
                int RandomY = r.nextInt(4);

                int temp = data[i][j];
                data[i][j] = data[RandomX][RandomY];
                data[RandomX][RandomY] = temp;
            }
        }
    }

    /**
     * 此方法用于初始化窗口
     */
    public void initFrame() {
        // 设置窗体的大小
        setSize(514, 595);
        // 设置窗体的关闭模式
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        // 设置窗体的标题
        setTitle("石头迷阵单机版V1.0");
        // 设置窗体居中
        setLocationRelativeTo(null);
        // 取消默认布局
        setLayout(null);
    }

    /**
     * 此方法用户窗口绘图
     */
    public void paintView() {
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                JLabel imageLabel = new JLabel(new ImageIcon("D:\\image\\" + data[i][j] + ".png"));
                imageLabel.setBounds(50 + 100 * j, 90 + 100 * i, 100, 100);
                getContentPane().add(imageLabel);
            }
        }

        JLabel background = new JLabel(new ImageIcon("D:\\image\\background.png"));
        background.setBounds(26, 30, 450, 484);
        getContentPane().add(background);
    }
}

5. 移动业务准备

5.1 注册键盘

package com.itheima.stonepuzzle;

import javax.swing.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;

public class MainFrame extends JFrame implements KeyListener {

    int[][] data = {
            {1, 2, 3, 4},
            {5, 6, 7, 8},
            {9, 10, 11, 12},
            {13, 14, 15, 0}
    };

    public MainFrame() {

        // 窗体对象.addKeyListener(KeyListener实现类对象)
        this.addKeyListener(this);
        // this: 当前类对象
        // 1) 窗体对象
        // 2) KeyListener实现类对象

        initFrame();
        initData();
        paintView();
        // 设置窗体可见
        setVisible(true);
    }

    /**
     * 初始化数据(打乱绘图)
     */
    public void initData() {
        // 产生随机数
        Random r = new Random();
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                int RandomX = r.nextInt(4);
                int RandomY = r.nextInt(4);

                int temp = data[i][j];
                data[i][j] = data[RandomX][RandomY];
                data[RandomX][RandomY] = temp;
            }
        }
    }

    /**
     * 此方法用于初始化窗口
     */
    public void initFrame() {
        // 设置窗体的大小
        setSize(514, 595);
        // 设置窗体的关闭模式
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        // 设置窗体的标题
        setTitle("石头迷阵单机版V1.0");
        // 设置窗体居中
        setLocationRelativeTo(null);
        // 取消默认布局
        setLayout(null);
    }

    /**
     * 此方法用户窗口绘图
     */
    public void paintView() {
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                JLabel imageLabel = new JLabel(new ImageIcon("D:\\image\\" + data[i][j] + ".png"));
                imageLabel.setBounds(50 + 100 * j, 90 + 100 * i, 100, 100);
                getContentPane().add(imageLabel);
            }
        }

        JLabel background = new JLabel(new ImageIcon("D:\\image\\background.png"));
        background.setBounds(26, 30, 450, 484);
        getContentPane().add(background);
    }


    @Override
    public void keyPressed(KeyEvent e) {
        int keyCode = e.getKeyCode();
        move(keyCode);
    }

    /**
     * 此方法用于处理移动业务
     */
    private void move(int keyCode) {
        if (keyCode == 37) {
            System.out.println("左移动业务执行");
        } else if (keyCode == 38) {
            System.out.println("上移动业务执行");
        } else if (keyCode == 39) {
            System.out.println("右移动业务执行");
        } else if (keyCode == 40) {
            System.out.println("下移动业务执行");
        }
    }

    // --------------------------------------------------------------
    @Override
    public void keyReleased(KeyEvent e) {

    }

    @Override
    public void keyTyped(KeyEvent e) {

    }
    // --------------------------------------------------------------
}

5.2 确定0号元素所在

package com.itheima.stonepuzzle;

import javax.swing.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;

public class MainFrame extends JFrame implements KeyListener {

    int[][] data = {
            {1, 2, 3, 4},
            {5, 6, 7, 8},
            {9, 10, 11, 12},
            {13, 14, 15, 0}
    };

    int row;    // 0号元素行坐标位置
    int column; // 0号元素列坐标位置

    public MainFrame() {

        // 窗体对象.addKeyListener(KeyListener实现类对象)
        this.addKeyListener(this);
        // this: 当前类对象
        // 1) 窗体对象
        // 2) KeyListener实现类对象

        initFrame();
        initData();
        paintView();
        // 设置窗体可见
        setVisible(true);
    }

    /**
     * 初始化数据(打乱绘图)
     */
    public void initData() {
        // 产生随机数
        Random r = new Random();
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                int RandomX = r.nextInt(4);
                int RandomY = r.nextInt(4);

                int temp = data[i][j];
                data[i][j] = data[RandomX][RandomY];
                data[RandomX][RandomY] = temp;
            }
        }

        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                if (data[i][j] == 0) {
                    row = i;
                    column = j;
                }
            }
        }

        System.out.println("0号元素的初始坐标位置为: " + row + ", " + column);
    }

    /**
     * 此方法用于初始化窗口
     */
    public void initFrame() {
        // 设置窗体的大小
        setSize(514, 595);
        // 设置窗体的关闭模式
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        // 设置窗体的标题
        setTitle("石头迷阵单机版V1.0");
        // 设置窗体居中
        setLocationRelativeTo(null);
        // 取消默认布局
        setLayout(null);
    }

    /**
     * 此方法用户窗口绘图
     */
    public void paintView() {
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                JLabel imageLabel = new JLabel(new ImageIcon("D:\\image\\" + data[i][j] + ".png"));
                imageLabel.setBounds(50 + 100 * j, 90 + 100 * i, 100, 100);
                getContentPane().add(imageLabel);
            }
        }

        JLabel background = new JLabel(new ImageIcon("D:\\image\\background.png"));
        background.setBounds(26, 30, 450, 484);
        getContentPane().add(background);
    }


    @Override
    public void keyPressed(KeyEvent e) {
        int keyCode = e.getKeyCode();
        move(keyCode);
    }

    /**
     * 此方法用于处理移动业务
     */
    private void move(int keyCode) {
        if (keyCode == 37) {
            System.out.println("左移动业务执行");
        } else if (keyCode == 38) {
            System.out.println("上移动业务执行");
        } else if (keyCode == 39) {
            System.out.println("右移动业务执行");
        } else if (keyCode == 40) {
            System.out.println("下移动业务执行");
        }
    }

    // --------------------------------------------------------------
    @Override
    public void keyReleased(KeyEvent e) {

    }

    @Override
    public void keyTyped(KeyEvent e) {

    }
    // --------------------------------------------------------------
}

6. 移动业务

6.1 基本实现

6.2 错误解决

添加 if 判断条件

package com.itheima.stonepuzzle;

import javax.swing.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;

public class MainFrame extends JFrame implements KeyListener {

    int[][] data = {
            {1, 2, 3, 4},
            {5, 6, 7, 8},
            {9, 10, 11, 12},
            {13, 14, 15, 0}
    };

    int row;    // 0号元素行坐标位置
    int column; // 0号元素列坐标位置

    public MainFrame() {

        // 窗体对象.addKeyListener(KeyListener实现类对象)
        this.addKeyListener(this);
        // this: 当前类对象
        // 1) 窗体对象
        // 2) KeyListener实现类对象

        initFrame();
        initData();
        paintView();
        // 设置窗体可见
        setVisible(true);
    }

    /**
     * 初始化数据(打乱绘图)
     */
    public void initData() {
        // 产生随机数
        Random r = new Random();
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                int RandomX = r.nextInt(4);
                int RandomY = r.nextInt(4);

                int temp = data[i][j];
                data[i][j] = data[RandomX][RandomY];
                data[RandomX][RandomY] = temp;
            }
        }

        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                if (data[i][j] == 0) {
                    row = i;
                    column = j;
                }
            }
        }

        System.out.println("0号元素的初始坐标位置为: " + row + ", " + column);
    }

    /**
     * 此方法用于初始化窗口
     */
    public void initFrame() {
        // 设置窗体的大小
        setSize(514, 595);
        // 设置窗体的关闭模式
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        // 设置窗体的标题
        setTitle("石头迷阵单机版V1.0");
        // 设置窗体居中
        setLocationRelativeTo(null);
        // 取消默认布局
        setLayout(null);
    }

    /**
     * 此方法用户窗口绘图
     */
    public void paintView() {
        // 移除现有组件
        getContentPane().removeAll();
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                JLabel imageLabel = new JLabel(new ImageIcon("D:\\image\\" + data[i][j] + ".png"));
                imageLabel.setBounds(50 + 100 * j, 90 + 100 * i, 100, 100);
                getContentPane().add(imageLabel);
            }
        }

        JLabel background = new JLabel(new ImageIcon("D:\\image\\background.png"));
        background.setBounds(26, 30, 450, 484);
        getContentPane().add(background);

        // 加载后, 刷新页面
        getContentPane().repaint();
    }


    @Override
    public void keyPressed(KeyEvent e) {
        int keyCode = e.getKeyCode();
        move(keyCode);
        // 每一次移动之后, 都重新绘制游戏界面
        paintView();
    }

    /**
     * 此方法用于处理移动业务
     */
    private void move(int keyCode) {
        if (keyCode == 37) {

            if (column == 3){
                return;
            }

            // 左移动: 空白块和右侧数据进行交换
            // data[row][column] data[row][column+1]
            int temp = data[row][column];
            data[row][column] = data[row][column + 1];
            data[row][column + 1] = temp;
            column++;
        } else if (keyCode == 38) {

            if (row == 3){
                return;
            }

            // 上移动: 空白块和下方数据进行交换
            // data[row][column] data[row+1][column]
            int temp = data[row][column];
            data[row][column] = data[row + 1][column];
            data[row + 1][column] = temp;
            row++;
        } else if (keyCode == 39) {

            if (column == 0){
                return;
            }

            // 右移动: 空白块和左侧数据进行交换
            // data[row][column] data[row][column-1]
            int temp = data[row][column];
            data[row][column] = data[row][column-1];
            data[row][column-1] = temp;
            column--;
        } else if (keyCode == 40) {

            if (row == 0){
                return;
            }

            // 下移动: 空白块和上方数据进行交换
            // data[row][column] data[row-1][column]
            int temp = data[row][column];
            data[row][column] = data[row - 1][column];
            data[row - 1][column] = temp;
            row--;
        } else if (keyCode == 90) {
            data = new int[][]{
                    {1, 2, 3, 4},
                    {5, 6, 7, 8},
                    {9, 10, 11, 12},
                    {13, 14, 15, 0}
            };
        }

    }

    /**
     * 此方法用于二维数组元素交换
     */
    private void Exchage(int a, int b) {
        int temp = a;
        a = b;
        b = temp;
    }

    // --------------------------------------------------------------
    @Override
    public void keyReleased(KeyEvent e) {

    }

    @Override
    public void keyTyped(KeyEvent e) {

    }
    // --------------------------------------------------------------
}

7. 判断胜利-统计步数-重新游戏

7.1 游戏判定胜利

package com.itheima.stonepuzzle;

import javax.swing.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;

public class MainFrame extends JFrame implements KeyListener {

    int[][] data = {
            {1, 2, 3, 4},
            {5, 6, 7, 8},
            {9, 10, 11, 12},
            {13, 14, 15, 0}
    };

    int[][] win = {
            {1, 2, 3, 4},
            {5, 6, 7, 8},
            {9, 10, 11, 12},
            {13, 14, 15, 0}
    };

    int row;    // 0号元素行坐标位置
    int column; // 0号元素列坐标位置

    public MainFrame() {

        // 窗体对象.addKeyListener(KeyListener实现类对象)
        this.addKeyListener(this);
        // this: 当前类对象
        // 1) 窗体对象
        // 2) KeyListener实现类对象

        initFrame();
        initData();
        paintView();

        // 设置窗体可见
        setVisible(true);
    }

    /**
     * 初始化数据(打乱绘图)
     */
    public void initData() {
        // 产生随机数
        Random r = new Random();
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                int RandomX = r.nextInt(4);
                int RandomY = r.nextInt(4);

                int temp = data[i][j];
                data[i][j] = data[RandomX][RandomY];
                data[RandomX][RandomY] = temp;
            }
        }

        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                if (data[i][j] == 0) {
                    row = i;
                    column = j;
                }
            }
        }

        System.out.println("0号元素的初始坐标位置为: " + row + ", " + column);
    }

    /**
     * 此方法用于初始化窗口
     */
    public void initFrame() {
        // 设置窗体的大小
        setSize(514, 595);
        // 设置窗体的关闭模式
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        // 设置窗体的标题
        setTitle("石头迷阵单机版V1.0");
        // 设置窗体居中
        setLocationRelativeTo(null);
        // 取消默认布局
        setLayout(null);
    }

    /**
     * 此方法用户窗口绘图
     */
    public void paintView() {
        // 移除现有组件
        getContentPane().removeAll();

        // 判断是否胜利, 从而展示胜利图片
        if (victory()){
            JLabel winLabel = new JLabel(new ImageIcon("D:\\image\\win.png"));
            winLabel.setBounds(124, 230, 266, 88);
            getContentPane().add(winLabel);
        }

        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                JLabel imageLabel = new JLabel(new ImageIcon("D:\\image\\" + data[i][j] + ".png"));
                imageLabel.setBounds(50 + 100 * j, 90 + 100 * i, 100, 100);
                getContentPane().add(imageLabel);
            }
        }

        JLabel background = new JLabel(new ImageIcon("D:\\image\\background.png"));
        background.setBounds(26, 30, 450, 484);
        getContentPane().add(background);

        // 加载后, 刷新页面
        getContentPane().repaint();
    }

    /**
     * 判断游戏是否胜利
     */
    private boolean victory(){
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                if(data[i][j] != win[i][j]){
                    return false;
                }
            }
        }

        return true;
    }

    @Override
    public void keyPressed(KeyEvent e) {
        int keyCode = e.getKeyCode();
        move(keyCode);
        // 每一次移动之后, 都重新绘制游戏界面
        paintView();
    }

    /**
     * 此方法用于处理移动业务
     */
    private void move(int keyCode) {

        if (victory()){
            return;
        }

        if (keyCode == 37) {

            if (column == 3){
                return;
            }

            // 左移动: 空白块和右侧数据进行交换
            // data[row][column] data[row][column+1]
            int temp = data[row][column];
            data[row][column] = data[row][column + 1];
            data[row][column + 1] = temp;
            column++;
        } else if (keyCode == 38) {

            if (row == 3){
                return;
            }

            // 上移动: 空白块和下方数据进行交换
            // data[row][column] data[row+1][column]
            int temp = data[row][column];
            data[row][column] = data[row + 1][column];
            data[row + 1][column] = temp;
            row++;
        } else if (keyCode == 39) {

            if (column == 0){
                return;
            }

            // 右移动: 空白块和左侧数据进行交换
            // data[row][column] data[row][column-1]
            int temp = data[row][column];
            data[row][column] = data[row][column-1];
            data[row][column-1] = temp;
            column--;
        } else if (keyCode == 40) {

            if (row == 0){
                return;
            }

            // 下移动: 空白块和上方数据进行交换
            // data[row][column] data[row-1][column]
            int temp = data[row][column];
            data[row][column] = data[row - 1][column];
            data[row - 1][column] = temp;
            row--;
        } else if (keyCode == 90) {
            data = new int[][]{
                    {1, 2, 3, 4},
                    {5, 6, 7, 8},
                    {9, 10, 11, 12},
                    {13, 14, 15, 0}
            };
        }

    }

    /**
     * 此方法用于二维数组元素交换
     */
    private void exchage(int a, int b) {
        int temp = a;
        a = b;
        b = temp;
    }

    // --------------------------------------------------------------
    @Override
    public void keyReleased(KeyEvent e) {

    }

    @Override
    public void keyTyped(KeyEvent e) {

    }
    // --------------------------------------------------------------
}

7.2 统计步数-重新游戏

7.2.1 统计步数

7.2.2 重新游戏

package com.itheima.stonepuzzle;

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 MainFrame extends JFrame implements KeyListener {

    int[][] data = {
            {1, 2, 3, 4},
            {5, 6, 7, 8},
            {9, 10, 11, 12},
            {13, 14, 15, 0}
    };

    int[][] win = {
            {1, 2, 3, 4},
            {5, 6, 7, 8},
            {9, 10, 11, 12},
            {13, 14, 15, 0}
    };

    int count = 0;

    int row;    // 0号元素行坐标位置
    int column; // 0号元素列坐标位置

    public MainFrame() {

        // 窗体对象.addKeyListener(KeyListener实现类对象)
        this.addKeyListener(this);
        // this: 当前类对象
        // 1) 窗体对象
        // 2) KeyListener实现类对象

        initFrame();
        initData();
        paintView();

        // 设置窗体可见
        setVisible(true);
    }

    /**
     * 初始化数据(打乱绘图)
     */
    public void initData() {
        // 产生随机数
        Random r = new Random();
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                int RandomX = r.nextInt(4);
                int RandomY = r.nextInt(4);

                int temp = data[i][j];
                data[i][j] = data[RandomX][RandomY];
                data[RandomX][RandomY] = temp;
            }
        }

        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                if (data[i][j] == 0) {
                    row = i;
                    column = j;
                }
            }
        }

        System.out.println("0号元素的初始坐标位置为: " + row + ", " + column);
    }

    /**
     * 此方法用于初始化窗口
     */
    public void initFrame() {
        // 设置窗体的大小
        setSize(514, 595);
        // 设置窗体的关闭模式
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        // 设置窗体的标题
        setTitle("石头迷阵单机版V1.0");
        // 设置窗体居中
        setLocationRelativeTo(null);
        // 取消默认布局
        setLayout(null);
    }

    /**
     * 此方法用户窗口绘图
     */
    public void paintView() {
        // 移除现有组件
        getContentPane().removeAll();

        // 判断是否胜利, 从而展示胜利图片
        if (victory()) {
            JLabel winLabel = new JLabel(new ImageIcon("D:\\image\\win.png"));
            winLabel.setBounds(124, 230, 266, 88);
            getContentPane().add(winLabel);
        }

        JLabel scoreLabel = new JLabel("步数为:" + count);
        scoreLabel.setBounds(50, 20, 100, 20);
        getContentPane().add(scoreLabel);

        JButton btn = new JButton("重新游戏");
        btn.setBounds(350, 20, 100, 20);
        getContentPane().add(btn);
        // 设置默认焦点为false
        btn.setFocusable(false);
        btn.addActionListener(e -> {
            count = 0;
            initData();
            paintView();
        });

        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                JLabel imageLabel = new JLabel(new ImageIcon("D:\\image\\" + data[i][j] + ".png"));
                imageLabel.setBounds(50 + 100 * j, 90 + 100 * i, 100, 100);
                getContentPane().add(imageLabel);
            }
        }

        JLabel background = new JLabel(new ImageIcon("D:\\image\\background.png"));
        background.setBounds(26, 30, 450, 484);
        getContentPane().add(background);

        // 加载后, 刷新页面
        getContentPane().repaint();
    }

    /**
     * 判断游戏是否胜利
     */
    private boolean victory() {
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                if (data[i][j] != win[i][j]) {
                    return false;
                }
            }
        }

        return true;
    }

    @Override
    public void keyPressed(KeyEvent e) {
        int keyCode = e.getKeyCode();
        move(keyCode);
        // 每一次移动之后, 都重新绘制游戏界面
        paintView();
    }

    /**
     * 此方法用于处理移动业务
     */
    private void move(int keyCode) {

        if (victory()) {
            return;
        }

        if (keyCode == 37) {

            if (column == 3) {
                return;
            }

            // 左移动: 空白块和右侧数据进行交换
            // data[row][column] data[row][column+1]
            int temp = data[row][column];
            data[row][column] = data[row][column + 1];
            data[row][column + 1] = temp;
            column++;
            count++;
        } else if (keyCode == 38) {

            if (row == 3) {
                return;
            }

            // 上移动: 空白块和下方数据进行交换
            // data[row][column] data[row+1][column]
            int temp = data[row][column];
            data[row][column] = data[row + 1][column];
            data[row + 1][column] = temp;
            row++;
            count++;
        } else if (keyCode == 39) {

            if (column == 0) {
                return;
            }

            // 右移动: 空白块和左侧数据进行交换
            // data[row][column] data[row][column-1]
            int temp = data[row][column];
            data[row][column] = data[row][column - 1];
            data[row][column - 1] = temp;
            column--;
            count++;
        } else if (keyCode == 40) {

            if (row == 0) {
                return;
            }

            // 下移动: 空白块和上方数据进行交换
            // data[row][column] data[row-1][column]
            int temp = data[row][column];
            data[row][column] = data[row - 1][column];
            data[row - 1][column] = temp;
            row--;
            count++;
        } else if (keyCode == 90) {
            // Ctrl + Z 作弊器
            data = new int[][]{
                    {1, 2, 3, 4},
                    {5, 6, 7, 8},
                    {9, 10, 11, 12},
                    {13, 14, 15, 0}
            };
        }

    }

    // --------------------------------------------------------------
    @Override
    public void keyReleased(KeyEvent e) {

    }

    @Override
    public void keyTyped(KeyEvent e) {

    }
    // --------------------------------------------------------------
}

由此完结...

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
android 游戏源码,宝石迷阵。 package wealk.android.jewels; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import javax.microedition.khronos.opengles.GL10; import org.anddev.andengine.audio.sound.Sound; import org.anddev.andengine.audio.sound.SoundFactory; import org.anddev.andengine.engine.Engine; import org.anddev.andengine.engine.camera.Camera; import org.anddev.andengine.engine.handler.IUpdateHandler; import org.anddev.andengine.engine.handler.timer.ITimerCallback; import org.anddev.andengine.engine.handler.timer.TimerHandler; import org.anddev.andengine.engine.options.EngineOptions; import org.anddev.andengine.engine.options.EngineOptions.ScreenOrientation; import org.anddev.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy; import org.anddev.andengine.entity.scene.Scene; import org.anddev.andengine.entity.scene.Scene.IOnSceneTouchListener; import org.anddev.andengine.entity.shape.modifier.AlphaModifier; import org.anddev.andengine.entity.shape.modifier.LoopShapeModifier; import org.anddev.andengine.entity.shape.modifier.RotationModifier; import org.anddev.andengine.entity.shape.modifier.ScaleModifier; import org.anddev.andengine.entity.shape.modifier.SequenceShapeModifier; import org.anddev.andengine.entity.sprite.Sprite; import org.anddev.andengine.entity.text.ChangeableText; import org.anddev.andengine.entity.text.Text; import org.anddev.andengine.input.touch.TouchEvent; import org.anddev.andengine.opengl.font.Font; import org.anddev.andengine.opengl.font.FontFactory; import org.anddev.andengine.opengl.texture.Texture; import org.anddev.andengine.opengl.texture.TextureOptions; import org.anddev.andengine.opengl.texture.region.TextureRegion; import org.anddev.andengine.opengl.texture.region.TextureRegionFactory; import org.anddev.andengine.ui.activity.BaseGameActivity; import org.anddev.andengine.util.Debug; import org.anddev.andengine.util.HorizontalAlign; import org.anddev.andengine.util.MathUtils; import wealk.android.jewels.constants.IConstants; import wealk.android.jewels.entity.BackgroundCell; import wealk.android.jewels.entity.BorderSprite; import wealk.android.jewels.entity.JewelSprite; import android.app.AlertDialog; import android.app.Dialog; import android.content.DialogInterface; import android.content.Intent; import android.graphics.Color; import android.graphics.Typeface; import android.os.Handler; import android.os.Message; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.View.OnClickListener; import android.widget.EditText; import android.widget.Toast; /** * @author Qingfeng * @time 2010-11-03 ~ 2010 */ public class Jewels extends BaseGameActivity implements IOnSceneTouchListener, IConstants { // =========================================================== // Constants // =========================================================== /**灞忓箷灏哄**/ private static final int CAMERA_WIDTH = 320; private static final int CAMERA_HEIGHT = 480; /**鍦烘櫙鍒嗗眰**/ private static final int LAYER_BACKGROUND = 0; private static final int LAYER_BG_CELL = LAYER_BACKGROUND + 1; private static final int LAYER_JEWELS = LAYER_BG_CELL + 1; private static final int LAYER_SCORE = LAYER_JEWELS + 1; // =========================================================== // Fields // =========================================================== private Camera mCamera;//闀滃ご protected Scene mMainScene;//涓诲満鏅� /**娓告垙妯″紡**/ private String mGameModel; /**娓告垙鐘舵�**/ private boolean mGameRunning;//娓告垙鐨勬�寮�叧(鍙鐞嗘潵鐢点�浠诲姟鍒囨崲绛� private boolean mIsSwaping;//浜ゆ崲鐘舵� private final int MOVE_UP = 1;//涓婄Щ private final int MOVE_DOWN = 2;//涓嬬Щ private final int MOVE_LEFT = 3;//宸︾Щ private final int MOVE_RIGHT = 4;//鍙崇Щ private final int FALL = 5;//涓嬭惤 private final int DEAD = 6;//姝诲眬 private final int CHECK = 0;//鎵ц妫�祴 private int STATE = CHECK;//涓�紑濮嬪氨妫�祴锛屾病鏈夌Щ鍔ㄥ懡浠ょ

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码里码理~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值