Java实现走迷宫

在这里插入图片描述

敢于知道,因为真理使我们自由!

图形绘制-普通方法(测试)

AlgoFrame 自定义窗口类

package com.company;

import javax.swing.*;

import javax.swing.*;
import java.awt.*;

public class AlgoFrame extends JFrame {

  private int canvasWidth;
  private int canvasHeight;

  public AlgoFrame(String title, int canvasWidth, int canvasHeight) {
    super(title);
    this.canvasWidth = canvasWidth;
    this.canvasHeight = canvasHeight;

    AlgoCanvas canvas = new AlgoCanvas();
    setContentPane(canvas);
    pack();
    
    setResizable(false);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);

  }

  public AlgoFrame(String title) {
    this(title, 1024, 768);
  }

  public int getCanvasWidth() {
    return canvasWidth;
  }

  public int getCanvasHeight() {
    return canvasHeight;
  }

  private class AlgoCanvas extends JPanel {
    @Override
    public void paintComponent(Graphics g) {
      super.paintComponent(g);
      g.drawOval(50, 50, 300, 300);
    }

    @Override
    public Dimension getPreferredSize() {
      return new Dimension(canvasWidth, canvasHeight);
    }
  }
}

Main 主函数逻辑

package com.company;

import java.awt.*;

public class Main {

  public static void main(String[] args) {
    EventQueue.invokeLater(() -> {
      AlgoFrame frame = new AlgoFrame("Welcome", 500, 500);
    });

  }
}

在这里插入图片描述

图形绘制-Graphics2D法(测试)

Graphics2D好处

相关代码

package com.company;

import javax.swing.*;

import javax.swing.*;
import java.awt.*;
import java.awt.geom.Ellipse2D;

public class AlgoFrame extends JFrame {

  private int canvasWidth;
  private int canvasHeight;

  public AlgoFrame(String title, int canvasWidth, int canvasHeight) {
    super(title);
    this.canvasWidth = canvasWidth;
    this.canvasHeight = canvasHeight;

    AlgoCanvas canvas = new AlgoCanvas();
    setContentPane(canvas);
    pack();

    setResizable(false);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);

  }

  public AlgoFrame(String title) {
    this(title, 1024, 768);
  }

  public int getCanvasWidth() {
    return canvasWidth;
  }

  public int getCanvasHeight() {
    return canvasHeight;
  }

  private class AlgoCanvas extends JPanel {
    @Override
    public void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2d = (Graphics2D) g;

      int strokeWidth = 5;
      g2d.setStroke(new BasicStroke(strokeWidth));

      g2d.setColor(Color.RED);
      Ellipse2D circle = new Ellipse2D.Double(50, 50, 300, 300);
      g2d.draw(circle);

      g2d.setColor(Color.BLUE);
      Ellipse2D circle2 = new Ellipse2D.Double(60, 60, 280, 280);
      g2d.fill(circle2);
    }

    @Override
    public Dimension getPreferredSize() {
      return new Dimension(canvasWidth, canvasHeight);
    }
  }
}

在这里插入图片描述

封装-工具类

AlgoVisHelper

package com.company;

import java.awt.*;
import java.awt.geom.Ellipse2D;

public class AlgoVisHelper {
  private AlgoVisHelper() {
  }

  public static void setColor(Graphics2D g2d,Color color){
    g2d.setColor(color);
  }

  public static void setStrokeWidth(Graphics2D g2d, int w) {
    int strokeWidth = w;
    g2d.setStroke(new BasicStroke(strokeWidth,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND));
  }

  public static void strokeCircle(Graphics2D g2d,int x,int y,int r){
    Ellipse2D circle = new Ellipse2D.Double(x-r,y-r,2*r,2*r);
    g2d.draw(circle);
  };

  public static void fillCircle(Graphics2D g2d,int x,int y,int r){
    Ellipse2D circle = new Ellipse2D.Double(x-r,y-r,2*r,2*r);
    g2d.fill(circle);
  };
}

AlgoFrame

package com.company;

import javax.swing.*;

import javax.swing.*;
import java.awt.*;
import java.awt.geom.Ellipse2D;

public class AlgoFrame extends JFrame {

  private int canvasWidth;
  private int canvasHeight;

  public AlgoFrame(String title, int canvasWidth, int canvasHeight) {
    super(title);
    this.canvasWidth = canvasWidth;
    this.canvasHeight = canvasHeight;

    AlgoCanvas canvas = new AlgoCanvas();
    setContentPane(canvas);
    pack();

    setResizable(false);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);

  }

  public AlgoFrame(String title) {
    this(title, 1024, 768);
  }

  public int getCanvasWidth() {
    return canvasWidth;
  }

  public int getCanvasHeight() {
    return canvasHeight;
  }

  private class AlgoCanvas extends JPanel {
    @Override
    public void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2d = (Graphics2D) g;

      int strokeWidth = 5;
      g2d.setStroke(new BasicStroke(strokeWidth));

      AlgoVisHelper.setColor(g2d, Color.BLUE);
      AlgoVisHelper.fillCircle(g2d, canvasWidth / 2, canvasHeight / 2, 200);

      AlgoVisHelper.setColor(g2d, Color.RED);
      AlgoVisHelper.strokeCircle(g2d, canvasWidth / 2, canvasHeight / 2, 200);

    }

    @Override
    public Dimension getPreferredSize() {
      return new Dimension(canvasWidth, canvasHeight);
    }
  }
}

在这里插入图片描述

抗锯齿

package com.company;

import javax.swing.*;

import javax.swing.*;
import java.awt.*;
import java.awt.geom.Ellipse2D;

public class AlgoFrame extends JFrame {

  private int canvasWidth;
  private int canvasHeight;

  public AlgoFrame(String title, int canvasWidth, int canvasHeight) {
    super(title);
    this.canvasWidth = canvasWidth;
    this.canvasHeight = canvasHeight;

    AlgoCanvas canvas = new AlgoCanvas();
    setContentPane(canvas);
    pack();

    setResizable(false);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);

  }

  public AlgoFrame(String title) {
    this(title, 1024, 768);
  }

  public int getCanvasWidth() {
    return canvasWidth;
  }

  public int getCanvasHeight() {
    return canvasHeight;
  }

  private class AlgoCanvas extends JPanel {
    @Override
    public void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2d = (Graphics2D) g;
      //抗锯齿
      RenderingHints hints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
      g2d.addRenderingHints(hints);

      //具体绘制
      AlgoVisHelper.setStrokeWidth(g2d, 5);

      AlgoVisHelper.setColor(g2d, Color.BLUE);
      AlgoVisHelper.fillCircle(g2d, canvasWidth / 2, canvasHeight / 2, 200);

      AlgoVisHelper.setColor(g2d, Color.RED);
      AlgoVisHelper.strokeCircle(g2d, canvasWidth / 2, canvasHeight / 2, 200);

    }

    @Override
    public Dimension getPreferredSize() {
      return new Dimension(canvasWidth, canvasHeight);
    }
  }
}

双缓存

package com.company;

import javax.swing.*;

import javax.swing.*;
import java.awt.*;
import java.awt.geom.Ellipse2D;

public class AlgoFrame extends JFrame {

  private int canvasWidth;
  private int canvasHeight;

  public AlgoFrame(String title, int canvasWidth, int canvasHeight) {
    super(title);
    this.canvasWidth = canvasWidth;
    this.canvasHeight = canvasHeight;

    AlgoCanvas canvas = new AlgoCanvas();
    setContentPane(canvas);
    pack();

    setResizable(false);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);

  }

  public AlgoFrame(String title) {
    this(title, 1024, 768);
  }

  public int getCanvasWidth() {
    return canvasWidth;
  }

  public int getCanvasHeight() {
    return canvasHeight;
  }

  private class AlgoCanvas extends JPanel {
    //双缓存
    public AlgoCanvas() {
      super(true);
    }

    @Override
    public void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2d = (Graphics2D) g;
      //抗锯齿
      RenderingHints hints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
      g2d.addRenderingHints(hints);

      //具体绘制
      AlgoVisHelper.setStrokeWidth(g2d, 5);

      AlgoVisHelper.setColor(g2d, Color.BLUE);
      AlgoVisHelper.fillCircle(g2d, canvasWidth / 2, canvasHeight / 2, 200);

      AlgoVisHelper.setColor(g2d, Color.RED);
      AlgoVisHelper.strokeCircle(g2d, canvasWidth / 2, canvasHeight / 2, 200);

    }

    @Override
    public Dimension getPreferredSize() {
      return new Dimension(canvasWidth, canvasHeight);
    }
  }
}

实现测试用例

Main

package com.company;

import java.awt.*;

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

    int sceneWidth = 800;
    int sceneHeight = 800;

    int N = 10;
    Circle[] circles = new Circle[N];
    int R = 50;

    for (int i = 0; i < N; i++) {
      int x = (int) Math.random() * (sceneWidth - 2 * R) + R;
      int y = (int) Math.random() * (sceneHeight - 2 * R) + R;
      int vx = (int) (Math.random() * 11 - 5);
      int vy = (int) (Math.random() * 11 - 5);
      circles[i] = new Circle(x, y, R, vx, vy);
    }

    EventQueue.invokeLater(() -> {
      AlgoFrame frame = new AlgoFrame("Welcome", sceneWidth, sceneHeight);
      new Thread(() -> {
        while (true) {
          //绘制数据
          frame.render(circles);
          AlgoVisHelper.pause(20);
          //更新数据
          for (Circle circle : circles) {
            circle.move(0, 0, sceneWidth, sceneHeight);
          }
        }
      }).start();

    });

  }
}

Circle

package com.company;

import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ;

public class Circle {
  public int x, y;
  private int r;

  public int getR() {
    return r;
  }

  public void setR(int r) {
    this.r = r;
  }


  public int vx, vy;

  public Circle(int x, int y, int r, int vx, int vy) {
    this.x = x;
    this.y = y;
    this.setR(r);
    this.vx = vx;
    this.vy = vy;
  }

  public void move(int minx, int miny, int maxx, int maxy) {
    x += vx;
    y += vy;
    checkCollision(minx, miny, maxx, maxy);
  }

  private void checkCollision(int minx, int miny, int maxx, int maxy) {
    if (x - r < minx) {
      x = r;
      vx = -vx;
    }
    if (x + r >= maxx) {
      x = maxx - r;
      vx = -vx;
    }
    if (y - r < miny) {
      y = r;
      vy = -vy;
    }
    if (y + r >= maxy) {
      y = maxy - r;
      vy = -vy;
    }
  }

}

AlgoVisHelper

package com.company;

import java.awt.*;
import java.awt.geom.Ellipse2D;

public class AlgoVisHelper {
  private AlgoVisHelper() {
  }

  public static void setColor(Graphics2D g2d,Color color){
    g2d.setColor(color);
  }

  public static void setStrokeWidth(Graphics2D g2d, int w) {
    int strokeWidth = w;
    g2d.setStroke(new BasicStroke(strokeWidth,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND));
  }

  public static void strokeCircle(Graphics2D g2d,int x,int y,int r){
    Ellipse2D circle = new Ellipse2D.Double(x-r,y-r,2*r,2*r);
    g2d.draw(circle);
  };

  public static void fillCircle(Graphics2D g2d,int x,int y,int r){
    Ellipse2D circle = new Ellipse2D.Double(x-r,y-r,2*r,2*r);
    g2d.fill(circle);
  };

  public static void pause(int t){
    try{
      Thread.sleep(t);
    }catch (InterruptedException e){
      System.out.println("Error in sleeping!");
    }
  }
}

AlgoFrame

package com.company;

import javax.swing.*;

import javax.swing.*;
import java.awt.*;
import java.awt.geom.Ellipse2D;

public class AlgoFrame extends JFrame {

  private int canvasWidth;
  private int canvasHeight;

  public AlgoFrame(String title, int canvasWidth, int canvasHeight) {
    super(title);
    this.canvasWidth = canvasWidth;
    this.canvasHeight = canvasHeight;

    AlgoCanvas canvas = new AlgoCanvas();
    setContentPane(canvas);
    pack();

    setResizable(false);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);

  }

  public AlgoFrame(String title) {
    this(title, 1024, 768);
  }

  public int getCanvasWidth() {
    return canvasWidth;
  }

  public int getCanvasHeight() {
    return canvasHeight;
  }

  private Circle[] circles;

  public void render(Circle[] circles) {
    this.circles = circles;
    repaint();
  }

  private class AlgoCanvas extends JPanel {
    //双缓存
    public AlgoCanvas() {
      super(true);
    }

    @Override
    public void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2d = (Graphics2D) g;
      //抗锯齿
      RenderingHints hints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
      g2d.addRenderingHints(hints);

      //具体绘制
      AlgoVisHelper.setStrokeWidth(g2d, 1);
      AlgoVisHelper.setColor(g2d, Color.RED);
      for (Circle circle : circles) {
        AlgoVisHelper.strokeCircle(g2d, circle.x, circle.y, circle.getR());
      }
    }

    @Override
    public Dimension getPreferredSize() {
      return new Dimension(canvasWidth, canvasHeight);
    }
  }
}

在这里插入图片描述

MVC应用(修改和新建类 )

Main

package com.company;

import java.awt.*;

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

    int sceneWidth = 800;
    int sceneHeight = 800;

    int N = 10;

    AlgoVisualizer visualizer = new AlgoVisualizer(sceneWidth, sceneHeight, N);

  }
}

AlgoVisualizer

package com.company;

import java.awt.*;

public class AlgoVisualizer {
  private Circle[] circles;
  private AlgoFrame frame;

  public AlgoVisualizer(int sceneWidth, int sceneHeight, int N) {
    circles = new Circle[N];
    int R = 50;

    for (int i = 0; i < N; i++) {
      int x = (int) Math.random() * (sceneWidth - 2 * R) + R;
      int y = (int) Math.random() * (sceneHeight - 2 * R) + R;
      int vx = (int) (Math.random() * 11 - 5);
      int vy = (int) (Math.random() * 11 - 5);
      circles[i] = new Circle(x, y, R, vx, vy);
    }

    EventQueue.invokeLater(() -> {
      frame = new AlgoFrame("Welcome", sceneWidth, sceneHeight);
      new Thread(() -> {
        run();
      }).start();

    });
  }

  //动画逻辑
  private void run() {
    while (true) {
      //绘制数据
      frame.render(circles);
      AlgoVisHelper.pause(20);
      //更新数据
      for (Circle circle : circles) {
        circle.move(0, 0, frame.getCanvasWidth(), frame.getCanvasHeight());
      }
    }
  }

}

键盘事件(去掉Main类)

键盘按空格暂停/继续

package com.company;

import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

public class AlgoVisualizer {
  private Circle[] circles;
  private AlgoFrame frame;
  private boolean isAnimated = true;

  public AlgoVisualizer(int sceneWidth, int sceneHeight, int N) {
    circles = new Circle[N];
    int R = 30;

    for (int i = 0; i < N; i++) {
      int x = (int) Math.random() * (sceneWidth - 2 * R) + R;
      int y = (int) Math.random() * (sceneHeight - 2 * R) + R;
      int vx = (int) (Math.random() * 11 - 5);
      int vy = (int) (Math.random() * 11 - 5);
      circles[i] = new Circle(x, y, R, vx, vy);
    }

    EventQueue.invokeLater(() -> {
      frame = new AlgoFrame("Welcome", sceneWidth, sceneHeight);
      frame.addKeyListener(new AlgoKeyListener());
      new Thread(() -> {
        run();
      }).start();

    });
  }

  //动画逻辑
  private void run() {
    while (true) {
      //绘制数据
      frame.render(circles);
      AlgoVisHelper.pause(20);
      //更新数据
      if (isAnimated) {
        for (Circle circle : circles) {
          circle.move(0, 0, frame.getCanvasWidth(), frame.getCanvasHeight());
        }
      }

    }
  }

  private class AlgoKeyListener extends KeyAdapter {
    @Override
    public void keyReleased(KeyEvent event) {
      if (event.getKeyChar() == ' ') {
        isAnimated = !isAnimated;
      }
    }
  }

  public static void main(String[] args) {

    int sceneWidth = 500;
    int sceneHeight = 500;

    int N = 10;

    AlgoVisualizer visualizer = new AlgoVisualizer(sceneWidth, sceneHeight, N);

  }

}

鼠标事件

Circle

package com.company;

import java.awt.*;

public class Circle {
  public int x, y;
  private int r;
  public boolean isFilled = false;

  public int getR() {
    return r;
  }

  public void setR(int r) {
    this.r = r;
  }


  public int vx, vy;

  public Circle(int x, int y, int r, int vx, int vy) {
    this.x = x;
    this.y = y;
    this.setR(r);
    this.vx = vx;
    this.vy = vy;
  }

  public void move(int minx, int miny, int maxx, int maxy) {
    x += vx;
    y += vy;
    checkCollision(minx, miny, maxx, maxy);
  }

  private void checkCollision(int minx, int miny, int maxx, int maxy) {
    if (x - r < minx) {
      x = r;
      vx = -vx;
    }
    if (x + r >= maxx) {
      x = maxx - r;
      vx = -vx;
    }
    if (y - r < miny) {
      y = r;
      vy = -vy;
    }
    if (y + r >= maxy) {
      y = maxy - r;
      vy = -vy;
    }


  }

  public boolean contain(Point p) {
    return (x - p.x) * (x - p.x) + (y - p.y) * (y - p.y) <= r * r;
  }

}

AlgoVisHelper

package com.company;

import java.awt.*;
import java.awt.geom.Ellipse2D;

public class AlgoVisHelper {
  private AlgoVisHelper() {
  }

  public static void setColor(Graphics2D g2d,Color color){
    g2d.setColor(color);
  }

  public static void setStrokeWidth(Graphics2D g2d, int w) {
    int strokeWidth = w;
    g2d.setStroke(new BasicStroke(strokeWidth,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND));
  }

  public static void strokeCircle(Graphics2D g2d,int x,int y,int r){
    Ellipse2D circle = new Ellipse2D.Double(x-r,y-r,2*r,2*r);
    g2d.draw(circle);
  };

  public static void fillCircle(Graphics2D g2d,int x,int y,int r){
    Ellipse2D circle = new Ellipse2D.Double(x-r,y-r,2*r,2*r);
    g2d.fill(circle);
  };

  public static void pause(int t){
    try{
      Thread.sleep(t);
    }catch (InterruptedException e){
      System.out.println("Error in sleeping!");
    }
  }
}

AlgoVisualizer

package com.company;

import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class AlgoVisualizer {
  private Circle[] circles;
  private AlgoFrame frame;
  private boolean isAnimated = true;

  public AlgoVisualizer(int sceneWidth, int sceneHeight, int N) {
    circles = new Circle[N];
    int R = 30;

    for (int i = 0; i < N; i++) {
      int x = (int) Math.random() * (sceneWidth - 2 * R) + R;
      int y = (int) Math.random() * (sceneHeight - 2 * R) + R;
      int vx = (int) (Math.random() * 11 - 5);
      int vy = (int) (Math.random() * 11 - 5);
      circles[i] = new Circle(x, y, R, vx, vy);
    }

    EventQueue.invokeLater(() -> {
      frame = new AlgoFrame("Welcome", sceneWidth, sceneHeight);
      frame.addKeyListener(new AlgoKeyListener());
      frame.addMouseListener(new AlgoMouseListener());
      new Thread(() -> {
        run();
      }).start();

    });
  }

  //动画逻辑
  private void run() {
    while (true) {
      //绘制数据
      frame.render(circles);
      AlgoVisHelper.pause(20);
      //更新数据
      if (isAnimated) {
        for (Circle circle : circles) {
          circle.move(0, 0, frame.getCanvasWidth(), frame.getCanvasHeight());
        }
      }

    }
  }

  private class AlgoMouseListener extends MouseAdapter{
    @Override
    public void mousePressed(MouseEvent event) {
      event.translatePoint(0,-(frame.getBounds().height-frame.getCanvasHeight()));
      for(Circle circle:circles){
        if(circle.contain(event.getPoint())){
          circle.isFilled = !circle.isFilled;
        }
      }
    }
  }


  private class AlgoKeyListener extends KeyAdapter {
    @Override
    public void keyReleased(KeyEvent event) {
      if (event.getKeyChar() == ' ') {
        isAnimated = !isAnimated;
      }
    }
  }

  public static void main(String[] args) {

    int sceneWidth = 500;
    int sceneHeight = 500;

    int N = 10;

    AlgoVisualizer visualizer = new AlgoVisualizer(sceneWidth, sceneHeight, N);

  }

}

AlgoFrame

package com.company;

import javax.swing.*;

import java.awt.*;

public class AlgoFrame extends JFrame {

  private int canvasWidth;
  private int canvasHeight;

  public AlgoFrame(String title, int canvasWidth, int canvasHeight) {
    super(title);
    this.canvasWidth = canvasWidth;
    this.canvasHeight = canvasHeight;

    AlgoCanvas canvas = new AlgoCanvas();
    setContentPane(canvas);
    pack();

    setResizable(false);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);

  }

  public AlgoFrame(String title) {
    this(title, 1024, 768);
  }

  public int getCanvasWidth() {
    return canvasWidth;
  }

  public int getCanvasHeight() {
    return canvasHeight;
  }

  private Circle[] circles;

  public void render(Circle[] circles) {
    this.circles = circles;
    repaint();
  }

  private class AlgoCanvas extends JPanel {
    //双缓存
    public AlgoCanvas() {
      super(true);
    }

    @Override
    public void paintComponent(Graphics g) {
      super.paintComponent(g);
      Graphics2D g2d = (Graphics2D) g;
      //抗锯齿
      RenderingHints hints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
      g2d.addRenderingHints(hints);

      //具体绘制
      AlgoVisHelper.setStrokeWidth(g2d, 1);
      AlgoVisHelper.setColor(g2d, Color.RED);
      for (Circle circle : circles) {
        if (!circle.isFilled) {
          AlgoVisHelper.strokeCircle(g2d, circle.x, circle.y, circle.getR());

        } else {
          AlgoVisHelper.fillCircle(g2d, circle.x, circle.y, circle.getR());

        }
      }
    }

    @Override
    public Dimension getPreferredSize() {
      return new Dimension(canvasWidth, canvasHeight);
    }
  }
}

持续更新中…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值