Java项目—— 拼图小游戏(基础版)

项目要求

1.通过可视化界面完成项目

2.添加事件监听进行游戏操作

通过鼠标单击菜单实现重新游戏,重新登录,退出游戏和弹出公众号二维码弹窗

通过上下左右键操控拼图移动

通过长按W键显示完整拼图样式

通过按键A实现一键通关

3.创建可视化计数器记录拼图移动步数

4.胜利后显示胜利图标

详细要求请见注释要求


分析

核心思路

Java项目—— 拼图小游戏(基础版)_第1张图片

定义数组,一个数字对应一快拼图,打乱数组,相当于打乱拼图

0代表空白拼图,定义x,y记录0的坐标,例如上述x=2,y=1


代码实现

App类(代码主入口)

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

        //创建游戏界面
        new GameJFrame();
    }
}

游戏界面类

import javax.swing.*;
import javax.swing.border.BevelBorder;
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 GameJFrame extends JFrame implements KeyListener, ActionListener {

    //多个方法需要用到的变量,记录在成员变量的位置
    //定义二维数组记录打乱后的0~15,每一个数字对应一张拼图
    int data[][] = new int[4][4];

    //定义胜利时的数据数组
    int[][] winArr = {
            {1, 2, 3, 4},
            {5, 6, 7, 8},
            {9, 10, 11, 12},
            {13, 14, 15, 0}
    };

    //定义坐标记录0的位置
    int x = 0;
    int y = 0;

    //定义计数器记录移动步数
    int stepCount = 0;

    //创建菜单选项里下面的条目
    JMenuItem restartItem = new JMenuItem("重新开始");
    JMenuItem reLoginItem = new JMenuItem("重新登录");
    JMenuItem exitItem = new JMenuItem("退出游戏");

    JMenuItem AccountItem = new JMenuItem("公众号");

    //定义图片路径,方便后面修改
    String path = "PuzzleGame\\image\\animal\\animal1\\";

    //空参构造初始化游戏
    public GameJFrame() {

        //调用方法初始化界面
        initFrame();

        //给界面添加事件监听,键盘监听KeyListener
        this.addKeyListener(this);

        //调用方法添加菜单
        initMenu();

        //给菜单里的条目添加事件监听,动作监听ActionListener
        restartItem.addActionListener(this);
        reLoginItem.addActionListener(this);
        exitItem.addActionListener(this);
        AccountItem.addActionListener(this);

        //调用方法初始化数据
        initData();

        //调用方法根据初始化后的数据加载图片
        loadImages();

        //设置界面可视,建议放在最后
        this.setVisible(true);
    }

    //定义方法判断游戏是否胜利
    private boolean victoty() {
        for (int i = 0; i < data.length; i++) {
            for (int j = 0; j < data[i].length; j++) {
                if (data[i][j] != winArr[i][j]) {
                    //data中的数据有一个与胜利数组中的数据不同,就说明没有胜利
                    return false;
                }
            }
        }
        return true;
    }

    //定义方法根据初始化后的数据加载图片
    private void loadImages() {

        //清空所有图片
        this.getContentPane().removeAll();

        //如果胜利,加载胜利图标
        if (victoty()) {
            JLabel vicJLabel = new JLabel(new ImageIcon("PuzzleGame\\image\\win.png"));
            vicJLabel.setBounds(203, 283, 197, 73);
            this.getContentPane().add(vicJLabel);
        }

        //加载计数器
        JLabel countJLabel = new JLabel("步数:" + stepCount);
        countJLabel.setBounds(50, 30, 100, 20);
        this.getContentPane().add(countJLabel);

        //利用循环加载拼图图片
        for (int i = 0; i < data.length; i++) {
            for (int j = 0; j < data[i].length; j++) {
                //获得data数组里的数据
                int number = data[i][j];
                //根据数据创建图片对象
                ImageIcon icon = new ImageIcon(path + number + ".jpg");
                //创建管理容器,将图片交给管理容器
                JLabel jLabel = new JLabel(icon);
                //设置管理容器位置,大小
                jLabel.setBounds(105 * j + 83, 105 * i + 134, 105, 105);
                //设置边框
                jLabel.setBorder(new BevelBorder(0));
                //将管理容器添加到界面中
                this.getContentPane().add(jLabel);
            }
        }

        //添加背景图片
        JLabel bgJLabel = new JLabel(new ImageIcon("PuzzleGame\\image\\background.png"));
        bgJLabel.setBounds(40, 40, 508, 560);
        this.getContentPane().add(bgJLabel);

        //刷新一下
        this.getContentPane().repaint();
    }

    //定义方法初始化数据
    private void initData() {

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

        Random r = new Random();

        //打乱数据,根据打乱后的数据就能实现打乱拼图
        for (int i = 0; i < tempArr.length; i++) {
            int index = r.nextInt(tempArr.length);
            int temp = tempArr[i];
            tempArr[i] = tempArr[index];
            tempArr[index] = temp;
        }

        //将打乱后的数据记录在二维数组data中
        for (int i = 0; i < tempArr.length; i++) {
            //如果是0,记录0的位置
            if (tempArr[i] == 0) {
                x = i / 4;
                y = i % 4;
            }
            data[i / 4][i % 4] = tempArr[i];
        }

    }

    //定义方法添加菜单
    private void initMenu() {

        //创建菜单
        JMenuBar jMenuBar = new JMenuBar();

        //创建菜单的选项
        JMenu functionJmenu = new JMenu("功能");
        JMenu aboutJmenu = new JMenu("关于我们");


        //将条目添加到选项中
        functionJmenu.add(restartItem);
        functionJmenu.add(reLoginItem);
        functionJmenu.add(exitItem);

        aboutJmenu.add(AccountItem);

        //将选项添加到菜单中
        jMenuBar.add(functionJmenu);
        jMenuBar.add(aboutJmenu);

        //将菜单添加到界面中
        this.setJMenuBar(jMenuBar);

    }

    //定义方法初始化界面
    private void initFrame() {
        //设置大小
        this.setSize(603, 680);
        //设置标题
        this.setTitle("拼图游戏");
        //设置居中
        this.setLocationRelativeTo(null);
        //设置置顶
        this.setAlwaysOnTop(true);
        //设置关闭模式
        this.setDefaultCloseOperation(3);

        //设置解除默认居中放置,只有解除了,才能根据xy轴的方式添加主件
        this.setLayout(null);


    }

    //动作监听ActionListener,鼠标单击或按空格调用该方法
    @Override
    public void actionPerformed(ActionEvent e) {
        Object source = e.getSource();
        if (source == restartItem) {
            //重新开始
            //重新初始化数据
            initData();
            //计数器归0
            stepCount = 0;
            //重新根据初始化后的数据加载图片
            loadImages();

        } else if (source == reLoginItem) {
            //重新登录
            //关闭本类(游戏类)
            this.setVisible(false);
            //创建登录界面
            //new LoginJFrame();

        } else if (source == exitItem) {
            //退出游戏
            System.exit(0);

        } else if (source == AccountItem) {
            //显示公众号
            //创建弹窗
            JDialog accJDialog = new JDialog();
            //加载弹窗中的图片
            JLabel aboutJLabel = new JLabel(new ImageIcon("PuzzleGame\\image\\about.png"));
            aboutJLabel.setBounds(0, 0, 258, 258);
            //将图片添加到弹窗中
            accJDialog.getContentPane().add(aboutJLabel);
            //设置弹窗的大小
            accJDialog.setSize(344, 344);
            //设置弹窗置顶
            accJDialog.setAlwaysOnTop(true);
            //设置弹窗居中放置
            accJDialog.setLocationRelativeTo(null);
            //设置关闭后进行其他操作
            accJDialog.setModal(true);
            //设置弹窗可视
            accJDialog.setVisible(true);
        }
    }

    //键盘监听KeyListener
    //该方法基本不使用
    @Override
    public void keyTyped(KeyEvent e) {

    }

    //长按键盘时调用该方法
    @Override
    public void keyPressed(KeyEvent e) {

        //判断是否胜利
        if (victoty()) {
            //如果胜利,禁止进行显示全图操作,直接结束方法
            return;
        }

        //长按w显示全图
        int keyCode = e.getKeyCode();
        if (keyCode == 87) {
            //清空所有图片
            this.getContentPane().removeAll();

            //加载计数器
            JLabel countJLabel = new JLabel("步数:" + stepCount);
            countJLabel.setBounds(50, 30, 100, 20);
            this.getContentPane().add(countJLabel);

            //加载全图
            JLabel picJLabel = new JLabel(new ImageIcon(path + "all.jpg"));
            picJLabel.setBounds(83, 134, 420, 420);
            this.getContentPane().add(picJLabel);

            //添加背景图片
            JLabel bgJLabel = new JLabel(new ImageIcon("PuzzleGame\\image\\background.png"));
            bgJLabel.setBounds(40, 40, 508, 560);
            this.getContentPane().add(bgJLabel);

            //刷新一下
            this.getContentPane().repaint();
        }

    }

    //按下并松开键盘时调用该方法
    @Override
    public void keyReleased(KeyEvent e) {
        //判断是否胜利
        if (victoty()) {
            //如果胜利,禁止进行移动操作,直接结束方法
            return;
        }
        int keyCode = e.getKeyCode();
        if (keyCode == 37) {
            //判断是否到了最左边
            if (y == 0) {
                //如果到了最左边,不能进行向左,直接结束方法
                return;
            }
            //没到最左边,进行下面的操作
            System.out.println("向左");
            //更改data数组里的数据
            data[x][y] = data[x][y - 1];
            data[x][y - 1] = 0;
            //更改0的坐标
            y--;
            //步数加1
            stepCount++;
            //按照此数据重新加载图片
            loadImages();

        } else if (keyCode == 38) {
            //判断是否到了最上边
            if (x == 0) {
                //如果到了最上边,不能进行向上,直接结束方法
                return;
            }
            //没到最上边,进行下面的操作
            System.out.println("向上");
            //更改data数组里的数据
            data[x][y] = data[x - 1][y];
            data[x - 1][y] = 0;
            //更改0的坐标
            x--;
            //步数加1
            stepCount++;
            //按照此数据重新加载图片
            loadImages();

        } else if (keyCode == 39) {
            //判断是否到了最右边
            if (y == 3) {
                //如果到了最右边,不能进行向右,直接结束方法
                return;
            }
            //没到最右边,进行下面的操作
            System.out.println("向右");
            //更改data数组里的数据
            data[x][y] = data[x][y + 1];
            data[x][y + 1] = 0;
            //更改0的坐标
            y++;
            //步数加1
            stepCount++;
            //按照此数据重新加载图片
            loadImages();

        } else if (keyCode == 40) {
            //判断是否到了最下边
            if (x == 3) {
                //如果到了最下边,不能进行向下,直接结束方法
                return;
            }
            //没到最下边,进行下面的操作
            System.out.println("向下");
            //更改data数组里的数据
            data[x][y] = data[x + 1][y];
            data[x + 1][y] = 0;
            //更改0的坐标
            x++;
            //步数加1
            stepCount++;
            //按照此数据重新加载图片
            loadImages();

        } else if (keyCode == 87) {
            //松开w恢复原状
            loadImages();

        } else if (keyCode == 65) {
            //一键通过
            for (int i = 0; i < data.length; i++) {
                for (int j = 0; j < data[i].length; j++) {
                    data[i][j] = winArr[i][j];
                }
            }
            loadImages();
        }

    }

}

你可能感兴趣的:(java,python,开发语言)