Java基础:拼图小游戏(包含Java代码)

涉及到的知识:

1.图形用户接口GUI(Graphical User Interface)用图形化的方式显示操作界面

两个体系: AWT包和Swing包

2.界面会用到JFrame类

3.界面中的菜单会用到JMenuBar, JMenu, JMenuItem

4.添加图片

在设置完JLabel的location之后还需要获得展示内容的窗体, 通过setLayout(null)来取消默认的居中放置, 这样才能使图片放在我们想放的位置. 

5.监听事件

5.1动作监听只能监听键盘的空格和鼠标的左键点击。

5.2鼠标监听

5.3键盘监听

6.背景图片的设置

注意:先加载的图片会置顶, 后加载的图片会被先加载的覆盖。

7.图片路径的简化

路径分为两种:
绝对路径:一定是从盘符开始的。如C:\

相对路径:不是从盘符开始的, 相对路径是相对当前项目而言的。
在当前项目下,去找aaa文件夹,里面再找bbb文件夹。

8.Java代码

8.1拼图游戏界面的代码

package com.orange.ui;

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 {
    private int zerolocationx = 0;
    private int zerolocationy = 0;
    private final int leftKeyCode = 37;
    private final int upKeyCode = 38;
    private final int rightKeyCode = 39;
    private final int bottomKeyCode = 40;
    private final int aKeyCode = 65;
    private final int cheatCode = 87;
    private int[][] randomarr = new int[4][4];
    private int[][] winArr = new int[4][4];
    private final String imagepath = "JigsawPuzzle\\image";
    private String imageType = "girl";
    private int numImage = 1;
    private String completePath = imagepath + "\\" + imageType + "\\" + imageType + numImage;
    private String backgroundPath = "JigsawPuzzle\\image\\background.png";
    private String winPath = "JigsawPuzzle\\image\\win.png";
    private boolean winFlag = false;
    int[] arr = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
    private int count = 0;
    // set JMenuItem
    JMenuItem replayJMenuItem = new JMenuItem("重新游戏");
    JMenuItem reLoginJMenuItem = new JMenuItem("重新登录");
    JMenuItem closeJMenuItem = new JMenuItem("关闭游戏");
    JMenuItem prettyGirl = new JMenuItem("妹子");
    JMenuItem animal = new JMenuItem("动物");
    JMenuItem sport = new JMenuItem("运动");

    JMenuItem focusmeJMenuItem = new JMenuItem("关注我");

    public GameJFrame(int width, int height){
        // initial Frame
        initialFrame(width, height);

        // initial JMenuBar
        initialJMenuBar();

        // initial Image
        initialImage();

        this.setVisible(true);
    }

    private void initialImage() {
        // clear
        this.getContentPane().removeAll();

        // set count
        JLabel stepCount = new JLabel("步数为:" + count);
        stepCount.setBounds(50, 30, 100, 20);
        this.getContentPane().add(stepCount);

        // set win image
        if (randomarr == winArr){
            JLabel win = new JLabel(new ImageIcon(winPath));
            win.setBounds(40, 40, 508, 560);
            this.getContentPane().add(win);
            winFlag = true;
        }

        // set patches image
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                // set JLabel
                JLabel jLabel = new JLabel(new ImageIcon(completePath + "\\" + randomarr[i][j] + ".jpg"));

                // set JLabel location
                jLabel.setBounds(j * 105 + 83, i * 105 + 134, 105, 105);
                // set border
                // 0 present RAISED, 1 present LOWERED
                jLabel.setBorder(new BevelBorder(BevelBorder.RAISED));

                // get panel
                this.getContentPane().add(jLabel);
            }
        }

        // set background image
        JLabel bg = new JLabel(new ImageIcon(backgroundPath));
        bg.setBounds(40, 40, 508, 560);
        this.getContentPane().add(bg);

        // refresh interface
        this.getContentPane().repaint();
    }

    private void initialJMenuBar() {
        // set JMenuBar
        JMenuBar jMenuBar = new JMenuBar();

        // setJMenu
        JMenu functionJMenu = new JMenu("功能");
        JMenu aboutusJMenu = new JMenu("关于我们");
        JMenu changeImage = new JMenu("更换图片");

        changeImage.add(prettyGirl);
        changeImage.add(animal);
        changeImage.add(sport);

        functionJMenu.add(changeImage);
        functionJMenu.add(replayJMenuItem);
        functionJMenu.add(reLoginJMenuItem);
        functionJMenu.add(closeJMenuItem);

        aboutusJMenu.add(focusmeJMenuItem);

        // binding ActionListener for JMenuItem
        prettyGirl.addActionListener(this);
        animal.addActionListener(this);
        sport.addActionListener(this);
        replayJMenuItem.addActionListener(this);
        reLoginJMenuItem.addActionListener(this);
        closeJMenuItem.addActionListener(this);
        focusmeJMenuItem.addActionListener(this);

        jMenuBar.add(functionJMenu);
        jMenuBar.add(aboutusJMenu);

        // set JMenuBar in the Frame
        this.setJMenuBar(jMenuBar);
    }

    private void initialFrame(int width, int height) {
        this.setSize(width, height);
        // set title
        this.setTitle("拼图小游戏");

        // set frame always on top
        this.setAlwaysOnTop(true);

        // set frame in the center of screen
        this.setLocationRelativeTo(null);

        // close the program when click the X
        this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        // cancel default center of frame
        this.setLayout(null);

        // add Key Listener
        this.addKeyListener(this);

        randomarr = randomArr(arr);

        // get winArr
        win();
    }

    public int[][] randomArr(int[] arr){
        Random random = new Random();
        for (int i = 0; i < arr.length; i++) {
            int index = random.nextInt(arr.length);
            int temp = arr[i];
            arr[i] = arr[index];
            arr[index] = temp;
        }
        int[][] twoDarr= new int[4][4];
        int k = 0;
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                if (arr[k] == 0){
                    zerolocationx = i;
                    zerolocationy = j;
                }
                twoDarr[i][j] = arr[k];
                k++;
            }
        }
        return twoDarr;
    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyPressed(KeyEvent e) {
        // game over
        if (winFlag){
            return;
        }
        int keyCode = e.getKeyCode();
        switch (keyCode){
            case aKeyCode:
                // view origin image
                // clear
                this.getContentPane().removeAll();
                // load origin image
                // set JLabel
                JLabel jLabel = new JLabel(new ImageIcon(completePath + "\\" + "all.jpg"));

                // set JLabel location
                jLabel.setBounds(83, 134, 420, 420);
                // set border
                // 0 present RAISED, 1 present LOWERED
                jLabel.setBorder(new BevelBorder(BevelBorder.RAISED));

                // get panel
                this.getContentPane().add(jLabel);

                // set background image
                JLabel bg = new JLabel(new ImageIcon(backgroundPath));
                bg.setBounds(40, 40, 508, 560);

                this.getContentPane().add(bg);

                // refresh interface
                this.getContentPane().repaint();
                break;
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
        // game over
        if (winFlag){
            return;
        }
        // Listener
        // left:37, up:38, right:39, bottom:40
        int keyCode = e.getKeyCode();
//        System.out.println("keyboard represent code is:" + keyCode);
        switch (keyCode){
            case leftKeyCode:
                changepatchlocation(0, 1);
                break;
            case upKeyCode:
                changepatchlocation(1, 0);
                break;
            case rightKeyCode:
                changepatchlocation(0, -1);
                break;
            case bottomKeyCode:
                changepatchlocation(-1, 0);
                break;
            case aKeyCode:
                initialImage();
                break;
            case cheatCode:
                cheat();
                break;
        }


    }

    private void cheat() {
        randomarr = winArr;
        initialImage();
    }

    private void win(){
        int k = 0;
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                winArr[i][j] = k;
                k++;
            }
        }
        winArr[0][0] = 1;
        winArr[3][3] = 0;
    }

    private void changepatchlocation(int codex, int codey) {
        if (zerolocationx + codex < 0 || zerolocationx + codex > 3 || zerolocationy + codey < 0 || zerolocationy + codey > 3){
            return;
        }
        randomarr[zerolocationx][zerolocationy] = randomarr[zerolocationx + codex][zerolocationy + codey];
        randomarr[zerolocationx + codex][zerolocationy + codey] = 0;
        zerolocationx = zerolocationx + codex;
        zerolocationy = zerolocationy + codey;
        count++;
        initialImage();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        Random r = new Random();
        Object source = e.getSource();
        if (source == replayJMenuItem){
            randomarr = randomArr(arr);
            count = 0;
            initialImage();
        } else if (source == reLoginJMenuItem) {
            this.setVisible(false);
            new LoginJFrame(300, 400);
        } else if (source == closeJMenuItem) {
            System.exit(0);
        } else if (source == focusmeJMenuItem) {
            JDialog jDialog = new JDialog();
            JLabel jLabel = new JLabel(new ImageIcon("JigsawPuzzle\\image\\focusme.jpg"));
            jLabel.setBounds(0, 0, 934, 936);
            jDialog.getContentPane().add(jLabel);
            jDialog.setSize(1000, 1000);
            jDialog.setAlwaysOnTop(true);
            jDialog.setLocationRelativeTo(null);
            // if JDialog don't close, we can't continue
            jDialog.setModal(true);
            jDialog.setVisible(true);
        } else if (source == prettyGirl) {
            int i = r.nextInt(13) + 1;
            imageType = "girl";
            numImage = i;
            completePath = imagepath + "\\" + imageType + "\\" + imageType + numImage;
            randomarr = randomArr(arr);
            count = 0;
            initialImage();
        }else if (source == animal){
            int i = r.nextInt(8) + 1;
            imageType = "animal";
            numImage = i;
            completePath = imagepath + "\\" + imageType + "\\" + imageType + numImage;
            randomarr = randomArr(arr);
            count = 0;
            initialImage();
        } else if (source == sport) {
            int i = r.nextInt(10) + 1;
            imageType = "sport";
            numImage = i;
            completePath = imagepath + "\\" + imageType + "\\" + imageType + numImage;
            randomarr = randomArr(arr);
            count = 0;
            initialImage();
        }
    }
}

8.2登录界面的代码

package com.orange.ui;

import test.CodeUtil;
import test.UserMember;

import javax.swing.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.Objects;

public class LoginJFrame extends JFrame implements MouseListener {

    private String codeStr = CodeUtil.getCode();
    private String logInImage = "JigsawPuzzle\\image\\login\\登录按钮.png";
    private String registerImage = "JigsawPuzzle\\image\\login\\注册按钮.png";
    JButton login = new JButton();
    JButton register = new JButton();
    JTextField usernameText = new JTextField();
    JPasswordField passwordText = new JPasswordField();
    JTextField codeText = new JTextField();
    JLabel rightCode = new JLabel();

    //创建一个集合存储正确的用户名和密码
    static ArrayList<UserMember> list = new ArrayList<>();
    static {
        list.add(new UserMember("zhangsan","123"));
        list.add(new UserMember("lisi","1234"));
    }
    public LoginJFrame(int width, int height){

        //初始化界面
        initJFrame(width, height);

        //在这个界面中添加内容
        initView();

        //让当前界面显示出来
        this.setVisible(true);
    }

    public void initView() {
        // clear
        this.getContentPane().removeAll();

        //1. 添加用户名文字
        JLabel usernameImage = new JLabel(new ImageIcon("JigsawPuzzle\\image\\login\\用户名.png"));
        usernameImage.setBounds(116, 135, 47, 17);
        this.getContentPane().add(usernameImage);

        //2.添加用户名输入框
        usernameText.setBounds(195, 134, 200, 30);
        this.getContentPane().add(usernameText);

        //3.添加密码文字
        JLabel passwordImage = new JLabel(new ImageIcon("JigsawPuzzle\\image\\login\\密码.png"));
        passwordImage.setBounds(130, 195, 32, 16);
        this.getContentPane().add(passwordImage);

        //4.密码输入框
        passwordText.setBounds(195, 195, 200, 30);
        this.getContentPane().add(passwordText);

        //验证码提示
        JLabel codeImage = new JLabel(new ImageIcon("JigsawPuzzle\\image\\login\\验证码.png"));
        codeImage.setBounds(133, 256, 50, 30);
        this.getContentPane().add(codeImage);

        //验证码的输入框
        codeText.setBounds(195, 256, 100, 30);
        this.getContentPane().add(codeText);

        // 验证码内容
        //设置内容
        rightCode.setText(codeStr);
        //位置和宽高
        rightCode.setBounds(300, 256, 50, 30);
        //添加到界面
        this.getContentPane().add(rightCode);

        //5.添加登录按钮
        login.setBounds(123, 310, 128, 47);
        login.setIcon(new ImageIcon(logInImage));
        //去除按钮的默认边框
        login.setBorderPainted(false);
        //去除按钮的默认背景
        login.setContentAreaFilled(false);
        this.getContentPane().add(login);

        //6.添加注册按钮
        register.setBounds(256, 310, 128, 47);
        register.setIcon(new ImageIcon(registerImage));
        //去除按钮的默认边框
        register.setBorderPainted(false);
        //去除按钮的默认背景
        register.setContentAreaFilled(false);
        this.getContentPane().add(register);

        // 鼠标点击监听
        login.addMouseListener(this);
        register.addMouseListener(this);
        rightCode.addMouseListener(this);

        //7.添加背景图片
        JLabel background = new JLabel(new ImageIcon("JigsawPuzzle\\image\\login\\background.png"));
        background.setBounds(0, 0, 470, 390);
        this.getContentPane().add(background);

        // refresh interface
        this.getContentPane().repaint();
    }


    public void initJFrame(int width, int height) {
        this.setSize(width, height);//设置宽高
        this.setTitle("拼图小游戏--登录");//设置标题
        this.setDefaultCloseOperation(3);//设置关闭模式
        this.setLocationRelativeTo(null);//居中
        this.setAlwaysOnTop(true);//置顶
        this.setLayout(null);//取消内部默认布局
    }


    //要展示用户名或密码错误
    public void showJDialog(String content) {
        //创建一个弹框对象
        JDialog jDialog = new JDialog();
        //给弹框设置大小
        jDialog.setSize(200, 150);
        //让弹框置顶
        jDialog.setAlwaysOnTop(true);
        //让弹框居中
        jDialog.setLocationRelativeTo(null);
        //弹框不关闭永远无法操作下面的界面
        jDialog.setModal(true);

        //创建Jlabel对象管理文字并添加到弹框当中
        JLabel warning = new JLabel(content);
        warning.setBounds(0, 0, 200, 150);
        jDialog.getContentPane().add(warning);

        //让弹框展示出来
        jDialog.setVisible(true);
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        Object source = e.getSource();
        if (source == rightCode){
            codeStr = CodeUtil.getCode();
            initView();
        } else if (source == login) {
            String utext = usernameText.getText();
            String ptext = passwordText.getText();
            String ctext = codeText.getText();
            if (Objects.equals(ctext, codeStr)){
                boolean flag = userPasswordCorrect(list, utext, ptext);
                if (flag){
//                    showJDialog("登录成功, 开始游戏!");
                    this.setVisible(false);
                    GameJFrame gameJFrame = new GameJFrame(603, 680);
                }else {
                    showJDialog("用户名或密码错误, 请重新填写!");
                }
            }else {
                showJDialog("验证码错误, 请重新填写!");
            }
//            codeStr = CodeUtil.getCode();
//            initView();
        } else if (source == register) {
            RegisterJFrame registerJFrame = new RegisterJFrame(500, 600);

        }
    }

    // judgment the Username and Password correct
    // need list and Username text and Password text
    public boolean userPasswordCorrect(ArrayList<UserMember> arrayList, String usernameText, String passwordText){
        boolean flag = false;
        for (UserMember userMember : list) {
            if (Objects.equals(usernameText, userMember.getUsername()) && Objects.equals(passwordText, userMember.getPassword())) {
                flag = true;
                break;
            }
        }
        return flag;
    }

    @Override
    public void mousePressed(MouseEvent e) {
        Object source = e.getSource();
        if (source == login){
            logInImage = "JigsawPuzzle\\image\\login\\登录按下.png";
            initView();
        } else if (source == register) {
            registerImage = "JigsawPuzzle\\image\\login\\注册按下.png";
            initView();
        }
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        Object source = e.getSource();
        if (source == login){
            logInImage = "JigsawPuzzle\\image\\login\\登录按钮.png";
            initView();
        } else if (source == register) {
            registerImage = "JigsawPuzzle\\image\\login\\注册按钮.png";
            initView();
        }
    }

    @Override
    public void mouseEntered(MouseEvent e) {

    }

    @Override
    public void mouseExited(MouseEvent e) {

    }
}

登录界面中的CodeUtil类产生验证码

package test;

import java.util.Random;

public class CodeUtil {
        // 开发验证码
        // 需求:
        // 定义方法实现随机产生一个5位的验证码
        // 验证码格式:
        // 长度为5
        // 有四位是大写字母或者小写字母
        // 有一位是数字
    public static String getCode(){
        // 65--90,97--122
        String code = "";
        Random r = new Random();
        for (int i = 0; i < 4; i++) {
            int random = r.nextInt(2);
            if (random == 0){
                // 大写字母
                int a = r.nextInt(26) + 65;
                code = code + (char) a;
            } else if (random == 1) {
                // 小写字母
                int a = r.nextInt(26) + 97;
                code = code + (char) a;
            }
        }
//        System.out.println(code);
        int num = r.nextInt(10);
        int location = r.nextInt(5);
        String newCode = "";
        if (location == 4){
            newCode = code + num;
        }else {
            for (int i = 0; i < code.length(); i++) {
                if (i == location){
                    newCode = newCode + num + code.charAt(i);
                    continue;
                }else {
                    newCode = newCode + code.charAt(i);
                }
            }
        }

        return newCode;
    }
}

9.存在的问题

当我在登录成功的上面加上showJDialog()函数时, 程序会不断地访问鼠标点击事件, 出现弹窗关掉又出现的情况, 最后我没有好的解决办法只好将showJDialog()注释掉.

猜你喜欢

转载自blog.csdn.net/Orange_sparkle/article/details/129176401
今日推荐