Java坦克大战防重叠优化

Java坦克大战优化

基础思路

举例(敌人坦克与我方坦克):
第一种: 当我方坦克方向向上(宽40,高60),敌人坦克方向向上或向下时。我方坦克左上角或者右上角坐标落在敌人坦克的区域内。

第二种: 当我方坦克方向向上(宽40,高60),敌人坦克方向向左或向右时。我方坦克左上角或者右上角坐标落在敌人坦克的区域内。

第三种:当我方坦克方向向右(宽60,高40),敌人坦克方向向上或向下时。我方坦克右上角或者右下角坐标落在敌人坦克的区域内。

第四种:当我方坦克方向向右(宽60,高40),敌人坦克方向向左或向右时。我方坦克右上角或者右下角坐标落在敌人坦克的区域内。

第五种:当我方坦克方向向下(宽40,高60),敌人坦克方向向上或向下时。我方坦克左下角或者右下角坐标落在敌人坦克的区域内。

第六种:当我方坦克方向向下(宽40,高60),敌人坦克方向向左或向右时。我方坦克左下角或者右下角坐标落在敌人坦克的区域内。

第七种:当我方坦克方向向左(宽60,高40),敌人坦克方向向上或向下时。我方坦克左上角或者右下角坐标落在敌人坦克的区域内。

第八种:当我方坦克方向向左(宽60,高40),敌人坦克方向向左或向右时。我方坦克左下角或者右下角坐标落在敌人坦克的区域内。

刚开始不明白为什么什么要判断两个点的,后来才明白是因为当我方坦克方向向上,敌人坦克方向下,我方坦克在敌方左下角重叠时我方坦克 x 坐标会小很多如图,只判断一个角还是会重叠,所以两个都需要判断。

在这里插入图片描述

// 当我坦克是向上方向,敌方坦克是向上或向下方向
if (tank.direction == UP || tank.direction == DOWN) {
    // 当前坦克左上角的坐标在重叠的范围内
    // 我方坦克左上角坐标 [x, y]
    if (x >= tank.x
        && x <= tank.x + WIDTH
        && y >= tank.y
        && y <= tank.y + HEIGHT) {
        return true;
    }

    // 当前坦克右上角的坐标在重叠范围内,当我方坦克在敌方坦克的左方重叠时 我方的 x 坐标会比敌方 x 坐标小,
    // 只判断一个左上角还是会重叠,所以要判断两个角的坐标
    // 我方坦克右上角坐标 [x + WIDTH, y]
    if (x + WIDTH >= tank.x
        && x <= tank.x + WIDTH
        && y >= tank.y
        && y <= tank.y + HEIGHT) {
        return true;
    }

未优化代码

package com.example.tankgame06;


import java.util.List;
import java.util.Vector;

import static com.example.tankgame04.GameConstant.*;


/**
 * @author XiaoAi
 * @date 2024/6/22 10:44
 */
public abstract class Tank {
    private int x;
    private int y;
    private int direction; // 0 1 2 3
    private int speed = 1;
    private List<Bullet> bulletList = new Vector<>(); // 子弹
    // 总宽度(x)90 高度(80)
    public final static int WIDTH = 90;
    public final static int HEIGHT = 80;
    private boolean isLive = true;
    public static final List<Tank> ALL_TANK = new Vector<>();

    public Tank() {
    }

    public Tank(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public void moveUp() {
        boolean isTouch = isTouchTank();
        if (isTouch) {
            return;
        }
        setY(this.y - speed);
    }

    public void moveRight() {
        boolean isTouch = isTouchTank();
        if (isTouch) {
            return;
        }
        setX(this.x + speed);
    }

    public void moveDown() {
        boolean isTouch = isTouchTank();
        if (isTouch) {
            return;
        }
        setY(this.y + speed);
    }

    public void moveLeft() {
        boolean isTouch = isTouchTank();
        if (isTouch) {
            return;
        }
        setX(this.x - speed);
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        if (x >= 0 && x <= TankGame06.WIDTH - Tank.WIDTH) {
            this.x = x;
        }
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        if (y >= 0 && y <= TankGame06.HEIGHT - Tank.HEIGHT) {
            this.y = y;
        }
    }

  	//....get/set

    public void shotTank() {
        if (!this.isLive) {
            return;
        }

        List<Bullet> bulletList = getBulletList();
        Bullet bullet = null;
        switch (getDirection()) {
            case UP:
                bullet = new Bullet(getX() + WIDTH / 2 - 2, getY() - 10, UP);
                break;
            case RIGHT:
                bullet = new Bullet(getX() + WIDTH + 10, getY() + HEIGHT / 2 + 2, RIGHT);
                break;
            case DOWN:
                bullet = new Bullet(getX() + HEIGHT / 2 + 2, getY() + WIDTH, DOWN);
                break;
            case LEFT:
                bullet = new Bullet(getX() - 10, getY() + HEIGHT / 2 + 2, LEFT);
                break;
        }
        if (bullet != null) {
            bulletList.add(bullet);
            new Thread(bullet).start();
        }
    }

    /**
     * 坦克重叠判断
     *
     * @return 是否重叠
     */
    public boolean isTouchTank() {

        int offset = 20;
        if (ALL_TANK.size() == 1) {
            return false;
        }

        switch (direction) {
            case UP:
                for (int i = 0; i < ALL_TANK.size(); i++) {
                    Tank tank = ALL_TANK.get(i);
                    if (tank != this) {
                        // 当我坦克是向上方向,敌方坦克是向上或向下方向
                        if (tank.direction == UP || tank.direction == DOWN) {
                            // 当前坦克左上角的坐标在重叠的范围内
                            // 我方坦克左上角坐标 [x, y]
                            if (x >= tank.x
                                    && x <= tank.x + WIDTH
                                    && y >= tank.y
                                    && y <= tank.y + HEIGHT) {
                                return true;
                            }

                            // 当前坦克右上角的坐标在重叠范围内,当我方坦克在敌方坦克的左方重叠时 我方的 x 坐标会比敌方 x 坐标小,
                            // 只判断一个左上角还是会重叠,所以要判断两个角的坐标
                            // 我方坦克右上角坐标 [x + WIDTH, y]
                            if (x + WIDTH >= tank.x
                                    && x <= tank.x + WIDTH
                                    && y >= tank.y
                                    && y <= tank.y + HEIGHT) {
                                return true;
                            }
                        }
                        // 当我坦克是向上方向,敌方坦克是向右或向左方向
                        // 敌方坦克向右等于旋转九十度高宽互换
                        if (tank.direction == RIGHT || tank.direction == LEFT) {
                            // 当前坦克左上角的坐标在重叠的范围内
                            // 我方坦克左上角坐标 [x, y]
                            if (x >= tank.x
                                    && x <= tank.x + HEIGHT
                                    && y >= tank.y
                                    && y <= tank.y + WIDTH) {
                                return true;
                            }

                            // 当前坦克右上角的坐标在重叠的范围内
                            // 我方坦克右上角坐标 [x + WIDTH, y]
                            if (x + WIDTH >= tank.x
                                    && x <= tank.x + HEIGHT
                                    && y >= tank.y
                                    && y <= tank.y + WIDTH) {
                                return true;
                            }
                        }

                    }
                }
                break;
            case RIGHT:
                // 我方坦克向右,右上角坐标[x + HEIGHT, y ]
                // 我方坦克向右,左下角坐标[x + HEIGHT, y + WIDTH]
                for (int i = 0; i < ALL_TANK.size(); i++) {
                    Tank tank = ALL_TANK.get(i);
                    if (tank != this) {
                        // 当我坦克是向右方向,敌方坦克是向上或下方向
                        if (tank.direction == UP || tank.direction == DOWN) {
                            // 当前坦克右上角的坐标在重叠的范围内
                            // 当前坦克右上角坐标 [x + HEIGHT, y ]
                            System.out.println(x + HEIGHT >= tank.x
                                    && x + HEIGHT <= tank.x + WIDTH);
                            System.out.println(y >= tank.y
                                    && y <= tank.y + HEIGHT);
                            if (x + HEIGHT >= tank.x
                                    && x + HEIGHT <= tank.x + WIDTH
                                    && y >= tank.y
                                    && y <= tank.y + HEIGHT) {
                                return true;
                            }
                            // 当前坦克左下角的坐标在重叠的范围内
                            // 当前坦克左下角坐标 [x + HEIGHT, y + WIDTH]
                            if (x + HEIGHT >= tank.x
                                    && x + HEIGHT <= tank.x + WIDTH
                                    && y + WIDTH >= tank.y
                                    && y + WIDTH <= tank.y + HEIGHT) {
                                return true;
                            }
                        }

                        // 当我坦克是向右方向,敌方坦克是向左或向右方向
                        if (tank.direction == LEFT || tank.direction == RIGHT) {
                            // 当前坦克右上角的坐标在重叠的范围内
                            // 当前坦克右上角坐标 [x + HEIGHT, y]
                            if (x + HEIGHT >= tank.x
                                    && x + HEIGHT <= tank.x + HEIGHT
                                    && y >= tank.y
                                    && y <= tank.y + WIDTH) {
                                return true;
                            }
                            // 当前坦克左下角的坐标在重叠的范围内
                            // 当前坦克左下角坐标 [x + HEIGHT, y + WIDTH]
                            if (x + HEIGHT >= tank.x
                                    && x + HEIGHT <= tank.x + HEIGHT
                                    && y + WIDTH >= tank.y
                                    && y + WIDTH <= tank.y + WIDTH) {
                                return true;
                            }
                        }
                    }
                }
                break;
            case DOWN:
                // 我方坦克向下,左下角坐标 [x, y + HEIGHT]
                // 我方坦克向下,右下角坐标 [x + WIDTH, y + HEIGHT]
                for (int i = 0; i < ALL_TANK.size(); i++) {
                    Tank tank = ALL_TANK.get(i);
                    if (tank != this) {
                        // 当我坦克是向下方向,敌方坦克是向上或下方向
                        if (tank.direction == UP || tank.direction == DOWN) {
                            // 我方左下角在重叠范围内
                            if (x >= tank.x
                                    && x <= tank.x + WIDTH
                                    && y + HEIGHT >= tank.y
                                    && y + HEIGHT <= tank.y + HEIGHT) {
                                return true;
                            }
                            // 我方右下角在重叠范围内
                            if (x + WIDTH >= tank.x
                                    && x + WIDTH <= tank.x + WIDTH
                                    && y + HEIGHT >= tank.y
                                    && y + HEIGHT <= tank.y + HEIGHT) {
                                return true;
                            }
                        }

                        // 当我坦克是向下方向,敌方坦克是向左或右方向
                        if (tank.direction == LEFT || tank.direction == RIGHT) {
                            // 我方左下角在重叠范围内
                            // 左下角坐标 [x, y + HEIGHT]
                            if (x >= tank.x
                                    && x <= tank.x + HEIGHT
                                    && y + HEIGHT >= tank.y
                                    && y + HEIGHT <= tank.y + WIDTH) {
                                return true;
                            }
                            // 我方右下角在重叠范围内
                            // 右下角坐标 [x + WIDTH, y + HEIGHT]
                            if (x + WIDTH >= tank.x
                                    && x + WIDTH <= tank.x + HEIGHT
                                    && y + HEIGHT >= tank.y
                                    && y + HEIGHT <= tank.y + WIDTH) {
                                return true;
                            }
                        }
                    }
                }
                break;
            case LEFT:
                // 我方坦克向左,左上角坐标 [x, y]
                // 我方坦克向左,左下角坐标 [x, y + WIDTH]
                for (int i = 0; i < ALL_TANK.size(); i++) {
                    Tank tank = ALL_TANK.get(i);
                    if (tank != this) {
                        if (tank.direction == UP || tank.direction == DOWN) {
                            // 左上角
                            if (x >= tank.x
                                    && x <= tank.x + WIDTH
                                    && y >= tank.y
                                    && y <= tank.y + HEIGHT) {
                                return true;
                            }
                            // 左下角
                            if (x >= tank.x
                                    && x <= tank.x + WIDTH
                                    && y + WIDTH >= tank.y
                                    && y + WIDTH <= tank.y + HEIGHT) {
                                return true;
                            }
                        }

                        if (tank.direction == LEFT || tank.direction == RIGHT) {
                            // 左上角
                            if (x >= tank.x
                                    && x <= tank.x + HEIGHT
                                    && y >= tank.y
                                    && y <= tank.y + WIDTH) {
                                return true;
                            }
                            // 左下角
                            if (x >= tank.x
                                    && x <= tank.x + HEIGHT
                                    && y + WIDTH >= tank.y
                                    && y + WIDTH <= tank.y + WIDTH) {
                                return true;
                            }
                        }
                    }
                }
                break;

        }
        return false;
    }
}
	

优化代码

说是优化其实只是套了一层娃,分离出来一个 calcTouch 方计算是否重叠1对1作比较。

对了一个offset变量偏移量,没有偏移量会重叠一个轮子的宽度如图

在这里插入图片描述

加减偏移量主要看你往哪个方向重叠,

如上图就是向右x就要加偏移量,向左重叠就要减偏移量

向下方向重叠y加偏移量,向上方向重叠y减偏移量;

x-- 左移 x++ 右移,y++上移 y–下移;

增加偏移量后
在这里插入图片描述

package com.example.tankgame06;


import java.util.List;
import java.util.Vector;

import static com.example.tankgame04.GameConstant.*;


/**
 * @author XiaoAi
 * @date 2024/6/22 10:44
 */
public abstract class Tank {
    private int x;
    private int y;
    private int direction; // 0 1 2 3
    private int speed = 1;
    private List<Bullet> bulletList = new Vector<>(); // 子弹
    // 总宽度(x)90 高度(80)
    public final static int WIDTH = 90;
    public final static int HEIGHT = 80;
    private boolean isLive = true;
    public static final List<Tank> ALL_TANK = new Vector<>();

    public Tank() {
    }

    public Tank(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public void moveUp() {
        boolean isTouch = isTouchTank();
        if (isTouch) {
            return;
        }
        setY(this.y - speed);
    }

    public void moveRight() {
        boolean isTouch = isTouchTank();
        if (isTouch) {
            return;
        }
        setX(this.x + speed);
    }

    public void moveDown() {
        boolean isTouch = isTouchTank();
        if (isTouch) {
            return;
        }
        setY(this.y + speed);
    }

    public void moveLeft() {
        boolean isTouch = isTouchTank();
        if (isTouch) {
            return;
        }
        setX(this.x - speed);
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        if (x >= 0 && x <= TankGame06.WIDTH - Tank.WIDTH) {
            this.x = x;
        }
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        if (y >= 0 && y <= TankGame06.HEIGHT - Tank.HEIGHT) {
            this.y = y;
        }
    }
		
    // ... get/set

    public void shotTank() {
        if (!this.isLive) {
            return;
        }

        List<Bullet> bulletList = getBulletList();
        Bullet bullet = null;
        switch (getDirection()) {
            case UP:
                bullet = new Bullet(getX() + WIDTH / 2 - 2, getY() - 10, UP);
                break;
            case RIGHT:
                bullet = new Bullet(getX() + WIDTH + 10, getY() + HEIGHT / 2 + 2, RIGHT);
                break;
            case DOWN:
                bullet = new Bullet(getX() + HEIGHT / 2 + 2, getY() + WIDTH, DOWN);
                break;
            case LEFT:
                bullet = new Bullet(getX() - 10, getY() + HEIGHT / 2 + 2, LEFT);
                break;
        }
        if (bullet != null) {
            bulletList.add(bullet);
            new Thread(bullet).start();
        }
    }

    /**
     * 坦克重叠判断
     *
     * @return 是否重叠
     */
    public boolean isTouchTank() {

        int offset = 20;
        if (ALL_TANK.size() == 1) {
            return false;
        }
        return isTouch(this, ALL_TANK);
    }

    public boolean isTouch(Tank myTank, List<Tank> allTank) {
        if (allTank == null || allTank.size() == 1) {
            return false;
        }
        for (int i = 0; i < allTank.size(); i++) {
            boolean isTouch = calcTouch(myTank, allTank.get(i));
            if (isTouch) {
                return true;
            }
        }
        return false;
    }


    /**
     * 计算是否重叠
     *
     * @param tank      我方坦克
     * @param enemyTank 敌方坦克
     * @return
     */
    public boolean calcTouch(Tank tank, Tank enemyTank) {
        if (tank == null || enemyTank == null) {
            return false;
        }
        if (tank == enemyTank) {
            return false;
        }
        int x = tank.x;
        int y = tank.y;
        int offset = 20; // 重叠偏移量 一个轮子的宽度
        switch (tank.direction) {
            case UP:
                // 当我坦克是向上方向,敌方坦克是向上或向下方向
                if (enemyTank.direction == UP || enemyTank.direction == DOWN) {
                    // 当前坦克左上角的坐标在重叠的范围内
                    // 我方坦克左上角坐标 [x, y]
                    if (x >= enemyTank.x
                            && x <= enemyTank.x + WIDTH
                            && y - offset >= enemyTank.y
                            && y - offset <= enemyTank.y + HEIGHT) {
                        return true;
                    }

                    // 当前坦克右上角的坐标在重叠范围内,当我方坦克在敌方坦克的左方重叠时 我方的 x 坐标会比敌方 x 坐标小,
                    // 只判断一个左上角还是会重叠,所以要判断两个角的坐标
                    // 我方坦克右上角坐标 [x + WIDTH, y]
                    if (x + WIDTH >= enemyTank.x
                            && x <= enemyTank.x + WIDTH
                            && y - offset >= enemyTank.y
                            && y - offset <= enemyTank.y + HEIGHT) {
                        return true;
                    }
                }
                // 当我坦克是向上方向,敌方坦克是向右或向左方向
                // 敌方坦克向右等于旋转九十度高宽互换
                if (enemyTank.direction == RIGHT || enemyTank.direction == LEFT) {
                    // 当前坦克左上角的坐标在重叠的范围内
                    // 我方坦克左上角坐标 [x, y]
                    if (x >= enemyTank.x
                            && x <= enemyTank.x + HEIGHT
                            && y - offset >= enemyTank.y
                            && y - offset <= enemyTank.y + WIDTH) {
                        return true;
                    }

                    // 当前坦克右上角的坐标在重叠的范围内
                    // 我方坦克右上角坐标 [x + WIDTH, y]
                    if (x + WIDTH >= enemyTank.x
                            && x <= enemyTank.x + HEIGHT
                            && y - offset >= enemyTank.y
                            && y - offset <= enemyTank.y + WIDTH) {
                        return true;
                    }
                }


                break;
            case RIGHT:
                // 我方坦克向右,右上角坐标[x + HEIGHT, y ]
                // 我方坦克向右,左下角坐标[x + HEIGHT, y + WIDTH]

                // 当我坦克是向右方向,敌方坦克是向上或下方向
                if (enemyTank.direction == UP || enemyTank.direction == DOWN) {
                    // 当前坦克右上角的坐标在重叠的范围内
                    // 当前坦克右上角坐标 [x + HEIGHT, y ]

                    if (x + HEIGHT + offset >= enemyTank.x
                            && x + HEIGHT + offset <= enemyTank.x + WIDTH
                            && y >= enemyTank.y
                            && y <= enemyTank.y + HEIGHT) {
                        return true;
                    }
                    // 当前坦克左下角的坐标在重叠的范围内
                    // 当前坦克左下角坐标 [x + HEIGHT, y + WIDTH]
                    if (x + HEIGHT + offset >= enemyTank.x
                            && x + HEIGHT + offset <= enemyTank.x + WIDTH
                            && y + WIDTH >= enemyTank.y
                            && y + WIDTH <= enemyTank.y + HEIGHT) {
                        return true;
                    }
                }

                // 当我坦克是向右方向,敌方坦克是向左或向右方向
                if (enemyTank.direction == LEFT || enemyTank.direction == RIGHT) {
                    // 当前坦克右上角的坐标在重叠的范围内
                    // 当前坦克右上角坐标 [x + HEIGHT, y]
                    if (x + HEIGHT + offset >= enemyTank.x
                            && x + HEIGHT + offset <= enemyTank.x + HEIGHT
                            && y >= enemyTank.y
                            && y <= enemyTank.y + WIDTH) {
                        return true;
                    }
                    // 当前坦克左下角的坐标在重叠的范围内
                    // 当前坦克左下角坐标 [x + HEIGHT, y + WIDTH]
                    if (x + HEIGHT + offset >= enemyTank.x
                            && x + HEIGHT + offset <= enemyTank.x + HEIGHT
                            && y + WIDTH  >= enemyTank.y
                            && y + WIDTH <= enemyTank.y + WIDTH) {
                        return true;
                    }
                }
                break;
            case DOWN:
                // 我方坦克向下,左下角坐标 [x, y + HEIGHT]
                // 我方坦克向下,右下角坐标 [x + WIDTH, y + HEIGHT]

                // 当我坦克是向下方向,敌方坦克是向上或下方向
                if (enemyTank.direction == UP || enemyTank.direction == DOWN) {
                    // 我方左下角在重叠范围内
                    if (x >= enemyTank.x
                            && x <= enemyTank.x + WIDTH
                            && y + HEIGHT + offset >= enemyTank.y
                            && y + HEIGHT + offset <= enemyTank.y + HEIGHT) {
                        return true;
                    }
                    // 我方右下角在重叠范围内
                    if (x + WIDTH >= enemyTank.x
                            && x + WIDTH <= enemyTank.x + WIDTH
                            && y + HEIGHT + offset >= enemyTank.y
                            && y + HEIGHT + offset <= enemyTank.y + HEIGHT) {
                        return true;
                    }
                }

                // 当我坦克是向下方向,敌方坦克是向左或右方向
                if (enemyTank.direction == LEFT || enemyTank.direction == RIGHT) {
                    // 我方左下角在重叠范围内
                    // 左下角坐标 [x, y + HEIGHT]
                    if (x >= enemyTank.x
                            && x <= enemyTank.x + HEIGHT
                            && y + HEIGHT + offset >= enemyTank.y
                            && y + HEIGHT + offset <= enemyTank.y + WIDTH) {
                        return true;
                    }
                    // 我方右下角在重叠范围内
                    // 右下角坐标 [x + WIDTH, y + HEIGHT]
                    if (x + WIDTH >= enemyTank.x
                            && x + WIDTH <= enemyTank.x + HEIGHT
                            && y + HEIGHT + offset >= enemyTank.y
                            && y + HEIGHT + offset <= enemyTank.y + WIDTH) {
                        return true;
                    }
                }
                break;
            case LEFT:
                // 我方坦克向左,左上角坐标 [x, y]
                // 我方坦克向左,左下角坐标 [x, y + WIDTH]

                if (enemyTank.direction == UP || enemyTank.direction == DOWN) {
                    // 左上角
                    if (x - offset>= enemyTank.x
                            && x - offset <= enemyTank.x + WIDTH
                            && y >= enemyTank.y
                            && y <= enemyTank.y + HEIGHT) {
                        return true;
                    }
                    // 左下角
                    if (x - offset >= enemyTank.x
                            && x - offset <= enemyTank.x + WIDTH
                            && y + WIDTH >= enemyTank.y
                            && y + WIDTH <= enemyTank.y + HEIGHT) {
                        return true;
                    }
                }

                if (enemyTank.direction == LEFT || enemyTank.direction == RIGHT) {
                    // 左上角
                    if (x - offset >= enemyTank.x
                            && x - offset <= enemyTank.x + HEIGHT
                            && y >= enemyTank.y
                            && y <= enemyTank.y + WIDTH) {
                        return true;
                    }
                    // 左下角
                    if (x - offset >= enemyTank.x
                            && x - offset <= enemyTank.x + HEIGHT
                            && y + WIDTH >= enemyTank.y
                            && y + WIDTH <= enemyTank.y + WIDTH) {
                        return true;
                    }
                }

                break;

        }
        return false;
    }

}

源代码网盘链接

游戏记录使用 json字符存储对象,导入fastjson
在这里插入图片描述

链接:https://pan.baidu.com/s/1DFc8nw6BGxFTzRV4t48YFA?pwd=gth4
提取码:gth4

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值