阶段项目——拼图小游戏

Java学习笔记(新手纯小白向)

第一章 JAVA基础概念

第二章 JAVA安装和环境配置

第三章 IntelliJ IDEA安装

第四章 运算符

第五章 运算符联系

第六章 判断与循环

第七章 判断与循环练习

第八章 循环高级综合

第九章 数组介绍及其内存图

第十章 数组基础练习

第十一章 方法基础及简单应用

第十二章 方法基础练习

第十三章 前续知识综合练习

第十四章 面向对象基础

第十五章 面向对象综合训练

第十六章 字符串基础

第十七章 字符串基础练习

第十八章 ArrayList集合

第十九章 ArrayList集合基础练习

第二十章 面向对象进阶

第二十一章 面向对象进阶基础练习

第二十二章 阶段项目——拼图小游戏


目录

Java学习笔记(新手纯小白向)

前言

代码示例

一、UI界面搭建

        1.游戏主界面

        2.登录界面

        3.注册界面

二、业务逻辑编写 

        1.用户类

        2.生成验证码的工具类

三、游戏主入口

四、游戏打包exe说明

总结


前言

本篇章主要展示了阶段项目——拼图小游戏,该项目基本包括了之前所学的所有知识点,可以很好得巩固所学知识点。


代码示例

一、UI界面搭建

        1.游戏主界面

//创建游戏主界面
public class GameJFrame extends JFrame implements KeyListener, ActionListener {
    //创建获取随机数的对象
    Random r = new Random();

    //定义二维数组,记录图片的编号
    int[][] imageCode = new int[4][4];

    //定义二维数组,记录胜利后图片的编号
    int[][] win = new int[][]{
            {1, 2, 3, 4},
            {5, 6, 7, 8},
            {9, 10, 11, 12},
            {13, 14, 15, 0}
    };

    //定义变量x和y,记录空白方块在二维数组中的位置
    int x = 0;
    int y = 0;

    //定义变量path,记录当前加载图片的相对路径
    String path = "gigsawgame\\image\\animal\\animal1\\";

    //定义变量step,记录移动的步数
    int step = 0;

    //创建选项下的条目对象
    JMenuItem replayItem = new JMenuItem("重新游戏");
    JMenuItem reLoginItem = new JMenuItem("重新登录");
    JMenuItem closeItem = new JMenuItem("关闭游戏");
    JMenuItem rewardItem = new JMenuItem("谢谢打赏");
    JMenuItem girlItem = new JMenuItem("美女");
    JMenuItem animalItem = new JMenuItem("动物");
    JMenuItem sportsItem = new JMenuItem("运动");

    //定义空参构造,对界面进行初始化
    public GameJFrame() {
        //初始化游戏主界面
        initJFrame();

        //初始化菜单
        initJMenuBar();

        //初始化数据
        initImageCode();

        //初始化图片
        initImage();

        //设置界面是否显示,建议写在最后
        this.setVisible(true);
    }

    //打乱图片编号
    private void initImageCode() {
        //定义一维数组,记录图片编号
        int[] tempArr = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
        //打乱数组中号码的顺序
        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;
        }
        //定义变量index,记录一维数组的索引
        int index = 0;
        //将打乱后的一维数组中的编号,添加到二维数组中
        for (int i = 0; i < imageCode.length; i++) {
            for (int j = 0; j < imageCode[i].length; j++) {
                if (tempArr[index] == 0) {
                    x = i;
                    y = j;
                }
                imageCode[i][j] = tempArr[index];
                index++;
            }
        }
    }

    //将图片加载到界面中
    private void initImage() {
        //清空已经出现的图片
        this.getContentPane().removeAll();

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

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

        //使用循环添加每一行图片
        for (int i = 0; i < 4; i++) {
            //使用循坏添加每一列图片
            for (int j = 0; j < 4; j++) {
                //定义变量code,记录图片编号
                int code = imageCode[i][j];
                //创建ImageIcon图片对象,并创建JLabel管理容器
                JLabel jLabel = new JLabel(new ImageIcon(path
                        + code + ".jpg"));

                //指定图片位置
                jLabel.setBounds(105 * j + 83, 105 * i + 134, 105, 105);

                //给图片添加边框
                jLabel.setBorder(new BevelBorder(BevelBorder.LOWERED));

                //将JLabel管理容器添加到界面中(将JLabel管理容器添加到隐藏容器之中)
                this.getContentPane().add(jLabel);
            }
        }

        //添加背景图片(后添加的在下方)
        JLabel background = new JLabel(new ImageIcon("gigsawgame\\image\\background.png"));
        background.setBounds(40, 40, 508, 560);
        this.getContentPane().add(background);

        //刷新界面
        this.getContentPane().repaint();
    }

    //设置菜单栏基础信息
    private void initJMenuBar() {
        //创建菜单栏对象
        JMenuBar jMenuBar = new JMenuBar();

        //创建菜单上面的两个选项:功能、关于我们
        JMenu functionJMenu = new JMenu("功能");
        JMenu aboutJMenu = new JMenu("关于我们");

        //创建功能选项中的更换图片选项
        JMenu replaceImage = new JMenu("更换图片");

        //匹配选项与条目
        //匹配功能选项与其条目
        functionJMenu.add(replaceImage);
        functionJMenu.add(replayItem);
        functionJMenu.add(reLoginItem);
        functionJMenu.add(closeItem);

        //匹配功能选项下的更换图片选项与其条目
        replaceImage.add(girlItem);
        replaceImage.add(animalItem);
        replaceImage.add(sportsItem);

        //匹配关于我们选项与其条目
        aboutJMenu.add(rewardItem);

        //给条目绑定事件
        replayItem.addActionListener(this);
        reLoginItem.addActionListener(this);
        closeItem.addActionListener(this);
        rewardItem.addActionListener(this);
        girlItem.addActionListener(this);
        animalItem.addActionListener(this);
        sportsItem.addActionListener(this);

        //将选项添加到菜单栏中
        jMenuBar.add(functionJMenu);
        jMenuBar.add(aboutJMenu);

        //设置界面菜单栏
        this.setJMenuBar(jMenuBar);
    }

    //设置界面基础信息
    private void initJFrame() {
        //设置界面的宽高
        this.setSize(603, 680);

        //设置界面的标题
        this.setTitle("拼图单机版 v1.0");

        //设置界面置顶
        this.setAlwaysOnTop(true);

        //设置界面居中
        this.setLocationRelativeTo(null);

        //设置关闭模式
        this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        //取消默认的居中放置
        this.setLayout(null);

        //添加游戏操作(给整个界面添加键盘监听事件)
        this.addKeyListener(this);
    }

    //空实现keyTyped方法
    @Override
    public void keyTyped(KeyEvent e) {

    }

    //实现键盘按下不松按键操作方法,查看完整图片
    @Override
    public void keyPressed(KeyEvent e) {
        //定义变量keyCode,记录按下按键的值
        int keyCode = e.getKeyCode();
        if (keyCode == 65) {
            //清空之前的图片
            this.getContentPane().removeAll();

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

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

        //重新加载图片
        this.getContentPane().repaint();
    }

    //实现键盘松开按键操作方法,使图片可以左上右下移动及一键通关
    @Override
    public void keyReleased(KeyEvent e) {
        //如果游戏胜利,则结束方法
        if (victory()) {
            return;
        }

        //定义变量keyCode,记录按键的值
        int keyCode = e.getKeyCode();

        //对按键进行判断,做出对应行为
        switch (keyCode) {
            //左键操作
            case 37 -> {
                //判断是否为空白方块是否位于最右侧
                if (y == 3) {
                    return;
                } else {
                    imageCode[x][y] = imageCode[x][y + 1];
                    imageCode[x][y + 1] = 0;
                    y++;

                    //移动一次,步数增加一次
                    step++;
                }
                //调用方法initImage,重新加载图片
                initImage();
            }
            //上键操作
            case 38 -> {
                //判断是否为空白方块是否位于最下侧
                if (x == 3) {
                    return;
                } else {
                    imageCode[x][y] = imageCode[x + 1][y];
                    imageCode[x + 1][y] = 0;
                    x++;

                    //移动一次,步数增加一次
                    step++;
                }
                //调用方法initImage,重新加载图片
                initImage();
            }
            //右键操作
            case 39 -> {
                //判断是否为空白方块是否位于最左侧
                if (y == 0) {
                    return;
                } else {
                    imageCode[x][y] = imageCode[x][y - 1];
                    imageCode[x][y - 1] = 0;
                    y--;

                    //移动一次,步数增加一次
                    step++;
                }
                //调用方法initImage,重新加载图片
                initImage();
            }
            //下键操作
            case 40 -> {
                //判断是否为空白方块是否位于最上侧
                if (x == 0) {
                    return;
                } else {
                    imageCode[x][y] = imageCode[x - 1][y];
                    imageCode[x - 1][y] = 0;
                    x--;

                    //移动一次,步数增加一次
                    step++;
                }
                //调用方法initImage,重新加载图片
                initImage();
            }
            //松开A键,恢复之前的打乱效果
            case 65 -> {
                initImage();
            }
            //松开按键W,实现一键通关
            case 87 -> {
                imageCode = new int[][]{
                        {1, 2, 3, 4},
                        {5, 6, 7, 8},
                        {9, 10, 11, 12},
                        {13, 14, 15, 0}
                };
                initImage();
            }
        }
    }

    //定义方法victory,判断游戏是否胜利
    public boolean victory() {
        for (int i = 0; i < imageCode.length; i++) {
            for (int j = 0; j < imageCode[i].length; j++) {
                if (imageCode[i][j] != win[i][j]) {
                    return false;
                }
            }
        }
        return true;
    }

    //给菜单栏中选项下的条目对象绑定事件
    @Override
    public void actionPerformed(ActionEvent e) {
        //获取被点击的条目对象
        Object clickItem = e.getSource();
        //判断并执行
        if (clickItem == replayItem) {
            //步数归零
            step = 0;
            //重新打乱图片编号
            initImageCode();
            //重新加载图片
            initImage();
        } else if (clickItem == reLoginItem) {
            //关闭当前游戏界面
            this.setVisible(false);
            //打开登录界面
            new LoginJFrame();
        } else if (clickItem == closeItem) {
            //关闭虚拟机
            System.exit(0);
        } else if (clickItem == rewardItem) {
            //创建一个弹框对象
            JDialog jDialog = new JDialog();
            //创建图片管理容器JLabel
            JLabel jLabel = new JLabel(new ImageIcon("gigsawgame\\image\\reward.jpg"));
            //设置管理容器的位置和宽高
            jLabel.setBounds(0, 0, 514, 514);
            //把管理容器添加到弹框中
            jDialog.getContentPane().add(jLabel);
            //设置弹框的大小
            jDialog.setSize(600, 600);
            //设置弹框置顶
            jDialog.setAlwaysOnTop(true);
            //设置弹框居中
            jDialog.setLocationRelativeTo(null);
            //弹窗不关闭,则无法操作下面的界面
            jDialog.setModal(true);
            //让弹窗显示
            jDialog.setVisible(true);
        } else if (clickItem == girlItem) {
            //步数归零
            step = 0;

            //随机获取美女图片编号
            int beautyCode = r.nextInt(13) + 1;
            path = "gigsawgame\\image\\girl\\girl" + beautyCode + "\\";

            //重新打乱图片编号
            initImageCode();

            //重新加载图片
            initImage();
        } else if (clickItem == animalItem) {
            //步数归零
            step = 0;

            //随机获取动物图片编号
            int animalCode = r.nextInt(8) + 1;
            path = "gigsawgame\\image\\animal\\animal" + animalCode + "\\";

            //重新打乱图片编号
            initImageCode();

            //重新加载图片
            initImage();
        } else if (clickItem == sportsItem) {
            //步数归零
            step = 0;

            //随机获取运动图片编号
            int sportsCode = r.nextInt(10) + 1;
            path = "gigsawgame\\image\\sport\\sport" + sportsCode + "\\";

            //重新打乱图片编号
            initImageCode();

            //重新加载图片
            initImage();
        }
    }
}

        2.登录界面

//创建登录界面
public class LoginJFrame extends JFrame implements MouseListener {
    //数据初始化
    //创建集合user,存储正确的用户名和密码
    static ArrayList<User> users = new ArrayList<>();

    static {
        users.add(new User("张三", "123"));
        users.add(new User("李四", "abc"));
    }

    //加载用户名、密码和验证码输入框
    JTextField usernameField = new JTextField();
    JPasswordField passwordField = new JPasswordField();
    JTextField iCodeField = new JTextField();

    //加载显示密码按钮、登录按钮、注册按钮和验证码内容管理器
    JButton passwordVisible = new JButton();
    JButton loginButton = new JButton();
    JButton registerButton = new JButton();
    JLabel rightCode = new JLabel();

    //加载正确验证码
    String rightICode = ICodeUtil.getCode();

    //定义空参构造,对界面进行初始化
    public LoginJFrame() {
        //初始化登录主界面
        initJFrame();

        //初始化图片、输入框及按钮
        initTextButton();

        //设置界面是否显示,建议写在最后
        this.setVisible(true);
    }

    //设置输入框、按钮及图片
    private void initTextButton() {
        //清空已经出现的图片、输入框及按钮
        this.getContentPane().removeAll();

        //加载输入框基础图片
        JLabel usernameImage = new JLabel(new ImageIcon("gigsawgame\\image\\login\\用户名.png"));
        usernameImage.setBounds(105, 129, 47, 17);
        JLabel passwordImage = new JLabel(new ImageIcon("gigsawgame\\image\\login\\密码.png"));
        passwordImage.setBounds(112, 202, 32, 16);
        JLabel iCodeImage = new JLabel(new ImageIcon("gigsawgame\\image\\login\\验证码.png"));
        iCodeImage.setBounds(100, 274, 56, 21);

        //设置用户名、密码和验证码输入框的基础信息
        usernameField.setBounds(200, 123, 150, 29);
        passwordField.setBounds(200, 196, 150, 29);
        iCodeField.setBounds(200, 270, 75, 29);

        //设置正确验证码内容管理器的基础信息
        rightCode.setText(rightICode);
        rightCode.setBounds(275, 270, 75, 29);

        //设置显示密码按钮、登录按钮和注册按钮的基础信息
        passwordVisible.setBounds(332, 196, 18, 29);
        passwordVisible.setIcon(new ImageIcon("gigsawgame\\image\\login\\显示密码.png"));
        loginButton.setBounds(64, 320, 128, 47);
        loginButton.setIcon(new ImageIcon("gigsawgame\\image\\login\\登录按钮.png"));
        registerButton.setBounds(275, 320, 128, 47);
        registerButton.setIcon(new ImageIcon("gigsawgame\\image\\login\\注册按钮.png"));

        //去除按钮的默认边框及背景
        passwordVisible.setBorderPainted(false);
        passwordVisible.setContentAreaFilled(false);
        loginButton.setBorderPainted(false);
        loginButton.setContentAreaFilled(false);
        registerButton.setBorderPainted(false);
        registerButton.setContentAreaFilled(false);

        //加载背景图片
        JLabel background = new JLabel(new ImageIcon("gigsawgame\\image\\login\\background.png"));
        background.setBounds(0, 0, 470, 390);

        //给按钮及验证码内容管理器绑定事件
        rightCode.addMouseListener(this);
        passwordVisible.addMouseListener(this);
        loginButton.addMouseListener(this);
        registerButton.addMouseListener(this);

        //将图片、输入框及按钮添加到界面中
        this.getContentPane().add(usernameImage);
        this.getContentPane().add(usernameField);
        this.getContentPane().add(passwordImage);
        this.getContentPane().add(passwordVisible);
        this.getContentPane().add(passwordField);
        this.getContentPane().add(iCodeImage);
        this.getContentPane().add(iCodeField);
        this.getContentPane().add(rightCode);
        this.getContentPane().add(loginButton);
        this.getContentPane().add(registerButton);
        this.getContentPane().add(background);

        //刷新界面
        this.getContentPane().repaint();
    }

    //设置界面基础信息
    private void initJFrame() {
        //设置界面的宽高
        this.setSize(488, 430);

        //设置界面的标题
        this.setTitle("用户登录");

        //设置界面置顶
        this.setAlwaysOnTop(true);

        //设置界面居中
        this.setLocationRelativeTo(null);

        //设置关闭模式
        this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        //取消默认的居中放置
        this.setLocationRelativeTo(null);
    }

    //展示用户名或密码错误提示弹窗
    private void tipJDialog(String tip) {
        //创建弹窗
        JDialog tipJDialog = new JDialog();

        //设置弹窗大小
        tipJDialog.setSize(200, 150);

        //设置弹窗置顶
        tipJDialog.setAlwaysOnTop(true);

        //设置弹窗居中
        tipJDialog.setLocationRelativeTo(null);

        //设置弹窗不关闭无法操作下方界面
        tipJDialog.setModal(true);

        //添加提示内容
        JLabel tips = new JLabel(tip);
        tips.setBounds(0, 0, 200, 150);
        tipJDialog.getContentPane().add(tips);

        //使弹窗可见
        tipJDialog.setVisible(true);
    }

    //实现按钮的鼠标监听事件方法
    @Override
    public void mouseClicked(MouseEvent e) {
        //获取点击的按钮
        Object source = e.getSource();

        //根据点击按钮不同,做出相应操作
        if (source == rightCode) {
            //更换一个新的验证码
            rightICode = ICodeUtil.getCode();
            rightCode.setText(rightICode);
        }
    }

    @Override
    public void mousePressed(MouseEvent e) {
        //获取按下的按钮
        Object source = e.getSource();

        //根据按下按钮不同,做出相应操作
        if (source == passwordVisible) {
            //切换显示密码按钮的背景图片
            passwordVisible.setIcon(new ImageIcon("gigsawgame\\image\\login\\显示密码按下.png"));
        } else if (source == loginButton) {
            //切换登录按钮的背景图片
            loginButton.setIcon(new ImageIcon("gigsawgame\\image\\login\\登录按下.png"));
        } else if (source == registerButton) {
            //切换注册按钮的背景图片
            registerButton.setIcon(new ImageIcon("gigsawgame\\image\\login\\注册按下.png"));
        }
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        //获取松开的按钮
        Object source = e.getSource();

        //根据松开按钮不同,做出相应操作
        if (source == passwordVisible) {
            //恢复显示密码按钮的背景图片
            passwordVisible.setIcon(new ImageIcon("gigsawgame\\image\\login\\显示密码.png"));
        } else if (source == loginButton) {
            //获取用户输入的用户名,密码,验证码
            String username = usernameField.getText();
            String password = passwordField.getText();
            String iCode = iCodeField.getText();

            //判断验证码是否正确
            //判断用户名和密码是否为空
            //判断用户名、密码是否正确
            if (iCode.equalsIgnoreCase(rightICode)) {
                if (username.length() != 0 || password.length() != 0) {
                    if (contains(username, password)){
                        new GameJFrame();
                    }else {
                        tipJDialog("用户名或密码错误");
                    }
                } else {
                    tipJDialog("用户名或者密码为空");
                }
            } else {
                tipJDialog("验证码输入错误");
                //更换一个新的验证码
                rightICode = ICodeUtil.getCode();
                rightCode.setText(rightICode);
            }

            //恢复登录按钮的背景图片
            loginButton.setIcon(new ImageIcon("gigsawgame\\image\\login\\登录按钮.png"));
        } else if (source == registerButton) {
            //恢复注册按钮的背景图片
            registerButton.setIcon(new ImageIcon("gigsawgame\\image\\login\\注册按钮.png"));
        }
    }
    //判断用户在集合中是否存在
    public boolean contains(String username, String password) {
        for (int i = 0; i < users.size(); i++) {
            if (username.equals(users.get(i).getUsername()) && password.equals(users.get(i).getPassword())) {
                return true;
            }
        }
        return false;
    }

    @Override
    public void mouseEntered(MouseEvent e) {

    }

    @Override
    public void mouseExited(MouseEvent e) {

    }
}

        3.注册界面

//创建注册界面
public class RegisterJFrame extends JFrame {
    //定义空参构造,对界面进行初始化
    public RegisterJFrame() {
        //初始化注册主界面
        initJFrame();

        //初始化图片及输入框
    }

    //设置界面基础信息
    private void initJFrame() {
        //设置界面的宽高
        this.setSize(488, 500);

        //设置界面的标题
        this.setTitle("用户注册");

        //设置界面置顶
        this.setAlwaysOnTop(true);

        //设置界面居中
        this.setLocationRelativeTo(null);

        //设置关闭模式
        this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        //取消默认的居中放置
        this.setLocationRelativeTo(null);

        //设置界面是否显示,建议写在最后
        this.setVisible(true);
    }
}

二、业务逻辑编写 

        1.用户类

public class User {
    //定义用户的属性
    private String username;
    private String password;

    //定义空参构造和带参构造
    public User() {
    }
    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }

    //定义所有成员变量的get和set方法
    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

        2.生成验证码的工具类

public class ICodeUtil {
    //私有化空参构造
    private ICodeUtil() {
    }

    //定义静态方法getCode,获取验证码
    public static String getCode() {
        //创建获取随机数的对象
        Random r = new Random();

        //创建字符数组,存储验证码
        char[] code = new char[5];

        //随机添加一个数字
        code[0] = (char) (r.nextInt(10) + 48);

        //定义字符数组,存储大小写字母
        char[] letter = new char[52];

        //将大小写字母添加进letter字符数组
        for (int i = 0; i < letter.length; i++) {
            if (i >= 26) {
                letter[i] = (char) (97 + i - 26);
            } else {
                letter[i] = (char) (65 + i);
            }
        }

        //随机将大小写字母加入code字符数组
        for (int i = 1; i < code.length; i++) {
            code[i] = letter[r.nextInt(letter.length)];
        }

        //将数组中的字符打乱
        char temp;
        int index = 0;
        for (int i = 0; i < code.length; i++) {
            index = r.nextInt(code.length - 1);
            temp = code[i];
            code[i] = code[index];
            code[index] = temp;
        }

        return new String(code);
    }
}

三、游戏主入口

//程序的启动入口
public class App {
    public static void main(String[] args) {
        //想开启哪个界面,就创建谁的对象
//        new RegisterJFrame();
        new LoginJFrame();
//        new GameJFrame();
    }
}

四、游戏打包exe说明

        说明文本及工具在百度网盘中。链接: https://pan.baidu.com/s/1QxUXy_1ksPxfZ5xYvJQwnQ?pwd=0806 提取码: 0806

若过期,请在评论区留言。


总结

拼图小游戏有助于了解Java的GUI相关知识,但在以后并不常用,了解即可。因此,该项目的重中之重还是游戏的业务逻辑,及对所学知识的巩固。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值